|
|
1.1 root 1: /*
2: * diction -- print all sentences containing one of default phrases
3: *
4: * status returns:
5: * 0 - ok, and some matches
6: * 1 - ok, but no matches
7: * 2 - some error
8: */
9:
10: #include <stdio.h>
11: #include <ctype.h>
12:
13: #define MAXSIZ 6500
14: #define QSIZE 2000
15: #define DICT ""
16: int linemsg;
17: long olcount;
18: long lcount;
19: struct words {
20: char inp;
21: char out;
22: char code;
23: struct words *nst;
24: struct words *link;
25: struct words *fail;
26: } w[MAXSIZ], *smax, *q;
27:
28: char table[128] = {
29: 0, 0, 0, 0, 0, 0, 0, 0,
30: 0, 0, ' ', 0, 0, 0, 0, 0,
31: 0, 0, 0, 0, 0, 0, 0, 0,
32: 0, 0, 0, 0, 0, 0, 0, 0,
33: ' ', '!', '"', '#', '$', '%', '&', '\'',
34: '(', ')', '*', '+', ' ', '-', '.', '/',
35: '0', '1', '2', '3', '4', '5', '6', '7',
36: '8', '9', ':', ' ', '<', '=', '>', '?',
37: '@', 'a', 'b', 'c', 'd', 'e', 'f', 'g',
38: 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
39: 'p', 'q', 'r', 's', 't', 'u', 'v', 'w',
40: 'x', 'y', 'z', '[', '\\', ']', '^', '_',
41: ' ', 'a', 'b', 'c', 'd', 'e', 'f', 'g',
42: 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
43: 'p', 'q', 'r', 's', 't', 'u', 'v', 'w',
44: 'x', 'y', 'z', '{', '|', '}', '~', ' '
45: };
46: int caps = 0;
47: int lineno = 1;
48: int fflag= 0;
49: int nflag = 0; /*use default file*/
50: char *filename;
51: int mflg = 0; /*don't catch output*/
52: int nfile;
53: int nsucc;
54: long nsent = 0;
55: long nhits = 0;
56: char *nlp;
57: char *begp, *endp;
58: int beg, last;
59: char *myst;
60: int myct = 0;
61: int oct = 0;
62: FILE *wordf;
63: FILE *mine;
64: FILE *fl;
65: char *listn;
66: int list = 0;
67: char *argptr;
68: long tl = 0;
69: long th = 0;
70:
71: main(argc, argv)
72: char *argv[];
73: {
74: int sv;
75: char cc;
76: while (--argc > 0 && (++argv)[0][0]=='-')
77: switch (argv[0][1]) {
78:
79: case 'f':
80: fflag++;
81: filename = (++argv)[0];
82: argc--;
83: continue;
84:
85: case 'n':
86: nflag = 0;
87: continue;
88: case 'd':
89: mflg=0;
90: continue;
91: case 'c':
92: caps++;
93: continue;
94: case 'l':
95: lineno++;
96: continue;
97: case 'A': /* for acro */
98: for(cc='A';cc<='Z';cc++)
99: table[cc] = cc;
100: continue;
101: case 'o': /*to put hits to file*/
102: listn = (++argv)[0];
103: argc--;
104: list++;
105: if((fl=fopen(listn,"w"))== NULL){
106: fprintf(stderr,"diction: can't open file %s\n",
107: listn);
108: exit(2);
109: }
110: continue;
111: default:
112: fprintf(stderr, "diction: unknown flag\n");
113: continue;
114: }
115: out:
116: if(nflag){
117: wordf = fopen(DICT,"r");
118: if(wordf == NULL){
119: fprintf(stderr,"diction: can't open default dictionary\n");
120: exit(2);
121: }
122: }
123: else {
124: wordf = fopen(filename,"r");
125: if(wordf == NULL){
126: fprintf(stderr,"diction: can't open %s\n",filename);
127: exit(2);
128: }
129: }
130:
131: #ifdef CATCH
132: if(fopen(CATCH,"r") != NULL){
133: if((mine=fopen(CATCH,"a"))==NULL)mflg=0;
134: else mflg = 1;
135: }
136: #else
137: mflg = 0;
138: #endif
139: #ifdef MACS
140: if(caps){
141: printf(".so ");
142: printf(MACS);
143: printf("\n");
144: }
145: #endif
146: cgotofn();
147: cfail();
148: nfile = argc;
149: if (argc<=0) {
150: execute((char *)NULL);
151: }
152: else while (--argc >= 0) {
153: execute(*argv);
154: if(lineno){
155: printf("file %s: number of lines %ld number of phrases found %ld\n",
156: *argv, lcount-1, nhits);
157: tl += lcount-1;
158: th += nhits;
159: sv = lcount-1;
160: lcount = nhits = 0;
161: }
162: argv++;
163: }
164: if(mflg)fprintf(mine,"number of sentences %ld %ld number of hits %ld %ld\n",nsent,tl,nhits,th);
165: if(!caps&& !lineno)printf("number of sentences %ld number of phrases found %ld\n",nsent,nhits);
166: else if(tl != sv)
167: if(!caps)printf("totals: number of lines %ld number of phrases found %ld\n",tl,th);
168: exit(nsucc == 0);
169: }
170:
171: execute(file)
172: char *file;
173: {
174: register char *p;
175: register struct words *c;
176: register ccount;
177: int count1;
178: char *beg1;
179: struct words *savc;
180: char *savp, *seen;
181: int savct;
182: int scr;
183: char buf[1024];
184: int f;
185: int hit;
186: last = 0;
187: if (file) {
188: if ((f = open(file, 0)) < 0) {
189: fprintf(stderr, "diction: can't open %s\n", file);
190: exit(2);
191: }
192: }
193: else f = 0;
194: lcount = olcount = 1;
195: linemsg = 1;
196: ccount = 0;
197: count1 = -1;
198: p = buf;
199: nlp = p;
200: c = w;
201: oct = hit = 0;
202: savc = (struct words *) 0;
203: savp = (char *) 0;
204: for (;;) {
205: if(--ccount <= 0) {
206: if (p == &buf[1024]) p = buf;
207: if (p > &buf[512]) {
208: if ((ccount = read(f, p, &buf[1024] - p)) <= 0) break;
209: }
210: else if ((ccount = read(f, p, 512)) <= 0){
211: break;
212: }
213: if(caps && (count1 > 0))
214: fwrite(beg1,sizeof(*beg1),count1,stdout);
215: count1 = ccount;
216: beg1 = p;
217: }
218: if(p == &buf[1024])p=buf;
219: nstate:
220: if (c->inp == table[*p]) {
221: c = c->nst;
222: }
223: else if (c->link != 0) {
224: c = c->link;
225: goto nstate;
226: }
227: else {
228: if(savp != 0){
229: c=savc;
230: p=savp;
231: if(ccount > savct)ccount += savct;
232: else ccount = savct;
233: savc = (struct words *) 0;
234: savp = (char *) 0;
235: goto hadone;
236: }
237: c = c->fail;
238: if (c==0) {
239: c = w;
240: istate:
241: if (c->inp == table[*p]) {
242: c = c->nst;
243: }
244: else if (c->link != 0) {
245: c = c->link;
246: goto istate;
247: }
248: }
249: else goto nstate;
250: }
251: if(c->out){
252: if((c->inp == table[*(p+1)]) && (c->nst != 0)){
253: savp=p;
254: savc=c;
255: savct=ccount;
256: goto cont;
257: }
258: else if(c->link != 0){
259: savc=c;
260: while((savc=savc->link)!= 0){
261: if(savc->inp == table[*(p+1)]){
262: savp=p;
263: savc=c;
264: savct=ccount;
265: goto cont;
266: }
267: }
268: }
269: hadone:
270: savc = (struct words *) 0;
271: savp = (char *) 0;
272: if(c->out == (char)(0377)){
273: c=w;
274: goto nstate;
275: }
276: begp = p - (c->out);
277: if(begp < &buf[0])begp = &buf[1024] - (&buf[0]-begp);
278: endp=p;
279: if(mflg){
280: if(begp-20 < &buf[0]){
281: myst = &buf[1024]-20;
282: if(nlp < &buf[512])myst=nlp;
283: }
284: else myst = begp-20;
285: if(myst < nlp)myst = nlp;
286: beg = 0;
287: }
288: hit = 1;
289: nhits++;
290: if(*p == '\n'){lcount++;
291: seen = p;
292: }
293: if (table[*p++] == '.') {
294: linemsg = 1;
295: if (--ccount <= 0) {
296: if (p == &buf[1024]) p = buf;
297: if (p > &buf[512]) {
298: if ((ccount = read(f, p, &buf[1024] - p)) <= 0) break;
299: }
300: else if ((ccount = read(f, p, 512)) <= 0) break;
301: if(caps && (count1 > 0))
302: fwrite(beg1,sizeof(*beg1),count1,stdout);
303: count1=ccount;
304: beg1=p;
305: }
306: }
307: succeed: nsucc = 1;
308: {
309: if (p <= nlp) {
310: outc(&buf[1024],file,c->code);
311: nlp = buf;
312: }
313: outc(p,file,c->code);
314: }
315: if(mflg)last=1;
316: nomatch:
317: nlp = p;
318: c = w;
319: begp = endp = 0;
320: continue;
321: }
322: cont:
323: if(*p == '\n' && p != seen){lcount++;
324: seen = p;
325: }
326: if (table[*p++] == '.'){
327: if(hit){
328: if(p <= nlp){
329: outc(&buf[1024],file,c->code);
330: nlp = buf;
331: }
332: outc(p,file,c->code);
333: if(!caps)printf("\n\n");
334: if(mflg && last){putc('\n',mine);myct = 0;}
335: }
336: linemsg = 1;
337: if(*p == '\n')olcount = lcount+1;
338: else
339: olcount=lcount;
340: last = 0;
341: hit = 0;
342: oct = 0;
343: nlp = p;
344: c = w;
345: begp = endp = 0;
346: nsent++;
347: }
348: }
349: if(caps && (count1 > 0))
350: fwrite(beg1,sizeof(*beg1),count1,stdout);
351: close(f);
352: }
353:
354: getargc()
355: {
356: register c;
357: if (wordf){
358: if((c=getc(wordf))==EOF){
359: fclose(wordf);
360: if(nflag && fflag){
361: nflag=0;
362: wordf=fopen(filename,"r");
363: if(wordf == NULL){
364: fprintf(stderr,"diction can't open %s\n",filename);
365: exit(2);
366: }
367: return(getc(wordf));
368: }
369: else return(EOF);
370: }
371: else if(c == ',' || c == ';')return(' ');
372: else return(c);
373: }
374: if ((c = *argptr++) == '\0')
375: return(EOF);
376: if(c == ',' || c == ';')return(' ');
377: return(c);
378: }
379:
380: cgotofn() {
381: register c, cx;
382: register struct words *s;
383: register ct;
384: int neg;
385:
386: s = smax = w;
387: neg = ct = 0;
388: nword: for(;;) {
389: c = getargc();
390: if(c == '~'){
391: neg++;
392: c = getargc();
393: }
394: if (c==EOF)
395: return;
396: if (c == '\n'|| c == '\t') {
397: if(neg)s->out = 0377;
398: else s->out = ct-1;
399: if(c == '\t'){
400: s->code = getargc();
401: if((cx=getargc()) != '\n')
402: overflo("bad code");
403: }
404: else s->code = 0;
405: neg = ct = 0;
406: s = w;
407: } else {
408: loop: if (s->inp == c) {
409: s = s->nst;
410: ct++;
411: continue;
412: }
413: if (s->inp == 0) goto enter;
414: if (s->link == 0) {
415: if (smax >= &w[MAXSIZ - 1]) overflo("w1");
416: s->link = ++smax;
417: s = smax;
418: goto enter;
419: }
420: s = s->link;
421: goto loop;
422: }
423: }
424:
425: enter:
426: do {
427: s->inp = c;
428: ct++;
429: if (smax >= &w[MAXSIZ - 1]) overflo("w2");
430: s->nst = ++smax;
431: s = smax;
432: } while ((c = getargc()) != '\n' && c != '\t' && c!=EOF);
433: if(neg)smax->out = 0377;
434: else smax->out = ct-1;
435: if(c == '\t'){
436: s->code = getargc();
437: if((cx=getargc()) != '\n')
438: overflo("bad code2");
439: }
440: else s->code = 0;
441: neg = ct = 0;
442: s = w;
443: if (c != EOF)
444: goto nword;
445: }
446:
447: overflo(s)
448: char *s;
449: {
450: fprintf(stderr, "wordlist too large %s\n",s);
451: exit(2);
452: }
453: cfail() {
454: struct words *queue[QSIZE];
455: struct words **front, **rear;
456: struct words *state;
457: int bstart;
458: register char c;
459: register struct words *s;
460: s = w;
461: front = rear = queue;
462: init: if ((s->inp) != 0) {
463: *rear++ = s->nst;
464: if (rear >= &queue[QSIZE - 1]) overflo("queue1");
465: }
466: if ((s = s->link) != 0) {
467: goto init;
468: }
469:
470: while (rear!=front) {
471: s = *front;
472: if (front == &queue[QSIZE-1])
473: front = queue;
474: else front++;
475: cloop: if ((c = s->inp) != 0) {
476: bstart=0;
477: *rear = (q = s->nst);
478: if (front < rear)
479: if (rear >= &queue[QSIZE-1])
480: if (front == queue) overflo("queue2");
481: else rear = queue;
482: else rear++;
483: else
484: if (++rear == front) overflo("queue3");
485: state = s->fail;
486: floop: if (state == 0){ state = w;bstart=1;}
487: if (state->inp == c) {
488: qloop: q->fail = state->nst;
489: if ((state->nst)->out != 0 && q->out == 0){
490: q->out = (state->nst)->out;
491: q->code = (state->nst)->code;
492: }
493: if((q=q->link) != 0)goto qloop;
494: /* do {
495: q->fail = state->nst;
496: if((state->nst)->out != 0)q->out=(state->nst)->out;
497: }while((q=q->link) != 0);*/
498: }
499: else if((state->link) != 0){
500: state = state->link;
501: goto floop;
502: }
503: else if((state = state->fail) != 0)
504: goto floop;
505: else if(bstart==0){state=0; goto floop;}
506: }
507: if ((s = s->link) != 0)
508: goto cloop;
509: }
510: /* for(s=w;s<=smax;s++)
511: printf("s %d ch %c out %d nst %d link %d fail %d\n",s,
512: s->inp,s->out,s->nst,s->link,s->fail);
513: */
514: }
515: outc(addr,file,code)
516: char *addr;
517: char *file;
518: char code;
519: {
520: static inside = 0;
521:
522: if(!caps && lineno && linemsg){
523: if(list)fprintf(fl,"%ld ",olcount);
524: printf("beginning line %ld",olcount);
525: if(file != (char *)NULL)printf(" %s\n",file);
526: else printf("\n");
527: linemsg = 0;
528: }
529: while(nlp < addr){
530: if(!caps && oct > 60 && table[*nlp] == ' ' && nlp != begp && nlp != endp){
531: oct=0;
532: putchar('\n');
533: }
534: if(nlp == begp){
535: if(caps)inside++;
536: else {
537: if(list)inside++;
538: if( oct >45){putchar('\n');
539: oct=0;
540: }
541: if( oct==0 || table[*nlp] != ' '){
542: printf("*[");
543: oct+=2;
544: }
545: else {printf(" *[");;
546: oct+=3;
547: }
548: }
549: if(mflg)putc('[',mine);
550: }
551: if(inside && caps){
552: if(islower(*nlp))*nlp = toupper(*nlp);
553: }
554: else {
555: if(inside && list)putc(table[*nlp],fl);
556: if(!caps && *nlp == '\n')*nlp = ' ';
557: if(*nlp == ' ' && oct==0);
558: else if(!caps) {putchar(*nlp); oct++;}
559: }
560: if(nlp == endp){
561: if(caps)
562: inside= 0;
563: else {
564: if(list && inside){
565: inside = 0;
566: if(code){
567: putc('\t',fl);
568: putc(code,fl);
569: }
570: putc('\n',fl);
571: }
572: if(*(nlp) != ' '){printf("]*");
573: oct+=2;
574: }
575: else {printf("]* ");
576: oct+=3;
577: }
578: if(oct >60){putchar('\n');
579: oct=0;
580: }
581: }
582: if(mflg)putc(']',mine);
583: beg = 0;
584: }
585: if(mflg){
586: if(nlp == myst)beg = 1;
587: if(beg || last){
588: putc(*nlp,mine);
589: if(myct++ >= 72 || last == 20){
590: putc('\n',mine);
591: if(last == 20)last=myct=0;
592: else myct=0;
593: }
594: if(last)last++;
595: }
596: }
597: nlp++;
598: }
599: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.