|
|
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,stdout);
96: while(getword(entry,WORDSIZ)) {
97: canon(entry+3,word);
98: switch((*compare)(key,word)) {
99: case -1:
100: if(exact)
101: break;
102: case 0:
103: puts(entry,stdout);
104: continue;
105: }
106: break;
107: }
108: fflush(stdout);
109: } while(iflag);
110: return(0);
111:
112: }
113:
114: locate(key,entry)
115: char *key;
116: {
117: long top,bot,mid;
118: register c;
119: bot = 0;
120: fseek(dfile,0L,2);
121: top = ftell(dfile);
122: for(;;) {
123: mid = (top+bot)/2;
124: fseek(dfile,mid,0);
125: do {
126: c = getc(dfile);
127: mid++;
128: if(c==EOF)
129: break;
130: if(c!='\n')
131: continue;
132: c = getc(dfile);
133: mid++;
134: } while(c!=EOF && c!='\n');
135: if(!getword(entry,WORDSIZ))
136: break;
137: canon(entry+3,word);
138: switch((*compare)(key,word)) {
139: case -2:
140: case -1:
141: case 0:
142: if(top<=mid)
143: break;
144: top = mid;
145: continue;
146: case 1:
147: case 2:
148: bot = mid;
149: continue;
150: }
151: break;
152: }
153: fseek(dfile,bot,0);
154: while(getword(entry,WORDSIZ)) {
155: canon(entry+3,word);
156: switch((*compare)(key,word)) {
157: case -2:
158: return(0);
159: case -1:
160: if(exact)
161: return(0);
162: case 0:
163: return(1);
164: case 1:
165: case 2:
166: continue;
167: }
168: }
169: return(0);
170: }
171:
172: /* acomp(s,t) returns -2 if s strictly precedes t
173: -1 if s is a prefix of t
174: 0 if s is the same as t
175: 1 if t is a prefix of s
176: 2 if t strictly precedes s
177: */
178:
179: acomp(s,t)
180: register char *s,*t;
181: {
182: /* printf(":%s:%s:\n",s,t); fflush(stdout); */
183: for(;*s==*t;s++,t++)
184: if(*s==0)
185: return(0);
186: return(*s==0? -1:
187: *t==0? 1:
188: *s<*t? -2:
189: 2);
190: }
191:
192: getword(w,n)
193: char *w;
194: {
195: register c;
196: while(--n>0) {
197: c = getc(dfile);
198: if(c==EOF)
199: return(0);
200: *w++ = c;
201: if(c!='\n')
202: continue;
203: c = getc(dfile);
204: if(c==EOF)
205: return 0;
206: if(c=='\n') {
207: *w = 0;
208: return 1;
209: }
210: *w++ = c;
211: }
212: fprintf(stderr,"look: line too long\n");
213: return(0);
214: }
215:
216: canon(old,new)
217: char *old,*new;
218: {
219: register c;
220: char *savenew = new;
221: /* printf("<%s\n",old); fflush(stdout); */
222: for(;;) {
223: *new = c = *old++;
224: if(c==0||c=='\n'||c=='*') {
225: *new = 0;
226: break;
227: }
228: if(direc) {
229: if(!(isalnum(c)||c==' '||c=='\t'))
230: continue;
231: }
232: if(fold) {
233: if(isupper(c))
234: *new += 'a' - 'A';
235: }
236: new++;
237: }
238: /* printf(">%s\n",savenew); fflush(stdout);*/
239: }
240:
241: ncomp(s,t)
242: register char *s, *t;
243: {
244: char *is, *it, *js, *jt;
245: int a, b;
246: int ssgn, tsgn;
247: while(isspace(*s))
248: s++;
249: while(isspace(*t))
250: t++;
251: ssgn = tsgn = -2*rev;
252: if(*s == '-') {
253: s++;
254: ssgn = -ssgn;
255: }
256: if(*t == '-') {
257: t++;
258: tsgn = -tsgn;
259: }
260: for(is = s; isdigit(*is); is++) ;
261: for(it = t; isdigit(*it); it++) ;
262: js = is;
263: jt = it;
264: a = 0;
265: if(ssgn==tsgn)
266: while(it>t && is>s)
267: if(b = *--it - *--is)
268: a = b;
269: while(is > s)
270: if(*--is != '0')
271: return(-ssgn);
272: while(it > t)
273: if(*--it != '0')
274: return(tsgn);
275: if(a) return(sgn(a)*ssgn);
276: if(*(s=js) == '.')
277: s++;
278: if(*(t=jt) == '.')
279: t++;
280: if(ssgn==tsgn)
281: while(isdigit(*s) && isdigit(*t))
282: if(a = *t++ - *s++)
283: return(sgn(a)*ssgn);
284: while(isdigit(*s))
285: if(*s++ != '0')
286: return(-ssgn);
287: while(isdigit(*t))
288: if(*t++ != '0')
289: return(tsgn);
290: return(0);
291: }
292: sgn(x)
293: {
294: return x>0?1:x<0?-1:0;
295: }
296:
297: char *
298: ggets(s,n,f)
299: char *s;
300: FILE *f;
301: {
302: char *p = fgets(s,n,f);
303: char *q;
304: if(p && (q=strchr(s,'\n')))
305: *q = 0;
306: return p;
307: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.