|
|
1.1 ! root 1: /* @(#)spellin.c 1.1 */ ! 2: #include <stdio.h> ! 3: #include "hash.h" ! 4: ! 5: #define S (BYTE*sizeof(long)) ! 6: #define B (BYTE*sizeof(unsigned)) ! 7: unsigned tabword; ! 8: unsigned short index[NI]; ! 9: unsigned wp; /* word pointer*/ ! 10: int bp =B; /* bit pointer*/ ! 11: int extra; ! 12: ! 13: /* usage: hashin N ! 14: where N is number of words in dictionary ! 15: and standard input contains sorted, unique ! 16: hashed words in octal ! 17: */ ! 18: main(argc,argv) ! 19: char **argv; ! 20: { ! 21: long h,k,d; ! 22: register i; ! 23: long count; ! 24: long w; ! 25: long x; ! 26: int t,u; ! 27: extern double huff(); ! 28: extern long ftell(); ! 29: long seekpt; ! 30: double atof(); ! 31: double z; ! 32: double nwords; ! 33: k = 0; ! 34: u = 0; ! 35: if(argc!=2) { ! 36: fprintf(stderr,"spellin: arg count\n"); ! 37: exit(1); ! 38: } ! 39: nwords = atof(argv[1]); ! 40: z = huff((1L<<HASHWIDTH)/nwords); ! 41: fprintf(stderr, "spellin: expected code widths = %f", z); ! 42: z += sizeof(tabword)*BYTE/2*(double)(1<<INDEXWIDTH)/nwords; ! 43: fprintf(stderr, " +breakage = %f\n", z); /*t half word per bin */ ! 44: whuff(); ! 45: seekpt = ftell(stdout); ! 46: fwrite((char*)index, sizeof(*index), NI, stdout); /*dummy data */ ! 47: for(count=0; scanf("%lo", &h) == 1; ++count) { ! 48: if((t=h>>(HASHWIDTH-INDEXWIDTH)) != u) { ! 49: if(bp!=B) ! 50: newword(); ! 51: bp = B; ! 52: while(u<t) ! 53: index[++u] = wp; ! 54: k = (long)t<<(HASHWIDTH-INDEXWIDTH); ! 55: } ! 56: d = h-k; ! 57: k = h; ! 58: for(;;) { ! 59: for(x=d;;x/=2) { ! 60: i = encode(x,&w); ! 61: if(i>0) ! 62: break; ! 63: } ! 64: if(i>B) { ! 65: append((unsigned)(w>>(i-B)), B); ! 66: append((unsigned)(w<<(B+B-i)), i-B); ! 67: } else ! 68: append((unsigned)(w<<(B-i)), i); ! 69: d -= x; ! 70: if(d>0) ! 71: extra++; ! 72: else ! 73: break; ! 74: } ! 75: } ! 76: if(bp!=B) ! 77: newword(); ! 78: while(++u<NI) ! 79: index[u] = wp; ! 80: newword(); /* padding allows one out-of-bounds fetch */ ! 81: newword(); ! 82: newword(); ! 83: fseek(stdout, seekpt, 0); /* overwrite dummy data */ ! 84: fwrite((char*)index, sizeof(*index), NI, stdout); ! 85: fprintf(stderr, "spellin: %ld items, %d extra, %u words occupied\n", ! 86: count,extra,wp); ! 87: fprintf(stderr, "spellin: %f table bits/item, ", ! 88: ((float)BYTE*wp)*sizeof(tabword)/count); ! 89: fprintf(stderr, "%f table+index bits\n", ! 90: BYTE*((float)wp*sizeof(tabword) + sizeof(index))/count); ! 91: return(0); ! 92: } ! 93: ! 94: append(w, i) ! 95: register unsigned w; ! 96: register i; ! 97: { ! 98: for(;;) { ! 99: tabword |= w>>(B-bp); ! 100: i -= bp; ! 101: if(i<0) { ! 102: bp = -i; ! 103: return; ! 104: } ! 105: w <<= bp; ! 106: bp = B; ! 107: newword(); ! 108: } ! 109: } ! 110: ! 111: newword() ! 112: { ! 113: fwrite((char*)&tabword, sizeof(tabword), 1, stdout); ! 114: wp++; ! 115: tabword = 0; ! 116: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.