|
|
1.1 ! root 1: #include <stdio.h> ! 2: #include <ctype.h> ! 3: ! 4: #define DICT "/usr/dict/words" ! 5: extern char *ggets(), *fgets(), *strchr(); ! 6: #define WORDSIZ BUFSIZ ! 7: ! 8: char *filename = DICT; ! 9: FILE *dfile; ! 10: ! 11: int fold; ! 12: int direc; ! 13: int exact; ! 14: int iflag; ! 15: int rev = 1; /*-1 for reverse-ordered file, not implemented*/ ! 16: int acomp(); ! 17: int ncomp(); ! 18: int (*compare)() = acomp; ! 19: int tab; ! 20: char entry[WORDSIZ]; ! 21: char word[WORDSIZ]; ! 22: char key[50]; ! 23: ! 24: main(argc,argv) ! 25: char **argv; ! 26: { ! 27: char *arg; ! 28: while(argc>=2 && *argv[1]=='-') { ! 29: for(arg=argv[1];;arg++) { ! 30: switch(arg[1]) { ! 31: case 'd': ! 32: direc++; ! 33: continue; ! 34: case 'f': ! 35: fold++; ! 36: continue; ! 37: case 'i': ! 38: iflag++; ! 39: continue; ! 40: case 'n': ! 41: compare = ncomp; ! 42: continue; ! 43: case 't': ! 44: tab = arg[2]; ! 45: if(tab) ! 46: ++arg; ! 47: continue; ! 48: case 'x': ! 49: exact++; ! 50: continue; ! 51: case 0: ! 52: break; ! 53: default: ! 54: fprintf(stderr,"look: bad option %s\n",arg); ! 55: return(2); ! 56: } ! 57: break; ! 58: } ! 59: argc --; ! 60: argv++; ! 61: } ! 62: if(!iflag) { ! 63: if(argc<2) ! 64: iflag++; ! 65: else { ! 66: canon(argv[1],key); ! 67: argv++; ! 68: argc--; ! 69: } ! 70: } ! 71: if(argc>=2) ! 72: filename = argv[1]; ! 73: else { ! 74: direc++; ! 75: fold++; ! 76: canon(key,key); ! 77: } ! 78: dfile = fopen(filename,"r"); ! 79: if(dfile==NULL) { ! 80: fprintf(stderr,"look: can't open %s\n",filename); ! 81: return(2); ! 82: } ! 83: if(!iflag) { ! 84: if(locate(key,entry)==0) ! 85: return(1); ! 86: } ! 87: do { ! 88: if(iflag) { ! 89: if(ggets(entry,sizeof entry,stdin)==0) ! 90: return(0); ! 91: canon(entry,key); ! 92: if(locate(key,entry)==0) ! 93: continue; ! 94: } ! 95: puts(entry); ! 96: while(getword(entry,WORDSIZ)) { ! 97: canon(entry,word); ! 98: switch((*compare)(key,word)) { ! 99: case -1: ! 100: if(exact) ! 101: break; ! 102: case 0: ! 103: puts(entry); ! 104: continue; ! 105: } ! 106: break; ! 107: } ! 108: } while(iflag); ! 109: return(0); ! 110: ! 111: } ! 112: ! 113: locate(key,entry) ! 114: char *key; ! 115: { ! 116: long top,bot,mid; ! 117: register c; ! 118: bot = 0; ! 119: fseek(dfile,0L,2); ! 120: top = ftell(dfile); ! 121: for(;;) { ! 122: mid = (top+bot)/2; ! 123: fseek(dfile,mid,0); ! 124: do { ! 125: c = getc(dfile); ! 126: mid++; ! 127: } while(c!=EOF && c!='\n'); ! 128: if(!getword(entry,WORDSIZ)) ! 129: break; ! 130: canon(entry,word); ! 131: switch((*compare)(key,word)) { ! 132: case -2: ! 133: case -1: ! 134: case 0: ! 135: if(top<=mid) ! 136: break; ! 137: top = mid; ! 138: continue; ! 139: case 1: ! 140: case 2: ! 141: bot = mid; ! 142: continue; ! 143: } ! 144: break; ! 145: } ! 146: fseek(dfile,bot,0); ! 147: while(getword(entry,WORDSIZ)) { ! 148: canon(entry,word); ! 149: switch((*compare)(key,word)) { ! 150: case -2: ! 151: return(0); ! 152: case -1: ! 153: if(exact) ! 154: return(0); ! 155: case 0: ! 156: return(1); ! 157: case 1: ! 158: case 2: ! 159: continue; ! 160: } ! 161: } ! 162: return(0); ! 163: } ! 164: ! 165: /* acomp(s,t) returns -2 if s strictly precedes t ! 166: -1 if s is a prefix of t ! 167: 0 if s is the same as t ! 168: 1 if t is a prefix of s ! 169: 2 if t strictly precedes s ! 170: */ ! 171: ! 172: acomp(s,t) ! 173: register char *s,*t; ! 174: { ! 175: for(;*s==*t;s++,t++) ! 176: if(*s==0) ! 177: return(0); ! 178: return(*s==0? -1: ! 179: *t==0? 1: ! 180: *s<*t? -2: ! 181: 2); ! 182: } ! 183: ! 184: getword(w,n) ! 185: char *w; ! 186: { ! 187: register c; ! 188: while(--n>0) { ! 189: c = getc(dfile); ! 190: if(c==EOF) ! 191: return(0); ! 192: if(c=='\n') { ! 193: *w = 0; ! 194: return 1; ! 195: } ! 196: *w++ = c; ! 197: } ! 198: fprintf(stderr,"look: line too long\n"); ! 199: return(0); ! 200: } ! 201: ! 202: canon(old,new) ! 203: char *old,*new; ! 204: { ! 205: register c; ! 206: /* printf(">%s\n",old); */ ! 207: for(;;) { ! 208: *new = c = *old++; ! 209: if(c==0||c==tab) { ! 210: *new = 0; ! 211: break; ! 212: } ! 213: if(direc) { ! 214: if(!(isalnum(c)||c==' '||c=='\t')) ! 215: continue; ! 216: } ! 217: if(fold) { ! 218: if(isupper(c)) ! 219: *new += 'a' - 'A'; ! 220: } ! 221: new++; ! 222: } ! 223: } ! 224: ! 225: ncomp(s,t) ! 226: register char *s, *t; ! 227: { ! 228: char *is, *it, *js, *jt; ! 229: int a, b; ! 230: int ssgn, tsgn; ! 231: while(isspace(*s)) ! 232: s++; ! 233: while(isspace(*t)) ! 234: t++; ! 235: ssgn = tsgn = -2*rev; ! 236: if(*s == '-') { ! 237: s++; ! 238: ssgn = -ssgn; ! 239: } ! 240: if(*t == '-') { ! 241: t++; ! 242: tsgn = -tsgn; ! 243: } ! 244: for(is = s; isdigit(*is); is++) ; ! 245: for(it = t; isdigit(*it); it++) ; ! 246: js = is; ! 247: jt = it; ! 248: a = 0; ! 249: if(ssgn==tsgn) ! 250: while(it>t && is>s) ! 251: if(b = *--it - *--is) ! 252: a = b; ! 253: while(is > s) ! 254: if(*--is != '0') ! 255: return(-ssgn); ! 256: while(it > t) ! 257: if(*--it != '0') ! 258: return(tsgn); ! 259: if(a) return(sgn(a)*ssgn); ! 260: if(*(s=js) == '.') ! 261: s++; ! 262: if(*(t=jt) == '.') ! 263: t++; ! 264: if(ssgn==tsgn) ! 265: while(isdigit(*s) && isdigit(*t)) ! 266: if(a = *t++ - *s++) ! 267: return(sgn(a)*ssgn); ! 268: while(isdigit(*s)) ! 269: if(*s++ != '0') ! 270: return(-ssgn); ! 271: while(isdigit(*t)) ! 272: if(*t++ != '0') ! 273: return(tsgn); ! 274: return(0); ! 275: } ! 276: ! 277: char * ! 278: ggets(s,n,f) ! 279: char *s; ! 280: FILE *f; ! 281: { ! 282: char *p = fgets(s,n,f); ! 283: char *q; ! 284: if(p && (q=strchr(s,'\n'))) ! 285: *q = 0; ! 286: return p; ! 287: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.