home *** CD-ROM | disk | FTP | other *** search
/ minnie.tuhs.org / unixen.tar / unixen / PDP-11 / Trees / V7 / usr / src / cmd / fgrep.c < prev    next >
Encoding:
C/C++ Source or Header  |  1979-04-23  |  5.5 KB  |  346 lines

  1. /*
  2.  * fgrep -- print all lines containing any of a set of keywords
  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.  
  12. #define    MAXSIZ 6000
  13. #define QSIZE 400
  14. struct words {
  15.     char     inp;
  16.     char    out;
  17.     struct    words *nst;
  18.     struct    words *link;
  19.     struct    words *fail;
  20. } w[MAXSIZ], *smax, *q;
  21.  
  22. long    lnum;
  23. int    bflag, cflag, fflag, lflag, nflag, vflag, xflag;
  24. int    hflag    = 1;
  25. int    sflag;
  26. int    nfile;
  27. long    blkno;
  28. int    nsucc;
  29. long    tln;
  30. FILE    *wordf;
  31. char    *argptr;
  32.  
  33. main(argc, argv)
  34. char **argv;
  35. {
  36.     while (--argc > 0 && (++argv)[0][0]=='-')
  37.         switch (argv[0][1]) {
  38.  
  39.         case 's':
  40.             sflag++;
  41.             continue;
  42.  
  43.         case 'h':
  44.             hflag = 0;
  45.             continue;
  46.  
  47.         case 'b':
  48.             bflag++;
  49.             continue;
  50.  
  51.         case 'c':
  52.             cflag++;
  53.             continue;
  54.  
  55.         case 'e':
  56.             argc--;
  57.             argv++;
  58.             goto out;
  59.  
  60.         case 'f':
  61.             fflag++;
  62.             continue;
  63.  
  64.         case 'l':
  65.             lflag++;
  66.             continue;
  67.  
  68.         case 'n':
  69.             nflag++;
  70.             continue;
  71.  
  72.         case 'v':
  73.             vflag++;
  74.             continue;
  75.  
  76.         case 'x':
  77.             xflag++;
  78.             continue;
  79.  
  80.         default:
  81.             fprintf(stderr, "egrep: unknown flag\n");
  82.             continue;
  83.         }
  84. out:
  85.     if (argc<=0)
  86.         exit(2);
  87.     if (fflag) {
  88.         wordf = fopen(*argv, "r");
  89.         if (wordf==NULL) {
  90.             fprintf(stderr, "egrep: can't open %s\n", *argv);
  91.             exit(2);
  92.         }
  93.     }
  94.     else argptr = *argv;
  95.     argc--;
  96.     argv++;
  97.  
  98.     cgotofn();
  99.     cfail();
  100.     nfile = argc;
  101.     if (argc<=0) {
  102.         if (lflag) exit(1);
  103.         execute((char *)NULL);
  104.     }
  105.     else while (--argc >= 0) {
  106.         execute(*argv);
  107.         argv++;
  108.     }
  109.     exit(nsucc == 0);
  110. }
  111.  
  112. execute(file)
  113. char *file;
  114. {
  115.     register char *p;
  116.     register struct words *c;
  117.     register ccount;
  118.     char buf[1024];
  119.     int f;
  120.     int failed;
  121.     char *nlp;
  122.     if (file) {
  123.         if ((f = open(file, 0)) < 0) {
  124.             fprintf(stderr, "fgrep: can't open %s\n", file);
  125.             exit(2);
  126.         }
  127.     }
  128.     else f = 0;
  129.     ccount = 0;
  130.     failed = 0;
  131.     lnum = 1;
  132.     tln = 0;
  133.     blkno = 0;
  134.     p = buf;
  135.     nlp = p;
  136.     c = w;
  137.     for (;;) {
  138.         if (--ccount <= 0) {
  139.             if (p == &buf[1024]) p = buf;
  140.             if (p > &buf[512]) {
  141.                 if ((ccount = read(f, p, &buf[1024] - p)) <= 0) break;
  142.             }
  143.             else if ((ccount = read(f, p, 512)) <= 0) break;
  144.             blkno += ccount;
  145.         }
  146.         nstate:
  147.             if (c->inp == *p) {
  148.                 c = c->nst;
  149.             }
  150.             else if (c->link != 0) {
  151.                 c = c->link;
  152.                 goto nstate;
  153.             }
  154.             else {
  155.                 c = c->fail;
  156.                 failed = 1;
  157.                 if (c==0) {
  158.                     c = w;
  159.                     istate:
  160.                     if (c->inp == *p) {
  161.                         c = c->nst;
  162.                     }
  163.                     else if (c->link != 0) {
  164.                         c = c->link;
  165.                         goto istate;
  166.                     }
  167.                 }
  168.                 else goto nstate;
  169.             }
  170.         if (c->out) {
  171.             while (*p++ != '\n') {
  172.                 if (--ccount <= 0) {
  173.                     if (p == &buf[1024]) p = buf;
  174.                     if (p > &buf[512]) {
  175.                         if ((ccount = read(f, p, &buf[1024] - p)) <= 0) break;
  176.                     }
  177.                     else if ((ccount = read(f, p, 512)) <= 0) break;
  178.                     blkno += ccount;
  179.                 }
  180.             }
  181.             if ( (vflag && (failed == 0 || xflag == 0)) || (vflag == 0 && xflag && failed) )
  182.                 goto nomatch;
  183.     succeed:    nsucc = 1;
  184.             if (cflag) tln++;
  185.             else if (sflag)
  186.                 ;    /* ugh */
  187.             else if (lflag) {
  188.                 printf("%s\n", file);
  189.                 close(f);
  190.                 return;
  191.             }
  192.             else {
  193.                 if (nfile > 1 && hflag) printf("%s:", file);
  194.                 if (bflag) printf("%ld:", (blkno-ccount-1)/512);
  195.                 if (nflag) printf("%ld:", lnum);
  196.                 if (p <= nlp) {
  197.                     while (nlp < &buf[1024]) putchar(*nlp++);
  198.                     nlp = buf;
  199.                 }
  200.                 while (nlp < p) putchar(*nlp++);
  201.             }
  202.     nomatch:    lnum++;
  203.             nlp = p;
  204.             c = w;
  205.             failed = 0;
  206.             continue;
  207.         }
  208.         if (*p++ == '\n')
  209.             if (vflag) goto succeed;
  210.             else {
  211.                 lnum++;
  212.                 nlp = p;
  213.                 c = w;
  214.                 failed = 0;
  215.             }
  216.     }
  217.     close(f);
  218.     if (cflag) {
  219.         if (nfile > 1)
  220.             printf("%s:", file);
  221.         printf("%ld\n", tln);
  222.     }
  223. }
  224.  
  225. getargc()
  226. {
  227.     register c;
  228.     if (wordf)
  229.         return(getc(wordf));
  230.     if ((c = *argptr++) == '\0')
  231.         return(EOF);
  232.     return(c);
  233. }
  234.  
  235. cgotofn() {
  236.     register c;
  237.     register struct words *s;
  238.  
  239.     s = smax = w;
  240. nword:    for(;;) {
  241.         c = getargc();
  242.         if (c==EOF)
  243.             return;
  244.         if (c == '\n') {
  245.             if (xflag) {
  246.                 for(;;) {
  247.                     if (s->inp == c) {
  248.                         s = s->nst;
  249.                         break;
  250.                     }
  251.                     if (s->inp == 0) goto nenter;
  252.                     if (s->link == 0) {
  253.                         if (smax >= &w[MAXSIZ -1]) overflo();
  254.                         s->link = ++smax;
  255.                         s = smax;
  256.                         goto nenter;
  257.                     }
  258.                     s = s->link;
  259.                 }
  260.             }
  261.             s->out = 1;
  262.             s = w;
  263.         } else {
  264.         loop:    if (s->inp == c) {
  265.                 s = s->nst;
  266.                 continue;
  267.             }
  268.             if (s->inp == 0) goto enter;
  269.             if (s->link == 0) {
  270.                 if (smax >= &w[MAXSIZ - 1]) overflo();
  271.                 s->link = ++smax;
  272.                 s = smax;
  273.                 goto enter;
  274.             }
  275.             s = s->link;
  276.             goto loop;
  277.         }
  278.     }
  279.  
  280.     enter:
  281.     do {
  282.         s->inp = c;
  283.         if (smax >= &w[MAXSIZ - 1]) overflo();
  284.         s->nst = ++smax;
  285.         s = smax;
  286.     } while ((c = getargc()) != '\n' && c!=EOF);
  287.     if (xflag) {
  288.     nenter:    s->inp = '\n';
  289.         if (smax >= &w[MAXSIZ -1]) overflo();
  290.         s->nst = ++smax;
  291.     }
  292.     smax->out = 1;
  293.     s = w;
  294.     if (c != EOF)
  295.         goto nword;
  296. }
  297.  
  298. overflo() {
  299.     fprintf(stderr, "wordlist too large\n");
  300.     exit(2);
  301. }
  302. cfail() {
  303.     struct words *queue[QSIZE];
  304.     struct words **front, **rear;
  305.     struct words *state;
  306.     register char c;
  307.     register struct words *s;
  308.     s = w;
  309.     front = rear = queue;
  310. init:    if ((s->inp) != 0) {
  311.         *rear++ = s->nst;
  312.         if (rear >= &queue[QSIZE - 1]) overflo();
  313.     }
  314.     if ((s = s->link) != 0) {
  315.         goto init;
  316.     }
  317.  
  318.     while (rear!=front) {
  319.         s = *front;
  320.         if (front == &queue[QSIZE-1])
  321.             front = queue;
  322.         else front++;
  323.     cloop:    if ((c = s->inp) != 0) {
  324.             *rear = (q = s->nst);
  325.             if (front < rear)
  326.                 if (rear >= &queue[QSIZE-1])
  327.                     if (front == queue) overflo();
  328.                     else rear = queue;
  329.                 else rear++;
  330.             else
  331.                 if (++rear == front) overflo();
  332.             state = s->fail;
  333.         floop:    if (state == 0) state = w;
  334.             if (state->inp == c) {
  335.                 q->fail = state->nst;
  336.                 if ((state->nst)->out == 1) q->out = 1;
  337.                 continue;
  338.             }
  339.             else if ((state = state->link) != 0)
  340.                 goto floop;
  341.         }
  342.         if ((s = s->link) != 0)
  343.             goto cloop;
  344.     }
  345. }
  346.