|
|
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.