home *** CD-ROM | disk | FTP | other *** search
/ minnie.tuhs.org / unixen.tar / unixen / PDP-11 / Trees / V6 / usr / source / s1 / grep.c < prev    next >
Encoding:
C/C++ Source or Header  |  1975-07-17  |  4.5 KB  |  343 lines

  1. #
  2. /*
  3.  * grep -- print lines matching (or not matching) a pattern
  4.  *
  5.  */
  6.  
  7. #define    CCHR    2
  8. #define    CDOT    4
  9. #define    CCL    6
  10. #define    NCCL    8
  11. #define    CDOL    10
  12. #define    CEOF    11
  13.  
  14. #define    STAR    01
  15.  
  16. #define    LBSIZE    256
  17. #define    ESIZE    256
  18.  
  19. char    ibuf[512];
  20. char    expbuf[ESIZE];
  21. int    lnum[2];
  22. char    linebuf[LBSIZE+1];
  23. int    bflag;
  24. int    nflag;
  25. int    cflag;
  26. int    vflag;
  27. int    nfile;
  28. int    circf;
  29. int    blkno;
  30. int    tln[2];
  31.  
  32. main(argc, argv)
  33. char **argv;
  34. {
  35.     extern fout;
  36.  
  37.     fout = dup(1);
  38.     flush();
  39.     while (--argc > 0 && (++argv)[0][0]=='-')
  40.         switch (argv[0][1]) {
  41.  
  42.         case 'v':
  43.             vflag++;
  44.             continue;
  45.  
  46.         case 'b':
  47.             bflag++;
  48.             continue;
  49.  
  50.         case 'c':
  51.             cflag++;
  52.             continue;
  53.  
  54.         case 'n':
  55.             nflag++;
  56.             continue;
  57.  
  58.         default:
  59.             printf2("Unknown flag\n");
  60.             continue;
  61.         }
  62.     if (argc<=0)
  63.         exit(2);
  64.     compile(*argv);
  65.     nfile = --argc;
  66.     if (argc<=0)
  67.         execute(0);
  68.     else while (--argc >= 0) {
  69.         argv++;
  70.         execute(*argv);
  71.     }
  72.     flush();
  73.     exit(0);
  74. }
  75.  
  76. compile(astr)
  77. char *astr;
  78. {
  79.     register c;
  80.     register char *ep, *sp;
  81.     char *lastep;
  82.     int cclcnt;
  83.  
  84.     ep = expbuf;
  85.     sp = astr;
  86.     if (*sp == '^') {
  87.         circf++;
  88.         sp++;
  89.     }
  90.     for (;;) {
  91.         if (ep >= &expbuf[ESIZE])
  92.             goto cerror;
  93.         if ((c = *sp++) != '*')
  94.             lastep = ep;
  95.         switch (c) {
  96.  
  97.         case '\0':
  98.             *ep++ = CEOF;
  99.             return;
  100.  
  101.         case '.':
  102.             *ep++ = CDOT;
  103.             continue;
  104.  
  105.         case '*':
  106.             if (lastep==0)
  107.                 goto defchar;
  108.             *lastep =| STAR;
  109.             continue;
  110.  
  111.         case '$':
  112.             if (*sp != '\0')
  113.                 goto defchar;
  114.             *ep++ = CDOL;
  115.             continue;
  116.  
  117.         case '[':
  118.             *ep++ = CCL;
  119.             *ep++ = 0;
  120.             cclcnt = 1;
  121.             if ((c = *sp++) == '^') {
  122.                 c = *sp++;
  123.                 ep[-2] = NCCL;
  124.             }
  125.             do {
  126.                 *ep++ = c;
  127.                 cclcnt++;
  128.                 if (c=='\0' || ep >= &expbuf[ESIZE])
  129.                     goto cerror;
  130.             } while ((c = *sp++) != ']');
  131.             lastep[1] = cclcnt;
  132.             continue;
  133.  
  134.         case '\\':
  135.             if ((c = *sp++) == '\0')
  136.                 goto cerror;
  137.         defchar:
  138.         default:
  139.             *ep++ = CCHR;
  140.             *ep++ = c;
  141.         }
  142.     }
  143.     cerror:
  144.     printf2("RE error\n");
  145. }
  146.  
  147. execute(file)
  148. {
  149.     register char *p1, *p2;
  150.     register c;
  151.     int f;
  152.     char *ebp, *cbp;
  153.  
  154.     if (file) {
  155.         if ((f = open(file, 0)) < 0) {
  156.             printf2("Can't open %s\n", file);
  157.         }
  158.     } else
  159.         f = 0;
  160.     ebp = ibuf;
  161.     cbp = ibuf;
  162.     lnum[0] = 0;
  163.     lnum[1] = 0;
  164.     tln[0] = 0;
  165.     tln[1] = 0;
  166.     blkno = -1;
  167.     for (;;) {
  168.         if ((++lnum[1])==0)
  169.             lnum[1]++;
  170.         if((lnum[1]&0377) == 0)
  171.             flush();
  172.         p1 = linebuf;
  173.         p2 = cbp;
  174.         for (;;) {
  175.             if (p2 >= ebp) {
  176.                 if ((c = read(f, ibuf, 512)) <= 0) {
  177.                     close(f);
  178.                     if (cflag) {
  179.                         if (nfile > 1)
  180.                             printf("%s:", file);
  181.                         p1 = locv(tln[0],tln[1]);
  182.                         printf("%s\n", p1);
  183.                     }
  184.                     return;
  185.                 }
  186.                 blkno++;
  187.                 p2 = ibuf;
  188.                 ebp = ibuf+c;
  189.             }
  190.             if ((c = *p2++) == '\n')
  191.                 break;
  192.             if(c)
  193.             if (p1 < &linebuf[LBSIZE-1])
  194.                 *p1++ = c;
  195.         }
  196.         *p1++ = 0;
  197.         cbp = p2;
  198.         p1 = linebuf;
  199.         p2 = expbuf;
  200.         if (circf) {
  201.             if (advance(p1, p2))
  202.                 goto found;
  203.             goto nfound;
  204.         }
  205.         /* fast check for first character */
  206.         if (*p2==CCHR) {
  207.             c = p2[1];
  208.             do {
  209.                 if (*p1!=c)
  210.                     continue;
  211.                 if (advance(p1, p2))
  212.                     goto found;
  213.             } while (*p1++);
  214.             goto nfound;
  215.         }
  216.         /* regular algorithm */
  217.         do {
  218.             if (advance(p1, p2))
  219.                 goto found;
  220.         } while (*p1++);
  221.     nfound:
  222.         if (vflag)
  223.             succeed(file);
  224.         continue;
  225.     found:
  226.         if (vflag==0)
  227.             succeed(file);
  228.     }
  229. }
  230.  
  231. advance(alp, aep)
  232. {
  233.     register char *lp, *ep, *curlp;
  234.     char *nextep;
  235.  
  236.     lp = alp;
  237.     ep = aep;
  238.     for (;;) switch (*ep++) {
  239.  
  240.     case CCHR:
  241.         if (*ep++ == *lp++)
  242.             continue;
  243.         return(0);
  244.  
  245.     case CDOT:
  246.         if (*lp++)
  247.             continue;
  248.         return(0);
  249.  
  250.     case CDOL:
  251.         if (*lp==0)
  252.             continue;
  253.         return(0);
  254.  
  255.     case CEOF:
  256.         return(1);
  257.  
  258.     case CCL:
  259.         if (cclass(ep, *lp++, 1)) {
  260.             ep =+ *ep;
  261.             continue;
  262.         }
  263.         return(0);
  264.  
  265.     case NCCL:
  266.         if (cclass(ep, *lp++, 0)) {
  267.             ep =+ *ep;
  268.             continue;
  269.         }
  270.         return(0);
  271.  
  272.     case CDOT|STAR:
  273.         curlp = lp;
  274.         while (*lp++);
  275.         goto star;
  276.  
  277.     case CCHR|STAR:
  278.         curlp = lp;
  279.         while (*lp++ == *ep);
  280.         ep++;
  281.         goto star;
  282.  
  283.     case CCL|STAR:
  284.     case NCCL|STAR:
  285.         curlp = lp;
  286.         while (cclass(ep, *lp++, ep[-1]==(CCL|STAR)));
  287.         ep =+ *ep;
  288.         goto star;
  289.  
  290.     star:
  291.         do {
  292.             lp--;
  293.             if (advance(lp, ep))
  294.                 return(1);
  295.         } while (lp > curlp);
  296.         return(0);
  297.  
  298.     default:
  299.         printf2("RE botch\n");
  300.     }
  301. }
  302.  
  303. cclass(aset, ac, af)
  304. {
  305.     register char *set, c;
  306.     register n;
  307.  
  308.     set = aset;
  309.     if ((c = ac) == 0)
  310.         return(0);
  311.     n = *set++;
  312.     while (--n)
  313.         if (*set++ == c)
  314.             return(af);
  315.     return(!af);
  316. }
  317.  
  318. printf2(s, a)
  319. {
  320.     extern fout;
  321.     flush();
  322.     fout = 2;
  323.     printf(s, a);
  324.     flush();
  325.     exit(2);
  326. }
  327.  
  328. succeed(f)
  329. {
  330.     if (cflag) {
  331.         if (++tln[1]==0)
  332.             tln[0]++;
  333.         return;
  334.     }
  335.     if (nfile > 1)
  336.         printf("%s:", f);
  337.     if (bflag)
  338.         printf("%l:", blkno);
  339.     if (nflag)
  340.         printf("%s:", locv(lnum[0], lnum[1]));
  341.     printf("%s\n", linebuf);
  342. }
  343.