├── ch19 ├── GeneratedCode.txt ├── TestInput.txt ├── testinput.small ├── Syntax.txt ├── testinput.big ├── syntax.small └── README ├── ch07 ├── ch07s046.c ├── ch07s004.c ├── ch07s023.c ├── ch07s047.c ├── ch07s030.c ├── ch07s044.c ├── ch07s040.c ├── ch07s045.c ├── ch07s012.c ├── ch07s039.c ├── ch07s015.c ├── ch07s043.c ├── ch07s026.c ├── ch07s034.c ├── ch07s008.c ├── ch07s035.c ├── ch07s041.c ├── ch07s005.c ├── ch07s042.c ├── ch07s007.c ├── ch07s022.c ├── ch07s038.c ├── ch07s009.c ├── ch07s031.c ├── ch07s032.c ├── ch07s033.c ├── ch07s049.c ├── ch07s016.c ├── ch07s006.c ├── ch07s002.c ├── ch07s025.c ├── ch07s036.c ├── ch07s010.c ├── ch07s020.c ├── ch07s011.c ├── ch07s001.c ├── ch07s013.c ├── ch07s014.c ├── ch07s037.c ├── ch07s017.c ├── ch07s003.c ├── ch07s019.c ├── ch07s027.c ├── ch07s018.c ├── ch07s024.c ├── ch07s021.c └── ch07s048.c ├── ch20 ├── calcgram ├── copygram ├── grammar ├── quine.c ├── genhelp ├── help ├── tee.c ├── limn.c ├── sandra.c └── ascebc.txt ├── ch11 ├── C11_004.c ├── C11_005.c ├── C11_001.c ├── C11_006.c ├── C11_011.c ├── C11_012.c ├── C11_009.c ├── C11_013.c ├── C11_002.c ├── C11_003.c ├── C11_014.c ├── C11_007.c ├── C11_008.c ├── C11_010.c ├── c11_019.c ├── strarr.h ├── stack.h ├── queue.h ├── clist.h ├── C11_016.c ├── deque.h ├── c11_022.c ├── c11_020.c ├── heap.h ├── c11_017.c └── c11_015.c ├── ch13 ├── DCSRLIC.TXT ├── SINT.C ├── MTRAND.H ├── DOUBLE.C ├── STRINGS.C ├── INTELTYP.H ├── BARPROTO.H ├── CPPCOMP.H ├── DISTRIBS.H ├── COMPOBJ.H ├── COMPSTR.H ├── SICOMP.H ├── DCOMP.H ├── STRCOMP.H └── KEYXFRM.C ├── ch10 ├── hello.c ├── Makefile ├── fib1.c ├── fact3.c ├── fact1.c ├── fib3.c ├── fib2.c ├── tok1.c ├── gcd3.c ├── fact2.c ├── tok2.c ├── gcd2.c ├── gcd1.c ├── tok3.c └── search.c ├── ch09 ├── README └── asm.asm ├── ch16 ├── topsort.h ├── adjmatrix.h ├── adjlist.h ├── dfsfuncs.h ├── mstree.h ├── testing3.cbb ├── pqueue.h ├── graphprv.h ├── dfsfuncs.c ├── testing5.cbb ├── testing4.cbb ├── README ├── topsort.c └── testing2.cbb ├── ch25 └── NoSource ├── ch08 ├── CH08_05.C ├── CH08_03.C ├── CH08_01.C ├── CH08_02.C ├── CH08_04.C └── MEMTRKMN.C ├── ch04 ├── Listing06.c ├── Listing05.c ├── Listing02.c ├── Listing01.c ├── Listing03.c ├── Listing04.c └── Listing07.c ├── ch03 ├── Makefile ├── README ├── refs └── bubble.c ├── ch02 └── obscure.c ├── ch23 ├── proto.html └── cgi.h ├── Bonus ├── README └── CHEAT ├── ch17 └── mtest1.mat ├── ch18 ├── accel1.pid ├── accel2.pid ├── ionly.pid ├── id.pid ├── pid.pid ├── fax.h ├── step.pid ├── chekline.c └── parity.c ├── ch06 ├── getcols.c ├── csvwrite.c ├── README ├── getwords.c ├── csvburst.c ├── time_t.c ├── inifetch.c └── binio.c ├── README.md ├── ch24 ├── ch24e.c └── ch24Drft.c ├── ch15 ├── del_tuple.c ├── makefile ├── add_tuple.c ├── get_range_min.c ├── get_range_max.c ├── next_node.c ├── previous_node.c └── get_node_list.c ├── ch14 └── trie_extra.c └── ch22 ├── Index.txt ├── cuc.c ├── uuc.c ├── w_cups.h ├── u_cups.h ├── ctc.c ├── wuc.c ├── utc.c └── cus.c /ch19/GeneratedCode.txt: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /ch07/ch07s046.c: -------------------------------------------------------------------------------- 1 | char *p; 2 | -------------------------------------------------------------------------------- /ch19/TestInput.txt: -------------------------------------------------------------------------------- 1 | c+ 2 | 3 | -------------------------------------------------------------------------------- /ch07/ch07s004.c: -------------------------------------------------------------------------------- 1 | #pragma warn -aus 2 | -------------------------------------------------------------------------------- /ch07/ch07s023.c: -------------------------------------------------------------------------------- 1 | free(NULL); 2 | -------------------------------------------------------------------------------- /ch07/ch07s047.c: -------------------------------------------------------------------------------- 1 | strcpy(p, q); 2 | -------------------------------------------------------------------------------- /ch19/testinput.small: -------------------------------------------------------------------------------- 1 | c+ 2 | 3 | -------------------------------------------------------------------------------- /ch07/ch07s030.c: -------------------------------------------------------------------------------- 1 | #define PRINT(x) printf x 2 | -------------------------------------------------------------------------------- /ch07/ch07s044.c: -------------------------------------------------------------------------------- 1 | puts("This is correct."); 2 | -------------------------------------------------------------------------------- /ch07/ch07s040.c: -------------------------------------------------------------------------------- 1 | assert(fabs(hour) > DBL_MIN); 2 | -------------------------------------------------------------------------------- /ch07/ch07s045.c: -------------------------------------------------------------------------------- 1 | puts("This is incorrect."); 2 | -------------------------------------------------------------------------------- /ch07/ch07s012.c: -------------------------------------------------------------------------------- 1 | for(i = 0; i < numelems - 1; i++) 2 | -------------------------------------------------------------------------------- /ch07/ch07s039.c: -------------------------------------------------------------------------------- 1 | if(fabs(hour) > DBL_MIN) 2 | /* ... */ 3 | -------------------------------------------------------------------------------- /ch20/calcgram: -------------------------------------------------------------------------------- 1 | LeftOp D 2 | Operator S 1 3 | RightOp D 4 | 5 | -------------------------------------------------------------------------------- /ch07/ch07s015.c: -------------------------------------------------------------------------------- 1 | if(NULL = root->left) 2 | { 3 | /* ... */ 4 | -------------------------------------------------------------------------------- /ch07/ch07s043.c: -------------------------------------------------------------------------------- 1 | char dummy[sizeof(FOO) == sizeof(BAR) ? 1 : -1]; 2 | -------------------------------------------------------------------------------- /ch20/copygram: -------------------------------------------------------------------------------- 1 | InFile S 255 2 | OutFile S 255 3 | -overwrite 4 | 5 | -------------------------------------------------------------------------------- /ch07/ch07s026.c: -------------------------------------------------------------------------------- 1 | int GetLoginNameFromUser(char buffer[100]) 2 | /* ... */ 3 | -------------------------------------------------------------------------------- /ch07/ch07s034.c: -------------------------------------------------------------------------------- 1 | #ifndef NDEBUG 2 | DebugDumpList(&Root); 3 | #endif 4 | -------------------------------------------------------------------------------- /ch07/ch07s008.c: -------------------------------------------------------------------------------- 1 | foo = bar(baz); 2 | if(baz == 9) 3 | foo = 13.4; 4 | -------------------------------------------------------------------------------- /ch07/ch07s035.c: -------------------------------------------------------------------------------- 1 | enum { DEBUG = 0 }; 2 | 3 | if(DEBUG) 4 | printf(.... 5 | -------------------------------------------------------------------------------- /ch07/ch07s041.c: -------------------------------------------------------------------------------- 1 | int foo(char *bar) 2 | { 3 | assert(bar); 4 | /* ... */ 5 | } 6 | -------------------------------------------------------------------------------- /ch07/ch07s005.c: -------------------------------------------------------------------------------- 1 | void sink(void *p, int i) 2 | { 3 | if(i > 0) 4 | sink(p, 0); 5 | } 6 | -------------------------------------------------------------------------------- /ch07/ch07s042.c: -------------------------------------------------------------------------------- 1 | int foo(char *bar) 2 | { 3 | assert(bar != NULL); 4 | /* ... */ 5 | } 6 | -------------------------------------------------------------------------------- /ch11/C11_004.c: -------------------------------------------------------------------------------- 1 | int GetOrders(ORDER_LINE OrderArray[], 2 | size_t MaxEntries) 3 | -------------------------------------------------------------------------------- /ch11/C11_005.c: -------------------------------------------------------------------------------- 1 | int GetOrders(ORDER_LINE *OrderArray, 2 | size_t MaxEntries) 3 | -------------------------------------------------------------------------------- /ch13/DCSRLIC.TXT: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eliben/c-unleashed-book-souce-code/HEAD/ch13/DCSRLIC.TXT -------------------------------------------------------------------------------- /ch11/C11_001.c: -------------------------------------------------------------------------------- 1 | #define MAX_ORDER_ENTRIES 16 2 | 3 | ORDER_LINE OrderLine[MAX_ORDER_ENTRIES] = {0}; 4 | -------------------------------------------------------------------------------- /ch19/Syntax.txt: -------------------------------------------------------------------------------- 1 | expression ::= this that # 2 | this ::= "a" | "b" | "c" | "x" # 3 | that ::= "+" [genlt] # 4 | -------------------------------------------------------------------------------- /ch19/testinput.big: -------------------------------------------------------------------------------- 1 | a + b - c 2 | a = 0 3 | b = 2 4 | c = a + b 5 | a b 6 | 7 | -------------------------------------------------------------------------------- /ch20/grammar: -------------------------------------------------------------------------------- 1 | -internal 2 | InFile S 255 3 | OutFile S 255 4 | LogFile S 255 5 | HelpFile S 255 6 | 7 | -------------------------------------------------------------------------------- /ch20/quine.c: -------------------------------------------------------------------------------- 1 | char*f="char *f=%c%s%c;main(){printf(f,34,f,34,10);}%c"; 2 | main(){printf(f,34,f,34,10);} 3 | -------------------------------------------------------------------------------- /ch10/hello.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int 4 | main(void) { 5 | printf("hello, world!\n"); 6 | return 0; 7 | } 8 | -------------------------------------------------------------------------------- /ch19/syntax.small: -------------------------------------------------------------------------------- 1 | expression ::= this that # 2 | this ::= "a" | "b" | "c" | "x" # 3 | that ::= "+" [genlt] # 4 | -------------------------------------------------------------------------------- /ch09/README: -------------------------------------------------------------------------------- 1 | Editor's Note: If you have problems compiling this, have a close look at the very first line of the file. 2 | -------------------------------------------------------------------------------- /ch11/C11_006.c: -------------------------------------------------------------------------------- 1 | #define MAX_AGE 130 2 | #define NUM_GENDERS 2 3 | 4 | double Loading[MAX_AGE][NUM_GENDERS] = {0}; 5 | -------------------------------------------------------------------------------- /ch07/ch07s007.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(void) 4 | { 5 | printf("Hello world\n"); 6 | return 0; 7 | } 8 | -------------------------------------------------------------------------------- /ch07/ch07s022.c: -------------------------------------------------------------------------------- 1 | while(p->Next != NULL) 2 | { 3 | free(p); 4 | free(p->Data); 5 | p = p->Next; 6 | } 7 | -------------------------------------------------------------------------------- /ch07/ch07s038.c: -------------------------------------------------------------------------------- 1 | double CalcMetresPerSecond(double miles, double hour) 2 | { 3 | return miles * 0.447 / hour; 4 | } 5 | -------------------------------------------------------------------------------- /ch16/topsort.h: -------------------------------------------------------------------------------- 1 | /* topsort.h */ 2 | 3 | #include "graphs.h" 4 | 5 | int TopologicalSort(struct Graph * G, int ** sorted); 6 | -------------------------------------------------------------------------------- /ch07/ch07s009.c: -------------------------------------------------------------------------------- 1 | /* Care! Several bugs here! */ 2 | char *strdup(char *s) 3 | { 4 | return strcpy(malloc(strlen(s)), s); 5 | } 6 | -------------------------------------------------------------------------------- /ch25/NoSource: -------------------------------------------------------------------------------- 1 | Chapter 25 does not contain any example source code. 2 | 3 | If it did, it would fill the CD-ROM easily, let alone the book. 4 | 5 | -------------------------------------------------------------------------------- /ch11/C11_011.c: -------------------------------------------------------------------------------- 1 | for(i = 0; i < OUTER; i++) 2 | { 3 | for(j = 0; j < INNER; i++) 4 | { 5 | total += array[i][j]; 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /ch11/C11_012.c: -------------------------------------------------------------------------------- 1 | int Cube[3][8] = 2 | { 3 | { 0, 1, 1, 0, 0, 1, 1, 0 }, 4 | { 0, 0, 1, 1, 0, 0, 1, 1 }, 5 | { 0, 0, 0, 0, 1, 1, 1, 1 } 6 | }; 7 | -------------------------------------------------------------------------------- /ch07/ch07s031.c: -------------------------------------------------------------------------------- 1 | 2 | /* ... some code ... */ 3 | 4 | PRINT(("foo = %s, bar = %d, baz = %f", foo, bar, baz)); 5 | 6 | /* ... code continues ... */ 7 | 8 | -------------------------------------------------------------------------------- /ch07/ch07s032.c: -------------------------------------------------------------------------------- 1 | CF_CODE({) 2 | CF_CODE( int i); 3 | CF_CODE( for(i = 0; i < 10; i++)) 4 | CF_CODE( F_FOLLOW2("arr[%d] = [%d]\n", i, arr[i]);) 5 | CF_CODE(}) 6 | -------------------------------------------------------------------------------- /ch07/ch07s033.c: -------------------------------------------------------------------------------- 1 | #ifdef CFOLLOW_ON__ 2 | { 3 | int i; 4 | for(i = 0; i < 10; i++) 5 | F_FOLLOW2("arr[%d] = [%d]\n", i, arr[i]); 6 | } 7 | #endif 8 | -------------------------------------------------------------------------------- /ch11/C11_009.c: -------------------------------------------------------------------------------- 1 | void PopulateLoadingArray(double Loading[][NUM_GENDERS], 2 | size_t MaxAge, 3 | size_t NumGenders) 4 | -------------------------------------------------------------------------------- /ch07/ch07s049.c: -------------------------------------------------------------------------------- 1 | #define SWAP(x, y) do{unsigned long tmp;\ 2 | tmp = x;\ 3 | x = y;\ 4 | y = tmp;} while(0) 5 | -------------------------------------------------------------------------------- /ch07/ch07s016.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | int main(void) 4 | { 5 | char *s; 6 | strcpy(s, "Hello world!"); 7 | printf("%s\n", s); 8 | return 0; 9 | } 10 | -------------------------------------------------------------------------------- /ch07/ch07s006.c: -------------------------------------------------------------------------------- 1 | size_t len = 0; 2 | char buffer[1024]; 3 | 4 | sink(&len, 0); 5 | if(fgets(buffer, sizeof buffer, stdin) != NULL) 6 | { 7 | len = strlen(buffer); 8 | /* ... */ 9 | -------------------------------------------------------------------------------- /ch09/asm.asm: -------------------------------------------------------------------------------- 1 | 2 | * this is a comment 3 | 4 | 5 | 6 | LOADAI 10 7 | :label 8 | PRINTA 9 | ADDA 1 10 | 11 | COMPAI 15 12 | BLT label 13 | 14 | BREAK 15 | NOP 16 | 17 | -------------------------------------------------------------------------------- /ch10/Makefile: -------------------------------------------------------------------------------- 1 | CFLAGS="-ansi -pedantic -Wall -O2 -pipe" 2 | 3 | ALL = fact1 fact2 fact3 fib1 fib2 fib3 gcd1 gcd2 gcd3 hello search tok1 tok2 tok3 4 | 5 | all: $(ALL) 6 | 7 | clean: 8 | rm -f $(ALL) 9 | -------------------------------------------------------------------------------- /ch07/ch07s002.c: -------------------------------------------------------------------------------- 1 | typedef struct FOO 2 | { 3 | unsigned int i: 1; 4 | unsigned int j: 1; 5 | } FOO; 6 | 7 | FOO foo; 8 | 9 | unsigned int *p; 10 | 11 | p = &foo.j; 12 | -------------------------------------------------------------------------------- /ch16/adjmatrix.h: -------------------------------------------------------------------------------- 1 | /* adjmatrix.h */ 2 | 3 | #ifndef ADJMATRIX_H 4 | #define ADJMATRIX_H 5 | 6 | #include "graphprv.h" 7 | 8 | extern struct Graph_Spec AdjMatrix_Spec; 9 | 10 | #endif 11 | -------------------------------------------------------------------------------- /ch07/ch07s025.c: -------------------------------------------------------------------------------- 1 | int GetLoginNameFromUser(char *buffer) 2 | { 3 | int Result = 0; 4 | if(fgets(buffer, sizeof buffer, stdin) == NULL) 5 | { 6 | Result = -1; 7 | } 8 | return Result; 9 | } 10 | -------------------------------------------------------------------------------- /ch08/CH08_05.C: -------------------------------------------------------------------------------- 1 | /* Listing 8.5 */ 2 | 3 | FOO f = {0}; 4 | FOO *p; 5 | 6 | p = malloc(n * sizeof *p); 7 | if(p != NULL) 8 | { 9 | for(i = 0; i < N; i++) 10 | p[i] = f; 11 | } 12 | -------------------------------------------------------------------------------- /ch07/ch07s036.c: -------------------------------------------------------------------------------- 1 | char *p; 2 | 3 | p = malloc(len); 4 | 5 | foomem(p); 6 | 7 | /* ... */ 8 | } 9 | 10 | void foomem(char *p) 11 | { 12 | assert(p != NULL); 13 | dosomethingwith(p); 14 | } 15 | -------------------------------------------------------------------------------- /ch11/C11_013.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | /* ... */ 4 | 5 | T *p; 6 | p = malloc(N * sizeof *p); 7 | if(p != NULL) 8 | { 9 | /* we have our array, and may now use it for storage */ 10 | } 11 | -------------------------------------------------------------------------------- /ch07/ch07s010.c: -------------------------------------------------------------------------------- 1 | int CalcTotal(int *arr, size_t numelems) 2 | { 3 | size_t i; 4 | int total = 0; 5 | 6 | for(i = 0; i <= numelems; i++) 7 | { 8 | total += *arr++; 9 | } 10 | return total; 11 | } 12 | -------------------------------------------------------------------------------- /ch07/ch07s020.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(void) 4 | { 5 | char *s = "string"; 6 | int d = 42; 7 | double f = 3.14; 8 | printf("String is %s, int is %d, double is %f\n"); 9 | return 0; 10 | } 11 | -------------------------------------------------------------------------------- /ch07/ch07s011.c: -------------------------------------------------------------------------------- 1 | int CalcDiffSum(int *arr, size_t numelems) 2 | { 3 | int Sum = 0; 4 | size_t i; 5 | for(i = 0; i < numelems; i++) 6 | { 7 | Sum += *arr - *(arr + 1); 8 | } 9 | 10 | return Sum; 11 | } 12 | -------------------------------------------------------------------------------- /ch13/SINT.C: -------------------------------------------------------------------------------- 1 | /* 2 | ** The proper usage and copyright information for 3 | ** this software is covered in DSCRLic.TXT 4 | ** This code is Copyright 1999 by Dann Corbit 5 | */ 6 | 7 | #define ETYPE_SIGNED_INT 8 | #include "allsort.h" 9 | -------------------------------------------------------------------------------- /ch07/ch07s001.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(void) 4 | { 5 | unsigned int count = 0; 6 | while(getchar() != EOF) 7 | { 8 | ++count; 9 | } 10 | printf("Character count is %u\n", count); 11 | return 0; 12 | } 13 | -------------------------------------------------------------------------------- /ch07/ch07s013.c: -------------------------------------------------------------------------------- 1 | void WriteCharacterSet(char *filename) 2 | { 3 | unsigned char ch; 4 | FILE *fp = fopen(filename, "wb"); 5 | for(ch = 0; ch < 256; ch++) 6 | { 7 | fwrite(&ch, 1, 1, fp); 8 | } 9 | fclose(fp); 10 | } 11 | -------------------------------------------------------------------------------- /ch07/ch07s014.c: -------------------------------------------------------------------------------- 1 | NODE *AddNode(NODE *root, char *data) 2 | { 3 | diff = strcmp(data, root->data); 4 | if(diff > 0) 5 | { 6 | if(root->left = NULL) 7 | { 8 | root->left = malloc(sizeof *root->left); 9 | 10 | /* ... */ 11 | -------------------------------------------------------------------------------- /ch07/ch07s037.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main(void) 5 | { 6 | char buff[32]; 7 | printf("Type your name\n"); 8 | assert(NULL != fgets(buff, sizeof buff, stdin)); 9 | printf("Your name is %s\n", buff); 10 | return 0; 11 | } 12 | -------------------------------------------------------------------------------- /ch07/ch07s017.c: -------------------------------------------------------------------------------- 1 | /* caution - gets() is an unsafe function. Never use it */ 2 | #include 3 | 4 | int main(void) 5 | { 6 | char s[13]; 7 | printf("Please type in your name\n"); 8 | gets(s); 9 | printf("Your name is %s\n", s); 10 | return 0; 11 | } 12 | -------------------------------------------------------------------------------- /ch11/C11_002.c: -------------------------------------------------------------------------------- 1 | int GetOrders(ORDER_LINE OrderArray[MAX_ORDER_ENTRIES]) 2 | { 3 | size_t i; 4 | int GotAnOrder = 1; 5 | for(i = 0; i < MAX_ORDER_ENTRIES && GotAnOrder; i++) 6 | { 7 | GotAnOrder = GetOneOrder(&OrderArray[i]); 8 | } 9 | return --i; 10 | } 11 | -------------------------------------------------------------------------------- /ch16/adjlist.h: -------------------------------------------------------------------------------- 1 | /* adjlist.h */ 2 | 3 | #ifndef ADJLIST_H 4 | #define ADJLIST_H 5 | 6 | #include "graphprv.h" 7 | 8 | struct Graph_AdjList { 9 | int Cost; 10 | int Destination; 11 | struct Graph_AdjList * Next; 12 | }; 13 | 14 | extern struct Graph_Spec AdjList_Spec; 15 | 16 | #endif 17 | -------------------------------------------------------------------------------- /ch11/C11_003.c: -------------------------------------------------------------------------------- 1 | int GetOrders(ORDER_LINE OrderArray[MAX_ORDER_ENTRIES], 2 | size_t MaxEntries) 3 | { 4 | size_t i; 5 | int GotAnOrder = 1; 6 | for(i = 0; i < MaxEntries && GotAnOrder; i++) 7 | { 8 | GotAnOrder = GetOneOrder(&OrderArray[i]); 9 | } 10 | return --i; 11 | } 12 | -------------------------------------------------------------------------------- /ch11/C11_014.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | /* ... */ 4 | 5 | T *tmp; 6 | tmp = realloc(p, NewNumElems * sizeof *p); 7 | if(tmp != NULL) 8 | { 9 | /* the resizing worked */ 10 | p = tmp; 11 | } 12 | else 13 | { 14 | /* The resizing didn't work, p still points to the 15 | * old data. 16 | */ 17 | } 18 | -------------------------------------------------------------------------------- /ch04/Listing06.c: -------------------------------------------------------------------------------- 1 | int resolve_year(int year2dig, int yearnow) 2 | { 3 | int result = yearnow - yearnow%100 + year2dig; 4 | 5 | if (result >= yearnow) { 6 | if (result > yearnow+50) 7 | result -= 100; 8 | } else { 9 | if (result <= yearnow-50) 10 | result += 100; 11 | } 12 | 13 | return result; 14 | } 15 | -------------------------------------------------------------------------------- /ch07/ch07s003.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main(void) 5 | { 6 | size_t len = 0; 7 | char buffer[1024] = {0}; 8 | if(fgets(buffer, sizeof buffer, stdin) != NULL) 9 | { 10 | len = strlen(buffer); 11 | printf("The input string is %u bytes long.\n", 12 | (unsigned)len); 13 | } 14 | 15 | return 0; 16 | } 17 | -------------------------------------------------------------------------------- /ch08/CH08_03.C: -------------------------------------------------------------------------------- 1 | /* Listing 8.3 */ 2 | 3 | static char *buffer = NULL; 4 | static size_t bufsize = 0; 5 | while(strlen(s) >= bufsize) 6 | 7 | p = realloc(buffer, bufsize * 2); 8 | if(p != NULL) 9 | { 10 | bufsize *= 2; 11 | buffer = p; 12 | } 13 | else 14 | { 15 | printf("er...now what?\n"); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /ch03/Makefile: -------------------------------------------------------------------------------- 1 | 2 | # important: compile with optimizations off 3 | 4 | all: bubble speed 5 | 6 | speed: speed.c 7 | gcc -ansi -W -Wall -Wno-unused -lm -o speed speed.c 8 | 9 | bubble.o: bubble.c 10 | gcc -pg -c -ansi -W -Wall -Wno-unused bubble.c 11 | 12 | bubble: bubble.o 13 | gcc -pg bubble.o -o bubble 14 | 15 | clean: 16 | -rm -f speed bubble *.o gmon.out 17 | 18 | -------------------------------------------------------------------------------- /ch11/C11_007.c: -------------------------------------------------------------------------------- 1 | void PopulateLoadingArray(double **Loading, 2 | size_t MaxAge, 3 | size_t NumGenders) 4 | { 5 | size_t Age, Gender; 6 | for(Age = 0; Age < MaxAge; Age++) 7 | { 8 | for(Gender = 0; Gender < NumGenders; Gender++) 9 | { 10 | Loading[Age][Gender] = CalcLoading(Age, Gender); 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /ch02/obscure.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #define P printf 4 | #define I atoi 5 | int main(int a,char*v 6 | []){int r=7, i;if(a>1 7 | ) r=I(v[1]); if(r<=0) 8 | r=5;if(r%2==0)++r;for 9 | (i=0; i 2 | #include 3 | 4 | int main(void) 5 | { 6 | clock_t start, end; 7 | 8 | start = clock(); 9 | 10 | /* The code you want timed goes here */ 11 | 12 | end = clock(); 13 | 14 | printf("Interval = %.2f seconds\n", (double)(end-start) / 15 | (double)CLOCKS_PER_SEC); 16 | return 0; 17 | } 18 | 19 | -------------------------------------------------------------------------------- /ch11/C11_008.c: -------------------------------------------------------------------------------- 1 | void PopulateLoadingArray(double **Loading, 2 | size_t MaxAge, 3 | size_t NumGenders) 4 | { 5 | size_t Age, Gender; 6 | 7 | for(Age = 0; Age < MaxAge; Age++) 8 | { 9 | for(Gender = 0; Gender < NumGenders; Gender++) 10 | 11 | **(Loading + Age * MaxAge + Gender) = 12 | CalcLoading(Age, Gender); 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /ch07/ch07s019.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(void) 4 | { 5 | char CharacterSet[128] = {0}; /* init array to all 0 */ 6 | int ch; 7 | int i; 8 | 9 | while((ch = getchar()) != EOF) 10 | { 11 | ++CharacterSet[ch]; 12 | } 13 | 14 | printf("Char Frequency\n"); 15 | printf("---- ---------\n"); 16 | for(i = 0; i < sizeof CharacterSet; i++) 17 | { 18 | printf("%3d %d\n", i, CharacterSet[i]); 19 | } 20 | return 0; 21 | } 22 | -------------------------------------------------------------------------------- /ch07/ch07s027.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int foo(char *p) 4 | { 5 | return (int)sizeof(p); 6 | } 7 | 8 | int bar(char s[100]) 9 | { 10 | return (int)sizeof(s); 11 | } 12 | 13 | int main(void) 14 | { 15 | char baz[100]; 16 | 17 | printf("sizeof char[100] in main() = %d\n", 18 | (int)sizeof baz); 19 | printf("sizeof char * in foo() = %d\n", foo(baz)); 20 | printf("sizeof char[100] in bar() = %d\n", bar(baz)); 21 | return 0; 22 | } 23 | -------------------------------------------------------------------------------- /ch07/ch07s018.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main(void) 5 | { 6 | char Name[12]; 7 | char First[12]; 8 | char Second[12]; 9 | 10 | printf("First name?\n"); 11 | fgets(First, sizeof First, stdin); 12 | printf("Last name?\n"); 13 | fgets(Second, sizeof Second, stdin); 14 | 15 | strcat(Name, First); 16 | strcat(Name, " "); 17 | strcat(Name, Second); 18 | 19 | printf("Full name: %s\n", Name); 20 | 21 | return 0; 22 | } 23 | -------------------------------------------------------------------------------- /ch04/Listing02.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | int main(void) 6 | { 7 | time_t timeval; 8 | struct tm *tmptr; 9 | 10 | timeval = time(NULL); 11 | 12 | printf("Time as local time is %s", ctime(&timeval)); 13 | 14 | if ((tmptr = gmtime(&timeval)) == NULL) 15 | printf("UTC time not available\n"); 16 | else 17 | printf("Time as UTC time is %s", asctime(tmptr)); 18 | 19 | return 0; 20 | } 21 | -------------------------------------------------------------------------------- /ch10/fib1.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | static unsigned long count; 5 | 6 | int 7 | fib(int x) { 8 | int r; 9 | ++count; 10 | if (x == 1 || x == 2) 11 | return 1; 12 | return fib(x - 2) + fib(x - 1); 13 | } 14 | 15 | int 16 | main(void) { 17 | int i, f; 18 | 19 | for (i = 1; i < 20; ++i) { 20 | count = 0; 21 | f = fib(i); 22 | printf("fib(%02d) gives %d after %lu iteration%s.\n", 23 | i, f, count, count == 1 ? "" : "s"); 24 | } 25 | 26 | return 0; 27 | } 28 | -------------------------------------------------------------------------------- /ch23/proto.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | C standard function prototypes 5 | 6 | 7 | 8 |
 9 |       
10 | 11 | Please type in the name of the function 12 | whose prototype you wish to see. 13 | 14 | 15 |
16 | 17 | 18 |
19 |
20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /Bonus/README: -------------------------------------------------------------------------------- 1 | A little bonus for you, in the shape of a puzzle. 2 | 3 | Take a look at gcg8.c. Without compiling it, try to find out what it does. 4 | 5 | At some point, you may wish to compile it, of course. If your compiler rejects it as containing 6 | too many characters per line (which your compiler is entitled to do), you may wish to compile 7 | gcg5.c instead, which all ANSI C compilers must accept. 8 | 9 | If you get stuck, read the CHEAT file. 10 | 11 | 12 | Richard Heathfield 13 | 14 | 19 June 2000. 15 | -------------------------------------------------------------------------------- /ch20/genhelp: -------------------------------------------------------------------------------- 1 | Generic helpfile. Consult crystal ball for full instructions. 2 | 3 | Please note that the code generating routine is not clever enough to understand 4 | that some characters need to be protected in printf statements. Therefore, 5 | if you want your help display to contain special characters, they should be protected. 6 | 7 | In other words, treat everything in this file as if it were in a printf statement. 8 | 9 | Thus, \" for quotes, \\ for backslash (as in a DOS pathname) 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /ch10/fact3.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | static unsigned long count; 5 | 6 | long 7 | fact(int x) { 8 | long accumulator = 1; 9 | ++count; 10 | while (x > 1) { 11 | accumulator *= x--; 12 | } 13 | return accumulator; 14 | } 15 | 16 | int 17 | main(void) { 18 | int i; 19 | long f; 20 | 21 | for (i = 1; i < 20; ++i) { 22 | count = 0; 23 | f = fact(i); 24 | printf("fact(%02d) gives %ld after %lu iteration%s.\n", 25 | i, f, count, count == 1 ? "" : "s"); 26 | } 27 | 28 | return 0; 29 | } 30 | -------------------------------------------------------------------------------- /ch08/CH08_02.C: -------------------------------------------------------------------------------- 1 | /* Listing 8.2 */ 2 | char *ReadTextFile(FILE *fp, int *Error) 3 | { 4 | size_t size = 0; 5 | size_t len; 6 | char *p = NULL; 7 | char *q; 8 | char buffer[128]; 9 | 10 | *Error = 0; 11 | 12 | while(fgets(buffer, sizeof buffer, fp)) 13 | { 14 | len = strlen(buffer); 15 | q = realloc(p, size + len); 16 | if(q != NULL) 17 | { 18 | p = q; 19 | strcpy(p + size, buffer); 20 | size += len; 21 | } 22 | else 23 | { 24 | *Error = 1; 25 | } 26 | } 27 | return p; 28 | } 29 | -------------------------------------------------------------------------------- /ch10/fact1.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | static unsigned long count; 5 | 6 | long 7 | fact(int x) { 8 | ++count; 9 | /* fact(0) is 1, negative numbers don't make sense so we pretend 10 | * they're 1. */ 11 | if (x < 2) 12 | return 1; 13 | 14 | return x * fact(x - 1); 15 | } 16 | 17 | int 18 | main(void) { 19 | int i; 20 | long f; 21 | 22 | for (i = 1; i < 20; ++i) { 23 | count = 0; 24 | f = fact(i); 25 | printf("fact(%02d) gives %ld after %lu iteration%s.\n", 26 | i, f, count, count == 1 ? "" : "s"); 27 | } 28 | 29 | return 0; 30 | } 31 | -------------------------------------------------------------------------------- /ch07/ch07s024.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | int main(void) 6 | { 7 | clock_t start, end; 8 | 9 | unsigned long count = 0; 10 | start = clock(); 11 | 12 | while(malloc(1024)) 13 | { 14 | ++count; 15 | if(count % 16 == 0) 16 | { 17 | end = clock(); 18 | 19 | printf("%7f CPU seconds: %d kilobytes allocated\n", 20 | (double)(end - start) / CLOCKS_PER_SEC, 21 | count); 22 | } 23 | } 24 | printf("Out of memory (no more kilobytes).\n"); 25 | return 0; 26 | } 27 | -------------------------------------------------------------------------------- /ch10/fib3.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | static unsigned long count; 5 | 6 | int 7 | fib(int x) { 8 | int i, a[3]; 9 | 10 | if (x < 3) 11 | return 1; 12 | 13 | a[1] = a[0] = 1; 14 | for (i = 2; i < x; ++i) { 15 | a[2] = a[0] + a[1]; 16 | a[0] = a[1]; 17 | a[1] = a[2]; 18 | } 19 | 20 | return a[2]; 21 | } 22 | 23 | int 24 | main(void) { 25 | int i, f; 26 | 27 | for (i = 1; i < 20; ++i) { 28 | count = 0; 29 | f = fib(i); 30 | printf("fib(%02d) gives %d after %lu iteration%s.\n", 31 | i, f, count, count == 1 ? "" : "s"); 32 | } 33 | 34 | return 0; 35 | } 36 | -------------------------------------------------------------------------------- /ch04/Listing01.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | int main(void) 6 | { 7 | time_t start, end; 8 | 9 | start = time(NULL); 10 | if (start == (time_t)-1) { 11 | printf("Sorry, the time is unavailable on this system\n"); 12 | exit(EXIT_FAILURE); 13 | } 14 | 15 | printf("Please wait a few seconds and then press your ENTER/RETURN key"); 16 | fflush(stdout); 17 | 18 | getchar(); 19 | 20 | end = time(NULL); 21 | printf("\nThe interval was %.2f seconds\n", difftime(end, start)); 22 | 23 | return 0; 24 | } 25 | -------------------------------------------------------------------------------- /ch16/dfsfuncs.h: -------------------------------------------------------------------------------- 1 | /* dfsfuncs.h */ 2 | 3 | #ifndef DFSFUNCS_H 4 | #define DFSFUNCS_H 5 | 6 | #include "graphs.h" 7 | 8 | int AreVerticesConnected(struct Graph * G,int Source, int Dest); 9 | /* determines whether there is a path from Source to Dest 10 | It should work for directed and undirected graphs. Cost 11 | is not determined - only that a path exists. Because a 12 | depth first search is used, upto G->NumVertices iterations 13 | are required to determine that there is a path 14 | returns <0 on error (GRAPH_OUTOFMEM,GRAPH_BADPARAM) 15 | 0 denotes no path, >0 denotes a path 16 | */ 17 | 18 | #endif 19 | -------------------------------------------------------------------------------- /ch13/DOUBLE.C: -------------------------------------------------------------------------------- 1 | /* 2 | ** The proper usage and copyright information for 3 | ** this software is covered in DSCRLic.TXT 4 | ** This code is Copyright 1999 by Dann Corbit 5 | */ 6 | 7 | 8 | /* 9 | ** Believe it or not, this is a complete routine to sort arrays of double. 10 | ** The define ETYPE_DOUBLE will cause allsort.h to generate functions that 11 | ** operate on array of double. 12 | ** 13 | ** Why all this bother and not just use a comparison function? 14 | ** Because the qsort() style interface is slow. This is a bit more painful, 15 | ** but the payoff in speed is worth it. 16 | */ 17 | #define ETYPE_DOUBLE 18 | #include "allsort.h" 19 | -------------------------------------------------------------------------------- /ch13/STRINGS.C: -------------------------------------------------------------------------------- 1 | /* 2 | ** The proper usage and copyright information for 3 | ** this software is covered in DSCRLic.TXT 4 | ** This code is Copyright 1999 by Dann Corbit 5 | */ 6 | 7 | 8 | /* 9 | ** Believe it or not, this is a complete routine to sort arrays of strings. 10 | ** The define ETYPE_STRING will cause allsort.h to generate functions that 11 | ** operate on array of strings. 12 | ** 13 | ** Why all this bother and not just use a comparison function? 14 | ** Because the qsort() style interface is slow. This is a bit more painful, 15 | ** but the payoff in speed is worth it. 16 | */ 17 | #define ETYPE_STRING 18 | #include "allsort.h" 19 | -------------------------------------------------------------------------------- /ch10/fib2.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | static unsigned long count; 5 | 6 | int 7 | fib(int x) { 8 | int i, *a, r; 9 | 10 | if (x < 3) 11 | return 1; 12 | 13 | a = malloc(x * sizeof(int)); 14 | 15 | if (!a) 16 | return -1; 17 | 18 | a[1] = a[0] = 1; 19 | for (i = 2; i < x; ++i) { 20 | a[i] = a[i - 1] + a[i - 2]; 21 | } 22 | 23 | r = a[x - 1]; 24 | free(a); 25 | return r; 26 | } 27 | 28 | int 29 | main(void) { 30 | int i, f; 31 | 32 | for (i = 1; i < 20; ++i) { 33 | count = 0; 34 | f = fib(i); 35 | printf("fib(%02d) gives %d after %lu iteration%s.\n", 36 | i, f, count, count == 1 ? "" : "s"); 37 | } 38 | 39 | return 0; 40 | } 41 | -------------------------------------------------------------------------------- /ch17/mtest1.mat: -------------------------------------------------------------------------------- 1 | # matrix test file 2 | # first matrix 3 | rows,3 4 | cols,2 5 | 1.,2. 6 | 3.,4. 7 | 5.,6. 8 | # next matrix 9 | rows,3 10 | cols,2 11 | 3.,4, 12 | 5.,6. 13 | 7.,8. 14 | # a square matrix 15 | rows,3 16 | cols,3 17 | 1.,3.,1. 18 | 1.,2.,5. 19 | 2.,1.,2. 20 | # 9 x 9 matrix 21 | rows,9 22 | cols,9 23 | 1,2,3,4,5,6,7,8,9 24 | 9,8,7,6,5,4,3,2,1 25 | 25,1,2,3,4,5,6,7,8 26 | 8,7,26,5,4,3,2,1,0 27 | 10,1,2,3,14,5,6,7,8 28 | 8,7,6,35,4,3,2,1,10 29 | 1,3,5,7,99,7,5,3,1 30 | 2,4,6,8,10,12,1,2,1 31 | 2,4,6,8,10,12,1,2,1.001 32 | # 9 x 9 vector 33 | rows,9 34 | cols,1 35 | 1 36 | 2 37 | 3 38 | 4 39 | 5 40 | 6 41 | 7 42 | 8 43 | 9 44 | 45 | -------------------------------------------------------------------------------- /ch16/mstree.h: -------------------------------------------------------------------------------- 1 | /* mstree.h */ 2 | 3 | #ifndef MSTREE_H 4 | #define MSTREE_H 5 | 6 | #include "graphs.h" 7 | 8 | int Kruskal_Undirected(struct Graph * G,struct Graph ** TreePtr); 9 | /* The graph G is examined to produce a new graph, which is 10 | a minimum spanning tree and the struct Graph * denoted 11 | by TreePtr is assigned the new value. 12 | return 0 on success, <0 on error (GRAPH_BADPARAM, GRAPH_OUTOFMEM) 13 | */ 14 | 15 | 16 | int Prim_Undirected(struct Graph * G,struct Graph ** TreePtr); 17 | /* As above, but using Prim's algorithm instead. 18 | return 0 on success, <0 on error (GRAPH_BADPARAM, GRAPH_OUTOFMEM) 19 | */ 20 | 21 | #endif 22 | -------------------------------------------------------------------------------- /ch10/tok1.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | void 5 | tok(char *s, char *delim) { 6 | char *tmp; 7 | 8 | tmp = strtok(s, delim); 9 | while (tmp) { 10 | printf("token: %s\n", tmp); 11 | tmp = strtok(NULL, delim); 12 | } 13 | } 14 | 15 | int 16 | main(void) { 17 | /* never used a fixed size buffer like this in real code! */ 18 | char buf[1024]; 19 | /* to eat the newline */ 20 | char *nl; 21 | 22 | while (fgets(buf, 1024, stdin)) { 23 | /* I consider the != NULL superfluous, but some compilers 24 | * will give a warning without it. 25 | */ 26 | if ((nl = strchr(buf, '\n')) != NULL) { 27 | /* no need for newline */ 28 | *nl = '\0'; 29 | } 30 | tok(buf, " "); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /ch13/INTELTYP.H: -------------------------------------------------------------------------------- 1 | /* 2 | ** The proper usage and copyright information for 3 | ** this software is covered in DSCRLic.TXT 4 | ** This code is Copyright 1999 by Dann Corbit 5 | */ 6 | 7 | 8 | /* 9 | ** Typdefs for Intel formats. 10 | ** See keyxfrm.c for usage. 11 | */ 12 | 13 | typedef unsigned long uint32; 14 | #define SB_MASK32 0x80000000UL 15 | 16 | #ifdef _MSC_VER 17 | typedef unsigned __int64 uint64; 18 | typedef __int64 sint64; 19 | #define SB_MASK64 0x8000000000000000ui64 20 | #else 21 | typedef unsigned long long uint64; 22 | typedef long long sint64; 23 | #define SB_MASK64 0x8000000000000000ULL 24 | #endif 25 | extern uint32 float2key(float f); 26 | uint64 double2key(double d); 27 | -------------------------------------------------------------------------------- /ch03/README: -------------------------------------------------------------------------------- 1 | 2 | This is the source code supplement for chapter 3, Optimization and Optimism. 3 | It contains: 4 | 5 | Makefile--this is set up for a system which has gcc installed, 6 | but there is no reason the included programs couldn't 7 | be used on a different platform. 8 | 9 | speed.c--this is a little program that exercises some basic language 10 | constructs and measures how long they take on average. 11 | 12 | bubble.c--this is a deliberately poorly written program that YOU 13 | can optimize! Use a profiler to find out which functions 14 | are slow, then apply optimizations to speed it up. Hints 15 | are given in the chapter itself. 16 | 17 | refs--for further reading on the subject of optimization. 18 | -------------------------------------------------------------------------------- /ch08/CH08_04.C: -------------------------------------------------------------------------------- 1 | /* Listing 8.4 */ 2 | static char *buffer = NULL; 3 | static size_t bufsize = 0; 4 | size_t len = strlen(s) + 1; 5 | 6 | while(len > bufsize) 7 | { 8 | p = realloc(buffer, bufsize * 2); 9 | if(p != NULL) 10 | { 11 | bufsize *= 2; 12 | buffer = p; 13 | } 14 | else 15 | { 16 | p = realloc(buffer, len); 17 | if(p != NULL) 18 | { 19 | bufsize = len; 20 | buffer = p; 21 | } 22 | else 23 | { 24 | /* What to do next depends very heavily 25 | * on the nature of the application. 26 | */ 27 | printf("What we need here is a design decision!\n"); 28 | } 29 | } 30 | } -------------------------------------------------------------------------------- /ch07/ch07s021.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main(void) 5 | { 6 | char *filename; 7 | FILE *fp; 8 | int Result = EXIT_SUCCESS; 9 | int i; 10 | 11 | printf("This program calculates perfect squares.\n"); 12 | printf("Please enter a filename for the output:\n"); 13 | 14 | fgets(filename, 13, stdin); 15 | fp = fopen(filename, "w"); 16 | if(fp != NULL) 17 | { 18 | fprintf(fp, "Perfect squares\n"); 19 | for(i = 0; i < 100; i++) 20 | { 21 | fprintf(fp, "%2d %4d\n", i, i * i); 22 | } 23 | fclose(fp); 24 | } 25 | else 26 | { 27 | printf("Couldn't open file %s\n", filename); 28 | Result = EXIT_FAILURE; 29 | } 30 | return 0; 31 | } 32 | -------------------------------------------------------------------------------- /ch10/gcd3.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | static int depth; 5 | 6 | int 7 | gcd(int x, int y) { 8 | int tmp; 9 | if (x < y) { 10 | tmp = x; 11 | x = y; 12 | y = tmp; 13 | } 14 | while ((x % y) != 0) { 15 | tmp = x % y; 16 | x = y; 17 | y = tmp; 18 | } 19 | printf("returning %d\n", y); 20 | return y; 21 | } 22 | 23 | int 24 | main(void) { 25 | int i, j; 26 | printf("two numbers? "); 27 | fflush(stdout); 28 | if (scanf("%d %d", &i, &j) == 2) { 29 | printf("calling gcd(%d, %d):\n", i, j); 30 | gcd(i, j); 31 | } else if (feof(stdin)) { 32 | printf("\nbye-bye!\n"); 33 | return 0; 34 | } else { 35 | printf("\ninput confusing. giving up.\n"); 36 | return 1; 37 | } 38 | return 0; 39 | } 40 | -------------------------------------------------------------------------------- /ch18/accel1.pid: -------------------------------------------------------------------------------- 1 | # accel1.pid 2 | # 3 | # combines proportional, integral and 4 | # derivative gains with acceleration 5 | 6 | P=1.3 Proportional gain 7 | I=1.2 Integral gain 8 | D=0.025 Derivative gain 9 | H=0 output Hold 10 | A=0 Acceleration feed forward 11 | F=0 Friction feed forward 12 | V=0.0 Velocity feed forward 13 | B=0 constant Bias 14 | R=3 acceleration Rate 15 | S=70 Set point 16 | T=1 Transfer ratio 17 | L=.368 response Lag 18 | N=-100 miNimum output 19 | M=100 Maximum output 20 | W=0 sleW limit 21 | Y=51 cYcle count 22 | @51 s=0 23 | @51 y=50 24 | @101 q 25 | -------------------------------------------------------------------------------- /ch10/fact2.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | static unsigned long count; 5 | 6 | long 7 | fact(int x) { 8 | long accumulator = 1; 9 | start: 10 | ++count; 11 | /* fact(0) is 1, negative numbers don't make sense so we pretend 12 | * they're 1. */ 13 | if (x < 2) 14 | return accumulator; 15 | 16 | /* we multiply the accumulator by our top-level x */ 17 | accumulator *= x; 18 | /* and trim x by one */ 19 | x = x - 1; 20 | goto start; 21 | } 22 | 23 | int 24 | main(void) { 25 | int i; 26 | long f; 27 | 28 | for (i = 1; i < 20; ++i) { 29 | count = 0; 30 | f = fact(i); 31 | printf("fact(%02d) gives %ld after %lu iteration%s.\n", 32 | i, f, count, count == 1 ? "" : "s"); 33 | } 34 | 35 | return 0; 36 | } 37 | -------------------------------------------------------------------------------- /ch16/testing3.cbb: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #define INF INT_MAX 5 | 6 | int main(void) { 7 | 8 | int i,j,k; 9 | int R[4][4]={ 10 | { 0, -1,INF, 2}, 11 | {INF, 0, 2,INF}, 12 | { 4,INF, 0, 3}, 13 | {INF, 1,INF, 0} 14 | }; 15 | 16 | for (k=0;k<4;k++) { 17 | for (i=0;i<4;i++) { 18 | for (j=0;j<4;j++) { 19 | if (R[i][k]==INF || R[k][j]==INF) continue; 20 | R[i][j]= (R[i][j] > R[i][k]+R[k][j])? R[i][k]+R[k][j] : R[i][j]; 21 | } 22 | } 23 | 24 | for (i=0;i<4;i++) { 25 | for (j=0;j<4;j++) { 26 | if (R[i][j]!=INF) printf("%d -> %d = %d\n",i,j,R[i][j]); 27 | else printf("%d -> %d = !\n",i,j); 28 | } 29 | } 30 | } 31 | 32 | return 0; 33 | 34 | } 35 | -------------------------------------------------------------------------------- /ch19/README: -------------------------------------------------------------------------------- 1 | Chapter 19 - Expression Parsing and Evaluation 2 | 3 | This directory contains source code for processing 4 | expressions written in an arbitrary language. 5 | 6 | Unfortunately, the code doesn't work. 7 | 8 | We tried very hard (through-the-night hard) to get this code 9 | working before the book went to press, but it couldn't be done 10 | in time. 11 | 12 | We didn't give up, though, and we very much hope that, by 13 | the time this book enters your possession, we will 14 | have produced working code. Please check the 15 | "C Unleashed" errata site, at: 16 | 17 | http://users.powernet.co.uk/eton/unleashed/errata/index.html 18 | 19 | for updated code. 20 | 21 | 22 | 23 | 24 | Ian Kelly and Richard Heathfield 25 | 18 June 2000 26 | -------------------------------------------------------------------------------- /ch18/accel2.pid: -------------------------------------------------------------------------------- 1 | # accel2.pid 2 | # 3 | # combines proportional, integral and 4 | # derivative gains and adds acceleration 5 | # and velocity feed forwards 6 | 7 | P=1.3 Proportional gain 8 | I=1.2 Integral gain 9 | D=0.025 Derivative gain 10 | H=0 output Hold 11 | A=1.0 Acceleration feed forward 12 | F=0 Friction feed forward 13 | V=1.0 Velocity feed forward 14 | B=0 constant Bias 15 | R=3 acceleration Rate 16 | S=70 Set point 17 | T=1 Transfer ratio 18 | L=.368 response Lag 19 | N=-100 miNimum output 20 | M=100 Maximum output 21 | W=0 sleW limit 22 | Y=51 cYcle count 23 | @51 s=0 24 | @51 y=50 25 | @101 q 26 | -------------------------------------------------------------------------------- /ch18/ionly.pid: -------------------------------------------------------------------------------- 1 | # ionly.pid 2 | # 3 | # integral gain only 4 | 5 | # initial settings 6 | 7 | P=0 Proportional gain 8 | I=1.0 Integral gain 9 | D=.0 Derivative gain 10 | H=0 output Hold 11 | A=0 Acceleration feed forward 12 | F=0 Friction feed forward 13 | V=0 Velocity feed forward 14 | B=0 constant Bias 15 | R=0 acceleration Rate 16 | S=60 Set point 17 | T=1 Transfer ratio 18 | L=.368 response Lag 19 | N=0 miNimum output 20 | M=100 Maximum output 21 | W=0 sleW limit 22 | Y=21 cYcle count 23 | 24 | # timed events 25 | 26 | # finished 21 cycles, time to quit 27 | 28 | @21 Q Quit 29 | -------------------------------------------------------------------------------- /ch06/getcols.c: -------------------------------------------------------------------------------- 1 | /**************************************/ 2 | /* */ 3 | /* Code from the book C Unleashed */ 4 | /* Macmillan, 2000 */ 5 | /* Chapter 6: Data Files */ 6 | /* Steve Summit 2000-03-17 */ 7 | /* */ 8 | /**************************************/ 9 | 10 | #include 11 | 12 | int getcols(char *line, char *words[], int maxwords, int delim) 13 | { 14 | char *p = line, *p2; 15 | int nwords = 0; 16 | 17 | while(*p != '\0') 18 | { 19 | words[nwords++] = p; 20 | if(nwords >= maxwords) 21 | return nwords; 22 | p2 = strchr(p, delim); 23 | if(p2 == NULL) 24 | break; 25 | *p2 = '\0'; 26 | p = p2 + 1; 27 | } 28 | return nwords; 29 | } 30 | -------------------------------------------------------------------------------- /ch18/id.pid: -------------------------------------------------------------------------------- 1 | # id.pid 2 | # 3 | # same integral gain as ionly.pid, 4 | # derivative gain added 5 | 6 | # initial settings 7 | 8 | P=0 Proportional gain 9 | I=1.0 Integral gain 10 | D=.3 Derivative gain 11 | H=0 output Hold 12 | A=0 Acceleration feed forward 13 | F=0 Friction feed forward 14 | V=0 Velocity feed forward 15 | B=0 constant Bias 16 | R=0 acceleration Rate 17 | S=60 Set point 18 | T=1 Transfer ratio 19 | L=.368 response Lag 20 | N=0 miNimum output 21 | M=100 Maximum output 22 | W=0 sleW limit 23 | Y=21 cYcle count 24 | 25 | # timed events 26 | 27 | # finished 21 cycles, time to quit 28 | 29 | @21 Q Quit 30 | -------------------------------------------------------------------------------- /ch18/pid.pid: -------------------------------------------------------------------------------- 1 | # pid.pid 2 | # 3 | # putting it all together, proportional 4 | # integral, and derivative gain 5 | 6 | # initial settings 7 | 8 | P=1.30 Proportional gain 9 | I=1.20 Integral gain 10 | D=0.025 Derivative gain 11 | H=0 output Hold 12 | A=0 Acceleration feed forward 13 | F=0 Friction feed forward 14 | V=0 Velocity feed forward 15 | B=0 constant Bias 16 | R=0 acceleration Rate 17 | S=60 Set point 18 | T=1 Transfer ratio 19 | L=.368 response Lag 20 | N=0 miNimum output 21 | M=100 Maximum output 22 | W=0 sleW limit 23 | Y=51 cYcle count 24 | 25 | # timed events 26 | 27 | # finished 51 cycles, time to quit 28 | 29 | @51 Q Quit 30 | -------------------------------------------------------------------------------- /ch10/tok2.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | void 5 | tok(char *s, char *delim) { 6 | char *tmp; 7 | 8 | tmp = strtok(s, delim); 9 | while (tmp) { 10 | if (strspn(tmp, "0123456789,") == strlen(tmp) && 11 | strchr(tmp, ',')) { 12 | tok(tmp, ","); 13 | } else { 14 | printf("token: %s\n", tmp); 15 | } 16 | tmp = strtok(NULL, delim); 17 | } 18 | } 19 | 20 | int 21 | main(void) { 22 | /* never used a fixed size buffer like this in real code! */ 23 | char buf[1024]; 24 | /* to eat the newline */ 25 | char *nl; 26 | 27 | while (fgets(buf, 1024, stdin)) { 28 | /* I consider the != NULL superfluous, but some compilers 29 | * will give a warning without it. 30 | */ 31 | if ((nl = strchr(buf, '\n')) != NULL) { 32 | /* no need for newline */ 33 | *nl = '\0'; 34 | } 35 | tok(buf, " "); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /ch07/ch07s048.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #define SWAP(x, y) x^= y^= x; 5 | 6 | int 7 | main() 8 | { 9 | char *s="uvwxyz"; 10 | char *t; 11 | unsigned long a, b, c; 12 | int i; 13 | 14 | printf("String: %s (%d entries).\n" 15 | "Change which character to '1'? ", s, 16 | strlen(s)); 17 | scanf("%d", &a); 18 | 19 | assert((0 <= a) && (a < strlen(s))); 20 | s[a]= '1'; 21 | 22 | printf("Original changed to %s\n", s); 23 | printf("Reverse which range of characters (from-to)? ", 24 | b, c); 25 | 26 | scanf("%lu%lu", &a, &b); 27 | assert(a<=b); 28 | 29 | t= malloc(strlen(s+1)); 30 | 31 | strcpy(t, s); 32 | for (i=b; i<(b+c)/2; i++) 33 | SWAP(t[b+i], t[c-i]); 34 | 35 | printf("Result of reverse is %s -> %s\n", s, t); 36 | return 0; 37 | } 38 | -------------------------------------------------------------------------------- /Bonus/CHEAT: -------------------------------------------------------------------------------- 1 | Those with picky compilers, skip 20 lines. 2 | 3 | Compile gcg8.c. 4 | 5 | Run it, like this: 6 | 7 | gcg8 > gcg7.c 8 | 9 | Compile gcg7.c. 10 | 11 | Run it, like this: 12 | 13 | gcg7 > gcg6.c 14 | 15 | Compile gcg6.c. 16 | 17 | Run it, like this: 18 | 19 | gcg6 > gcg5.c 20 | 21 | Those with picky compilers, start here: 22 | 23 | Compile gcg5.c. 24 | 25 | Run it, like this: 26 | 27 | gcg5 > gcg4.c 28 | 29 | Keep doing this, compiling each output file in turn, until 30 | you get gcg1.c. Compile this, run it, and save the output 31 | as gcg.c. 32 | 33 | Compile that, and run it like this: 34 | 35 | gcg < anyCprogramYouLike > gen.c 36 | 37 | Have a close look at gen.c 38 | 39 | Compile it. Run it. Save the output. Compare the output to anyCprogramYouLike.c. 40 | 41 | Notice anything odd? 42 | 43 | :-) 44 | 45 | Richard Heathfield 46 | 47 | 19 June 2000. 48 | -------------------------------------------------------------------------------- /ch10/gcd2.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int depth; 5 | 6 | int 7 | gcd(int x, int y) { 8 | start: 9 | if (x < y) { 10 | int tmp = x; 11 | printf("x < y, setting x to y and y to x\n"); 12 | x = y; 13 | y = tmp; 14 | goto start; 15 | } else if ((x % y) != 0) { 16 | int tmp = x % y; 17 | printf("remainder %d, setting x to y (%d) and y to (x %% y)\n", 18 | x % y, y); 19 | x = y; 20 | y = tmp; 21 | goto start; 22 | } else { 23 | printf("remainder 0, returning y (%d)\n", y); 24 | return y; 25 | } 26 | } 27 | 28 | int 29 | main(void) { 30 | int i, j; 31 | printf("two numbers? "); 32 | fflush(stdout); 33 | if (scanf("%d %d", &i, &j) == 2) { 34 | printf("calling gcd(%d, %d):\n", i, j); 35 | gcd(i, j); 36 | } else if (feof(stdin)) { 37 | printf("\nbye-bye!\n"); 38 | return 0; 39 | } else { 40 | printf("\ninput confusing. giving up.\n"); 41 | return 1; 42 | } 43 | return 0; 44 | } 45 | -------------------------------------------------------------------------------- /ch06/csvwrite.c: -------------------------------------------------------------------------------- 1 | /**************************************/ 2 | /* */ 3 | /* Code from the book C Unleashed */ 4 | /* Macmillan, 2000 */ 5 | /* Chapter 6: Data Files */ 6 | /* Steve Summit 2000-03-17 */ 7 | /* */ 8 | /**************************************/ 9 | 10 | #include 11 | #include 12 | 13 | void csvwrite(char *arr[], int narr, FILE *ofp) 14 | { 15 | int i; 16 | for(i = 0; i < narr; i++) 17 | { 18 | if(strpbrk(arr[i], ",\"\n") == NULL) 19 | fputs(arr[i], ofp); 20 | else { 21 | char *p; 22 | putc('"', ofp); 23 | for(p = arr[i]; *p != '\0'; p++) 24 | { 25 | if(*p == '"') 26 | fputs("\"\"", ofp); 27 | else if(*p == '\n') 28 | putc(' ', ofp); 29 | else putc(*p, ofp); 30 | } 31 | putc('"', ofp); 32 | } 33 | putc(i < narr-1 ? ',' : '\n', ofp); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /ch11/C11_010.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | typedef struct ARRAY_INT_4_6 4 | { 5 | int array[4][6]; 6 | } ARRAY_INT_4_6; 7 | 8 | int SumArray(ARRAY_INT_4_6 *); 9 | 10 | int main(void) 11 | { 12 | ARRAY_INT_4_6 Array = 13 | { 14 | { 15 | { 1, 2, 3, 4, 5, 6 }, 16 | { 2, 3, 4, 5, 6, 7 }, 17 | { 3, 4, 5, 6, 7, 8 }, 18 | { 4, 5, 6, 7, 8, 9 } 19 | } 20 | }; 21 | int Total; 22 | 23 | Total = SumArray(&Array); 24 | 25 | printf("Total is %d\n", Total); 26 | 27 | return 0; 28 | } 29 | 30 | int SumArray(ARRAY_INT_4_6 *a) 31 | { 32 | size_t outer, inner; 33 | int Total = 0; 34 | 35 | for(outer = 0; 36 | outer < sizeof a->array / sizeof a->array[0]; 37 | outer++) 38 | { 39 | for(inner = 0; 40 | inner < sizeof a->array[0] / sizeof a->array[0][0]; 41 | inner++) 42 | { 43 | Total += a->array[outer][inner]; 44 | } 45 | } 46 | return Total; 47 | } 48 | -------------------------------------------------------------------------------- /ch06/README: -------------------------------------------------------------------------------- 1 | /**************************************/ 2 | /* */ 3 | /* Code from the book C Unleashed */ 4 | /* Macmillan, 2000 */ 5 | /* Chapter 6: Data Files */ 6 | /* Steve Summit 2000-03-17 */ 7 | /* */ 8 | /**************************************/ 9 | 10 | binio.c binary I/O functions putint(), getint(), putlong(), 11 | getlong(), etc. 12 | csvburst.c function csvburst() for unpacking CSV lines 13 | csvwrite.c function csvwrite() for writing CSV lines 14 | getcols.c function getcols() for unpacking rigidly delimited columns 15 | getwords.c function getwords() for unpacking whitespace-separated columns 16 | ieee754.c functions for converting native float and double 17 | to IEEE-754 single and double 18 | inifetch.c function inifetch() for fetching values from .ini files 19 | time_t.c functions for portably or semiportably handling 20 | date/timestamps in data files (text and binary) 21 | -------------------------------------------------------------------------------- /ch11/c11_019.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | typedef int T; 4 | 5 | T *****Alloc5DArrayOfT(size_t m, 6 | size_t n, 7 | size_t p, 8 | size_t q, 9 | size_t r) 10 | { 11 | T *****Array = NULL; 12 | int Success = 1; 13 | size_t a, b, c, d; 14 | 15 | Array = 16 | malloc(m * sizeof *Array); 17 | for(a = 0; a < m; a++) 18 | { 19 | Array[a] = 20 | malloc(n * sizeof *Array[0]); 21 | for(b = 0; b < n; b++) 22 | { 23 | Array[a][b] = 24 | malloc(p * sizeof *Array[0][0]); 25 | for(c = 0; c < p; c++) 26 | { 27 | Array[a][b][c] = 28 | malloc(q * sizeof *Array[0][0][0]); 29 | for(d = 0; d < q; d++) 30 | { 31 | Array[a][b][c][d] = 32 | malloc(r * sizeof *Array[0][0][0][0]); 33 | } 34 | } 35 | } 36 | } 37 | 38 | return Array; 39 | } 40 | 41 | /* end of c11_019.c */ 42 | -------------------------------------------------------------------------------- /ch10/gcd1.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int depth; 5 | 6 | int 7 | gcd(int x, int y) { 8 | int r; 9 | ++depth; 10 | if (x < y) { 11 | printf("%*sswap...\n", depth, ""); 12 | r = gcd(y, x); 13 | printf("%*sreturning %d\n", depth, "", r); 14 | --depth; 15 | return r; 16 | } else if ((x % y) != 0) { 17 | printf("%*sremainder %d, calling gcd(%d, %d)\n", 18 | depth, "", x % y, y, x % y); 19 | r = gcd(y, x % y); 20 | printf("%*sreturning %d\n", depth, "", r); 21 | --depth; 22 | return r; 23 | } else { 24 | printf("%*sremainder 0, returning %d\n", depth, "", y); 25 | --depth; 26 | return y; 27 | } 28 | } 29 | 30 | int 31 | main(void) { 32 | int i, j; 33 | printf("two numbers? "); 34 | fflush(stdout); 35 | if (scanf("%d %d", &i, &j) == 2) { 36 | printf("calling gcd(%d, %d):\n", i, j); 37 | gcd(i, j); 38 | } else if (feof(stdin)) { 39 | printf("\nbye-bye!\n"); 40 | return 0; 41 | } else { 42 | printf("\ninput confusing. giving up.\n"); 43 | return 1; 44 | } 45 | return 0; 46 | } 47 | -------------------------------------------------------------------------------- /ch16/pqueue.h: -------------------------------------------------------------------------------- 1 | /* pqueue.h */ 2 | 3 | #ifndef PQUEUE_H 4 | #define PQUEUE_H 5 | 6 | #include "graphs.h" 7 | 8 | /* a prioritesed queue for vertices */ 9 | 10 | struct PQueue { 11 | struct PQueue_Node * Front; 12 | }; 13 | 14 | struct PQueue_Node { 15 | int Weight; 16 | int Index; 17 | struct PQueue_Node * Next; 18 | }; 19 | 20 | void PQ_Initialise(struct PQueue * Q); 21 | void PQ_Free(struct PQueue * Q); 22 | int PQ_Enqueue(struct PQueue * Q, int Weight, int Index); 23 | int PQ_Dequeue(struct PQueue * Q); 24 | 25 | /* a prioritesed queue for edges */ 26 | 27 | struct PEdgeQueue { 28 | struct PEdgeQueue_Node * Front; 29 | }; 30 | 31 | struct PEdgeQueue_Node { 32 | int Weight; 33 | int Source; 34 | int Dest; 35 | struct PEdgeQueue_Node * Next; 36 | }; 37 | 38 | void PEQ_Initialise(struct PEdgeQueue * Q); 39 | void PEQ_Free(struct PEdgeQueue * Q); 40 | int PEQ_Enqueue(struct PEdgeQueue * Q, struct EdgeScan * EScan); 41 | int PEQ_Dequeue(struct PEdgeQueue * Q, struct EdgeScan * EScan); 42 | 43 | #endif 44 | -------------------------------------------------------------------------------- /ch16/graphprv.h: -------------------------------------------------------------------------------- 1 | /* graphprivate.h */ 2 | 3 | /* This header file defines internal (i.e. private) structures. This 4 | is only the Graph_Spec structure - it defines the functions to call 5 | from the functions defined in graph.h which are representation 6 | specific. Each representation should have a Graph_Spec structure 7 | defined extern in it's header file, and fully defined in the 8 | accompanying c file. 9 | */ 10 | 11 | #ifndef GRAPHPRIVATE_H 12 | #define GRAPHPRIVATE_H 13 | 14 | #include "graphs.h" 15 | 16 | struct Graph_Spec 17 | { 18 | int (*MakeGraph) (struct Graph *); 19 | void (*FreeGraph) (struct Graph *); 20 | int (*AddVertex) (struct Graph *, int Index); 21 | void (*RemoveVertex) (struct Graph *, int Index); 22 | int (*ConnectVertex) (struct Graph *, int Source, int Destination, int Cost); 23 | int (*DisconnectVertex)(struct Graph *, int Source, int Destination); 24 | int (*EdgeScanStart) (struct Graph *, int Index, struct EdgeScan *); 25 | int (*EdgeScanEnd) (struct EdgeScan *); 26 | int (*EdgeScanNext) (struct EdgeScan *); 27 | }; 28 | 29 | #endif 30 | -------------------------------------------------------------------------------- /ch06/getwords.c: -------------------------------------------------------------------------------- 1 | /**************************************/ 2 | /* */ 3 | /* Code from the book C Unleashed */ 4 | /* Macmillan, 2000 */ 5 | /* Chapter 6: Data Files */ 6 | /* Steve Summit 2000-03-17 */ 7 | /* */ 8 | /**************************************/ 9 | 10 | /* 11 | * Takes a string (line) and builds an array of pointers to each word in it. 12 | * Words are separated by spaces as defined by isspace(). At most maxwords 13 | * pointers are calculated. \0's are inserted in line, so that each word 14 | * becomes a string in its own right. The number of words is returned. 15 | */ 16 | 17 | #include 18 | #include 19 | 20 | int getwords(char *line, char *words[], int maxwords) 21 | { 22 | char *p = line; 23 | int nwords = 0; 24 | 25 | while(1) 26 | { 27 | while(isspace(*p)) p++; 28 | if(*p == '\0') return nwords; 29 | words[nwords++] = p; 30 | while(!isspace(*p) && *p != '\0') p++; 31 | if(*p == '\0') return nwords; 32 | if(nwords >= maxwords) return nwords; 33 | *p++ = '\0'; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /ch13/BARPROTO.H: -------------------------------------------------------------------------------- 1 | /* 2 | ** The proper usage and copyright information for 3 | ** this software is covered in DSCRLic.TXT 4 | ** This code is Copyright 1999 by Dann Corbit 5 | */ 6 | 7 | 8 | /* 9 | ** Definitions for our priority queue model merge sort. 10 | */ 11 | typedef struct tag_fileset { 12 | FILE *fin; 13 | char empty; 14 | char filename[FILENAME_MAX]; 15 | char buffer[8192]; /* max record size */ 16 | } fileset; 17 | 18 | extern int fgetitem(struct tag_fileset * p); 19 | extern char *fdeletemin(struct tag_fileset * p, char *end); 20 | extern void fshellsort(struct tag_fileset * fset, unsigned int count); 21 | extern void fnormalize(struct tag_fileset * fset, unsigned int count); 22 | extern void foutputr(char *e); 23 | extern int ge(char *l, char *r); 24 | extern int le(char *l, char *r); 25 | extern int lt(char *l, char *r); 26 | static int readlines(char *file_name, char **lines, int maxlines, unsigned int *offset); 27 | extern void writelines(char **t, int nlines, FILE * fout); 28 | extern int main(int argc, char **argv); 29 | -------------------------------------------------------------------------------- /ch04/Listing03.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | int main(void) 7 | { 8 | time_t timeval; 9 | struct tm *tmptr; 10 | char *localename, *category; 11 | char format[100]; 12 | char timestr[30]; 13 | 14 | if ((localename = getenv("LOCALE")) != NULL) { 15 | if ((category = setlocale(LC_TIME, localename)) == NULL) 16 | printf("Warning - locale change failed\n"); 17 | else 18 | printf("Locale changed to %s (%s)\n", localename, category); 19 | } 20 | 21 | for (;;) { 22 | printf("Enter a strftime() format string or q to quit\n"); 23 | fflush(stdout); 24 | if (fgets(format, sizeof format, stdin) == NULL) 25 | break; 26 | if (format[0] == 'q' && format[1] == '\n') 27 | break; 28 | 29 | timeval = time(NULL); 30 | tmptr = localtime(&timeval); 31 | if (strftime(timestr, sizeof timestr, format, tmptr) == 0) 32 | printf("The timestr array isn't big enough\n"); 33 | else 34 | printf("%s", timestr); 35 | } 36 | return 0; 37 | } 38 | -------------------------------------------------------------------------------- /ch04/Listing04.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main(void) 5 | { 6 | time_t timeval; 7 | struct tm tmval; 8 | char inbuff[30]; 9 | 10 | for (;;) { 11 | printf("\nEnter a date and time formatted as YYYY/MM/DD HH:MM:SS\n"); 12 | printf("or q to quit\n"); 13 | fflush(stdout); 14 | if (fgets(inbuff, sizeof inbuff, stdin) == NULL) 15 | break; 16 | if (inbuff[0] == 'q' && inbuff[1] == '\n') 17 | break; 18 | 19 | if (sscanf(inbuff, "%d/%d/%d %d:%d:%d", 20 | &tmval.tm_year, &tmval.tm_mon, &tmval.tm_mday, 21 | &tmval.tm_hour, &tmval.tm_min, &tmval.tm_sec) != 6) { 22 | printf("Invalid date format\n"); 23 | continue; 24 | } 25 | tmval.tm_year -= 1900; 26 | tmval.tm_mon--; 27 | tmval.tm_isdst = -1; 28 | 29 | if ((timeval = mktime(&tmval)) == (time_t)-1) { 30 | printf("time_t cannot represent that date and time\n"); 31 | continue; 32 | } 33 | 34 | printf("The date and time you entered is %s", asctime(&tmval)); 35 | } 36 | 37 | return 0; 38 | } 39 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Source code from the book "C Unleashed" 2 | 3 | "C Unleashed" was written by Richard Heathfield, Lawrence Kirby and several 4 | other collaborators and published by SAMS in 2000. It's a really good book with 5 | lots of high-quality C code for various programming tasks. 6 | 7 | It comes with a CD-ROM of the book's complete source code. While looking for 8 | this code online recently, I could not find it, though from archived 9 | `comp.lang.c` posts it was apparent that the authors made the code publicly 10 | available. The main author's website at http://www.cpax.org.uk/ was supposed to 11 | host it, but this website is down now. I also ran into sites that offer to 12 | purchase this code, which was pretty annoying since it was originally offered 13 | for free. 14 | 15 | So I dug up my copy of the book and my trusty external CD reader and copied the 16 | code from the book's CD-ROM into this repository (it's remarkable how smoothly 17 | it worked on a 20-year-old CD-ROM). 18 | 19 | This code is presented as-is, along with its original license (GPL as mentioned 20 | in the comment headers of the source files). 21 | 22 | Hope others find this useful! If you believe that this repository is infringing 23 | someone's rights by existing, please get in touch. 24 | -------------------------------------------------------------------------------- /ch16/dfsfuncs.c: -------------------------------------------------------------------------------- 1 | /* dfsfuncs.c */ 2 | 3 | #include "dfsfuncs.h" 4 | #include 5 | 6 | /* An implementation of a depth-first search to determine if there is a 7 | path (of any length) from S to D. Visited is required to avert infinitely 8 | moving around cycles, must be sizeof(int)*NumberOfVertices), and be 9 | initialised with zeros before first executing. 10 | */ 11 | int AVC_Inner(struct Graph * G, int S, int D,int * Visited) 12 | { 13 | int retval; 14 | struct EdgeScan EScan; 15 | 16 | retval=0; 17 | Visited[S]=1; 18 | EdgeScanStart(G,S,&EScan); 19 | while (EdgeScanNext(&EScan)==0 && retval==0) 20 | { 21 | if (EScan.Dest==D) retval=0; 22 | else if (!Visited[EScan.Dest]) retval=AVC_Inner(G,EScan.Dest,D,Visited); 23 | } 24 | EdgeScanEnd(&EScan); 25 | return retval; 26 | } 27 | 28 | int AreVerticesConnected(struct Graph * G,int Source, int Dest) 29 | { 30 | int * Visited; 31 | int i, retval; 32 | 33 | if (!G || Source<0 || Dest<0 || Source>=G->NumVertices || Dest>=G->NumVertices) return GRAPH_BADPARAM; 34 | 35 | Visited=malloc(sizeof(int)*G->NumVertices); 36 | if (!Visited) return GRAPH_OUTOFMEM; 37 | for (i=0;iNumVertices;i++) Visited[i]=0; 38 | 39 | retval=AVC_Inner(G,Source,Dest,Visited); 40 | free(Visited); 41 | 42 | return retval; 43 | } 44 | 45 | -------------------------------------------------------------------------------- /ch18/fax.h: -------------------------------------------------------------------------------- 1 | /* fax.h - defines constants used in Group 3 Facsimilie 2 | * T.4 encoding and decoding 3 | * 4 | * Copyright (C) 2000 Jack Klein 5 | * Macmillan Computer Publishing 6 | * 7 | * This program is free software; you can redistribute it 8 | * and/or modify it under the terms of the GNU General 9 | * Public License as published by the Free Software 10 | * Foundation; either version 2 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will 14 | * be useful, but WITHOUT ANY WARRANTY; without even the 15 | * implied warranty of MERCHANTABILITY or FITNESS FOR A 16 | * PARTICULAR PURPOSE. See the GNU General Public License 17 | * for more details. 18 | * 19 | * You should have received a copy of the GNU General 20 | * Public License along with this program; if not, write 21 | * to the Free Software Foundation, Inc., 675 Mass Ave, 22 | * Cambridge, MA 02139, USA. 23 | * 24 | * Jack Klein may be contacted by email at: 25 | * The_C_Guru@yahoo.com 26 | * 27 | */ 28 | 29 | #define PIXELS_PER_ROW 1728 30 | #define PIXELS_PER_OCTET 8 31 | #define OCTETS_PER_ROW (PIXELS_PER_ROW / PIXELS_PER_OCTET) 32 | #define MAXIMUM_ROWS 1024 33 | #define T4_BUFFER_SIZE 1024 34 | #define EOL_LENGTH 12 35 | #define OCTET_MASK 0xff 36 | 37 | 38 | -------------------------------------------------------------------------------- /ch06/csvburst.c: -------------------------------------------------------------------------------- 1 | /**************************************/ 2 | /* */ 3 | /* Code from the book C Unleashed */ 4 | /* Macmillan, 2000 */ 5 | /* Chapter 6: Data Files */ 6 | /* Steve Summit 2000-03-17 */ 7 | /* */ 8 | /**************************************/ 9 | 10 | #define TRUE 1 11 | #define FALSE 0 12 | 13 | #include 14 | 15 | int 16 | csvburst(char *line, char *arr[], int narr) 17 | { 18 | char *p; 19 | int na = 0; 20 | char prevc = ','; /* force recognizing first field */ 21 | char *dp = NULL; 22 | int inquote = FALSE; 23 | 24 | for(p = line; *p != '\0'; prevc = *p, p++) 25 | { 26 | if(prevc == ',' && !inquote) 27 | { 28 | /* start new field */ 29 | if(dp != NULL) 30 | *dp = '\0'; /*terminate prev*/ 31 | if(na >= narr) 32 | return na; 33 | arr[na++] = p; 34 | dp = p; 35 | if(*p == '"') 36 | { 37 | inquote = TRUE; 38 | continue; /* skip quote */ 39 | } 40 | } 41 | 42 | if(inquote && *p == '"') 43 | { 44 | /* doubled quote goes to one quote; */ 45 | /* otherwise quote ends quote mode */ 46 | if(*(p+1) != '"') 47 | inquote = FALSE; 48 | p++; /* skip first quote */ 49 | } 50 | 51 | if(*p != ',' || inquote) 52 | *dp++ = *p; 53 | } 54 | 55 | if(dp != NULL) 56 | *dp = '\0'; 57 | 58 | if(na < narr) 59 | arr[na] = NULL; 60 | 61 | return na; 62 | } 63 | -------------------------------------------------------------------------------- /ch18/step.pid: -------------------------------------------------------------------------------- 1 | # step.pid 2 | # 3 | # shows the step function response with a 10% 4 | # step in "manual mode", that is using the 5 | # constant bias parameter only 6 | # 7 | # sets the Set point value the same as the 8 | # desired output, even though it has no 9 | # real effect, so my plot capture routine 10 | # picks it up and it shows in the illustration 11 | # 12 | # Copyright (C) 2000 Jack Klein 13 | # Macmillan Computer Publishing 14 | # 15 | 16 | # ordinary parameters, set before execution begins 17 | 18 | P=0 Proportional gain 19 | I=0 Integral gain 20 | D=0 Derivative gain 21 | H=0 output Hold 22 | A=0 Acceleration feed forward 23 | F=0 Friction feed forward 24 | V=0 Velocity feed forward 25 | B=20 constant Bias 26 | R=0 acceleration Rate 27 | S=20 Set point 28 | T=1 Transfer ratio 29 | L=0.368 response Lag 30 | N=-100 miNimum output 31 | M=100 Maximum output 32 | W=0 sleW limit 33 | 34 | # execute 51 cycles altogether, 11 with the 35 | # original parameters to allow the output to settle 36 | 37 | Y=51 cYcle count 38 | 39 | # now events triggered after 11 cycles 40 | # change the constant Bias and Set point 41 | # both from 20 to 30, a 10% step and turn 42 | # on the P with a high gain 43 | 44 | @11 S=30 Set point 45 | @11 P=1.9 Proportional gain 46 | 47 | # finished 51 cycles, time to quit 48 | 49 | @51 Q Quit 50 | -------------------------------------------------------------------------------- /ch24/ch24e.c: -------------------------------------------------------------------------------- 1 | /* Code by Ian D. K. Kelly for Chapter 24, "C Unleashed" */ 2 | /* Calculate the number "e" to as much accuracy as possible */ 3 | 4 | /* Ch24E.c 5 | * 6 | * E - compute e to as much accuracy as possible for "long double" 7 | * 8 | * Copyright (C) 1999 Ian D. K. Kelly, 9 | * idkk Consultancy Ltd. 10 | * Macmillan Computer Publishing 11 | * 12 | * This program is free software; you can redistribute it and/or modify 13 | * it under the terms of the GNU General Public License as published by 14 | * the Free Software Foundation; either version 2 of the License, or 15 | * (at your option) any later version. 16 | * 17 | * This program is distributed in the hope that it will be useful, 18 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 | * GNU General Public License for more details. 21 | * 22 | * You should have received a copy of the GNU General Public License 23 | * along with this program; if not, write to the Free Software 24 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 25 | * 26 | * Ian Kelly may be contacted at idkk@idkk.com 27 | * 28 | */ 29 | 30 | #include 31 | int main(int argc, char * argv[]) 32 | { 33 | long double dResult; 34 | long double dWork; 35 | int i; 36 | 37 | dResult = 1.0; 38 | dWork = 1.0; 39 | 40 | for (i=1;(i<30);i++) 41 | { 42 | dWork /= i; 43 | dResult += dWork; 44 | } 45 | printf("e = %32.28lf\n",dResult); 46 | 47 | return 0; 48 | } 49 | -------------------------------------------------------------------------------- /ch06/time_t.c: -------------------------------------------------------------------------------- 1 | /**************************************/ 2 | /* */ 3 | /* Code from the book C Unleashed */ 4 | /* Macmillan, 2000 */ 5 | /* Chapter 6: Data Files */ 6 | /* Steve Summit 2000-03-17 */ 7 | /* */ 8 | /**************************************/ 9 | 10 | #include 11 | #include 12 | 13 | #define TRUE 1 14 | #define FALSE 0 15 | 16 | void 17 | timetprint(time_t t, FILE *ofp) 18 | { 19 | char buf[25]; 20 | struct tm *tp = localtime(&t); 21 | strftime(buf, sizeof(buf), "%Y-%m-%dT%H:%M:%S", tp); 22 | fputs(buf, ofp); 23 | } 24 | 25 | time_t 26 | timetparse(char *str) 27 | { 28 | int y, mo, d; 29 | int h, m, s = 0; 30 | struct tm tm = {0}; 31 | 32 | if(sscanf(str, "%d-%d-%dT%d:%d:%d", &y, &mo, &d, &h, &m, &s) 33 | < 5 && sscanf(str, "%4d%2d%2dT%2d%2d%2d", 34 | &y, &mo, &d, &h, &m, &s) < 5) 35 | return (time_t)(-1); 36 | 37 | tm.tm_year = y - 1900; tm.tm_mon = mo - 1; tm.tm_mday = d; 38 | tm.tm_hour = h; tm.tm_min = m; tm.tm_sec = s; 39 | 40 | return mktime(&tm); 41 | } 42 | 43 | void puttime(time_t t, FILE *ofp) 44 | { 45 | int i; 46 | for(i = 0; i < 6; i++) 47 | { 48 | putc(t & 0xff, ofp); 49 | t >>= 8; 50 | } 51 | } 52 | 53 | int gettime(time_t *tp, FILE *ifp) 54 | { 55 | time_t t; 56 | char buf[6]; 57 | int i; 58 | if(fread(buf, 1, 6, ifp) != 6) 59 | return FALSE; 60 | t = buf[5]; /* sign extend, probably */ 61 | for(i = 5-1; i >= 0; i--) 62 | t = (t << 8) | (buf[i] & 0xff); 63 | *tp = t; 64 | return TRUE; 65 | } 66 | -------------------------------------------------------------------------------- /ch20/help: -------------------------------------------------------------------------------- 1 | genargs - C program generator, R Heathfield, January 2000 2 | 3 | Usage: 4 | genargs [-internal] infile outfile logfile helpfile 5 | 6 | Purpose: creates a C program with 7 | primitive argv checking 8 | 9 | -internal: optional switch. If 10 | specified, generates 11 | an application function. 12 | 13 | infile: specifies the arguments 14 | expected by the program, 15 | using the grammar detailed below. 16 | 17 | outfile: filename in which to store output. 18 | 19 | logfile: parse errors recorded here. 20 | 21 | helpfile: used for writing Help() function, 22 | displayed when args are incorrect. 23 | 24 | --- infile grammar --- 25 | 26 | infile: 27 | specifier 28 | infile specifier 29 | 30 | specifier: one of 31 | switchspecifier 32 | doublespecifier 33 | longspecifier 34 | stringspecifier 35 | 36 | switchspecifier: 37 | -identifier 38 | 39 | doublespecifier: 40 | identifier D 41 | 42 | longspecifier: 43 | identifier L 44 | 45 | stringspecifier: 46 | identifier S length 47 | 48 | identifier: 49 | letter 50 | identifiertail letter 51 | 52 | identifiertail: 53 | letterorunderscore identifiertail 54 | digit identifiertail 55 | letterorunderscore 56 | digit 57 | 58 | letterorunderscore: 59 | letter 60 | _ 61 | 62 | letter: one of 63 | A B C D E F G H I J K L M N O P Q R S T U V W X Y Z 64 | a b c d e f g h i j k l m n o p q r s t u v w x y z 65 | 66 | digit: one of 67 | 0 1 2 3 4 5 6 7 8 9 68 | 69 | length: 70 | 1 to 255 71 | 72 | -------------------------------------------------------------------------------- /ch13/CPPCOMP.H: -------------------------------------------------------------------------------- 1 | /* 2 | ** The proper usage and copyright information for 3 | ** this software is covered in DSCRLic.TXT 4 | ** This code is Copyright 1999 by Dann Corbit 5 | */ 6 | 7 | /* 8 | ** Etype comparison functions for C++ templates. 9 | */ 10 | 11 | #define PRELUDE template < class Etype > inline 12 | 13 | /* 14 | ** Is object a strictly greater than object b? 15 | */ 16 | PRELUDE 17 | int GT(Etype & a, Etype & b) 18 | { 19 | return a > b; 20 | } 21 | 22 | /* 23 | ** Is object a greater than or equal to object b? 24 | */ 25 | PRELUDE 26 | int GE(Etype & a, Etype & b) 27 | { 28 | return a >= b; 29 | } 30 | 31 | /* 32 | ** Is object a strictly less than object b? 33 | */ 34 | PRELUDE 35 | int LT(Etype & a, Etype & b) 36 | { 37 | return a < b; 38 | } 39 | 40 | /* 41 | ** Is object a less than or equal to object b? 42 | */ 43 | PRELUDE 44 | int LE(Etype & a, Etype & b) 45 | { 46 | return a <= b; 47 | } 48 | 49 | /* 50 | ** Is object a exactly equal to object b? 51 | */ 52 | PRELUDE 53 | int EQ(Etype & a, Etype & b) 54 | { 55 | return a == b; 56 | } 57 | 58 | /* 59 | ** A generic compare. The others are better. 60 | ** This requres an average of 1.5 compare operations per call. 61 | */ 62 | PRELUDE 63 | int CMP(Etype & a, Etype & b) 64 | { 65 | return a > b ? 1 : a < b ? -1 : 0; 66 | } 67 | 68 | /* 69 | ** Exchange two objects in an array. 70 | */ 71 | PRELUDE 72 | void SWAP(Etype & a, Etype & b) 73 | { 74 | Etype tmp = a; 75 | a = b; 76 | b = tmp; 77 | } 78 | -------------------------------------------------------------------------------- /ch03/refs: -------------------------------------------------------------------------------- 1 | 2 | WEB REFERENCES 3 | 4 | Hsieh, Paul 5 | Programming Optimization 6 | http://www.azillionmonkeys.com/qed/optimize.html 7 | 8 | This page looks at optimization from several 9 | different angles. The section which lays 10 | waste to common misconceptions about optimization 11 | is a must-read. 12 | 13 | Lee, Michael 14 | Optimization of Computer Programs in C 15 | http://www.ontek.com/mikey/optimization.html 16 | 17 | This page focuses on sample microoptimizations 18 | that could help speed up your code, with 19 | discussion of when such changes are useful and 20 | appropriate. It is essentially an expansion 21 | on the Microoptimization section in this chapter. 22 | 23 | Nullstone Corporation 24 | NULLSTONE Optimization Categories 25 | http://www.nullstone.com/htmls/category.htm 26 | 27 | This is an index to descriptions of common compiler-level 28 | optimizations. Each description includes a clear and 29 | readable example. 30 | 31 | PRINT REFERENCES 32 | 33 | Abrash, Michael. 34 | Zen of Program Optimization 35 | ISBN 1-883577-03-9 36 | 37 | Focuses on x86 and Pentium processors with in-depth 38 | examples of optimizing complete programs. He has 39 | several other interesting books specifically addressing 40 | graphics optimization. 41 | 42 | Dowd, Kevin & Severance, Charles. 43 | High Performance Computing, 2nd Edition 44 | O'Reilly & Associates. ISBN 1-56592-312-X 45 | 46 | This takes a high level view of computer performance, 47 | beyond the scope of language-specific optimizations 48 | and includes information on parallelism and supercomputers. 49 | 50 | -------------------------------------------------------------------------------- /ch10/tok3.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | char * 5 | sepstr(char **s, char *delim) { 6 | char *ret; 7 | size_t n; 8 | 9 | /* sanity check */ 10 | if (!s || !*s || !delim) 11 | return NULL; 12 | 13 | /* we return a pointer to the current value of s */ 14 | ret = *s; 15 | 16 | /* first, we find out how much of '*s' is *not* in 'delim' - we'll 17 | * call that value 'n'. 18 | * 19 | * if (*s)[n] is a null byte, the entire string contains no instances 20 | * of any character in delim; otherwise, it's the first delimiter 21 | * found. 22 | */ 23 | n = strcspn(*s, delim); 24 | if ((*s)[n]) { 25 | (*s)[n] = '\0'; 26 | /* advance s to one past the first delimiter */ 27 | *s += (n + 1); 28 | } else { 29 | /* no more strings to return */ 30 | *s = NULL; 31 | } 32 | 33 | /* and we return the saved pointer to the old contents of *s. */ 34 | return ret; 35 | } 36 | 37 | void 38 | tok(char *s, char *delim) { 39 | char *tmp; 40 | 41 | tmp = sepstr(&s, delim); 42 | while (tmp) { 43 | if (strspn(tmp, "0123456789,") == strlen(tmp) && 44 | strchr(tmp, ',')) { 45 | tok(tmp, ","); 46 | } else { 47 | printf("token: %s\n", tmp); 48 | } 49 | tmp = sepstr(&s, delim); 50 | } 51 | } 52 | 53 | int 54 | main(void) { 55 | /* never used a fixed size buffer like this in real code! */ 56 | char buf[1024]; 57 | /* to eat the newline */ 58 | char *nl; 59 | 60 | while (fgets(buf, 1024, stdin)) { 61 | /* I consider the != NULL superfluous, but some compilers 62 | * will give a warning without it. 63 | */ 64 | if ((nl = strchr(buf, '\n')) != NULL) { 65 | /* no need for newline */ 66 | *nl = '\0'; 67 | } 68 | tok(buf, " "); 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /ch23/cgi.h: -------------------------------------------------------------------------------- 1 | /* cgi.h - CGI Utilities 2 | * 3 | * 4 | * Copyright (C) 1999 Chad Dixon 5 | * Macmillan Computer Publishing 6 | * 7 | * This program is free software; you can redistribute it 8 | * and/or modify it under the terms of the GNU General 9 | * Public License as published by the Free Software 10 | * Foundation; either version 2 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will 14 | * be useful, but WITHOUT ANY WARRANTY; without even the 15 | * implied warranty of MERCHANTABILITY or FITNESS FOR A 16 | * PARTICULAR PURPOSE. See the GNU General Public License 17 | * for more details. 18 | * 19 | * You should have received a copy of the GNU General 20 | * Public License along with this program; if not, write 21 | * to the Free Software Foundation, Inc., 675 Mass Ave, 22 | * Cambridge, MA 02139, USA. 23 | * 24 | * Chad Dixon may be contacted by email at: 25 | * http://www.loopy.org 26 | * 27 | */ 28 | 29 | #ifndef CGI_H__ 30 | #define CGI_H__ 31 | 32 | #define CGI_SUCCESS 0 33 | #define CGI_NULL_REQ_METHOD 1 34 | #define CGI_UNKNOWN_METHOD 2 35 | #define CGI_NO_QUERY_STRING 3 36 | #define CGI_NO_MEMORY 4 37 | #define CGI_BAD_CONTENT_LENGTH 5 38 | #define CGI_NO_DATA 6 39 | 40 | typedef struct CGI_LIST 41 | { 42 | char *Variable; 43 | char *Value; 44 | struct CGI_LIST *Next; 45 | } CGI_LIST; 46 | 47 | char *DupString(const char *s); 48 | char *ReadCGIData(int *Error); 49 | int CGIHexToAscii(char *s); 50 | CGI_LIST *CGICreateList(char *Data); 51 | void CGIDestroyList(CGI_LIST *List); 52 | 53 | #endif 54 | -------------------------------------------------------------------------------- /ch10/search.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | /* search: finds 'key' if it's in a[0]..a[asize-1] */ 5 | int * 6 | search(int a[], int asize, int key) { 7 | int mid = asize / 2; 8 | 9 | /* sanity checks */ 10 | if (a == NULL || asize != 0) { 11 | return NULL; 12 | } 13 | if (a[mid] < key) { 14 | /* key is greater than middle element */ 15 | return search(a + mid + 1, asize - (mid + 1), key); 16 | } 17 | if (a[mid] > key) { 18 | /* key is less than middle element */ 19 | return search(a, mid, key); 20 | } 21 | /* not greater than, not less than - must be equal to! */ 22 | return &a[mid]; 23 | } 24 | 25 | int 26 | main(void) { 27 | int a[] = { 0, 2, 4, 5, 7, 9, 10, 12 }; 28 | 29 | printf("a == %p\n", (void *) a); 30 | printf("0 -> %p\n", (void *) search(a, sizeof(a)/sizeof(*a), 0)); 31 | printf("1 -> %p\n", (void *) search(a, sizeof(a)/sizeof(*a), 1)); 32 | printf("2 -> %p\n", (void *) search(a, sizeof(a)/sizeof(*a), 2)); 33 | printf("3 -> %p\n", (void *) search(a, sizeof(a)/sizeof(*a), 3)); 34 | printf("4 -> %p\n", (void *) search(a, sizeof(a)/sizeof(*a), 4)); 35 | printf("5 -> %p\n", (void *) search(a, sizeof(a)/sizeof(*a), 5)); 36 | printf("6 -> %p\n", (void *) search(a, sizeof(a)/sizeof(*a), 6)); 37 | printf("7 -> %p\n", (void *) search(a, sizeof(a)/sizeof(*a), 7)); 38 | printf("8 -> %p\n", (void *) search(a, sizeof(a)/sizeof(*a), 8)); 39 | printf("9 -> %p\n", (void *) search(a, sizeof(a)/sizeof(*a), 9)); 40 | printf("10 -> %p\n", (void *) search(a, sizeof(a)/sizeof(*a), 10)); 41 | printf("11 -> %p\n", (void *) search(a, sizeof(a)/sizeof(*a), 11)); 42 | printf("12 -> %p\n", (void *) search(a, sizeof(a)/sizeof(*a), 12)); 43 | printf("13 -> %p\n", (void *) search(a, sizeof(a)/sizeof(*a), 13)); 44 | 45 | return 0; 46 | } 47 | -------------------------------------------------------------------------------- /ch11/strarr.h: -------------------------------------------------------------------------------- 1 | /* strarr.h - header for string array demo 2 | * 3 | * STRARR - dynamic allocation of arrays of strings 4 | * 5 | * Copyright (C) 2000 Richard Heathfield 6 | * Eton Computer Systems Ltd 7 | * Macmillan Computer Publishing 8 | * 9 | * This program is free software; you can redistribute it 10 | * and/or modify it under the terms of the GNU General 11 | * Public License as published by the Free Software 12 | * Foundation; either version 2 of the License, or 13 | * (at your option) any later version. 14 | * 15 | * This program is distributed in the hope that it will 16 | * be useful, but WITHOUT ANY WARRANTY; without even the 17 | * implied warranty of MERCHANTABILITY or FITNESS FOR A 18 | * PARTICULAR PURPOSE. See the GNU General Public License 19 | * for more details. 20 | * 21 | * You should have received a copy of the GNU General 22 | * Public License along with this program; if not, write 23 | * to the Free Software Foundation, Inc., 675 Mass Ave, 24 | * Cambridge, MA 02139, USA. 25 | * 26 | * Richard Heathfield may be contacted by email at: 27 | * binary@eton.powernet.co.uk 28 | * 29 | */ 30 | 31 | #ifndef STRARR_H__ 32 | #define STRARR_H__ 33 | 34 | void FreeStrArray(char **Array, size_t NumRows); 35 | char **AllocStrArray(size_t NumRows, size_t Width); 36 | int ResizeOneString(char **Array, 37 | size_t Row, 38 | size_t NewSize); 39 | int AddRowsToStrArray(char ***ArrayPtr, 40 | size_t OldNumRows, 41 | int NumRowsToAdd, 42 | size_t InitWidth); 43 | int ConsolidateStrArray(char **ArrayPtr, 44 | size_t NumRows); 45 | 46 | #endif 47 | -------------------------------------------------------------------------------- /ch20/tee.c: -------------------------------------------------------------------------------- 1 | /* tee.c - T-pipe for stdout 2 | * 3 | * TEE - tee 4 | * 5 | * Copyright (C) 2000 Richard Heathfield 6 | * Eton Computer Systems Ltd 7 | * Macmillan Computer Publishing 8 | * 9 | * This program is free software; you can redistribute it 10 | * and/or modify it under the terms of the GNU General 11 | * Public License as published by the Free Software 12 | * Foundation; either version 2 of the License, or 13 | * (at your option) any later version. 14 | * 15 | * This program is distributed in the hope that it will 16 | * be useful, but WITHOUT ANY WARRANTY; without even the 17 | * implied warranty of MERCHANTABILITY or FITNESS FOR A 18 | * PARTICULAR PURPOSE. See the GNU General Public License 19 | * for more details. 20 | * 21 | * You should have received a copy of the GNU General 22 | * Public License along with this program; if not, write 23 | * to the Free Software Foundation, Inc., 675 Mass Ave, 24 | * Cambridge, MA 02139, USA. 25 | * 26 | * Richard Heathfield may be contacted by email at: 27 | * binary@eton.powernet.co.uk 28 | * 29 | */ 30 | #include 31 | 32 | void tee(FILE *fp) 33 | { 34 | char buffer[2048]; 35 | while(fgets(buffer, sizeof buffer, stdin)) 36 | { 37 | fprintf(stdout, "%s", buffer); 38 | if(NULL != fp) 39 | { 40 | fprintf(fp, "%s", buffer); 41 | } 42 | } 43 | } 44 | 45 | int main(int argc, char *argv[]) 46 | { 47 | FILE *fp = NULL; 48 | if(argc > 1) 49 | { 50 | fp = fopen(argv[1], "w"); 51 | if(NULL == fp) 52 | { 53 | fputs("Error opening output stream.", stderr); 54 | } 55 | } 56 | tee(fp); 57 | if(NULL != fp) 58 | { 59 | fclose(fp); 60 | } 61 | 62 | return 0; 63 | } 64 | 65 | -------------------------------------------------------------------------------- /ch13/DISTRIBS.H: -------------------------------------------------------------------------------- 1 | /* 2 | ** The proper usage and copyright information for 3 | ** this software is covered in DSCRLic.TXT 4 | ** This code is Copyright 1999 by Dann Corbit 5 | */ 6 | 7 | 8 | /* 9 | ** Prototypes for creation of data distributions. 10 | ** Testing purposes only. 11 | */ 12 | typedef struct { 13 | char *dtype; 14 | char *dname; 15 | char *iname; 16 | FILE *fdbl; 17 | FILE *fint; 18 | } sortfile; 19 | 20 | enum distribution_type { 21 | constant, five, ramp, haphazard, reverse, sorted, 22 | ten, twenty, two, perverse, trig, unknown 23 | }; 24 | 25 | int dopen(void); 26 | int dclose(void); 27 | void dsave(int[], double[], unsigned int, const char *); 28 | long dload(int[], double[], unsigned int, const char *); 29 | int drandom(int); 30 | 31 | void init_random(int[], double[], const int, const int, const int); 32 | void init_two(int[], double[], const int, const int); 33 | void init_five(int[], double[], const int, const int); 34 | void init_ten(int[], double[], const int, const int); 35 | void init_twenty(int[], double[], const int, const int); 36 | void init_sorted(int[], double[], const int, const int, const int); 37 | void init_reverse(int[], double[], const int); 38 | void init_constant(int[], double[], const int, const int); 39 | void init_ramp(int[], double[], const int, const int, const int); 40 | void init_trig(int[], double[], const int); 41 | void init_perverse(int[], double[], const int); 42 | 43 | void create_distribs(double[], int[], unsigned int); 44 | void make_distrib(double d[], int a[], size_t n, enum distribution_type which); 45 | -------------------------------------------------------------------------------- /ch15/del_tuple.c: -------------------------------------------------------------------------------- 1 | /************************************************************************** 2 | ** SP_DEL_TUPLE ** 3 | ** ** 4 | ** Delete a tuple ** 5 | ** ** 6 | ** INPUT: ** 7 | ** tuple -- The tuple which is to be deleted ** 8 | ** ** 9 | ** OUTPUT: ** 10 | ** void ** 11 | ** ** 12 | ** SIDE EFFECTS: ** 13 | ** None. ** 14 | ** ** 15 | ** NOTES: ** 16 | ** ** 17 | **************************************************************************/ 18 | 19 | #include 20 | #include 21 | #include "sparse.h" 22 | 23 | void sp_del_tuple(SP_TUPLE *tuple) 24 | /* SP_TUPLE *tuple The tuple which is to be deleted */ 25 | { 26 | /* If the tuple is empty, then no deletion is necessary */ 27 | if (tuple == (SP_TUPLE *)NULL) 28 | { 29 | return; 30 | } 31 | 32 | /* If there is data in the seq_stack, free it */ 33 | if (tuple->seq != (int *)NULL) 34 | { 35 | free(tuple->seq); 36 | } 37 | 38 | free(tuple); 39 | return; 40 | } 41 | -------------------------------------------------------------------------------- /ch15/makefile: -------------------------------------------------------------------------------- 1 | OBJS = get_header_list.o add_header_dimension.o add_tuple.o \ 2 | del_header_element.o del_node.o del_tuple.o get_node_list.o \ 3 | get_range_max.o get_range_min.o hdr_list_element_get.o \ 4 | ins_header_element.o ins_node.o next_node.o previous_node.o \ 5 | retrieve_node.o tuple_dim.o 6 | 7 | testme : $(OBJS) testme.o 8 | gcc -ansi $(OBJS) testme.o -o testme 9 | 10 | testme.o : testme.c sparse.h 11 | gcc -ansi -c testme.c 12 | 13 | get_header_list.o : get_header_list.c sparse.h 14 | gcc -ansi -c get_header_list.c 15 | 16 | add_header_dimension.o : add_header_dimension.c sparse.h 17 | gcc -ansi -c add_header_dimension.c 18 | 19 | add_tuple.o : add_tuple.c sparse.h 20 | gcc -ansi -c add_tuple.c 21 | 22 | del_header_element.o : del_header_element.c sparse.h 23 | gcc -ansi -c del_header_element.c 24 | 25 | del_node.o : del_node.c sparse.h 26 | gcc -ansi -c del_node.c 27 | 28 | del_tuple.o : del_tuple.c sparse.h 29 | gcc -ansi -c del_tuple.c 30 | 31 | get_node_list.o : get_node_list.c sparse.h 32 | gcc -ansi -c get_node_list.c 33 | 34 | get_range_max.o : get_range_max.c sparse.h 35 | gcc -ansi -c get_range_max.c 36 | 37 | get_range_min.o : get_range_min.c sparse.h 38 | gcc -ansi -c get_range_min.c 39 | 40 | hdr_list_element_get.o : hdr_list_element_get.c sparse.h 41 | gcc -ansi -c hdr_list_element_get.c 42 | 43 | ins_header_element.o : ins_header_element.c sparse.h 44 | gcc -ansi -c ins_header_element.c 45 | 46 | ins_node.o : ins_node.c sparse.h 47 | gcc -ansi -c ins_node.c 48 | 49 | next_node.o : next_node.c sparse.h 50 | gcc -ansi -c next_node.c 51 | 52 | previous_node.o : previous_node.c sparse.h 53 | gcc -ansi -c previous_node.c 54 | 55 | retrieve_node.o : retrieve_node.c sparse.h 56 | gcc -ansi -c retrieve_node.c 57 | 58 | tuple_dim.o : tuple_dim.c sparse.h 59 | gcc -ansi -c tuple_dim.c 60 | -------------------------------------------------------------------------------- /ch13/COMPOBJ.H: -------------------------------------------------------------------------------- 1 | /* 2 | ** The proper usage and copyright information for 3 | ** this software is covered in DSCRLic.TXT 4 | ** This code is Copyright 1999 by Dann Corbit 5 | */ 6 | 7 | 8 | #ifndef COMPARE_IS_DEFINED 9 | #define COMPARE_IS_DEFINED 10 | 11 | /* 12 | ** Generic methods needed to compare to direct objects 13 | ** (in contrast to comparing two pointers to object) 14 | */ 15 | 16 | /* 17 | ** stuff needed by radix sorts 18 | */ 19 | #define KEYSIZE (sizeof(Etype)) 20 | 21 | #define bitsbyte (CHAR_BIT) 22 | #define bytesword (KEYSIZE) 23 | #define bitsword (bitsbyte*bytesword) 24 | 25 | #define R (1 << bitsbyte) 26 | #define digit(A, B) ((A >> (bitsword-(B+1)*bitsbyte)) & (R-1)) 27 | 28 | /* 29 | ** Is object a strictly greater than object b? 30 | */ 31 | int GT(Etype a, Etype b) 32 | { 33 | return a > b; 34 | } 35 | 36 | /* 37 | ** Is object a greater than or equal to object b? 38 | */ 39 | int GE(Etype a, Etype b) 40 | { 41 | return a >= b; 42 | } 43 | 44 | /* 45 | ** Is object a strictly less than object b? 46 | */ 47 | int LT(Etype a, Etype b) 48 | { 49 | return a < b; 50 | } 51 | 52 | /* 53 | ** Is object a less than or equal to object b? 54 | */ 55 | int LE(Etype a, Etype b) 56 | { 57 | return a <= b; 58 | } 59 | 60 | /* 61 | ** Is object a exactly equal to object b? 62 | */ 63 | int EQ(Etype a, Etype b) 64 | { 65 | return a == b; 66 | } 67 | 68 | /* 69 | ** A generic compare. The others are better. 70 | */ 71 | int CMP(Etype a, Etype b) 72 | { 73 | return a > b ? 1 : a < b ? -1 : 0; 74 | } 75 | 76 | /* 77 | ** Exchange two objects in an array. 78 | */ 79 | void SWAP(Etype * a, Etype * b) 80 | { 81 | Etype tmp = *a; 82 | *a = *b; 83 | *b = tmp; 84 | } 85 | 86 | #endif /* COMPARE_IS_DEFINED */ 87 | 88 | -------------------------------------------------------------------------------- /ch18/chekline.c: -------------------------------------------------------------------------------- 1 | /* chekline.c - contains code to illustrate computing simple 2 | * checksums on strings read from stdin with 3 | * the standard function fgets() 4 | * 5 | * Copyright (C) 2000 Jack Klein 6 | * JK Technology 7 | * Macmillan Computer Publishing 8 | * 9 | * This program is free software; you can redistribute it 10 | * and/or modify it under the terms of the GNU General 11 | * Public License as published by the Free Software 12 | * Foundation; either version 2 of the License, or 13 | * (at your option) any later version. 14 | * 15 | * This program is distributed in the hope that it will 16 | * be useful, but WITHOUT ANY WARRANTY; without even the 17 | * implied warranty of MERCHANTABILITY or FITNESS FOR A 18 | * PARTICULAR PURPOSE. See the GNU General Public License 19 | * for more details. 20 | * 21 | * You should have received a copy of the GNU General 22 | * Public License along with this program; if not, write 23 | * to the Free Software Foundation, Inc., 675 Mass Ave, 24 | * Cambridge, MA 02139, USA. 25 | * 26 | * Jack Klein may be contacted by email at: 27 | * The_C_Guru@yahoo.com 28 | * 29 | */ 30 | 31 | #include 32 | #include 33 | 34 | int main(void) 35 | { 36 | char buff[100]; 37 | int count; 38 | unsigned long sum; 39 | char *nl; 40 | 41 | for ( ; ; ) 42 | { 43 | printf("Enter a string: "); 44 | fflush(stdout); 45 | if ( fgets(buff, sizeof buff, stdin) == NULL 46 | || buff[0] == '\n') 47 | { 48 | return 0; 49 | } 50 | if ((nl = strchr(buff, '\n')) != NULL) 51 | *nl = '\0'; 52 | 53 | for (count = 0, sum = 0; buff[count] != '\0'; ++count) 54 | { 55 | sum += (unsigned char)buff[count]; 56 | } 57 | printf("The checksum of \"%s\" is %lu decimal, %lX hex\n", 58 | buff, sum, sum); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /ch11/stack.h: -------------------------------------------------------------------------------- 1 | /* stack.h - source code for stack library 2 | * 3 | * STACK - Stack Library 4 | * 5 | * Copyright (C) 2000 Richard Heathfield 6 | * Eton Computer Systems Ltd 7 | * Macmillan Computer Publishing 8 | * 9 | * This program is free software; you can redistribute it 10 | * and/or modify it under the terms of the GNU General 11 | * Public License as published by the Free Software 12 | * Foundation; either version 2 of the License, or 13 | * (at your option) any later version. 14 | * 15 | * This program is distributed in the hope that it will 16 | * be useful, but WITHOUT ANY WARRANTY; without even the 17 | * implied warranty of MERCHANTABILITY or FITNESS FOR A 18 | * PARTICULAR PURPOSE. See the GNU General Public License 19 | * for more details. 20 | * 21 | * You should have received a copy of the GNU General 22 | * Public License along with this program; if not, write 23 | * to the Free Software Foundation, Inc., 675 Mass Ave, 24 | * Cambridge, MA 02139, USA. 25 | * 26 | * Richard Heathfield may be contacted by email at: 27 | * binary@eton.powernet.co.uk 28 | * 29 | */ 30 | 31 | #ifndef STACK_H__ 32 | #define STACK_H__ 33 | 34 | #include "sllist.h" 35 | 36 | #define STACK_SUCCESS 0 37 | #define STACK_PUSH_FAILURE 1 38 | #define STACK_POP_FAILURE 2 39 | #define STACK_EMPTY 3 40 | 41 | typedef struct STACK 42 | { 43 | #ifndef NDEBUG 44 | int CheckInit1; 45 | #endif 46 | 47 | SLLIST *StackPtr; 48 | size_t NumItems; 49 | 50 | #ifndef NDEBUG 51 | int CheckInit2; 52 | #endif 53 | } STACK; 54 | 55 | int StackPush(STACK *Stack, 56 | int Tag, 57 | void *Object, 58 | size_t Size); 59 | int StackPop(void *Object, STACK *Stack); 60 | 61 | void *StackGetData(STACK *Stack, int *Tag, size_t *Size); 62 | 63 | size_t StackCount(STACK *Stack); 64 | 65 | void StackDestroy(STACK *Stack); 66 | 67 | 68 | #endif 69 | -------------------------------------------------------------------------------- /ch11/queue.h: -------------------------------------------------------------------------------- 1 | /* queue.h - header for queue library 2 | * 3 | * QUEUE - Queue Library 4 | * 5 | * Copyright (C) 2000 Richard Heathfield 6 | * Eton Computer Systems Ltd 7 | * Macmillan Computer Publishing 8 | * 9 | * This program is free software; you can redistribute it 10 | * and/or modify it under the terms of the GNU General 11 | * Public License as published by the Free Software 12 | * Foundation; either version 2 of the License, or 13 | * (at your option) any later version. 14 | * 15 | * This program is distributed in the hope that it will 16 | * be useful, but WITHOUT ANY WARRANTY; without even the 17 | * implied warranty of MERCHANTABILITY or FITNESS FOR A 18 | * PARTICULAR PURPOSE. See the GNU General Public License 19 | * for more details. 20 | * 21 | * You should have received a copy of the GNU General 22 | * Public License along with this program; if not, write 23 | * to the Free Software Foundation, Inc., 675 Mass Ave, 24 | * Cambridge, MA 02139, USA. 25 | * 26 | * Richard Heathfield may be contacted by email at: 27 | * binary@eton.powernet.co.uk 28 | * 29 | */ 30 | 31 | #ifndef QUEUE_H__ 32 | #define QUEUE_H__ 33 | 34 | #include "sllist.h" 35 | 36 | #define QUEUE_SUCCESS 0 37 | #define QUEUE_ADD_FAILURE 1 38 | #define QUEUE_DEL_FAILURE 2 39 | #define QUEUE_EMPTY 3 40 | 41 | typedef struct QUEUE 42 | { 43 | #ifndef NDEBUG 44 | int CheckInit1; 45 | #endif 46 | 47 | SLLIST *HeadPtr; 48 | SLLIST *TailPtr; 49 | size_t NumItems; 50 | 51 | #ifndef NDEBUG 52 | int CheckInit2; 53 | #endif 54 | } QUEUE; 55 | 56 | int QueueAdd(QUEUE *Queue, 57 | int Tag, 58 | void *Object, 59 | size_t Size); 60 | int QueueRemove(void *Object, QUEUE *Queue); 61 | 62 | void *QueueGetData(QUEUE *Queue, int *Tag, size_t *Size); 63 | size_t QueueCount(QUEUE *Queue); 64 | 65 | void QueueDestroy(QUEUE *Queue); 66 | 67 | #endif 68 | -------------------------------------------------------------------------------- /ch16/testing5.cbb: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "graphs.h" 5 | #include "mstree.h" 6 | 7 | int main(void) 8 | { 9 | struct Graph * G; 10 | struct Graph * T; 11 | int i; 12 | int Index; 13 | struct EdgeScan E; 14 | 15 | /* make a graph */ 16 | G=MakeGraph(Matrix); 17 | if (!G) 18 | { 19 | puts("failed to make graph"); 20 | exit(0); 21 | } 22 | 23 | puts("Graph made"); 24 | 25 | /* add some nodes */ 26 | for (i=0;i<7;i++) 27 | { 28 | Index=AddVertex(G); 29 | if (Index<0) 30 | { 31 | puts("failed to add vertex"); 32 | exit(0); 33 | } 34 | printf("%d added\n",i); 35 | G->Vertices[Index]->Tag.Num=Index; 36 | puts("tag set"); 37 | } 38 | 39 | /* make some edges */ 40 | 41 | ConnectVertex(G,0,1,8); 42 | ConnectVertex(G,0,2,6); 43 | ConnectVertex(G,0,5,7); 44 | 45 | ConnectVertex(G,1,0,8); 46 | ConnectVertex(G,1,2,3); 47 | ConnectVertex(G,1,3,2); 48 | 49 | ConnectVertex(G,2,0,6); 50 | ConnectVertex(G,2,1,3); 51 | ConnectVertex(G,2,4,5); 52 | 53 | ConnectVertex(G,3,1,2); 54 | ConnectVertex(G,3,4,6); 55 | 56 | ConnectVertex(G,4,2,5); 57 | ConnectVertex(G,4,3,6); 58 | ConnectVertex(G,4,5,1); 59 | ConnectVertex(G,4,6,2); 60 | 61 | ConnectVertex(G,5,0,7); 62 | ConnectVertex(G,5,4,1); 63 | ConnectVertex(G,5,6,4); 64 | 65 | ConnectVertex(G,6,4,2); 66 | ConnectVertex(G,6,5,4); 67 | 68 | 69 | for (i=0;i<7;i++) { 70 | EdgeScanStart(G,i,&E); 71 | while (!EdgeScanNext(&E)) printf("%d ",E.Dest); 72 | EdgeScanEnd(&E); 73 | printf("\n"); 74 | } 75 | 76 | printf("About to prim...\n"); 77 | 78 | 79 | i=Prim_Undirected(G,&T); 80 | printf("prim done... \n"); 81 | if (i) { 82 | printf("error %d\n",i); 83 | exit(0); 84 | } 85 | 86 | for (i=0;i<7;i++) { 87 | EdgeScanStart(T,i,&E); 88 | while (!EdgeScanNext(&E)) printf("%d ",E.Dest); 89 | EdgeScanEnd(&E); 90 | printf("\n"); 91 | } 92 | 93 | 94 | FreeGraph(G); 95 | 96 | return 0; 97 | } 98 | -------------------------------------------------------------------------------- /ch13/COMPSTR.H: -------------------------------------------------------------------------------- 1 | /* 2 | ** The proper usage and copyright information for 3 | ** this software is covered in DSCRLic.TXT 4 | ** This code is Copyright 1999 by Dann Corbit 5 | */ 6 | 7 | 8 | #ifndef COMPSTR_IS_DEFINED 9 | #define COMPSTR_IS_DEFINED 10 | /* 11 | ** Generic methods needed to compare pointers to strings 12 | */ 13 | 14 | /* 15 | ** stuff needed by radix sorts 16 | */ 17 | #define KEYSIZE (8) 18 | 19 | #define bitsbyte (CHAR_BIT) 20 | #define bytesword (KEYSIZE) 21 | #define bitsword (bitsbyte*bytesword) 22 | 23 | #define R (1 << bitsbyte) 24 | #define digit(A, B) ((A >> (bitsword-(B+1)*bitsbyte)) & (R-1)) 25 | 26 | /* 27 | ** NOTE: These comparison methods could be made more efficient. 28 | ** This is just a lazy way to do it quickly. 29 | */ 30 | 31 | /* 32 | ** Is object a strictly greater than object b? 33 | */ 34 | int GT(Etype a, Etype b) 35 | { 36 | return (strcmp(a, b) > 0); 37 | } 38 | 39 | /* 40 | ** Is object a greater than or equal to object b? 41 | */ 42 | int GE(Etype a, Etype b) 43 | { 44 | return (strcmp(a, b) >= 0); 45 | } 46 | 47 | /* 48 | ** Is object a strictly less than object b? 49 | */ 50 | int LT(Etype a, Etype b) 51 | { 52 | return (strcmp(a, b) < 0); 53 | } 54 | 55 | /* 56 | ** Is object a less than or equal to object b? 57 | */ 58 | int LE(Etype a, Etype b) 59 | { 60 | return (strcmp(a, b) <= 0); 61 | } 62 | 63 | /* 64 | ** Is object a exactly equal to object b? 65 | */ 66 | int EQ(Etype a, Etype b) 67 | { 68 | return (strcmp(a, b) == 0); 69 | } 70 | 71 | /* 72 | ** A generic compare. 73 | */ 74 | int CMP(Etype a, Etype b) 75 | { 76 | return strcmp(a, b); 77 | } 78 | 79 | /* 80 | ** Exchange two pointers to char in an array. 81 | */ 82 | void SWAP(Etype * a, Etype * b) 83 | { 84 | Etype tmp = *a; 85 | *a = *b; 86 | *b = tmp; 87 | } 88 | 89 | #endif /* COMPPTR_IS_DEFINED */ 90 | 91 | -------------------------------------------------------------------------------- /ch16/testing4.cbb: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "graphs.h" 5 | #include "topsort.h" 6 | 7 | int main(void) 8 | { 9 | struct Graph * G; 10 | int i; 11 | int Index; 12 | int * res; 13 | 14 | /* make a graph */ 15 | G=MakeGraph(Matrix); 16 | if (!G) 17 | { 18 | puts("failed to make graph"); 19 | exit(0); 20 | } 21 | 22 | puts("Graph made"); 23 | 24 | /* add some nodes */ 25 | for (i=0;i<8;i++) 26 | { 27 | Index=AddVertex(G); 28 | if (Index<0) 29 | { 30 | puts("failed to add vertex"); 31 | exit(0); 32 | } 33 | printf("%d added\n",i); 34 | G->Vertices[Index]->Tag.Num=Index; 35 | puts("tag set"); 36 | } 37 | 38 | /* make some edges */ 39 | 40 | i=ConnectVertex(G,2,6,1); 41 | if (i) { 42 | puts("FAILED!"); 43 | exit(0); 44 | } 45 | 46 | i=ConnectVertex(G,2,0,1); 47 | if (i) { 48 | puts("FAILED!"); 49 | exit(0); 50 | } 51 | 52 | i=ConnectVertex(G,5,0,1); 53 | if (i) { 54 | puts("FAILED!"); 55 | exit(0); 56 | } 57 | 58 | i=ConnectVertex(G,5,3,1); 59 | if (i) { 60 | puts("FAILED!"); 61 | exit(0); 62 | } 63 | 64 | i=ConnectVertex(G,6,4,1); 65 | if (i) { 66 | puts("FAILED!"); 67 | exit(0); 68 | } 69 | 70 | i=ConnectVertex(G,0,7,1); 71 | if (i) { 72 | puts("FAILED!"); 73 | exit(0); 74 | } 75 | 76 | i=ConnectVertex(G,3,7,1); 77 | if (i) { 78 | puts("FAILED!"); 79 | exit(0); 80 | } 81 | 82 | i=ConnectVertex(G,4,1,1); 83 | if (i) { 84 | puts("FAILED!"); 85 | exit(0); 86 | } 87 | 88 | i=ConnectVertex(G,7,1,1); 89 | if (i) { 90 | puts("FAILED!"); 91 | exit(0); 92 | } 93 | 94 | puts("Edges done"); 95 | 96 | i=TopologicalSort(G,&res); 97 | printf("i=%d\n\n",i); 98 | if (i!=0) exit(0); 99 | 100 | for (i=0;iNumVertices;i++) { 101 | printf("%d",res[i]); 102 | } 103 | 104 | FreeGraph(G); 105 | 106 | return 0; 107 | } 108 | -------------------------------------------------------------------------------- /ch14/trie_extra.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "trie_internal.h" 5 | #include 6 | 7 | int 8 | print_node( trie_pointer node, char *prefix ) { 9 | if (!node) return 0; 10 | switch (*node) { 11 | case TRIE_LEAF: { 12 | struct trie_leaf *p = (struct trie_leaf*)node; 13 | printf( "%s: %*.*s -> %s\n", prefix, p->len_key, p->len_key, p->key, p->result ); 14 | return 0; 15 | } 16 | case TRIE_SUBTRIE: { 17 | struct trie_subtrie *p = (struct trie_subtrie*)node; 18 | int i; 19 | print_node( (trie_pointer)p->exact_match, prefix ); 20 | for (i=0; inext_level[i], new_prefix ); 24 | } 25 | return 0; 26 | } 27 | default: 28 | assert(0); /* if NDEBUG is not defined, the program will stop here */ 29 | } 30 | return 1; /* something went wrong */ 31 | } 32 | 33 | void print_trie( struct trie *trie ) 34 | { 35 | print_node( trie->root, "" ); 36 | } 37 | 38 | int validate_node( trie_pointer node ) 39 | { 40 | switch (*node) { 41 | case TRIE_LEAF: return 1; 42 | case TRIE_SUBTRIE: { 43 | struct trie_subtrie *p = (struct trie_subtrie*)node; 44 | int i, n; 45 | int count = p->count; 46 | int count2 = 0; 47 | if (count < 2) return 0; 48 | if (p->exact_match) { 49 | n = validate_node( (trie_pointer)p->exact_match ); 50 | if (!n) return 0; 51 | count2 += n; 52 | } 53 | for (i=0; inext_level[i]) { 55 | n = validate_node( (trie_pointer)p->next_level[i] ); 56 | if (!n) return 0; 57 | count2 += n; 58 | } 59 | if (count == count2) return count; else return 0; 60 | } 61 | default: assert( 0 ); return 0; 62 | } 63 | } 64 | 65 | int validate_trie( struct trie *trie ) 66 | { 67 | if (trie->root) 68 | return 0 != validate_node( trie->root ); 69 | else 70 | return 1; 71 | } 72 | -------------------------------------------------------------------------------- /ch13/SICOMP.H: -------------------------------------------------------------------------------- 1 | /* 2 | ** The proper usage and copyright information for 3 | ** this software is covered in DSCRLic.TXT 4 | ** This code is Copyright 1999 by Dann Corbit 5 | */ 6 | 7 | 8 | /* 9 | ** signed int comparison functions. 10 | */ 11 | 12 | typedef signed int Etype; 13 | 14 | #define CHUNK(x,y) digit(((Etype)*(x)-(Etype)INT_MIN),(y)) 15 | #define CHUNKS(x, a)\ 16 | { unsigned foo = (Etype)*(x)-(Etype)INT_MIN; \ 17 | int t;\ 18 | for (t = 0; t < sizeof(Etype); t++) \ 19 | a[digit(foo,t)+1][t]++;\ 20 | } 21 | #define COST 1 22 | #define GE ge_si 23 | #define GT gt_si 24 | #define LE le_si 25 | #define LT lt_si 26 | #define EQ eq_si 27 | #define CMP cmp_si 28 | 29 | #define INSORT InSort_si 30 | #define ARRAYISSORTED ArrayIsSorted_si 31 | #define ARRAYISREVERSED ArrayIsReversed_si 32 | #define BATCHER Batcher_si 33 | #define LINEARINSERTION LinearInsertion_si 34 | #define INSERTIONSORT InsertionSort_si 35 | #define INSERTONE InsertOne_si 36 | #define INSERTTWO InsertTwo_si 37 | #define INSERTFOUR InsertFour_si 38 | #define INSERTTHREE InsertThree_si 39 | #define INSERTZERO InsertZero_si 40 | #define MEDIAN Median_si 41 | #define RADIXLSD RadixLsd_si 42 | #define REVERSEARRAY ReverseArray_si 43 | #define SWAP Swap_si 44 | #define SHELLSORT Shellsort_si 45 | #define QSORTB qsort_si 46 | #define IQSORT5 Iqsort5_si 47 | #define HEAPSORT heapsort_si 48 | #define PERCDOWN percdown_si 49 | #define PARSCAN parscan_si 50 | #define PDELETEMIN pdeletemin_si 51 | #define PGETMIN pgetmin_si 52 | #define PNORMALIZE pnormalize_si 53 | #define PSHELLSORT pshellsort_si 54 | #define MERGE_SORT merge_sort_si 55 | #define RADIXMSD RadixMsd_si 56 | #define MMERGE Mmerge_si 57 | #define MSORT Msort_si 58 | #define MERGESORTB Mergesortb_si 59 | 60 | #include "compobj.h" 61 | -------------------------------------------------------------------------------- /ch16/README: -------------------------------------------------------------------------------- 1 | Chapter 16 - Graphs 2 | 3 | The files in this directory make up a simple but versatile library for 4 | manipulating graphs. Algorithms are provided for topological sorting, 5 | finding minimum spanning trees and finding shortest paths. Both adjacency 6 | lists and adjacency matrices are supported graph data structures. 7 | 8 | 9 | 10 | 11 | The following header files provide the 'front end' of the library: 12 | 13 | 14 | graphs.h The top level header file for the graph library. This provides 15 | top level prototypes for both adjacency lists and matrices. 16 | 17 | topsort.h Header file defining the topological sort function in topsort.c 18 | 19 | shpath.h Header file defining various structures and functions used to 20 | determine shortest paths. 21 | 22 | mstree.h Header file defining functions to determine the minimum spanning 23 | tree (or forest) of undirected graphs. 24 | 25 | dfsfuncs.h Header file defining an example depth-first search function to 26 | determine if two vertices are connected in less than E 27 | iterations. 28 | 29 | 30 | 31 | 32 | The following files are the library proper: 33 | 34 | 35 | graphs.c The workings behind most of the library. This code provides a 36 | common interface for both adjacency matrices and adjacency lists. 37 | The top level functions call the correct primitive function as 38 | defined in adjlist.c or adjmatrix depending on the type of graph. 39 | 40 | graphprv.h Internally used header which defines the Graph_Spec structure 41 | which is used to hold the pointers to the functions for each 42 | primitive operation of each graph type. 43 | 44 | adjlist.c An implementation of the primitives required for the library and 45 | adjlist.h an instance of a Graph_Spec structure for adjacency lists. 46 | 47 | adjmatrix.c An implementation of the primitives required for the library and 48 | adjmatrix.h an instance of a Graph_Spec structure for adjacency matrices. 49 | 50 | 51 | topsort.c Implementation of some useful algorithms. 52 | shpath.c 53 | mstree.c 54 | dfsfuncs.c 55 | 56 | -------------------------------------------------------------------------------- /ch03/bubble.c: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | void swap(char ** array, int i, int j) 11 | { 12 | char * tmp; 13 | 14 | tmp = array[i]; 15 | array[i] = array[j]; 16 | array[j] = tmp; 17 | } 18 | 19 | int compare(char * str1, char * str2) 20 | { 21 | char *tmp1, *tmp2, *x, *y; 22 | int result; 23 | 24 | tmp1 = malloc(strlen(str1)+1); 25 | if (tmp1 == NULL) 26 | { 27 | perror("ran out of memory"); 28 | exit(1); 29 | } 30 | 31 | x = str1; 32 | y = tmp1; 33 | while (*x != '\0') 34 | *y++ = toupper(*x++); 35 | 36 | tmp2 = malloc(strlen(str2)+1); 37 | if (tmp2 == NULL) 38 | { 39 | perror("ran out of memory"); 40 | exit(1); 41 | } 42 | 43 | x = str2; 44 | y = tmp2; 45 | while (*x != '\0') 46 | *y++ = toupper(*x++); 47 | 48 | result = strcmp(tmp1, tmp2); 49 | free(tmp1); 50 | free(tmp2); 51 | return result; 52 | } 53 | 54 | void bubblesort(char ** array, int len) 55 | { 56 | int i, j; 57 | 58 | for (i = 0; i < len - 1; i++) 59 | { 60 | for (j = 0; j < len - 1; j++) 61 | { 62 | if (compare(array[j], array[j+1]) > 1) 63 | swap(array, j, j+1); 64 | } 65 | } 66 | } 67 | 68 | int main(int argc, char ** argv) 69 | { 70 | int i, count; 71 | char ** array; 72 | char buffer[500]; 73 | FILE * file; 74 | 75 | if (argc < 2) exit(0); 76 | 77 | file = fopen(argv[1], "r"); 78 | if (file == NULL) 79 | { 80 | perror(argv[1]); 81 | exit(1); 82 | } 83 | 84 | array = calloc(10000, sizeof(char *)); 85 | for (i = 0; i < 10000; i++) 86 | { 87 | char * x; 88 | 89 | x = fgets(buffer, sizeof(buffer), file); 90 | if (x == NULL) break; 91 | 92 | array[i] = malloc(strlen(buffer)+1); 93 | strcpy(array[i], buffer); 94 | } 95 | count = i; 96 | 97 | fclose(file); 98 | 99 | bubblesort(array, count); 100 | 101 | for (i = 1; i < count; i ++) 102 | printf("%s", array[i]); 103 | 104 | free(array); 105 | return 0; 106 | } 107 | -------------------------------------------------------------------------------- /ch18/parity.c: -------------------------------------------------------------------------------- 1 | /* parity.c - contains a simple command line demonstration 2 | * of parity generation and its results 3 | * 4 | * Copyright (C) 2000 Jack Klein 5 | * Macmillan Computer Publishing 6 | * 7 | * This program is free software; you can redistribute it 8 | * and/or modify it under the terms of the GNU General 9 | * Public License as published by the Free Software 10 | * Foundation; either version 2 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will 14 | * be useful, but WITHOUT ANY WARRANTY; without even the 15 | * implied warranty of MERCHANTABILITY or FITNESS FOR A 16 | * PARTICULAR PURPOSE. See the GNU General Public License 17 | * for more details. 18 | * 19 | * You should have received a copy of the GNU General 20 | * Public License along with this program; if not, write 21 | * to the Free Software Foundation, Inc., 675 Mass Ave, 22 | * Cambridge, MA 02139, USA. 23 | * 24 | * Jack Klein may be contacted by email at: 25 | * The_C_Guru@yahoo.com 26 | * 27 | */ 28 | 29 | #include 30 | #include 31 | 32 | unsigned int even_parity(unsigned int ch) 33 | { 34 | int temp = 0; 35 | int count; 36 | 37 | /* trim to 7 bit ASCII */ 38 | ch &= 0x7f; 39 | 40 | /* set temp to 0 for even parity or 1 for odd parity */ 41 | for (count = 0; count < 8; ++count) 42 | { 43 | temp ^= ((ch >> count) & 1); 44 | } 45 | 46 | if (temp) 47 | { 48 | ch |= 0x80; 49 | } 50 | 51 | return ch; 52 | } 53 | 54 | int main(void) 55 | { 56 | char buff[22]; 57 | char *cp; 58 | 59 | for ( ; ; ) 60 | { 61 | printf("\nEnter up to 20 characters: "); 62 | fflush(stdout); 63 | 64 | if (fgets(buff, sizeof buff, stdin) == NULL || 65 | buff [0] == '\n') 66 | { 67 | puts("Goodbye!"); 68 | return 0; 69 | } 70 | 71 | /* remove newline from string if present */ 72 | if ((cp = strchr(buff, '\n')) != NULL) 73 | { 74 | *cp = '\0'; 75 | } 76 | 77 | for (cp = buff; *cp != '\0'; ++cp) 78 | { 79 | printf("0x%02X is 0x%02X with even parity\n", 80 | *cp & 0x7f, even_parity(*cp & 0x7f)); 81 | } 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /ch16/topsort.c: -------------------------------------------------------------------------------- 1 | /* topsort.c 2 | 3 | Implementation of a topological sort */ 4 | 5 | #include "topsort.h" 6 | #include 7 | 8 | #define Enqueue(zze) {queue[last]=zze;last++;} 9 | #define Dequeue(zze) {zze=queue[first];first++;} 10 | 11 | void InitIndegreeTable(struct Graph * G, int * itable) 12 | { 13 | /* 14 | build an indegree table from graph G 15 | itable must be at least G->NumVertices in length 16 | */ 17 | 18 | int i; 19 | struct EdgeScan E; 20 | 21 | for (i=0;iNumVertices;i++) { 22 | EdgeScanStart(G,i,&E); 23 | while (EdgeScanNext(&E)==0) 24 | { 25 | itable[E.Dest]++; 26 | } 27 | EdgeScanEnd(&E); 28 | } 29 | } 30 | 31 | int TopologicalSort(struct Graph * G, int ** sorted) 32 | { 33 | /* 34 | Perform a topological sort on graph G, creating 35 | an array of G->NumVertices integers and returning 36 | it in *sorted. 37 | 38 | Returns 0 on success, 39 | <0 on error (GRAPH_BADPARAM, GRAPH_OUTOFMEM, GRAPH_BADGRAPH) 40 | */ 41 | 42 | int first, last, i; 43 | int * queue; 44 | int * itable; 45 | struct EdgeScan E; 46 | 47 | if (!G || !sorted) return GRAPH_BADPARAM; 48 | 49 | queue=malloc(sizeof(int)*G->NumVertices); 50 | itable=malloc(sizeof(int)*G->NumVertices); 51 | if (!queue || !itable) 52 | { 53 | free(queue);free(itable); 54 | return GRAPH_OUTOFMEM; 55 | } 56 | 57 | InitIndegreeTable(G,itable); 58 | last=0;first=0; 59 | 60 | /* search for vertices with indegree 0 */ 61 | for (i=0;iNumVertices;i++) 62 | { 63 | if (itable[i]==0) Enqueue(i); 64 | } 65 | 66 | /* while there are still vertices with indegree 0... */ 67 | while (last!=first) 68 | { 69 | Dequeue(i); 70 | EdgeScanStart(G,i,&E); 71 | while (EdgeScanNext(&E)==0) 72 | { 73 | /* decrement the indegree of vertices adjacent to them */ 74 | 75 | itable[E.Dest]--; 76 | if (itable[E.Dest]==0) Enqueue(E.Dest); 77 | } 78 | EdgeScanEnd(&E); 79 | } 80 | 81 | free(itable); 82 | 83 | /* if we haven't dequeued G->NumVertices elements, we have a cyclic graph */ 84 | if (first!=G->NumVertices) 85 | { 86 | free(queue); 87 | return GRAPH_BADGRAPH; 88 | } 89 | 90 | *sorted=queue; 91 | return 0; 92 | } 93 | 94 | -------------------------------------------------------------------------------- /ch11/clist.h: -------------------------------------------------------------------------------- 1 | /* clist.h - header for circular list lib 2 | * 3 | * CLIST - Circular List Library 4 | * 5 | * Copyright (C) 2000 Richard Heathfield 6 | * Eton Computer Systems Ltd 7 | * Macmillan Computer Publishing 8 | * 9 | * This program is free software; you can redistribute it 10 | * and/or modify it under the terms of the GNU General 11 | * Public License as published by the Free Software 12 | * Foundation; either version 2 of the License, or 13 | * (at your option) any later version. 14 | * 15 | * This program is distributed in the hope that it will 16 | * be useful, but WITHOUT ANY WARRANTY; without even the 17 | * implied warranty of MERCHANTABILITY or FITNESS FOR A 18 | * PARTICULAR PURPOSE. See the GNU General Public License 19 | * for more details. 20 | * 21 | * You should have received a copy of the GNU General 22 | * Public License along with this program; if not, write 23 | * to the Free Software Foundation, Inc., 675 Mass Ave, 24 | * Cambridge, MA 02139, USA. 25 | * 26 | * Richard Heathfield may be contacted by email at: 27 | * binary@eton.powernet.co.uk 28 | * 29 | */ 30 | 31 | 32 | #ifndef CLIST_H__ 33 | #define CLIST_H__ 34 | 35 | #define CL_SUCCESS 0 36 | #define CL_NO_MEM 1 37 | #define CL_EMPTY 2 38 | #define CL_ZERO_SIZE 3 39 | 40 | typedef struct CL_ITEM 41 | { 42 | int Tag; 43 | struct CL_ITEM *Prev; 44 | struct CL_ITEM *Next; 45 | void *Object; 46 | size_t Size; 47 | } CL_ITEM; 48 | 49 | typedef struct CLIST 50 | { 51 | CL_ITEM *CurrentItem; 52 | size_t NumItems; 53 | } CLIST; 54 | 55 | CL_ITEM *CLCreate(int Tag, void *Object, size_t Size); 56 | 57 | int CLAddItem(CLIST *List, 58 | int Tag, 59 | void *Object, 60 | size_t Size); 61 | 62 | int CLUpdate(CLIST *List, 63 | int NewTag, 64 | void *NewObject, 65 | size_t NewSize); 66 | 67 | void *CLGetData(CLIST *List, 68 | int *Tag, 69 | size_t *Size); 70 | 71 | void CLRotate(CLIST *List, int Places); 72 | 73 | int CLDelete(CLIST *List); 74 | 75 | void CLDestroy(CLIST *List); 76 | 77 | int CLWalk(CLIST *List, 78 | int(*Func)(int, void *, void *), 79 | void *Args); 80 | #endif 81 | -------------------------------------------------------------------------------- /ch08/MEMTRKMN.C: -------------------------------------------------------------------------------- 1 | /* memtrkmn.c - driver for memory tracker 2 | * 3 | * MEMTRACK - Memory Tracking Library 4 | * 5 | * Copyright (C) 2000 Richard Heathfield 6 | * Eton Computer Systems Ltd 7 | * Macmillan Computer Publishing 8 | * 9 | * This program is free software; you can redistribute it 10 | * and/or modify it under the terms of the GNU General 11 | * Public License as published by the Free Software 12 | * Foundation; either version 2 of the License, or 13 | * (at your option) any later version. 14 | * 15 | * This program is distributed in the hope that it will 16 | * be useful, but WITHOUT ANY WARRANTY; without even the 17 | * implied warranty of MERCHANTABILITY or FITNESS FOR A 18 | * PARTICULAR PURPOSE. See the GNU General Public License 19 | * for more details. 20 | * 21 | * You should have received a copy of the GNU General 22 | * Public License along with this program; if not, write 23 | * to the Free Software Foundation, Inc., 675 Mass Ave, 24 | * Cambridge, MA 02139, USA. 25 | * 26 | * Richard Heathfield may be contacted by email at: 27 | * binary@eton.powernet.co.uk 28 | * 29 | */ 30 | #include 31 | #include 32 | 33 | #include "memtrack.h" 34 | 35 | #define N 128 36 | 37 | typedef struct FOO 38 | { 39 | char str[128]; 40 | double doub[8]; 41 | int i[16]; 42 | } FOO; 43 | 44 | int main(void) 45 | { 46 | char *a[N] = {0}; 47 | int *b[N] = {0}; 48 | long *c[N] = {0}; 49 | double *d[N] = {0}; 50 | FOO *f[N] = {0}; 51 | 52 | int i; 53 | 54 | for(i = 0; i < N; i++) 55 | { 56 | a[i] = AllocMemory(sizeof *a[i]); 57 | b[i] = AllocMemory(4 * sizeof *b[i]); 58 | c[i] = AllocMemory(4 * sizeof *c[i]); 59 | d[i] = AllocMemory(8 * sizeof *d[i]); 60 | f[i] = AllocMemory(sizeof *f[i]); 61 | } 62 | 63 | TrackMemory(MEMTRK_REPORT, 64 | 0, NULL, 0, NULL, 0); 65 | 66 | for(i = 0; i < N; i++) 67 | { 68 | ReleaseMemory(a[i]); 69 | ReleaseMemory(b[i]); 70 | ReleaseMemory(c[i]); 71 | ReleaseMemory(d[i]); 72 | ReleaseMemory(f[i]); 73 | } 74 | 75 | TrackMemory(MEMTRK_REPORT, 76 | 0, NULL, 0, NULL, 0); 77 | 78 | TrackMemory(MEMTRK_DESTROY, 79 | 0, NULL, 0, NULL, 0); 80 | return 0; 81 | } 82 | -------------------------------------------------------------------------------- /ch22/Index.txt: -------------------------------------------------------------------------------- 1 | /* CUPS - C Unleashed Portable Sockets Library 2 | * 3 | * 4 | * Copyright (C) 1999 Chad Dixon 5 | * Macmillan Computer Publishing 6 | * 7 | * This program is free software; you can redistribute it 8 | * and/or modify it under the terms of the GNU General 9 | * Public License as published by the Free Software 10 | * Foundation; either version 2 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will 14 | * be useful, but WITHOUT ANY WARRANTY; without even the 15 | * implied warranty of MERCHANTABILITY or FITNESS FOR A 16 | * PARTICULAR PURPOSE. See the GNU General Public License 17 | * for more details. 18 | * 19 | * You should have received a copy of the GNU General 20 | * Public License along with this program; if not, write 21 | * to the Free Software Foundation, Inc., 675 Mass Ave, 22 | * Cambridge, MA 02139, USA. 23 | * 24 | * Chad Dixon may be contacted at: 25 | * http://www.loopy.org 26 | * 27 | */ 28 | 29 | 30 | 31 | 32 | Index of files 33 | 34 | ctc.c CUPS TCP Client Code 35 | cts.c CUPS TCP Server Code 36 | cuc.c CUPS UDP Client Code 37 | cus.c CUPS UDP Server Code 38 | wtc.c Windows TCP Client Code 39 | wts.c Windows TCP Server Code 40 | wuc.c Windows UDP Client Code 41 | wus.c Windows UDP Server Code 42 | utc.c UNIX TCP Client Code 43 | uts.c UNIX TCP Server Code 44 | uuc.c UNIX UDP Client Code 45 | uus.c UNIX UDP Server Code 46 | u_cups.c UNIX CUPS Code 47 | u_cups.h UNIX CUPS Header File 48 | w_cups.c Windows CUPS Code 49 | w_cups.h Windows CUPS Header File 50 | pre.c Preprocessor Based TCP Server Code 51 | 52 | /*Note - The u_cups.h and w_cups.h MUST be renamed 53 | * to cups.c and cups.h for the library to function. 54 | * They are named as such for clarity here. In 55 | * actual use, you would use the associated cups 56 | * library for your platform 57 | */ 58 | 59 | 60 | /* Note: Chad means... 61 | 62 | If you're running Unix, copy u_cups.h to your Unix 63 | system as cups.h, and use u_cups.c to build your library. 64 | 65 | If you're running Windows, copy w_cups.h to your Windows 66 | system as cups.h, and use w_cups.c to build your library. 67 | 68 | If you're running both, do both. 69 | 70 | 71 | :-) 72 | 73 | RJH 18 June 2000. 74 | 75 | */ 76 | -------------------------------------------------------------------------------- /ch15/add_tuple.c: -------------------------------------------------------------------------------- 1 | /************************************************************************** 2 | ** SP_ADD_TUPLE ** 3 | ** ** 4 | ** Adds a sequence number into a tuple. ** 5 | ** ** 6 | ** INPUT: ** 7 | ** tuple -- The tuple which is to get the new sequence number ** 8 | ** dim -- The dimension getting a new sequence value ** 9 | ** seq -- The sequence number being added ** 10 | ** ** 11 | ** OUTPUT: ** 12 | ** SP_TUPLE * -- A pointer to the modified tuple ** 13 | ** ** 14 | ** SIDE EFFECTS: ** 15 | ** None. ** 16 | ** ** 17 | ** NOTES: ** 18 | ** ** 19 | **************************************************************************/ 20 | 21 | #include 22 | #include 23 | #include "sparse.h" 24 | 25 | SP_TUPLE *sp_add_tuple(SP_TUPLE *tuple, int dim, int seq) 26 | /* SP_TUPLE *tuple The tuple which is to get the new sequence number */ 27 | /* int dim The dimension number */ 28 | /* seq The sequence number being added */ 29 | { 30 | int *new_seq; 31 | 32 | /* If the tuple is empty, then no sequence can be added */ 33 | if (tuple == (SP_TUPLE *)NULL) 34 | { 35 | return((SP_TUPLE *)NULL); 36 | } 37 | 38 | /* If the passed dimension is outside the range of the tuple dimension, then 39 | the insert fails */ 40 | if ((tuple->dimensions < dim) || (dim < (int)1)) 41 | { 42 | return((SP_TUPLE *)NULL); 43 | } 44 | 45 | new_seq = (int *)(tuple->seq + ((dim - 1))); 46 | *new_seq = seq; 47 | return(tuple); 48 | } 49 | -------------------------------------------------------------------------------- /ch16/testing2.cbb: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "graphs.h" 5 | #include "shpath.h" 6 | 7 | int main(void) 8 | { 9 | struct Graph * G; 10 | int i; 11 | int Index; 12 | struct Dijkstra_Table T; 13 | 14 | /* make a graph */ 15 | G=MakeGraph(Matrix); 16 | if (!G) 17 | { 18 | puts("failed to make graph"); 19 | exit(0); 20 | } 21 | 22 | puts("Graph made"); 23 | 24 | /* add some nodes */ 25 | for (i=0;i<8;i++) 26 | { 27 | Index=AddVertex(G); 28 | if (Index<0) 29 | { 30 | puts("failed to add vertex"); 31 | exit(0); 32 | } 33 | printf("%d added\n",i); 34 | G->Vertices[Index]->Tag.Num=Index; 35 | puts("tag set"); 36 | } 37 | 38 | /* make some edges */ 39 | 40 | puts("1"); 41 | i=ConnectVertex(G,1,2,1); 42 | if (i) { 43 | puts("FAILED!"); 44 | exit(0); 45 | } 46 | 47 | puts("2"); 48 | i=ConnectVertex(G,1,4,2); 49 | if (i) { 50 | puts("FAILED!"); 51 | exit(0); 52 | } 53 | 54 | puts("4"); 55 | i=ConnectVertex(G,2,5,-3); 56 | if (i) { 57 | puts("FAILED!"); 58 | exit(0); 59 | } 60 | 61 | puts("5"); 62 | i=ConnectVertex(G,4,6,1); 63 | if (i) { 64 | puts("FAILED!"); 65 | exit(0); 66 | } 67 | 68 | puts("7"); 69 | i=ConnectVertex(G,6,7,3); 70 | if (i) { 71 | puts("FAILED!"); 72 | exit(0); 73 | } 74 | 75 | puts("8"); 76 | i=ConnectVertex(G,5,7,2); 77 | if (i) { 78 | puts("FAILED!"); 79 | exit(0); 80 | } 81 | 82 | puts("9"); 83 | i=ConnectVertex(G,3,2,5); 84 | if (i) { 85 | puts("FAILED!"); 86 | exit(0); 87 | } 88 | 89 | puts("12"); 90 | i=ConnectVertex(G,6,3,2); 91 | if (i) { 92 | puts("FAILED!"); 93 | exit(0); 94 | } 95 | 96 | puts("14"); 97 | 98 | Dijkstra_InitTable(&T); 99 | 100 | if (Bellman(G, 1,&T)) 101 | { /* some error handling */ 102 | puts("Error! Failed to perform Dijkstra's algorithm!\n"); 103 | exit(0); 104 | } 105 | puts("Beldone"); 106 | 107 | for (i=1;i<8;i++) { 108 | printf("%d %d %d\n",i,T.Results[i].Total,T.Results[i].Previous); 109 | } 110 | 111 | Dijkstra_FreeTable(&T); /* free the results from within the table (does not free T, just T->Results) */ 112 | 113 | puts("Freed"); 114 | 115 | FreeGraph(G); 116 | 117 | return 0; 118 | } 119 | -------------------------------------------------------------------------------- /ch24/ch24Drft.c: -------------------------------------------------------------------------------- 1 | /* Code by Ian D. K. Kelly for Chapter 24, "C Unleashed" */ 2 | 3 | /* Ch24Drft.c 4 | * 5 | * Drift - arithmetic drift detection 6 | * 7 | * Copyright (C) 1999 Ian D. K. Kelly, 8 | * idkk Consultancy Ltd. 9 | * Macmillan Computer Publishing 10 | * 11 | * This program is free software; you can redistribute it and/or modify 12 | * it under the terms of the GNU General Public License as published by 13 | * the Free Software Foundation; either version 2 of the License, or 14 | * (at your option) any later version. 15 | * 16 | * This program is distributed in the hope that it will be useful, 17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 | * GNU General Public License for more details. 20 | * 21 | * You should have received a copy of the GNU General Public License 22 | * along with this program; if not, write to the Free Software 23 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 24 | * 25 | * Ian Kelly may be contacted at idkk@idkk.com 26 | * 27 | */ 28 | 29 | /* This code may be used, with modifications, to detect arithmetic */ 30 | /* "drift" in your environment. You will need to consider: */ 31 | /* (a) different arithmetic types, other than "double, and */ 32 | /* (b) different values for "dB" and "dA" which may produce errors */ 33 | /* of rounding due to bias. */ 34 | 35 | #include 36 | 37 | int main (int argc, char * argv[]) 38 | { 39 | double dA; 40 | double dB; 41 | double dC; 42 | double dD; 43 | double dE; 44 | int i; 45 | 46 | dA = 1.0; 47 | dB = 0.555555555555555555555555555555; 48 | dC = dA + dB; 49 | dC -= dA; 50 | dE = dB - dC; 51 | printf("diff=%20.18f\n",dE); 52 | dD = dB; 53 | dE = dA; 54 | 55 | /* Drift may require many more iterations than 1000 - you need to */ 56 | /* experiment with this too: */ 57 | for (i=0;(i<1000);i++) 58 | { 59 | dD = (((dA + dD) - dA) + dA) - dA; 60 | dE = (((dB + dE) - dB) + dB) - dB; 61 | } 62 | 63 | printf("dA=%20.18f dB=%20.18f dC=%20.18f\n",dA,dB,dC); 64 | printf("dD=%20.18f dE=%20.18f\n",dD,dE); 65 | 66 | return 0; 67 | } 68 | -------------------------------------------------------------------------------- /ch11/C11_016.c: -------------------------------------------------------------------------------- 1 | /* c11_016.c - demo of dynamically allocated 2D array 2 | * 3 | * C11_016 - dynamic reallocation of arrays 4 | * 5 | * Copyright (C) 2000 Richard Heathfield 6 | * Eton Computer Systems Ltd 7 | * Macmillan Computer Publishing 8 | * 9 | * This program is free software; you can redistribute it 10 | * and/or modify it under the terms of the GNU General 11 | * Public License as published by the Free Software 12 | * Foundation; either version 2 of the License, or 13 | * (at your option) any later version. 14 | * 15 | * This program is distributed in the hope that it will 16 | * be useful, but WITHOUT ANY WARRANTY; without even the 17 | * implied warranty of MERCHANTABILITY or FITNESS FOR A 18 | * PARTICULAR PURPOSE. See the GNU General Public License 19 | * for more details. 20 | * 21 | * You should have received a copy of the GNU General 22 | * Public License along with this program; if not, write 23 | * to the Free Software Foundation, Inc., 675 Mass Ave, 24 | * Cambridge, MA 02139, USA. 25 | * 26 | * Richard Heathfield may be contacted by email at: 27 | * binary@eton.powernet.co.uk 28 | * 29 | */ 30 | 31 | #error Don't use this code. It invokes undefined behaviour. See comment. 32 | 33 | /* Please check the comment in c11_015.c for a full (ish) description 34 | * of why you shouldn't use this code. 35 | * 36 | * RJH 8/6/2000 37 | */ 38 | 39 | #include 40 | 41 | typedef int T; 42 | 43 | T **Reallocate(T **OldP, 44 | size_t oldm, 45 | size_t oldn, 46 | size_t newm, 47 | size_t newn) 48 | { 49 | T **NewP = NULL; 50 | T *p; 51 | size_t Row; 52 | 53 | /* Do we need more memory? */ 54 | if(newm * newn * sizeof **NewP + newm * sizeof *NewP > 55 | oldm * oldn * sizeof **OldP + oldm * sizeof *OldP) 56 | { 57 | /* Yes, so let's go get some */ 58 | NewP = realloc(OldP, 59 | newm * newn * sizeof **NewP + 60 | newm * sizeof *NewP); 61 | } 62 | else 63 | { 64 | NewP = OldP; 65 | } 66 | 67 | if(NewP != NULL) 68 | { 69 | /* Now we have to set up the pointer table again */ 70 | for(Row = 0, p = (T *)NewP + newm; 71 | Row < newm; 72 | Row++, p += newn) 73 | { 74 | NewP[Row] = p; 75 | } 76 | } 77 | 78 | return NewP; 79 | } 80 | -------------------------------------------------------------------------------- /ch11/deque.h: -------------------------------------------------------------------------------- 1 | /* deque.h - header for deque library 2 | * 3 | * DEQUE - Deque Library 4 | * 5 | * Depends on DLLIST 6 | * 7 | * Copyright (C) 2000 Richard Heathfield 8 | * Eton Computer Systems Ltd 9 | * Macmillan Computer Publishing 10 | * 11 | * This program is free software; you can redistribute it 12 | * and/or modify it under the terms of the GNU General 13 | * Public License as published by the Free Software 14 | * Foundation; either version 2 of the License, or 15 | * (at your option) any later version. 16 | * 17 | * This program is distributed in the hope that it will 18 | * be useful, but WITHOUT ANY WARRANTY; without even the 19 | * implied warranty of MERCHANTABILITY or FITNESS FOR A 20 | * PARTICULAR PURPOSE. See the GNU General Public License 21 | * for more details. 22 | * 23 | * You should have received a copy of the GNU General 24 | * Public License along with this program; if not, write 25 | * to the Free Software Foundation, Inc., 675 Mass Ave, 26 | * Cambridge, MA 02139, USA. 27 | * 28 | * Richard Heathfield may be contacted by email at: 29 | * binary@eton.powernet.co.uk 30 | * 31 | */ 32 | 33 | #ifndef DEQUE_H__ 34 | #define DEQUE_H__ 35 | 36 | #include "dllist.h" 37 | 38 | #define DEQUE_SUCCESS 0 39 | #define DEQUE_ADD_FAILURE 1 40 | #define DEQUE_DEL_FAILURE 2 41 | #define DEQUE_EMPTY 3 42 | 43 | typedef struct DEQUE 44 | { 45 | #ifndef NDEBUG 46 | int CheckInit1; 47 | #endif 48 | 49 | DLLIST *HeadPtr; 50 | DLLIST *TailPtr; 51 | size_t NumItems; 52 | 53 | #ifndef NDEBUG 54 | int CheckInit2; 55 | #endif 56 | } DEQUE; 57 | 58 | int DequeAddAtFront(DEQUE *Deque, 59 | int Tag, 60 | void *Object, 61 | size_t Size); 62 | int DequeAddAtBack(DEQUE *Deque, 63 | int Tag, 64 | void *Object, 65 | size_t Size); 66 | int DequeRemoveFromFront(void *Object, DEQUE *Deque); 67 | int DequeRemoveFromBack(void *Object, DEQUE *Deque); 68 | 69 | void *DequeGetDataFromFront(DEQUE *Deque, 70 | int *Tag, 71 | size_t *Size); 72 | void *DequeGetDataFromBack(DEQUE *Deque, 73 | int *Tag, 74 | size_t *Size); 75 | size_t DequeCount(DEQUE *Deque); 76 | 77 | #endif 78 | -------------------------------------------------------------------------------- /ch13/DCOMP.H: -------------------------------------------------------------------------------- 1 | /* 2 | ** The proper usage and copyright information for 3 | ** this software is covered in DSCRLic.TXT 4 | ** This code is Copyright 1999 by Dann Corbit 5 | */ 6 | 7 | 8 | /* 9 | ** Double comparison functions. 10 | */ 11 | 12 | typedef double Etype; 13 | 14 | /* 15 | ** stuff needed by radix sorts 16 | */ 17 | #define CHUNK(x, y) digit(double2key((*(x))), (y)) 18 | #define CHUNKS(x, a)\ 19 | { uint64 foo = double2key((*(x))); \ 20 | int t; \ 21 | for (t = 0; t < sizeof(foo); t++)\ 22 | a[digit(foo,t)+1][t]++;\ 23 | } 24 | 25 | #define COST 4 26 | /* 27 | ** Fake name mangling. Does not give us a true template in C. 28 | ** [If we try to sort two arrays of the same type in a single file 29 | ** by using allsort.h as an include file, we will get multiple 30 | ** function defintions. 31 | */ 32 | #define GE ge_d 33 | #define GT gt_d 34 | #define LE le_d 35 | #define LT lt_d 36 | #define EQ eq_d 37 | #define CMP cmp_d 38 | /* 39 | ** Token pasting would be neater, but less obvious. 40 | */ 41 | #define INSORT InSort_d 42 | #define ARRAYISSORTED ArrayIsSorted_d 43 | #define ARRAYISREVERSED ArrayIsReversed_d 44 | #define BATCHER Batcher_d 45 | #define LINEARINSERTION LinearInsertion_d 46 | #define INSERTIONSORT InsertionSort_d 47 | #define INSERTONE InsertOne_d 48 | #define INSERTTWO InsertTwo_d 49 | #define INSERTFOUR InsertFour_d 50 | #define INSERTTHREE InsertThree_d 51 | #define INSERTZERO InsertZero_d 52 | #define MEDIAN Median_d 53 | #define RADIXLSD RadixLsd_d 54 | #define REVERSEARRAY ReverseArray_d 55 | #define SWAP Swap_d 56 | #define SHELLSORT Shellsort_d 57 | #define IQSORT5 Iqsort5_d 58 | #define QSORTB qsort_d 59 | #define HEAPSORT heapsort_d 60 | #define PERCDOWN percdown_d 61 | #define PARSCAN parscan_d 62 | #define PDELETEMIN pdeletemin_d 63 | #define PGETMIN pgetmin_d 64 | #define PNORMALIZE pnormalize_d 65 | #define PSHELLSORT pshellsort_d 66 | #define MERGE_SORT merge_sort_d 67 | #define RADIXMSD RadixMsd_d 68 | #define MMERGE Mmerge_d 69 | #define MSORT Msort_d 70 | #define MERGESORTB Mergesortb_d 71 | 72 | #include "compobj.h" 73 | -------------------------------------------------------------------------------- /ch13/STRCOMP.H: -------------------------------------------------------------------------------- 1 | /* 2 | ** The proper usage and copyright information for 3 | ** this software is covered in DSCRLic.TXT 4 | ** This code is Copyright 1999 by Dann Corbit 5 | */ 6 | 7 | 8 | /* 9 | ** string comparison functions. 10 | */ 11 | 12 | /* 13 | ** stuff needed by radix sorts 14 | */ 15 | typedef unsigned char *Etype; 16 | 17 | #define CHUNK(x,y) *(x[(y)]) 18 | #define CHUNKS(x, a)\ 19 | { Etype foo = *x;\ 20 | int t;\ 21 | for (t = 0; t < 8 && *x[t]; t++) \ 22 | a[CHUNK((x),(y))+1][t]++;\ 23 | } 24 | #define COST 1 25 | 26 | /* 27 | ** Fake name mangling. Does not give us a true template in C. 28 | ** [If we try to sort two arrays of the same type in a single file 29 | ** by using allsort.h as an include file, we will get multiple 30 | ** function defintions. 31 | */ 32 | #define GE ge_str 33 | #define GT gt_str 34 | #define LE le_str 35 | #define LT lt_str 36 | #define EQ eq_str 37 | #define CMP cmp_str 38 | 39 | #define INSORT InSort_str 40 | #define ARRAYISSORTED ArrayIsSorted_str 41 | #define ARRAYISREVERSED ArrayIsReversed_str 42 | #define BATCHER Batcher_str 43 | #define LINEARINSERTION LinearInsertion_str 44 | #define INSERTIONSORT InsertionSort_str 45 | #define INSERTONE InsertOne_str 46 | #define INSERTTWO InsertTwo_str 47 | #define INSERTFOUR InsertFour_str 48 | #define INSERTTHREE InsertThree_str 49 | #define INSERTZERO InsertZero_str 50 | #define MEDIAN Median_str 51 | #define RADIXLSD RadixLsd_str 52 | #define REVERSEARRAY ReverseArray_str 53 | #define SWAP Swap_str 54 | #define SHELLSORT Shellsort_str 55 | #define QSORTB qsort_str 56 | #define IQSORT5 Iqsort5_str 57 | #define HEAPSORT heapsort_str 58 | #define PERCDOWN percdown_str 59 | #define PARSCAN parscan_str 60 | #define PDELETEMIN pdeletemin_str 61 | #define PGETMIN pgetmin_str 62 | #define PNORMALIZE pnormalize_str 63 | #define PSHELLSORT pshellsort_str 64 | #define MERGE_SORT merge_sort_str 65 | #define RADIXMSD RadixMsd_str 66 | #define RADIX_MISSING 1 67 | #define MMERGE Mmerge_str 68 | #define MSORT Msort_str 69 | #define MERGESORTB Mergesortb_str 70 | 71 | #include "compstr.h" 72 | -------------------------------------------------------------------------------- /ch11/c11_022.c: -------------------------------------------------------------------------------- 1 | /* c11_022.c - naive single linked list, using an array. 2 | * 3 | * C11_022 - single linked lists 4 | * 5 | * Copyright (C) 2000 Richard Heathfield 6 | * Eton Computer Systems Ltd 7 | * Macmillan Computer Publishing 8 | * 9 | * This program is free software; you can redistribute it 10 | * and/or modify it under the terms of the GNU General 11 | * Public License as published by the Free Software 12 | * Foundation; either version 2 of the License, or 13 | * (at your option) any later version. 14 | * 15 | * This program is distributed in the hope that it will 16 | * be useful, but WITHOUT ANY WARRANTY; without even the 17 | * implied warranty of MERCHANTABILITY or FITNESS FOR A 18 | * PARTICULAR PURPOSE. See the GNU General Public License 19 | * for more details. 20 | * 21 | * You should have received a copy of the GNU General 22 | * Public License along with this program; if not, write 23 | * to the Free Software Foundation, Inc., 675 Mass Ave, 24 | * Cambridge, MA 02139, USA. 25 | * 26 | * Richard Heathfield may be contacted by email at: 27 | * binary@eton.powernet.co.uk 28 | * 29 | */ 30 | 31 | #include 32 | 33 | typedef struct ITEM 34 | { 35 | char Title[30]; 36 | char Author[30]; 37 | int Next; 38 | } ITEM; 39 | 40 | int main(void) 41 | { 42 | ITEM List[] = 43 | { 44 | {"UNIX Unleashed", "Burk and Horvath", 2}, 45 | {"Algorithms in C", "Sedgewick", 9}, 46 | {"Builder Unleashed", "Calvert", 10}, 47 | {"C++ Unleashed", "Liberty", 12}, 48 | {"Linux Unleashed", "Husain and Parker", 8}, 49 | {"Teach Yourself BCB", "Reisdorph", 1}, 50 | {"Data Structures & Algorithms", "Lafore", 3}, 51 | {"DOS Programmers Reference", "Dettmann & Johnson", 11}, 52 | {"C Programming Language", "Kernighan & Ritchie", 6}, 53 | {"C++ Programming Language", "Stroustrup", 13}, 54 | {"C: How to Program", "Deitel & Deitel", 7}, 55 | {"C : A Reference Manual", "Harbison & Steele", 15}, 56 | {"The Standard C Library", "Plauger", 5}, 57 | {"C Programming FAQs", "Summit", 14}, 58 | {"Expert C Programming", "van der Linden", -1}, 59 | {"C Unleashed", "Heathfield & Kirby", 4} 60 | }; 61 | 62 | int Current = 0; 63 | 64 | while(Current != -1) 65 | { 66 | printf("Read %s, by %s.\n", 67 | List[Current].Title, 68 | List[Current].Author); 69 | Current = List[Current].Next; 70 | } 71 | 72 | return 0; 73 | } 74 | -------------------------------------------------------------------------------- /ch22/cuc.c: -------------------------------------------------------------------------------- 1 | /* cuc.c - CUPS UDP Client Code 2 | * 3 | * 4 | * Copyright (C) 1999 Chad Dixon 5 | * Macmillan Computer Publishing 6 | * 7 | * This program is free software; you can redistribute it 8 | * and/or modify it under the terms of the GNU General 9 | * Public License as published by the Free Software 10 | * Foundation; either version 2 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will 14 | * be useful, but WITHOUT ANY WARRANTY; without even the 15 | * implied warranty of MERCHANTABILITY or FITNESS FOR A 16 | * PARTICULAR PURPOSE. See the GNU General Public License 17 | * for more details. 18 | * 19 | * You should have received a copy of the GNU General 20 | * Public License along with this program; if not, write 21 | * to the Free Software Foundation, Inc., 675 Mass Ave, 22 | * Cambridge, MA 02139, USA. 23 | * 24 | * Chad Dixon may be contacted at: 25 | * http://www.loopy.org 26 | * 27 | */ 28 | 29 | 30 | 31 | #include 32 | #include 33 | 34 | #include "cups.h" 35 | 36 | 37 | int main(int argc, char *argv[]) 38 | { 39 | CUPS_INFO CupsInfo = {0}; 40 | CONNECTION ClientConnection = {0}; 41 | char data[32]={0}; 42 | 43 | int nRet=0; 44 | 45 | if (argc != 3) 46 | { 47 | printf("usage: application celcius hostname\n"); 48 | return EXIT_FAILURE; 49 | } 50 | 51 | sprintf(data, "%s", argv[1]); 52 | 53 | CUPSInit(&CupsInfo); 54 | if(CUPSStartup(&CupsInfo) != 0) 55 | { 56 | printf("Initialisation failed.\n"); 57 | fgets(data, sizeof data, stdin); 58 | return EXIT_FAILURE; 59 | } 60 | 61 | if (CUPSGetHostByName(&ClientConnection, argv[2]) != 0) 62 | { 63 | printf("Failure to resolve Hostname. %s\n", argv[2]); 64 | return EXIT_FAILURE; 65 | } 66 | 67 | if(0 != CUPSInitUDPConnection(&ClientConnection, INADDR_ANY, 1092)) 68 | { 69 | printf("Can't open a socket!\n"); 70 | return EXIT_FAILURE; 71 | } 72 | 73 | if (0 != CUPSSendTo(&ClientConnection, data, sizeof data)) 74 | { 75 | printf("Error on sendto\n"); 76 | } 77 | 78 | memset(data, 0, sizeof data); 79 | 80 | if (0 != CUPSRecvFrom(&ClientConnection, data, sizeof data)) 81 | { 82 | printf("Error on recvfrom\n"); 83 | } 84 | 85 | 86 | printf("%s Celcius = %s Fahrenheight\n",argv[1], data); 87 | 88 | CUPSShutdownClientConnection(&ClientConnection, 2); 89 | CUPSCleanup(&CupsInfo); 90 | 91 | return EXIT_SUCCESS; 92 | } 93 | 94 | 95 | -------------------------------------------------------------------------------- /ch13/KEYXFRM.C: -------------------------------------------------------------------------------- 1 | /* 2 | ** The proper usage and copyright information for 3 | ** this software is covered in DSCRLic.TXT 4 | ** This code is Copyright 1999 by Dann Corbit 5 | */ 6 | 7 | 8 | /* 9 | ** This file is INTEL specific. It should be pretty easy to generate one 10 | ** for any sort of architecture. 11 | ** 12 | ** The whole thing *can* be done generically by using frexp(). 13 | ** The most important bit is the sign of the number. 14 | ** The next most important bit is the sign of the exponent. 15 | ** Then comes the exponent magnitude, followed by the mantissa. 16 | ** You will need to add the bias to the exponent, so that it becomes unsigned. 17 | ** 18 | ** Finally, it would actually be a lot faster to transform the whole 19 | ** vector *first* then sort it, then transform it back. Some people 20 | ** might be a bit nervous about that, but there is no reason it should 21 | ** not work. 22 | ** 23 | ** Assume typedef's for uint32 and uint64, of the same size and endian-ness 24 | ** as float and double parameters! 25 | ** These floating point mapping functions are due to Terje Mathisen. 26 | ** They are reprinted with his permission. 27 | */ 28 | #include 29 | #include "inteltyp.h" 30 | 31 | #ifdef ASSERT 32 | #undef ASSERT 33 | #endif 34 | 35 | #ifdef _DEBUG 36 | #define ASSERT(x) assert((x)) 37 | #else 38 | #define ASSERT(x) 39 | #endif 40 | 41 | 42 | uint32 43 | float2key(float f) 44 | { 45 | uint32 sign, 46 | mant, 47 | mask; 48 | 49 | ASSERT(sizeof(float) == sizeof(uint32)); 50 | mant = *(uint32 *) & f; /* Load float as array of bits */ 51 | sign = mant & SB_MASK32; /* Isolate the leading sign bit */ 52 | mant ^= SB_MASK32; /* Invert the sign bit, making + > - */ 53 | mask = sign - (sign >> 31); /* Either 0 or 0x7fffffff */ 54 | mant ^= mask; /* Invert exp and mant if negative */ 55 | return mant; 56 | } 57 | 58 | uint64 59 | double2key(double d) 60 | { 61 | uint64 sign, 62 | mant, 63 | mask; 64 | 65 | ASSERT(sizeof(double) == sizeof(uint64)); 66 | mant = *(uint64 *) & d; /* Load float as array of bits */ 67 | sign = mant & SB_MASK64; /* Isolate the leading sign bit */ 68 | mant ^= SB_MASK64; /* Invert the sign bit, making + > - */ 69 | mask = sign - (sign >> 63); /* Either 0 or 0x7fffffffffffffff */ 70 | mant ^= mask; /* Invert exp and mant if negative */ 71 | return mant; 72 | } 73 | -------------------------------------------------------------------------------- /ch11/c11_020.c: -------------------------------------------------------------------------------- 1 | /* c11_020.c - do a random walk 2 | * 3 | * C11_020 - illustrate array of pointers to function. 4 | * 5 | * Copyright (C) 2000 Richard Heathfield 6 | * Eton Computer Systems Ltd 7 | * Macmillan Computer Publishing 8 | * 9 | * This program is free software; you can redistribute it 10 | * and/or modify it under the terms of the GNU General 11 | * Public License as published by the Free Software 12 | * Foundation; either version 2 of the License, or 13 | * (at your option) any later version. 14 | * 15 | * This program is distributed in the hope that it will 16 | * be useful, but WITHOUT ANY WARRANTY; without even the 17 | * implied warranty of MERCHANTABILITY or FITNESS FOR A 18 | * PARTICULAR PURPOSE. See the GNU General Public License 19 | * for more details. 20 | * 21 | * You should have received a copy of the GNU General 22 | * Public License along with this program; if not, write 23 | * to the Free Software Foundation, Inc., 675 Mass Ave, 24 | * Cambridge, MA 02139, USA. 25 | * 26 | * Richard Heathfield may be contacted by email at: 27 | * binary@eton.powernet.co.uk 28 | * 29 | */ 30 | 31 | #include 32 | #include 33 | #include 34 | 35 | int random(int i) 36 | { 37 | double d; 38 | 39 | d = rand() / ((double)RAND_MAX + 1.0); 40 | d *= i; 41 | return (int)d; 42 | } 43 | 44 | int go_left(int *x, int *y) 45 | { 46 | --*x; 47 | 48 | printf("Going left!\n"); 49 | 50 | return random(5); 51 | 52 | } 53 | 54 | int go_right(int *x, int *y) 55 | { 56 | ++*x; 57 | 58 | printf("Going right!\n"); 59 | return random(5); 60 | 61 | } 62 | 63 | int go_down(int *x, int *y) 64 | { 65 | --*y; 66 | 67 | printf("Going down!\n"); 68 | 69 | return random(5); 70 | 71 | } 72 | 73 | int go_up(int *x, int *y) 74 | { 75 | ++*y; 76 | 77 | printf("Going up!\n"); 78 | 79 | return random(5); 80 | 81 | } 82 | 83 | int stop(int *x, int *y) 84 | { 85 | printf("End of the road: (%d, %d)\n", *x, *y); 86 | 87 | return -1; 88 | } 89 | 90 | int main(void) 91 | { 92 | int (*action[])(int *, int *) = 93 | { 94 | go_left, go_right, go_down, go_up, stop 95 | }; 96 | 97 | int state = 0; 98 | int x = 0; 99 | int y = 0; 100 | 101 | srand((unsigned)time(NULL)); 102 | 103 | do 104 | { 105 | printf("Currently at (%d, %d)\n", x, y); 106 | state = (*action[state])(&x, &y); 107 | } while(state != -1); 108 | 109 | return 0; 110 | } 111 | 112 | -------------------------------------------------------------------------------- /ch15/get_range_min.c: -------------------------------------------------------------------------------- 1 | /************************************************************************** 2 | ** SP_GET_RANGE_MIN ** 3 | ** ** 4 | ** Retrieve the minimum range value associated with a passed ** 5 | ** dimension. ** 6 | ** ** 7 | ** INPUT: ** 8 | ** sp -- The sparse matrix from which the range value is to be ** 9 | ** retrieved. ** 10 | ** dim -- The dimension of the minimum range value ** 11 | ** ** 12 | ** OUTPUT: ** 13 | ** int -- The minimum range value ** 14 | ** ** 15 | ** SIDE EFFECTS: ** 16 | ** The error_no field of the sparse matrix can be set to an error if ** 17 | ** an error is encountered. Whenever an error is encountered, this ** 18 | ** value is set and a NULL pointer is returned. Thus, if a NULL ** 19 | ** pointer is returned from this function it is important to examine ** 20 | ** the error_no of the associated sparse matrix. ** 21 | ** ** 22 | ** NOTES: ** 23 | ** ** 24 | **************************************************************************/ 25 | 26 | #include 27 | #include 28 | #include "sparse.h" 29 | 30 | int sp_get_range_min(SPARSE_MATRIX *sp, int dim) 31 | /* SPARSE_MATRIX *sp The sparse matrix from which to retrieve the range 32 | value */ 33 | /* int dim The dimension number */ 34 | { 35 | /* If the sparse matrix is empty, then a range value cannot be retrieved */ 36 | if (sp == (SPARSE_MATRIX *)NULL) 37 | { 38 | return(0); 39 | } 40 | 41 | sp->error_no = SP_NOERR; 42 | 43 | /* Make sure that the dimension specified is legal */ 44 | if ((sp->dimensions < dim) || (dim < (int)1)) 45 | { 46 | sp->error_no = SP_DIM; 47 | return(0); 48 | } 49 | 50 | return(*(sp->hdr_ranges + ((dim - 1) * 2))); 51 | } 52 | -------------------------------------------------------------------------------- /ch15/get_range_max.c: -------------------------------------------------------------------------------- 1 | /************************************************************************** 2 | ** SP_GET_RANGE_MAX ** 3 | ** ** 4 | ** Retrieve the maximum range value associated with a passed ** 5 | ** dimension. ** 6 | ** ** 7 | ** INPUT: ** 8 | ** sp -- The sparse matrix from which the range value is to be ** 9 | ** retrieved. ** 10 | ** dim -- The dimension of the maximum range value ** 11 | ** ** 12 | ** OUTPUT: ** 13 | ** int -- The maximum range value ** 14 | ** ** 15 | ** SIDE EFFECTS: ** 16 | ** The error_no field of the sparse matrix can be set to an error if ** 17 | ** an error is encountered. Whenever an error is encountered, this ** 18 | ** value is set and a NULL pointer is returned. Thus, if a NULL ** 19 | ** pointer is returned from this function it is important to examine ** 20 | ** the error_no of the associated sparse matrix. ** 21 | ** ** 22 | ** NOTES: ** 23 | ** ** 24 | **************************************************************************/ 25 | 26 | #include 27 | #include 28 | #include "sparse.h" 29 | 30 | int sp_get_range_max(SPARSE_MATRIX *sp, int dim) 31 | /* SPARSE_MATRIX *sp The sparse matrix from which to retrieve the range 32 | value */ 33 | /* int dim The dimension number */ 34 | { 35 | /* If the sparse matrix is empty, then a range value cannot be retrieved */ 36 | if (sp == (SPARSE_MATRIX *)NULL) 37 | { 38 | return(0); 39 | } 40 | 41 | sp->error_no = SP_NOERR; 42 | 43 | /* Make sure that the dimension specified is legal */ 44 | if ((sp->dimensions < dim) || (dim < (int)1)) 45 | { 46 | sp->error_no = SP_DIM; 47 | return(0); 48 | } 49 | 50 | return(*(sp->hdr_ranges + ((dim - 1) * 2) + 1)); 51 | } 52 | -------------------------------------------------------------------------------- /ch06/inifetch.c: -------------------------------------------------------------------------------- 1 | /**************************************/ 2 | /* */ 3 | /* Code from the book C Unleashed */ 4 | /* Macmillan, 2000 */ 5 | /* Chapter 6: Data Files */ 6 | /* Steve Summit 2000-03-17 */ 7 | /* */ 8 | /**************************************/ 9 | 10 | #include 11 | #include 12 | #include 13 | 14 | /* 15 | * This version of inifetch() differs from the one printed 16 | * in the chapter in that it only opens the .ini file, and 17 | * searches for the requested section, when necessary 18 | * (not redundantly on each call). 19 | */ 20 | 21 | #define TRUE 1 22 | #define FALSE 0 23 | 24 | #define MAXLINE 1000 25 | 26 | static FILE *fp = NULL; 27 | static char *curfile = NULL; 28 | static char *cursect = NULL; 29 | static long int sectoffset; 30 | 31 | static int inisearch(FILE *, const char *); 32 | 33 | char * 34 | inifetch(const char *file, const char *sect, const char *key) 35 | { 36 | static char line[MAXLINE]; 37 | char *p, *retp = NULL; 38 | int len; 39 | 40 | if(fp == NULL || curfile == NULL || strcmp(curfile, file) != 0) 41 | { 42 | if(fp != NULL) 43 | fclose(fp); 44 | if(curfile != NULL) 45 | { free(curfile); curfile = NULL; } 46 | if(cursect != NULL) 47 | { free(cursect); cursect = NULL; } 48 | fp = fopen(file, "r"); 49 | if(fp == NULL) 50 | return NULL; 51 | 52 | curfile = malloc(strlen(file) + 1); 53 | if(curfile != NULL) 54 | strcpy(curfile, file); 55 | } 56 | 57 | if(cursect != NULL && strcmp(cursect, sect) == 0) 58 | fseek(fp, sectoffset, SEEK_SET); 59 | else { 60 | if(cursect != NULL) 61 | { free(cursect); cursect = NULL; } 62 | rewind(fp); 63 | if(!inisearch(fp, sect)) 64 | return NULL; 65 | sectoffset = ftell(fp); 66 | 67 | cursect = malloc(strlen(sect) + 1); 68 | if(cursect != NULL) 69 | strcpy(cursect, sect); 70 | } 71 | 72 | /* search for key */ 73 | len = strlen(key); 74 | while(fgets(line, MAXLINE, fp) != NULL) 75 | { 76 | if(*line == '[') 77 | break; 78 | if(strncmp(line, key, len) == 0 && 79 | line[len] == '=') 80 | { 81 | retp = &line[len+1]; 82 | if((p = strrchr(retp, '\n')) != NULL) 83 | *p = '\0'; 84 | break; 85 | } 86 | } 87 | 88 | return retp; 89 | } 90 | 91 | static int 92 | inisearch(FILE *fp, const char *sect) 93 | { 94 | char line[MAXLINE]; 95 | int len = strlen(sect); 96 | while(fgets(line, MAXLINE, fp) != NULL) 97 | { 98 | if(*line != '[') 99 | continue; 100 | if(strncmp(&line[1], sect, len) == 0 && 101 | line[1+len] == ']') 102 | return TRUE; /* found it */ 103 | } 104 | 105 | return FALSE; 106 | } 107 | -------------------------------------------------------------------------------- /ch11/heap.h: -------------------------------------------------------------------------------- 1 | /* HEAP handling 2 | 3 | Copyright (C) 1997, 1998 Free Software Foundation, Inc. 4 | Written by Ben Pfaff . 5 | Modified 1999, with Ben's permission, by Richard 6 | Heathfield to handle 7 | arbitrary data structures. Hacked for 'style' 8 | too. ;-) (Purely for consistency with existing 9 | code base.) 10 | 11 | This program is free software; you can redistribute it 12 | and/or modify it under the terms of the GNU General 13 | Public License as published by the Free Software 14 | Foundation; either version 2 of the License, or (at 15 | your option) any later version. 16 | 17 | This program is distributed in the hope that it will 18 | be useful, but WITHOUT ANY WARRANTY; without even the 19 | implied warranty of MERCHANTABILITY or FITNESS FOR A 20 | PARTICULAR PURPOSE. See the GNU General Public 21 | License for more details. 22 | 23 | You should have received a copy of the GNU General 24 | Public License along with this program; if not, write 25 | to the Free Software Foundation, Inc., 59 Temple 26 | Place - Suite 330, Boston, MA 02111-1307, USA. */ 27 | 28 | #ifndef HEAP_H__ 29 | #define HEAP_H__ 30 | 31 | /* This module implements a priority queue as a heap 32 | * as described in Knuth 5.2.3. This is a first-in- 33 | * smallest-out priority queue. 34 | */ 35 | 36 | /* One element of a heap. */ 37 | typedef struct HEAP_ELEMENT 38 | { 39 | int Tag; 40 | size_t Size; 41 | void *Object; 42 | } HEAP_ELEMENT; 43 | 44 | /* An entire heap. */ 45 | typedef struct HEAP 46 | { 47 | size_t Count; /* Number of elements in heap. */ 48 | size_t MaxCount; /* No. of elems allocated. */ 49 | HEAP_ELEMENT *Heap; /* Heap elements. */ 50 | } HEAP; 51 | 52 | typedef int (*HEAP_COMPARE)(const void *Left, 53 | int LeftTag, 54 | const void *Right, 55 | int RightTag); 56 | typedef int (*HEAP_PRINT)(const void *Object, 57 | int Tag, 58 | size_t Size, 59 | FILE *fp); 60 | 61 | HEAP *HeapCreate(size_t MaxCount); 62 | void HeapDestroy(HEAP *Heap); 63 | int HeapInsert(HEAP *Heap, 64 | int Tag, 65 | size_t Size, 66 | void *Object, 67 | HEAP_COMPARE Comp); 68 | int HeapPeek(int *Tag, size_t *Size); 69 | int HeapDelete(HEAP *Heap, 70 | int *Tag, 71 | size_t *Size, 72 | void *Object, 73 | HEAP_COMPARE Comp); 74 | 75 | int HeapGetSize(HEAP *Heap); 76 | 77 | int HeapVerify(HEAP *Heap, HEAP_COMPARE Comp, FILE *fp); 78 | void HeapDump(const HEAP *, HEAP_PRINT Print, FILE *fp); 79 | 80 | #endif /* HEAP_H__ */ 81 | -------------------------------------------------------------------------------- /ch06/binio.c: -------------------------------------------------------------------------------- 1 | /**************************************/ 2 | /* */ 3 | /* Code from the book C Unleashed */ 4 | /* Macmillan, 2000 */ 5 | /* Chapter 6: Data Files */ 6 | /* Steve Summit 2000-03-17 */ 7 | /* */ 8 | /**************************************/ 9 | 10 | #include 11 | 12 | #define TRUE 1 13 | #define FALSE 0 14 | 15 | extern void toieee(float, unsigned char [4]); 16 | extern float fromieee(unsigned char [4]); 17 | 18 | extern void toieeed(double, unsigned char [8]); 19 | extern double fromieeed(unsigned char [8]); 20 | 21 | void putint(int i, FILE *ofp) 22 | { 23 | putc(i & 0xff, ofp); 24 | putc((i >> 8) & 0xff, ofp); 25 | } 26 | 27 | void putlong(long int i2, FILE *ofp) 28 | { 29 | putc(i2 & 0xff, ofp); 30 | putc((i2 >> 8) & 0xff, ofp); 31 | putc((i2 >> 16) & 0xff, ofp); 32 | putc((i2 >> 24) & 0xff, ofp); 33 | } 34 | 35 | /* 36 | * This version of putfloat() is more complete than the one printed 37 | * in the chapter. It defers the packing step to the toieee() 38 | * function (in ieee754.c), which handles denormalized numbers 39 | * and rounding. 40 | */ 41 | 42 | void putfloat(float f, FILE *ofp) 43 | { 44 | unsigned char buf[4]; 45 | toieee(f, buf); 46 | fwrite(buf, 1, 4, ofp); 47 | } 48 | 49 | void putdouble(double d, FILE *ofp) 50 | { 51 | unsigned char buf[8]; 52 | toieeed(d, buf); 53 | fwrite(buf, 1, 8, ofp); 54 | } 55 | 56 | int getint(int *ip, FILE *ifp) 57 | { 58 | int i; 59 | int c; 60 | if((c = getc(ifp)) == EOF) 61 | return FALSE; 62 | i = c; 63 | if((c = getc(ifp)) == EOF) 64 | return FALSE; 65 | i |= c << 8; 66 | *ip = i; 67 | return TRUE; 68 | } 69 | 70 | int getlong(long int *ip, FILE *ifp) 71 | { 72 | long int i2; 73 | unsigned char buf[4]; 74 | if(fread(buf, 1, 4, ifp) != 4) 75 | return FALSE; 76 | i2 = buf[0]; 77 | i2 |= (unsigned long)buf[1] << 8; 78 | i2 |= (unsigned long)buf[2] << 16; 79 | i2 |= (unsigned long)buf[3] << 24; 80 | *ip = i2; 81 | return TRUE; 82 | } 83 | 84 | /* 85 | * This version of getfloat() is more complete than the one printed 86 | * in the chapter. It defers the unpacking step to the fromieee() 87 | * function (in ieee754.c), which handles denormalized numbers. 88 | */ 89 | 90 | int getfloat(float *fp, FILE *ifp) 91 | { 92 | unsigned char buf[4]; 93 | if(fread(buf, 1, 4, ifp) != 4) 94 | return FALSE; 95 | *fp = fromieee(buf); 96 | return TRUE; 97 | } 98 | 99 | int getdouble(double *dp, FILE *ifp) 100 | { 101 | unsigned char buf[8]; 102 | if(fread(buf, 1, 8, ifp) != 8) 103 | return FALSE; 104 | *dp = fromieeed(buf); 105 | return TRUE; 106 | } 107 | -------------------------------------------------------------------------------- /ch11/c11_017.c: -------------------------------------------------------------------------------- 1 | /* c11_017.c - demo of dynamically allocated 2D array 2 | * 3 | * C11_017 - dynamic allocation of arrays 4 | * 5 | * Copyright (C) 2000 Richard Heathfield 6 | * Eton Computer Systems Ltd 7 | * Macmillan Computer Publishing 8 | * 9 | * This program is free software; you can redistribute it 10 | * and/or modify it under the terms of the GNU General 11 | * Public License as published by the Free Software 12 | * Foundation; either version 2 of the License, or 13 | * (at your option) any later version. 14 | * 15 | * This program is distributed in the hope that it will 16 | * be useful, but WITHOUT ANY WARRANTY; without even the 17 | * implied warranty of MERCHANTABILITY or FITNESS FOR A 18 | * PARTICULAR PURPOSE. See the GNU General Public License 19 | * for more details. 20 | * 21 | * You should have received a copy of the GNU General 22 | * Public License along with this program; if not, write 23 | * to the Free Software Foundation, Inc., 675 Mass Ave, 24 | * Cambridge, MA 02139, USA. 25 | * 26 | * Richard Heathfield may be contacted by email at: 27 | * binary@eton.powernet.co.uk 28 | * 29 | */ 30 | 31 | #include 32 | #include 33 | 34 | typedef int T; 35 | 36 | void Release(T **a, size_t m) 37 | { 38 | size_t Row; 39 | 40 | for(Row = 0; Row < m; Row++) 41 | { 42 | if(a[Row] != NULL) 43 | { 44 | free(a[Row]); 45 | } 46 | } 47 | free(a); 48 | } 49 | 50 | 51 | 52 | T **Allocate(size_t m, size_t n) 53 | { 54 | T **a; 55 | size_t Row; 56 | int Success = 1; 57 | 58 | a = malloc(m * sizeof *a); 59 | if(a != NULL) 60 | { 61 | for(Row = 0; Row < m; Row++) 62 | { 63 | a[Row] = malloc(n * sizeof *a[Row]); 64 | if(NULL == a[Row]) 65 | { 66 | Success = 0; 67 | } 68 | } 69 | /* If any inner allocation failed, 70 | * we should clean up 71 | */ 72 | if(1 != Success) 73 | { 74 | Release(a, m); 75 | a = NULL; 76 | } 77 | } 78 | 79 | return a; 80 | } 81 | 82 | int main(void) 83 | { 84 | T **array; 85 | int i; 86 | int j; 87 | int total = 0; 88 | int row = 4; 89 | int col = 7; 90 | 91 | array = Allocate(row, col); 92 | 93 | if(array != NULL) 94 | { 95 | /* Populating the array */ 96 | for(i = 0; i < row; i++) 97 | for(j = 0; j < col; j++) 98 | array[i][j] = i + j; 99 | /* Accessing the array */ 100 | for(i = 0; i < row; i++) 101 | for(j = 0; j < col; j++) 102 | total += array[i][j]; 103 | 104 | printf("Total is %d\n", total); 105 | Release(array, row); 106 | } 107 | 108 | return 0; 109 | } 110 | -------------------------------------------------------------------------------- /ch11/c11_015.c: -------------------------------------------------------------------------------- 1 | /* c11_015.c - demo of dynamically allocated 2D array 2 | * 3 | * C11_015 - dynamic allocation of arrays 4 | * 5 | * Copyright (C) 2000 Richard Heathfield 6 | * Eton Computer Systems Ltd 7 | * Macmillan Computer Publishing 8 | * 9 | * This program is free software; you can redistribute it 10 | * and/or modify it under the terms of the GNU General 11 | * Public License as published by the Free Software 12 | * Foundation; either version 2 of the License, or 13 | * (at your option) any later version. 14 | * 15 | * This program is distributed in the hope that it will 16 | * be useful, but WITHOUT ANY WARRANTY; without even the 17 | * implied warranty of MERCHANTABILITY or FITNESS FOR A 18 | * PARTICULAR PURPOSE. See the GNU General Public License 19 | * for more details. 20 | * 21 | * You should have received a copy of the GNU General 22 | * Public License along with this program; if not, write 23 | * to the Free Software Foundation, Inc., 675 Mass Ave, 24 | * Cambridge, MA 02139, USA. 25 | * 26 | * Richard Heathfield may be contacted by email at: 27 | * binary@eton.powernet.co.uk 28 | * 29 | */ 30 | 31 | #include 32 | #include 33 | 34 | #error This code invokes undefined behaviour. Please don't use it. See comment. 35 | 36 | typedef int T; 37 | 38 | T **Allocate(size_t m, size_t n) 39 | { 40 | int **a; 41 | int *p; 42 | size_t Row; 43 | 44 | /* This method is not recommended in the chapter, but the chapter 45 | * indicates that the code is at least portable. It isn't. 46 | * This is because of possible differences in alignment requirements 47 | * between T* and T**. I only realised this after the chapter had 48 | * already been locked down, so I can't change the text, but at 49 | * least I can put a friendly warning here. 50 | * 51 | * Well, you didn't really want to do it this way anyway, did you? 52 | * :-) 53 | * 54 | * RJH 8 June 2000 55 | */ 56 | a = malloc(m * n * sizeof **a + m * sizeof *a); 57 | if(a != NULL) 58 | { 59 | for(Row = 0, p = (T *)a + m; Row < m; Row++, p += n) 60 | { 61 | a[Row] = p; 62 | } 63 | } 64 | return a; 65 | } 66 | 67 | int main(void) 68 | { 69 | T **array; 70 | int i; 71 | int j; 72 | int total = 0; 73 | int row = 4; 74 | int col = 7; 75 | 76 | array = Allocate(row, col); 77 | 78 | if(array != NULL) 79 | { 80 | /* Populating the array */ 81 | for(i = 0; i < row; i++) 82 | for(j = 0; j < col; j++) 83 | array[i][j] = i + j; 84 | /* Accessing the array */ 85 | for(i = 0; i < row; i++) 86 | for(j = 0; j < col; j++) 87 | total += array[i][j]; 88 | 89 | printf("Total is %d\n", total); 90 | free(array); 91 | } 92 | 93 | return 0; 94 | } 95 | -------------------------------------------------------------------------------- /ch22/uuc.c: -------------------------------------------------------------------------------- 1 | /* uuc.c - UNIX UDP Client Code 2 | * 3 | * 4 | * Copyright (C) 1999 Chad Dixon 5 | * Macmillan Computer Publishing 6 | * 7 | * This program is free software; you can redistribute it 8 | * and/or modify it under the terms of the GNU General 9 | * Public License as published by the Free Software 10 | * Foundation; either version 2 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will 14 | * be useful, but WITHOUT ANY WARRANTY; without even the 15 | * implied warranty of MERCHANTABILITY or FITNESS FOR A 16 | * PARTICULAR PURPOSE. See the GNU General Public License 17 | * for more details. 18 | * 19 | * You should have received a copy of the GNU General 20 | * Public License along with this program; if not, write 21 | * to the Free Software Foundation, Inc., 675 Mass Ave, 22 | * Cambridge, MA 02139, USA. 23 | * 24 | * Chad Dixon may be contacted at: 25 | * http://www.loopy.org 26 | * 27 | */ 28 | 29 | 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | 38 | 39 | int main(int argc, char *argv[]) 40 | { 41 | struct sockaddr_in their_addr; 42 | struct sockaddr_in my_addr; 43 | struct hostent *he; 44 | int sockfd; 45 | int addr_len; 46 | char data[32]={0}; 47 | 48 | int nRet=0; 49 | 50 | if (argc != 3) 51 | { 52 | printf("usage: application celsius hostname\n"); 53 | return EXIT_FAILURE; 54 | } 55 | 56 | sprintf(data, "%s", argv[1]); 57 | 58 | he = gethostbyname(argv[2]); 59 | if (he == NULL) 60 | { 61 | printf("Error in gethostbyname\n"); 62 | return EXIT_FAILURE; 63 | } 64 | 65 | sockfd = socket(AF_INET, SOCK_DGRAM, 0); 66 | if (sockfd == -1) 67 | { 68 | printf("Error Creating Socket\n"); 69 | return EXIT_FAILURE; 70 | } 71 | their_addr.sin_family = AF_INET; 72 | their_addr.sin_addr = *((struct in_addr *)he->h_addr); 73 | their_addr.sin_port = htons(1092); 74 | 75 | 76 | if (sendto(sockfd, data, strlen(data), 77 | 0, (struct sockaddr *)&their_addr, 78 | sizeof(struct sockaddr)) == -1) 79 | { 80 | printf("Error in sendto\n"); 81 | return EXIT_FAILURE; 82 | } 83 | 84 | 85 | memset(data, 0, sizeof data); 86 | 87 | addr_len = sizeof(struct sockaddr); 88 | if (recvfrom(sockfd, data, sizeof data, 89 | 0, (struct sockaddr *)&their_addr, &addr_len) == -1) 90 | { 91 | printf("Error in recvfrom\n"); 92 | return EXIT_FAILURE; 93 | } 94 | 95 | 96 | printf("%s Celsius = %s Fahrenheight\n",argv[1], data); 97 | 98 | 99 | shutdown(sockfd,2); 100 | return EXIT_SUCCESS; 101 | } 102 | 103 | 104 | -------------------------------------------------------------------------------- /ch22/w_cups.h: -------------------------------------------------------------------------------- 1 | /* cups.h - Windows Version of the CUPS Library Header File 2 | * 3 | * 4 | * Copyright (C) 1999 Chad Dixon 5 | * Macmillan Computer Publishing 6 | * 7 | * This program is free software; you can redistribute it 8 | * and/or modify it under the terms of the GNU General 9 | * Public License as published by the Free Software 10 | * Foundation; either version 2 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will 14 | * be useful, but WITHOUT ANY WARRANTY; without even the 15 | * implied warranty of MERCHANTABILITY or FITNESS FOR A 16 | * PARTICULAR PURPOSE. See the GNU General Public License 17 | * for more details. 18 | * 19 | * You should have received a copy of the GNU General 20 | * Public License along with this program; if not, write 21 | * to the Free Software Foundation, Inc., 675 Mass Ave, 22 | * Cambridge, MA 02139, USA. 23 | * 24 | * Chad Dixon may be contacted at: 25 | * http://www.loopy.org 26 | * 27 | */ 28 | 29 | /* this is the Windows version of cups.h */ 30 | #ifndef CUPS_H__ 31 | #define CUPS_H__ 32 | 33 | #include 34 | #include 35 | #include "winsock.h" 36 | 37 | #define CUPS_SHUTDOWN_RECEIVE 0 38 | #define CUPS_SHUTDOWN_SEND 1 39 | #define CUPS_SHUTDOWN_BOTH 2 40 | 41 | #define CUPS_MAX_OUT 256 42 | 43 | 44 | typedef struct CUPS_INFO 45 | { 46 | WORD VersionRequested; 47 | } CUPS_INFO; 48 | 49 | 50 | typedef struct CONNECTION 51 | { 52 | int address_length; 53 | SOCKADDR_IN my_addr; 54 | SOCKADDR_IN their_addr; 55 | SOCKET Socket; 56 | LPHOSTENT he; 57 | } CONNECTION; 58 | 59 | 60 | void CUPSInit(CUPS_INFO *pInfo); 61 | int CUPSEndServer(void); 62 | int CUPSStartup(CUPS_INFO *pInfo); 63 | int CUPSGetHostByName(CONNECTION *Connection, char *Host); 64 | int CUPSInitTCPConnection(CONNECTION *Connection, 65 | unsigned long Address, 66 | unsigned short Port); 67 | int CUPSInitUDPConnection(CONNECTION *Connection, 68 | unsigned long Address, 69 | unsigned short Port); 70 | int CUPSCheckForData(CONNECTION *Connection); 71 | int CUPSConnect(CONNECTION *Connection); 72 | int CUPSBind(CONNECTION *Connection); 73 | int CUPSListen(CONNECTION *Connection); 74 | int CUPSShutdown(CONNECTION *Connection, int ShutdownType); 75 | int CUPSAcceptConnection(CONNECTION *NewSocket, 76 | CONNECTION *ServerConnection); 77 | int CUPSCheckForData(CONNECTION *Connection); 78 | int CUPSRecv(CONNECTION *Connection, char *data, size_t size); 79 | int CUPSSend(CONNECTION *Connection, char *data, size_t size); 80 | int CUPSRecvFrom(CONNECTION *Connection, char *data, size_t size); 81 | int CUPSSendTo(CONNECTION *Connection, char *data, size_t size); 82 | int CUPSShutdownClientConnection(CONNECTION *Connection, 83 | int ShutdownType); 84 | int CUPSCleanup(CUPS_INFO *CupsInfo); 85 | 86 | #endif 87 | 88 | -------------------------------------------------------------------------------- /ch15/next_node.c: -------------------------------------------------------------------------------- 1 | /************************************************************************** 2 | ** SP_NEXT_NODE ** 3 | ** ** 4 | ** Returns the next node in a given dimension. ** 5 | ** ** 6 | ** INPUT: ** 7 | ** sp -- The sparse matrix which contains the nodes ** 8 | ** dim -- The dimension of the node being requested ** 9 | ** node -- The current node ** 10 | ** ** 11 | ** OUTPUT: ** 12 | ** SP_NODE -- A pointer to the node ** 13 | ** ** 14 | ** SIDE EFFECTS: ** 15 | ** The error_no field of the sparse matrix can be set to an error if ** 16 | ** an error is encountered. Whenever an error is encountered, this ** 17 | ** value is set and a NULL pointer is returned. Thus, if a NULL ** 18 | ** pointer is returned from this function it is important to examine ** 19 | ** the error_no of the associated sparse matrix before assuming that ** 20 | ** the node list is empty. ** 21 | ** ** 22 | ** NOTES: ** 23 | ** ** 24 | **************************************************************************/ 25 | 26 | #include 27 | #include "sparse.h" 28 | 29 | SP_NODE *sp_next_node(SPARSE_MATRIX *sp, int dim, SP_NODE *node) 30 | /* SPARSE_MATRIX *sp The sparse matrix in which to find the node */ 31 | /* int dim The dimension number of the next node to be found */ 32 | /* SP_NODE *node The current node */ 33 | { 34 | /* If the sparse matrix passed is empty, then there are no nodes to be found */ 35 | if (sp == (SPARSE_MATRIX *)NULL) 36 | return ((SP_NODE *)NULL); 37 | 38 | sp->error_no = SP_NOERR; 39 | 40 | /* Make sure the dimension is within range */ 41 | if (dim > sp->dimensions) 42 | { 43 | sp->error_no = SP_DIM; 44 | return((SP_NODE *)NULL); 45 | } 46 | 47 | /* The stack has next, then previous node pointers for each dimension in that 48 | order, so there are 2 pointers for each dimension. The next is the first 49 | of the two, so the offset is 2 * dim */ 50 | return(*((SP_NODE **)(node->dimension_stack + (2 * (dim - 1))))); 51 | } 52 | -------------------------------------------------------------------------------- /ch20/limn.c: -------------------------------------------------------------------------------- 1 | /* limn.c - limit lines to n bytes 2 | * 3 | * LIMN - LIMit line length to N bytes 4 | * 5 | * Copyright (C) 2000 Richard Heathfield 6 | * Eton Computer Systems Ltd 7 | * Macmillan Computer Publishing 8 | * 9 | * This program is free software; you can redistribute it 10 | * and/or modify it under the terms of the GNU General 11 | * Public License as published by the Free Software 12 | * Foundation; either version 2 of the License, or 13 | * (at your option) any later version. 14 | * 15 | * This program is distributed in the hope that it will 16 | * be useful, but WITHOUT ANY WARRANTY; without even the 17 | * implied warranty of MERCHANTABILITY or FITNESS FOR A 18 | * PARTICULAR PURPOSE. See the GNU General Public License 19 | * for more details. 20 | * 21 | * You should have received a copy of the GNU General 22 | * Public License along with this program; if not, write 23 | * to the Free Software Foundation, Inc., 675 Mass Ave, 24 | * Cambridge, MA 02139, USA. 25 | * 26 | * Richard Heathfield may be contacted by email at: 27 | * binary@eton.powernet.co.uk 28 | * 29 | */ 30 | 31 | #include 32 | #include 33 | #include 34 | 35 | void help(void) 36 | { 37 | char *helpmsg[] = 38 | { 39 | "limn", 40 | "Usage: limn ", 41 | "Example: limn 72", 42 | "Copies standard input to standard output,", 43 | "ensuring that no line exceeds n characters", 44 | "in length. Longer lines are split, and a", 45 | "terminating \\ character is added to the", 46 | "line at the split point. n must be at least 3." 47 | }; 48 | 49 | size_t i, j = sizeof helpmsg / sizeof helpmsg[0]; 50 | 51 | for(i = 0; i < j; i++) 52 | { 53 | puts(helpmsg[i]); 54 | } 55 | } 56 | 57 | int main(int argc, char **argv) 58 | { 59 | int status = EXIT_SUCCESS; 60 | 61 | char *endp; 62 | int thischar; 63 | size_t lim; 64 | size_t currline = 0; 65 | 66 | if(argc < 2 || strcmp(argv[1], "-?") == 0) 67 | { 68 | help(); 69 | status = EXIT_FAILURE; 70 | } 71 | else 72 | { 73 | lim = (size_t)strtoul(argv[1], &endp, 10); 74 | 75 | if(endp == argv[1] || lim < 3) 76 | { 77 | help(); 78 | printf("\nInvalid arg %s\n", argv[1]); 79 | status = EXIT_FAILURE; 80 | } 81 | else 82 | { 83 | while((thischar = getchar()) != EOF) 84 | { 85 | if(thischar == '\n') 86 | { 87 | currline = 0; 88 | } 89 | else if(++currline == lim) 90 | { 91 | putchar('\\'); 92 | putchar('\n'); 93 | currline = 1; 94 | } 95 | putchar(thischar); 96 | } 97 | } 98 | } 99 | 100 | return status; 101 | } 102 | -------------------------------------------------------------------------------- /ch22/u_cups.h: -------------------------------------------------------------------------------- 1 | /* cups.h - UNIX Version of the CUPS Library Header File 2 | * 3 | * 4 | * Copyright (C) 1999 Chad Dixon 5 | * Macmillan Computer Publishing 6 | * 7 | * This program is free software; you can redistribute it 8 | * and/or modify it under the terms of the GNU General 9 | * Public License as published by the Free Software 10 | * Foundation; either version 2 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will 14 | * be useful, but WITHOUT ANY WARRANTY; without even the 15 | * implied warranty of MERCHANTABILITY or FITNESS FOR A 16 | * PARTICULAR PURPOSE. See the GNU General Public License 17 | * for more details. 18 | * 19 | * You should have received a copy of the GNU General 20 | * Public License along with this program; if not, write 21 | * to the Free Software Foundation, Inc., 675 Mass Ave, 22 | * Cambridge, MA 02139, USA. 23 | * 24 | * Chad Dixon may be contacted at: 25 | * http://www.loopy.org 26 | * 27 | */ 28 | 29 | 30 | /* this is the Unix version of cups.h */ 31 | #ifndef CUPS_H__ 32 | #define CUPS_H__ 33 | 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include 41 | 42 | #define CUPS_SHUTDOWN_RECEIVE 0 43 | #define CUPS_SHUTDOWN_SEND 1 44 | #define CUPS_SHUTDOWN_BOTH 2 45 | 46 | typedef struct CUPS_INFO 47 | { 48 | int Dummy; /* placeholder: Windows needs init info, Unix doesn't */ 49 | } CUPS_INFO; 50 | 51 | typedef struct CONNECTION 52 | { 53 | int address_length; 54 | struct sockaddr_in my_addr; 55 | struct sockaddr_in their_addr; 56 | struct hostent *he; 57 | socklen_t sin_size; 58 | int Socket; 59 | } CONNECTION; 60 | 61 | void CUPSInit(CUPS_INFO *pInfo); 62 | int CUPSStartup(CUPS_INFO *pInfo); 63 | int CUPSGetHostByName(CONNECTION *Connection, char *); 64 | int CUPSConnect(CONNECTION *Connection); 65 | int CUPSCheckForData(CONNECTION *Connection); 66 | int CUPSInitTCPConnection(CONNECTION *Connection, 67 | unsigned long Address, 68 | unsigned short Port); 69 | int CUPSInitUDPConnection(CONNECTION *Connection, 70 | unsigned long Address, 71 | unsigned short Port); 72 | int CUPSBind(CONNECTION *Connection); 73 | int CUPSListen(CONNECTION *Connection); 74 | int CUPSShutDown(CONNECTION *Connection, int ShutdownType); 75 | int CUPSAcceptConnection(CONNECTION *NewSocket, 76 | CONNECTION *ServerConnection); 77 | int CUPSRecv(CONNECTION *Connection, char *data, size_t size); 78 | int CUPSSend(CONNECTION *Connection, char *data, size_t size); 79 | int CUPSRecvFrom(CONNECTION *Connection, char *data, size_t size); 80 | int CUPSSendTo(CONNECTION *Connection, char *data, size_t size); 81 | int CUPSShutdownClientConnection(CONNECTION *Connection, 82 | int ShutdownType); 83 | int CUPSCleanup(CUPS_INFO *CupsInfo); 84 | 85 | #endif 86 | 87 | 88 | -------------------------------------------------------------------------------- /ch15/previous_node.c: -------------------------------------------------------------------------------- 1 | /************************************************************************** 2 | ** SP_PREVIOUS_NODE ** 3 | ** ** 4 | ** Returns the previous node in a given dimension. ** 5 | ** ** 6 | ** INPUT: ** 7 | ** sp -- The sparse matrix which contains the nodes ** 8 | ** dim -- The dimension of the node being requested ** 9 | ** node -- The current node ** 10 | ** ** 11 | ** OUTPUT: ** 12 | ** SP_NODE -- A pointer to the node ** 13 | ** ** 14 | ** SIDE EFFECTS: ** 15 | ** The error_no field of the sparse matrix can be set to an error if ** 16 | ** an error is encountered. Whenever an error is encountered, this ** 17 | ** value is set and a NULL pointer is returned. Thus, if a NULL ** 18 | ** pointer is returned from this function it is important to examine ** 19 | ** the error_no of the associated sparse matrix before assuming that ** 20 | ** the node list is empty. ** 21 | ** ** 22 | ** NOTES: ** 23 | ** ** 24 | **************************************************************************/ 25 | 26 | #include 27 | #include "sparse.h" 28 | 29 | SP_NODE *sp_previous_node(SPARSE_MATRIX *sp, int dim, SP_NODE *node) 30 | /* SPARSE_MATRIX *sp The sparse matrix in which to find the node */ 31 | /* int dim The dimension number of the previous node to be 32 | found */ 33 | /* SP_NODE *node The current node */ 34 | { 35 | /* If the sparse matrix passed is empty, then there are no nodes to be found */ 36 | if (sp == (SPARSE_MATRIX *)NULL) 37 | return ((SP_NODE *)NULL); 38 | 39 | sp->error_no = SP_NOERR; 40 | 41 | /* Make sure the dimension is within range */ 42 | if (dim > sp->dimensions) 43 | { 44 | sp->error_no = SP_DIM; 45 | return((SP_NODE *)NULL); 46 | } 47 | 48 | /* The stack has next, then previous node pointers for each dimension in that 49 | order, so there are 2 pointers for each dimension. The previous is the second 50 | of the two, so the offset is (2 * dim) + 1 */ 51 | return(*((SP_NODE **)(node->dimension_stack + (2 * (dim - 1))) + 1)); 52 | } 53 | -------------------------------------------------------------------------------- /ch22/ctc.c: -------------------------------------------------------------------------------- 1 | /* ctc.c - CUPS TCP Client Code 2 | * 3 | * 4 | * Copyright (C) 1999 Chad Dixon 5 | * Macmillan Computer Publishing 6 | * 7 | * This program is free software; you can redistribute it 8 | * and/or modify it under the terms of the GNU General 9 | * Public License as published by the Free Software 10 | * Foundation; either version 2 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will 14 | * be useful, but WITHOUT ANY WARRANTY; without even the 15 | * implied warranty of MERCHANTABILITY or FITNESS FOR A 16 | * PARTICULAR PURPOSE. See the GNU General Public License 17 | * for more details. 18 | * 19 | * You should have received a copy of the GNU General 20 | * Public License along with this program; if not, write 21 | * to the Free Software Foundation, Inc., 675 Mass Ave, 22 | * Cambridge, MA 02139, USA. 23 | * 24 | * Chad Dixon may be contacted at: 25 | * http://www.loopy.org 26 | * 27 | */ 28 | 29 | #include 30 | #include 31 | #include 32 | 33 | #include "cups.h" 34 | 35 | int Random(int n) 36 | { 37 | return (int)(n * (rand() / (1.0 + (double)RAND_MAX))); 38 | } 39 | 40 | int main(int argc, char *argv[]) 41 | { 42 | CUPS_INFO CupsInfo = {0}; 43 | CONNECTION ClientConnection = {0}; 44 | 45 | char data[255]={0}; 46 | 47 | if (argc != 2) 48 | { 49 | printf("usage: application hostname\n"); 50 | return EXIT_FAILURE; 51 | } 52 | 53 | srand(time(NULL)); 54 | CUPSInit(&CupsInfo); 55 | if(CUPSStartup(&CupsInfo) != 0) 56 | { 57 | printf("Initialization failed.\n"); 58 | fgets(data, sizeof data, stdin); 59 | return EXIT_FAILURE; 60 | } 61 | 62 | if (CUPSGetHostByName(&ClientConnection, argv[1]) != 0) 63 | { 64 | printf("Failure to resolve Hostname. %s\n", argv[1]); 65 | return EXIT_FAILURE; 66 | } 67 | 68 | if(0 != CUPSInitTCPConnection(&ClientConnection, INADDR_ANY, 1091)) 69 | { 70 | printf("Error on call to socket().\n"); 71 | return EXIT_FAILURE; 72 | } 73 | 74 | 75 | if (0 != CUPSConnect(&ClientConnection)) 76 | { 77 | printf("Error on connect().\n"); 78 | return EXIT_FAILURE; 79 | } 80 | 81 | 82 | sprintf(data, "%lu Branch %d", (unsigned long)Random(10000), Random(100)); 83 | if(0 != CUPSSend(&ClientConnection, data, sizeof data)) 84 | { 85 | printf("Unexpected error on send()\n"); 86 | } 87 | 88 | memset(data, 0, sizeof data); 89 | 90 | 91 | if(0 != CUPSRecv(&ClientConnection, data, sizeof data)) 92 | { 93 | printf("Unexpected error on recv()\n"); 94 | } 95 | 96 | printf("Received: %s\n", data); 97 | 98 | CUPSShutdown(&ClientConnection, CUPS_SHUTDOWN_BOTH); 99 | return EXIT_SUCCESS; 100 | } 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | -------------------------------------------------------------------------------- /ch22/wuc.c: -------------------------------------------------------------------------------- 1 | /* wuc.c - Windows UDP Client Code 2 | * 3 | * 4 | * Copyright (C) 1999 Chad Dixon 5 | * Macmillan Computer Publishing 6 | * 7 | * This program is free software; you can redistribute it 8 | * and/or modify it under the terms of the GNU General 9 | * Public License as published by the Free Software 10 | * Foundation; either version 2 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will 14 | * be useful, but WITHOUT ANY WARRANTY; without even the 15 | * implied warranty of MERCHANTABILITY or FITNESS FOR A 16 | * PARTICULAR PURPOSE. See the GNU General Public License 17 | * for more details. 18 | * 19 | * You should have received a copy of the GNU General 20 | * Public License along with this program; if not, write 21 | * to the Free Software Foundation, Inc., 675 Mass Ave, 22 | * Cambridge, MA 02139, USA. 23 | * 24 | * Chad Dixon may be contacted at: 25 | * http://www.loopy.org 26 | * 27 | */ 28 | 29 | #include 30 | #include 31 | #include 32 | 33 | 34 | int main(int argc, char *argv[]) 35 | { 36 | WORD wVersionRequested = MAKEWORD(1,1); 37 | SOCKADDR_IN their_addr; 38 | WSADATA wsaData; 39 | SOCKET sockfd; 40 | LPHOSTENT he; 41 | int addr_len; 42 | char data[32]={0}; 43 | 44 | int nRet=0; 45 | 46 | if (argc != 3) 47 | { 48 | printf("usage: application celsius hostname\n"); 49 | return EXIT_FAILURE; 50 | } 51 | 52 | sprintf(data, "%s", argv[1]); 53 | 54 | nRet = WSAStartup(wVersionRequested, &wsaData); 55 | if (wsaData.wVersion != wVersionRequested) 56 | { 57 | printf("\n Wrong version of Winsock\n"); 58 | return EXIT_FAILURE; 59 | } 60 | 61 | 62 | he = gethostbyname(argv[2]); 63 | if (he == NULL) 64 | { 65 | printf("Error in gethostbyname\n"); 66 | return EXIT_FAILURE; 67 | } 68 | sockfd = socket(AF_INET, SOCK_DGRAM, 0); 69 | if (sockfd == INVALID_SOCKET) 70 | { 71 | printf("Error Creating Socket\n"); 72 | return EXIT_FAILURE; 73 | } 74 | their_addr.sin_family = AF_INET; 75 | their_addr.sin_addr = *((LPIN_ADDR)*he->h_addr_list); 76 | their_addr.sin_port = htons(1092); 77 | 78 | 79 | if (sendto(sockfd, data, strlen(data), 80 | 0, (struct sockaddr *)&their_addr, 81 | sizeof(struct sockaddr)) == -1) 82 | { 83 | printf("Error in sendto\n"); 84 | return EXIT_FAILURE; 85 | } 86 | 87 | 88 | memset(data, 0, sizeof data); 89 | 90 | addr_len = sizeof(struct sockaddr); 91 | if (recvfrom(sockfd, data, sizeof data, 92 | 0, (struct sockaddr *)&their_addr, &addr_len) == -1) 93 | { 94 | printf("Error in recvfrom\n"); 95 | return EXIT_FAILURE; 96 | } 97 | 98 | 99 | printf("%s Celsius = %s Fahrenheight\n",argv[1], data); 100 | 101 | 102 | shutdown(sockfd,2); 103 | WSACleanup(); 104 | return EXIT_SUCCESS; 105 | } 106 | 107 | 108 | -------------------------------------------------------------------------------- /ch22/utc.c: -------------------------------------------------------------------------------- 1 | /* utc.c - UNIX TCP Client Code 2 | * 3 | * 4 | * Copyright (C) 1999 Chad Dixon 5 | * Macmillan Computer Publishing 6 | * 7 | * This program is free software; you can redistribute it 8 | * and/or modify it under the terms of the GNU General 9 | * Public License as published by the Free Software 10 | * Foundation; either version 2 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will 14 | * be useful, but WITHOUT ANY WARRANTY; without even the 15 | * implied warranty of MERCHANTABILITY or FITNESS FOR A 16 | * PARTICULAR PURPOSE. See the GNU General Public License 17 | * for more details. 18 | * 19 | * You should have received a copy of the GNU General 20 | * Public License along with this program; if not, write 21 | * to the Free Software Foundation, Inc., 675 Mass Ave, 22 | * Cambridge, MA 02139, USA. 23 | * 24 | * Chad Dixon may be contacted at: 25 | * http://www.loopy.org 26 | * 27 | */ 28 | 29 | 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | 38 | 39 | int Random(int n) 40 | { 41 | return (int)(n * (rand() / (1.0 + (double)RAND_MAX))); 42 | } 43 | 44 | 45 | int main(int argc, char *argv[]) 46 | { 47 | int sockfd=0; 48 | char data[255]={0}; 49 | struct hostent *he; 50 | struct sockaddr_in their_addr; 51 | 52 | srand((unsigned)time(NULL)); 53 | 54 | if (argc < 2) 55 | { 56 | fprintf(stderr,"usage: application hostname\n"); 57 | return EXIT_FAILURE; 58 | } 59 | 60 | if ((he=gethostbyname(argv[1])) == NULL) 61 | { 62 | printf("Error with gethostbyname()\n"); 63 | return EXIT_FAILURE; 64 | } 65 | 66 | if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) 67 | { 68 | printf("Error with call to socket()\n"); 69 | return EXIT_FAILURE; 70 | } 71 | 72 | 73 | their_addr.sin_family = AF_INET; 74 | their_addr.sin_port = htons(1091); 75 | their_addr.sin_addr = *((struct in_addr *)he->h_addr); 76 | 77 | memset(their_addr.sin_zero, 0, sizeof their_addr.sin_zero); 78 | 79 | if (connect(sockfd, (struct sockaddr *)&their_addr, sizeof(struct sockaddr)) ==-1) 80 | { 81 | printf("Error with connect()\n"); 82 | return EXIT_FAILURE; 83 | } 84 | 85 | sprintf(data, "%lu Branch %d", (unsigned long)Random(10000), Random(100)); 86 | 87 | if (send(sockfd, data, sizeof data, 0) == -1) 88 | { 89 | printf("Error with send()\n"); 90 | return EXIT_FAILURE; 91 | } 92 | 93 | memset(data, 0, sizeof data); 94 | 95 | if (recv(sockfd, data, sizeof data, 0) == -1) 96 | { 97 | printf("Error with recv()\n"); 98 | return EXIT_FAILURE; 99 | } 100 | 101 | printf("Received: %s\n", data); 102 | 103 | shutdown(sockfd,2); 104 | return EXIT_SUCCESS; 105 | } 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | -------------------------------------------------------------------------------- /ch20/sandra.c: -------------------------------------------------------------------------------- 1 | /* sandra.c - simple byte substitution 2 | * 3 | * SANDRA - Search AND ReplAce bytes 4 | * 5 | * Copyright (C) 2000 Richard Heathfield 6 | * Eton Computer Systems Ltd 7 | * Macmillan Computer Publishing 8 | * 9 | * This program is free software; you can redistribute it 10 | * and/or modify it under the terms of the GNU General 11 | * Public License as published by the Free Software 12 | * Foundation; either version 2 of the License, or 13 | * (at your option) any later version. 14 | * 15 | * This program is distributed in the hope that it will 16 | * be useful, but WITHOUT ANY WARRANTY; without even the 17 | * implied warranty of MERCHANTABILITY or FITNESS FOR A 18 | * PARTICULAR PURPOSE. See the GNU General Public License 19 | * for more details. 20 | * 21 | * You should have received a copy of the GNU General 22 | * Public License along with this program; if not, write 23 | * to the Free Software Foundation, Inc., 675 Mass Ave, 24 | * Cambridge, MA 02139, USA. 25 | * 26 | * Richard Heathfield may be contacted by email at: 27 | * binary@eton.powernet.co.uk 28 | * 29 | */ 30 | 31 | 32 | #include 33 | #include 34 | #include 35 | #include 36 | 37 | int HexToInt(char *s) 38 | { 39 | int IntVal = 0; 40 | char Hex[] = "0123456789ABCDEF"; 41 | char *p = NULL; 42 | 43 | while(*s != '\0') 44 | { 45 | /* Caution! Undefined behaviour for some inputs */ 46 | IntVal <<= 4; 47 | p = strchr(Hex, toupper(*s)); 48 | if(NULL != p) 49 | { 50 | IntVal |= (p - Hex); 51 | } 52 | else 53 | { 54 | printf("Can't convert hex value %s.\n", s); 55 | exit(EXIT_FAILURE); 56 | } 57 | ++s; 58 | } 59 | return IntVal; 60 | } 61 | 62 | void Sandra(char *filename, int in, int out) 63 | { 64 | FILE *fp = NULL; 65 | unsigned long count = 0; 66 | unsigned char c; 67 | 68 | fp = fopen(filename, "r+b"); 69 | if(NULL == fp) 70 | { 71 | printf("Can't open file %s for update.\n", filename); 72 | exit(EXIT_FAILURE); 73 | } 74 | while(fread(&c, 1, 1, fp)) 75 | { 76 | if(c == (unsigned char)in) 77 | { 78 | c = (unsigned char)out; 79 | fseek(fp, -1L, SEEK_CUR); 80 | count++; 81 | if(1 != fwrite(&c, 1, 1, fp)) 82 | { 83 | puts("Can't write to file."); 84 | fclose(fp); 85 | exit(EXIT_FAILURE); 86 | } 87 | /* This flush is /essential/ */ 88 | fflush(fp); 89 | } 90 | } 91 | fclose(fp); 92 | printf("The byte was replaced %lu time%s.\n", 93 | count, 94 | count == 1UL ? "" : "s"); 95 | } 96 | 97 | int main(int argc, char *argv[]) 98 | { 99 | if(argc < 4) 100 | { 101 | printf("Usage: %s filename searchbyte replacebyte\n", 102 | argc > 0 ? argv[0] : "sandra"); 103 | } 104 | else 105 | { 106 | Sandra(argv[1], HexToInt(argv[2]), HexToInt(argv[3])); 107 | } 108 | return 0; 109 | } 110 | 111 | -------------------------------------------------------------------------------- /ch22/cus.c: -------------------------------------------------------------------------------- 1 | /* cus.c - CUPS UDP Server Code 2 | * 3 | * 4 | * Copyright (C) 1999 Chad Dixon 5 | * Macmillan Computer Publishing 6 | * 7 | * This program is free software; you can redistribute it 8 | * and/or modify it under the terms of the GNU General 9 | * Public License as published by the Free Software 10 | * Foundation; either version 2 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will 14 | * be useful, but WITHOUT ANY WARRANTY; without even the 15 | * implied warranty of MERCHANTABILITY or FITNESS FOR A 16 | * PARTICULAR PURPOSE. See the GNU General Public License 17 | * for more details. 18 | * 19 | * You should have received a copy of the GNU General 20 | * Public License along with this program; if not, write 21 | * to the Free Software Foundation, Inc., 675 Mass Ave, 22 | * Cambridge, MA 02139, USA. 23 | * 24 | * Chad Dixon may be contacted at: 25 | * http://www.loopy.org 26 | * 27 | */ 28 | 29 | 30 | #include 31 | #include 32 | #include 33 | #include 34 | 35 | #include "cups.h" 36 | 37 | volatile sig_atomic_t done; 38 | 39 | 40 | void inthandler(int Sig) 41 | { 42 | done = 1; 43 | } 44 | 45 | int main(int argc, char **argv) 46 | { 47 | CUPS_INFO CupsInfo = {0}; 48 | CONNECTION ServerConnection = {0}; 49 | char data[32]= {0}; 50 | int celc=0; 51 | int farh=0; 52 | 53 | 54 | CUPSInit(&CupsInfo); 55 | if(CUPSStartup(&CupsInfo) != 0) 56 | { 57 | printf("Initialisation failed.\n"); 58 | fgets(data, sizeof data, stdin); 59 | return EXIT_FAILURE; 60 | } 61 | 62 | 63 | if(signal(SIGINT, SIG_IGN) != SIG_IGN) 64 | { 65 | signal(SIGINT, inthandler); 66 | } 67 | 68 | if(signal(SIGTERM, SIG_IGN) != SIG_IGN) 69 | { 70 | signal(SIGTERM, inthandler); 71 | } 72 | 73 | if(0 != CUPSInitUDPConnection(&ServerConnection, INADDR_ANY, 1092)) 74 | { 75 | printf("Can't open a socket!\n"); 76 | return EXIT_FAILURE; 77 | } 78 | 79 | if(0 != CUPSBind(&ServerConnection)) 80 | { 81 | printf("Can't bind.\n"); 82 | return EXIT_FAILURE; 83 | } 84 | 85 | 86 | 87 | 88 | while(!done) 89 | { 90 | if(0 != CUPSCheckForData(&ServerConnection)) 91 | { 92 | memset(data, 0, sizeof data); 93 | 94 | if (0 != CUPSRecvFrom(&ServerConnection, data, sizeof data)) 95 | { 96 | printf("Error on recvfrom\n"); 97 | } 98 | 99 | 100 | celc=atoi(data); 101 | farh=(celc*2)+32; 102 | memset(data, 0, sizeof data); 103 | sprintf(data, "%d", farh); 104 | 105 | 106 | if (0 != CUPSSendTo(&ServerConnection, data, sizeof data)) 107 | { 108 | printf("Error on sendto\n"); 109 | } 110 | 111 | printf("%s\n", data); 112 | } 113 | } 114 | 115 | CUPSShutdownClientConnection(&ServerConnection, 2); 116 | CUPSCleanup(&CupsInfo); 117 | 118 | printf("User requested program to halt.\n"); 119 | 120 | return EXIT_SUCCESS; 121 | } 122 | 123 | 124 | 125 | -------------------------------------------------------------------------------- /ch20/ascebc.txt: -------------------------------------------------------------------------------- 1 | 0x00,0x00,NUL 2 | 0x01,0x01,SOH 3 | 0x02,0x02,STX 4 | 0x03,0x03,ETX 5 | 0x04,0x04,EOT 6 | 0x05,0x2D,ENQ 7 | 0x06,0x2E,ACK 8 | 0x07,0x2F,BEL 9 | 0x08,0x16,BS 10 | 0x09,0x05,TAB 11 | 0x0A,0x25,LF 12 | 0x0B,0x0B,VT 13 | 0x0C,0x0C,FF 14 | 0x0D,0x0D,CR 15 | 0x0E,0x0E,SO 16 | 0x0F,0x0F,SI 17 | 0x10,0x10,DLE 18 | 0x11,0x11,DC1 19 | 0x12,0x12,DC2 20 | 0x13,0x13,DC3 21 | 0x14,0x3C,DC4 22 | 0x15,0x3D,NAK 23 | 0x16,0x32,SYN 24 | 0x17,0x26,ETB 25 | 0x18,0x18,CAN 26 | 0x19,0x19,EM 27 | 0x1A,0x3f,SUB 28 | 0x1B,0x27,ESC 29 | 0x1C,0x1C,FS 30 | 0x1D,0x1D,GS 31 | 0x1E,0x1E,RS 32 | 0x1F,0x1F,US 33 | 0x20,0x40,Space 34 | 0x21,0x5A,Exclamation Mark 35 | 0x22,0x7F,Quotation Mark 36 | 0x23,0x7B,Number Sign 37 | 0x24,0x5B,Dollar Sign 38 | 0x25,0x6C,Percent Sign 39 | 0x26,0x50,Ampersand 40 | 0x27,0x7D,Apostrophe 41 | 0x28,0x4D,Left Parenthesis 42 | 0x29,0x5D,Right Parenthesis 43 | 0x2A,0x5C,Asterisk 44 | 0x2B,0x4E,Plus Sign 45 | 0x2C,0x6B,Comma 46 | 0x2D,0x60,Hyphen or Minus Sign 47 | 0x2E,0x4B,Full Stop 48 | 0x2F,0x61,Solidus 49 | 0x30,0xF0,Digit Zero 50 | 0x31,0xF1,Digit One 51 | 0x32,0xF2,Digit Two 52 | 0x33,0xF3,Digit Three 53 | 0x34,0xF4,Digit Four 54 | 0x35,0xF5,Digit Five 55 | 0x36,0xF6,Digit Six 56 | 0x37,0xF7,Digit Seven 57 | 0x38,0xF8,Digit Eight 58 | 0x39,0xF9,Digit Nine 59 | 0x3A,0x7A,Colon 60 | 0x3B,0x5E,Semicolon 61 | 0x3C,0x4C,Less-Than Sign 62 | 0x3D,0x7E,Equal Sign 63 | 0x3E,0x6E,Greater-Than Sign 64 | 0x3F,0x6F,Question Mark 65 | 0x40,0x7C,Commercial At 66 | 0x41,0xC1,Letter A 67 | 0x42,0xC2,Letter B 68 | 0x43,0xC3,Letter C 69 | 0x44,0xC4,Letter D 70 | 0x45,0xC5,Letter E 71 | 0x46,0xC6,Letter F 72 | 0x47,0xC7,Letter G 73 | 0x48,0xc8,Letter H 74 | 0x49,0xC9,Letter I 75 | 0x4A,0xD1,Letter J 76 | 0x4B,0xD2,Letter K 77 | 0x4C,0xD3,Letter L 78 | 0x4D,0xD4,Letter M 79 | 0x4E,0xD5,Letter N 80 | 0x4F,0xD6,Letter O 81 | 0x50,0xD7,Letter P 82 | 0x51,0xD8,Letter Q 83 | 0x52,0xD9,Letter R 84 | 0x53,0xE2,Letter S 85 | 0x54,0xE3,Letter T 86 | 0x55,0xE4,Letter U 87 | 0x56,0xE5,Letter V 88 | 0x57,0xE6,Letter W 89 | 0x58,0xE7,Letter X 90 | 0x59,0xE8,Letter Y 91 | 0x5A,0xE9,Letter Z 92 | 0x5B,0xBA,Left Square Bracket 93 | 0x5C,0xE0,Reverse Solidus 94 | 0x5D,0xBB,Right Square Bracket 95 | 0x5E,0xB0,Circumflex Accent 96 | 0x5F,0x6D,Underscore 97 | 0x60,0x79,Backtick 98 | 0x61,0x81,Letter a 99 | 0x62,0x82,Letter b 100 | 0x63,0x83,Letter c 101 | 0x64,0x84,Letter d 102 | 0x65,0x85,Letter e 103 | 0x66,0x86,Letter f 104 | 0x67,0x87,Letter g 105 | 0x68,0x88,Letter h 106 | 0x69,0x89,Letter i 107 | 0x6A,0x91,Letter j 108 | 0x6B,0x92,Letter k 109 | 0x6C,0x93,Letter l 110 | 0x6D,0x94,Letter m 111 | 0x6E,0x95,Letter n 112 | 0x6F,0x96,Letter o 113 | 0x70,0x97,Letter p 114 | 0x71,0x98,Letter q 115 | 0x72,0x99,Letter r 116 | 0x73,0xA2,Letter s 117 | 0x74,0xA3,Letter t 118 | 0x75,0xA4,Letter u 119 | 0x76,0xA5,Letter v 120 | 0x77,0xA6,Letter w 121 | 0x78,0xA7,Letter x 122 | 0x79,0xA8,Letter y 123 | 0x7A,0xA9,Letter z 124 | 0x7B,0xC0,Left Curly Bracket 125 | 0x7C,0x4F,Pipe Symbol 126 | 0x7D,0xD0,Right Curly Bracket 127 | 0x7E,0xA1,Tilde 128 | 0x7F,0x07,DEL 129 | -------------------------------------------------------------------------------- /ch04/Listing07.c: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * weeknum_ISO8601.c December 1999 L.Kirby 3 | * 4 | * Calculates the week number of a day in the year based on the ISO8601 week 5 | * numbering scheme. The arguments are: 6 | * 7 | * t - a pointer to a struct tm in which the following members must be set and 8 | * normalised to the standard ranges specified (as standard library 9 | * functions gmtime, localtime and mktime should do): 10 | * 11 | * tm_wday - The day of the week of the day in question: 12 | * 0-Sunday -> 6-Saturday 13 | * 14 | * tm_yday - The day of the year of the day in question: 0 -> 365 15 | * January 1st is day 0. 16 | * 17 | * tm_year - The year since 1900. 18 | * 19 | * firstDOW - This defines the day of the week on which a week starts: 20 | * 0-Sunday -> 6-Saturday. Normal ISO8601 weeks start on 21 | * a Monday in which case this should be 1. 22 | * 23 | ****************************************************************************** 24 | * 25 | * The week number is a value between 1 and 53 inclusive defined according to 26 | * the following rules: 27 | * 28 | * 1. The Gregorian calendar is assumed. 29 | * 30 | * 2. There are always 7 consecutive days with the same week number. 31 | * 32 | * 3. January 4th is defined to be in week 1. Equivalently week 1 is the 33 | * first week of the year which has at least 4 days in that year. 34 | * 35 | * 4. firstDOW defines the day of the week which starts a new week i.e. has 36 | * a different week number from the previous day. 37 | * 38 | * 5. Week numbers increase in sequence from week 1 until the week that is 39 | * defined to be week 1 of the following year. 40 | * 41 | * It follows that: 42 | * 43 | * 6. Up to January 3rd may be in either week 1 of the current year or in 44 | * weeks 52 or 53 of the previous year. 45 | * 46 | * 7. 29th December onwards may be in either weeks 52 or 53 of the current 47 | * year or week 1 of the following year. 48 | * 49 | * XPG4 specifies a slight difference to the ISO rules which is implemented 50 | * if the XPG4_WEEKNUMS macro is defined 51 | * 52 | ****************************************************************************** 53 | */ 54 | 55 | #include 56 | 57 | #define is_leap(year) (!((year) % 4) && (((year) % 100) || !((year) % 400))) 58 | 59 | int weeknum_ISO8601(const struct tm *t, int firstDOW) 60 | { 61 | const int tmp1 = firstDOW - t->tm_wday; 62 | const int tmp2 = t->tm_yday + ((tmp1 > 0) ? 3 : 10) + tmp1; 63 | const int fourthdaynum = tmp2 % 7; 64 | int weeknum = tmp2 / 7; 65 | 66 | if (weeknum == 0) { 67 | #ifdef XPG4_WEEKNUMS 68 | weeknum = 53; 69 | #else 70 | const int yearnum = t->tm_year + (1900 % 400)-1; 71 | 72 | weeknum = (fourthdaynum + is_leap(yearnum) >= 6) ? 53 : 52; 73 | #endif 74 | } else if (weeknum == 53) { 75 | const int yearnum = t->tm_year + (1900 % 400); 76 | 77 | if (fourthdaynum > is_leap(yearnum)) 78 | weeknum = 1; 79 | } 80 | 81 | return weeknum; 82 | } 83 | -------------------------------------------------------------------------------- /ch15/get_node_list.c: -------------------------------------------------------------------------------- 1 | /************************************************************************** 2 | ** SP_GET_NODE_LIST ** 3 | ** ** 4 | ** Retrieves a pointer to the node list associated with the passed ** 5 | ** dimension and header element sequence number. ** 6 | ** ** 7 | ** INPUT: ** 8 | ** sp -- The sparse matrix which contains the header list stack ** 9 | ** dim -- The dimension of the header list being requested ** 10 | ** seq -- The sequence number of the header element ** 11 | ** ** 12 | ** OUTPUT: ** 13 | ** SP_NODE -- A pointer to the node list ** 14 | ** ** 15 | ** SIDE EFFECTS: ** 16 | ** The error_no field of the sparse matrix can be set to an error if ** 17 | ** an error is encountered. Whenever an error is encountered, this ** 18 | ** value is set and a NULL pointer is returned. Thus, if a NULL ** 19 | ** pointer is returned from this function it is important to examine ** 20 | ** the error_no of the associated sparse matrix before assuming that ** 21 | ** the node list is empty. ** 22 | ** ** 23 | ** NOTES: ** 24 | ** It is possible for the node list associated with a dimension and ** 25 | ** header element to be empty if no values are in the matrix. ** 26 | ** Therefore, the error_no value should be checked in the associated ** 27 | ** sparse matrix whenever a NULL pointer is returned. ** 28 | ** ** 29 | **************************************************************************/ 30 | 31 | #include 32 | #include "sparse.h" 33 | 34 | SP_NODE *sp_get_node_list(SPARSE_MATRIX *sp, int dim, int seq) 35 | /* SPARSE_MATRIX *sp The sparse matrix in which to find the header list */ 36 | /* int dim The dimension number of the header list */ 37 | /* seq The sequence number of the header list element */ 38 | { 39 | SP_HDR_ELEMENT *header_element; 40 | 41 | /* If the sparse matrix passed is empty, then there are no nodes to 42 | be found */ 43 | if (sp == (SPARSE_MATRIX *)NULL) 44 | return ((SP_NODE *)NULL); 45 | 46 | sp->error_no = SP_NOERR; 47 | 48 | /* Retrieve the header list element associated with the dimension and 49 | sequence*/ 50 | header_element = sp_hdr_list_element_get(sp, dim, seq); 51 | if ((sp->error_no != SP_NOERR) || (header_element == (SP_HDR_ELEMENT *)NULL)) 52 | { 53 | return((SP_NODE *)NULL); 54 | } 55 | 56 | return(header_element->first); 57 | } 58 | --------------------------------------------------------------------------------