home *** CD-ROM | disk | FTP | other *** search
/ minnie.tuhs.org / unixen.tar / unixen / PDP-11 / Trees / V7 / usr / src / cmd / refer / glue5.c < prev    next >
Encoding:
C/C++ Source or Header  |  1979-01-10  |  6.4 KB  |  361 lines

  1. # include "stdio.h"
  2. # include "ctype.h"
  3. /*
  4.  * fgrep -- print all lines containing any of a set of keywords
  5.  *
  6.  *    status returns:
  7.  *        0 - ok, and some matches
  8.  *        1 - ok, but no matches
  9.  *        2 - some error
  10.  */
  11. #define    MAXSIZ 700
  12. #define QSIZE 400
  13. struct words {
  14.     char     inp;
  15.     char    out;
  16.     struct    words *nst;
  17.     struct    words *link;
  18.     struct    words *fail;
  19. *www, *smax, *q;
  20.  
  21. char    buf[1024];
  22. int    nsucc;
  23. int    need;
  24. char    *instr;
  25. int    inct;
  26. int    rflag;
  27. int    xargc;
  28. char    **xargv;
  29. int    numwords;
  30. int    nfound;
  31. static int flag 0;
  32.  
  33.  
  34. fgrep(argc, argv)
  35. char **argv;
  36. {
  37.     instr = nsucc = need = inct = rflag = numwords = nfound = 0;
  38.     flag = 0;
  39.     if (www==0)
  40.         www = zalloc(MAXSIZ, sizeof (*www));
  41.     if (www==NULL)
  42.         err("Can't get space for machines", 0);
  43.     for (q=www; q<www+MAXSIZ; q++)
  44.         q->inp = q->out = q->nst = q->link = q->fail =0;
  45.     xargc = argc-1;
  46.     xargv = argv+1;
  47.     while (xargc>0 && xargv[0][0]=='-')
  48.         {
  49.         switch(xargv[0][1])
  50.             {
  51.             case 'r': /* return value only */
  52.                 rflag++;
  53.                 break;
  54.             case 'n': /* number of answers needed */
  55.                 need = xargv[1];
  56.                 xargv++; xargc--;
  57.                 break;
  58.             case 'i':
  59.                 instr = xargv[1];
  60.                 inct = xargv[2]+2;
  61. # if D2
  62. fprintf(stderr,"inct %d xargv.2. %o %d\n",inct, xargv[2],xargv[2]);
  63. # endif
  64.                 xargv += 2; xargc -= 2;
  65.                 break;
  66.             }
  67.         xargv++; xargc--;
  68.         }
  69.     if (xargc<=0)
  70.         {
  71.         write (2, "bad fgrep call\n", 15);
  72.         exit(2);
  73.         }
  74. # if D1
  75.     fprintf(stderr, "before cgoto\n");
  76. # endif
  77.     cgotofn();
  78. # if D1
  79.     fprintf(stderr, "before cfail\n");
  80. # endif
  81.     cfail();
  82. # if D1
  83.     fprintf(stderr, "before execute instr %.20s\n", instr? instr: "");
  84.     fprintf(stderr, "end of string %d %c %c %c\n", inct, instr[inct-3],
  85.         instr[inct-2], instr[inct-1]);
  86. # endif
  87.     execute();
  88. # if D1
  89.     fprintf(stderr, "returning nsucc %d\n", nsucc);
  90.     fprintf(stderr, "fgrep done www %o\n",www);
  91. # endif
  92.     return(nsucc == 0);
  93. }
  94.  
  95. execute()
  96. {
  97.     register char *p;
  98.     register c;
  99.     register ch;
  100.     register ccount;
  101.     int f;
  102.     char *nlp;
  103.     f=0;
  104.     ccount = instr ? inct : 0;
  105.     nfound=0;
  106.     p = instr ? instr : buf;
  107.     if (need == 0) need = numwords;
  108.     nlp = p;
  109.     c = www;
  110. # if D2
  111. fprintf(stderr, "in execute ccount %d inct %d\n",ccount, inct );
  112. # endif
  113.     for (;;) {
  114. # if D3
  115. fprintf(stderr, "down ccount\n");
  116. # endif
  117.         if (--ccount <= 0) {
  118. # if D2
  119. fprintf(stderr, "ex loop ccount %d instr %o\n",ccount, instr);
  120. # endif
  121.             if (instr) break;
  122.             if (p == &buf[1024]) p = buf;
  123.             if (p > &buf[512]) {
  124.                 if ((ccount = read(f, p, &buf[1024] - p)) <= 0) break;
  125.             }
  126.             else if ((ccount = read(f, p, 512)) <= 0) break;
  127. # if D2
  128. fprintf(stderr, " normal read %d bytres\n", ccount);
  129. {char xx[20]; sprintf(xx, "they are %%.%ds\n", ccount);
  130. fprintf(stderr, xx, p);
  131. }
  132. # endif
  133.         }
  134. nstate:
  135.         ch = *p;
  136. # if D2
  137. fprintf(stderr, "roaming along in ex ch %c c %o\n",ch,c);
  138. # endif
  139.         if (isupper(ch)) ch |= 040;
  140.         if (c->inp == ch) {
  141.             c = c->nst;
  142.         }
  143.         else if (c->link != 0) {
  144.             c = c->link;
  145.             goto nstate;
  146.         }
  147.         else {
  148.             c = c->fail;
  149.             if (c==0) {
  150.                 c = www;
  151. istate:
  152.                 if (c->inp == ch) {
  153.                     c = c->nst;
  154.                 }
  155.                 else if (c->link != 0) {
  156.                     c = c->link;
  157.                     goto istate;
  158.                 }
  159.             }
  160.             else goto nstate;
  161.         }
  162.         if (c->out && new (c)) {
  163. # if D2
  164. fprintf(stderr, " found: nfound %d need %d\n",nfound,need);
  165. # endif
  166.             if (++nfound >= need)
  167.             {
  168. # if D1
  169. fprintf(stderr, "found, p %o nlp %o ccount %d buf %o buf[1024] %o\n",p,nlp,ccount,buf,buf+1024);
  170. # endif
  171.                 if (instr==0)
  172.                 while (*p++ != '\n') {
  173. # if D3
  174. fprintf(stderr, "down ccount2\n");
  175. # endif
  176.                     if (--ccount <= 0) {
  177.                         if (p == &buf[1024]) p = buf;
  178.                         if (p > &buf[512]) {
  179.                             if ((ccount = read(f, p, &buf[1024] - p)) <= 0) break;
  180.                         }
  181.                         else if ((ccount = read(f, p, 512)) <= 0) break;
  182. # if D2
  183. fprintf(stderr, " read %d bytes\n",ccount);
  184. { char xx[20]; sprintf(xx, "they are %%.%ds\n", ccount);
  185. fprintf(stderr, xx, p);
  186. }
  187. # endif
  188.                     }
  189.                 }
  190.                 nsucc = 1;
  191.                 if (rflag==0)
  192.                     {
  193. # if D2
  194. fprintf(stderr, "p %o nlp %o buf %o\n",p,nlp,buf);
  195. if (p>nlp)
  196. {write (2, "XX\n", 3); write (2, nlp, p-nlp); write (2, "XX\n", 3);}
  197. # endif
  198.                     if (p > nlp) write(1, nlp, p-nlp);
  199.                     else {
  200.                         write(1, nlp, &buf[1024] - nlp);
  201.                         write(1, buf, p-&buf[0]);
  202.                         }
  203.                     if (p[-1]!= '\n') write (1, "\n", 1);
  204.                     }
  205.                 if (instr==0)
  206.                     {
  207.                     nlp = p;
  208.                     c = www;
  209.                     nfound=0; 
  210.                     }
  211.             }
  212.             else
  213.                 ccount++;
  214.             continue;
  215.         }
  216. # if D2
  217. fprintf(stderr, "nr end loop p %o\n",p);
  218. # endif
  219.         if (instr)
  220.             p++;
  221.         else
  222.         if (*p++ == '\n')
  223.         {
  224.             nlp = p;
  225.             c = www;
  226.             nfound=0;
  227.         }
  228.     }
  229.     if (instr==0)
  230.         close(f);
  231. }
  232.  
  233. cgotofn() {
  234.     register c;
  235.     register s;
  236.     s = smax = www;
  237. nword:    
  238.     for(;;) {
  239. # if D1
  240.     fprintf(stderr, " in for loop c now %o %c\n",c, c>' ' ? c : ' ');
  241. # endif
  242.         if ((c = gch())==0) return;
  243.         else if (c == '\n') {
  244.             s->out = 1;
  245.             s = www;
  246.         }
  247.         else {
  248. loop:    
  249.             if (s->inp == c) {
  250.                 s = s->nst;
  251.                 continue;
  252.             }
  253.             if (s->inp == 0) goto enter;
  254.             if (s->link == 0) {
  255.                 if (smax >= &www[MAXSIZ - 1]) overflo();
  256.                 s->link = ++smax;
  257.                 s = smax;
  258.                 goto enter;
  259.             }
  260.             s = s->link;
  261.             goto loop;
  262.         }
  263.     }
  264.  
  265. enter:
  266.     do {
  267.         s->inp = c;
  268.         if (smax >= &www[MAXSIZ - 1]) overflo();
  269.         s->nst = ++smax;
  270.         s = smax;
  271.     } 
  272.     while ((c = gch()) != '\n');
  273.     smax->out = 1;
  274.     s = www;
  275.     numwords++;
  276.     goto nword;
  277.  
  278. }
  279.  
  280. gch()
  281. {
  282.     static char *s;
  283.     if (flag==0)
  284.     {
  285.         flag=1;
  286.         s = *xargv++;
  287. # if D1
  288.     fprintf(stderr, "next arg is %s xargc %d\n",s,xargc);
  289. # endif
  290.         if (xargc-- <=0) return(0);
  291.     }
  292.     if (*s) return(*s++);
  293.     for(flag=0; flag<1024; flag++)
  294.         buf[flag]=0;
  295.     flag=0;
  296.     return('\n');
  297. }
  298.  
  299. overflo() {
  300.     write(2,"wordlist too large\n", 19);
  301.     exit(2);
  302. }
  303. cfail() {
  304.     struct words *queue[QSIZE];
  305.     struct words **front, **rear;
  306.     struct words *state;
  307.     register char c;
  308.     register s;
  309.     s = www;
  310.     front = rear = queue;
  311. init:    
  312.     if ((s->inp) != 0) {
  313.         *rear++ = s->nst;
  314.         if (rear >= &queue[QSIZE - 1]) overflo();
  315.     }
  316.     if ((s = s->link) != 0) {
  317.         goto init;
  318.     }
  319.  
  320.     while (rear!=front) {
  321.         s = *front;
  322.         if (front == &queue[QSIZE-1])
  323.             front = queue;
  324.         else front++;
  325. cloop:    
  326.         if ((c = s->inp) != 0) {
  327.             *rear = (q = s->nst);
  328.             if (front < rear)
  329.                 if (rear >= &queue[QSIZE-1])
  330.                     if (front == queue) overflo();
  331.                     else rear = queue;
  332.             else rear++;
  333.             else
  334.                 if (++rear == front) overflo();
  335.             state = s->fail;
  336. floop:    
  337.             if (state == 0) state = www;
  338.             if (state->inp == c) {
  339.                 q->fail = state->nst;
  340.                 if ((state->nst)->out == 1) q->out = 1;
  341.                 continue;
  342.             }
  343.             else if ((state = state->link) != 0)
  344.                 goto floop;
  345.         }
  346.         if ((s = s->link) != 0)
  347.             goto cloop;
  348.     }
  349. }
  350. static int seen[50];
  351. new (x)
  352. {
  353.     int i;
  354.     for(i=0; i<nfound; i++)
  355.         if (seen[i]==x)
  356.             return(0);
  357.     seen[i]=x;
  358.     return(1);
  359. }
  360.