home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / vol_100 / 195_01 / find0.c < prev    next >
Text File  |  1987-10-05  |  4KB  |  202 lines

  1. /* [FIND0.C of JUGPDS Vol.18]
  2. *****************************************************************
  3. *                                *
  4. *    Written by  Hakuo Katayose (JUG-CP/M No.179)        *
  5. *            49-114 Kawauchi-Sanjuunin-machi        *
  6. *            Sendai, Miyagi 980                          *
  7. *            Phone: 0222-61-3219                *
  8. *                                *
  9. *    Edited & tested by Y. Monma (JUG-C/M Disk Editor)       * 
  10. *                                *
  11. *****************************************************************
  12. */
  13.  
  14. /* find - find patterns in text */
  15.  
  16. #include "stdio.h"
  17. #include "def.h"
  18. #include <dio.h>
  19.  
  20. main(argc, argv)
  21. int    argc;
  22. char    **argv;
  23.  
  24. {
  25.     char    lin[MAXLINE], pat[MAXPAT];
  26.     char    opt_l, *ap, *cp;
  27.     int    i, lno, nl, nx;
  28.  
  29.     dioinit(&argc, argv);
  30.     if (argc < 2) {
  31.         error("Usage: find0 pattern <infile >outfile\n");
  32.         exit();
  33.         }
  34.     opt_l = OFF;
  35.     nl = 1; i = 0;
  36.     i = 0;
  37.     while (--argc > 0) {
  38.         if ((*++argv)[0] == '-')
  39.             for (ap = argv[0]+1; *ap != '\0'; ap++) {
  40.                 if (tolower(*ap) == 'l') {
  41.                     opt_l = ON;
  42.                     nl = 0;
  43.                     for(; isdigit(nx = *(ap+1)); ap++)
  44.                         nl = nl*10 + nx - '0';
  45.                     nl = (nl == 0 ? 1 : nl);
  46.                     }
  47.                 else
  48.                     fprintf(STDERR,
  49.                     "[-%c]:Illigal option\n",tolower(*ap));
  50.                 }
  51.         cp = *argv;
  52.         }
  53.     if (getpat(cp, pat) == ERROR)
  54.         exit(fprintf(STDERR, "Illegal pattarn.\n"));
  55.     lno = 0;
  56.     while (getlin(lin, MAXLINE) > 0) {
  57.         lno += nl;
  58.         if (match(lin, pat) == YES)
  59.             if (opt_l == ON)
  60.                 printf("%6d: %s", lno, lin);
  61.             else
  62.                 printf("%s", lin);
  63.         }
  64.     dioflush();
  65. }
  66.  
  67. /* getpat - convert argument into pattern */
  68. getpat(arg, pat)
  69. char    *arg, *pat;
  70. {
  71.     return(makpat(arg, 0, '\0', pat));
  72. }
  73.  
  74. /* match - find match anywhere on line */
  75. match(lin, pat)
  76. char    lin[], *pat;
  77. {
  78.     int i;
  79.  
  80.  
  81.     for (i = 0; lin[i] != '\0'; i++)
  82.         if (amatch(lin, i, pat) >= 0)
  83.             return (YES);
  84.     return(NO);
  85. }
  86.  
  87. /* amatch (non-recursive) - look for stating at lin(from) */
  88. amatch(lin, from, pat)
  89. char    lin[], pat[];
  90. int    from;
  91.  
  92. {
  93.     int    i, j, offset, stack;
  94.  
  95.     stack = 0;
  96.     offset = from;
  97.     for (j = 0; pat[j] != '\0'; j += patsiz(pat, j))
  98.         if (pat[j] == CLOSURE) {
  99.             stack = j;
  100.             j += CLOSIZE;
  101.             for (i = offset; lin[i] != '\0'; )
  102.                 if (omatch(lin, &i, pat, j) == NO)
  103.                     break;
  104.             pat[stack + COUNT] = i - offset;
  105.             pat[stack + START] = offset;
  106.             offset = i;
  107.             }
  108.         else if (omatch(lin, &offset, pat, j) == NO) {
  109.             for (; stack > 0; stack = pat[stack + PREVCL]) {
  110.                 if (pat[stack + COUNT] > 0)
  111.                     break;
  112.                 }
  113.             if (stack <= 0)
  114.                 return(-1);
  115.             pat[stack + COUNT]--;
  116.             j = stack + CLOSIZE;
  117.             offset = pat[stack + START] + pat[stack + COUNT];
  118.             }
  119.     return(offset);
  120. }
  121.  
  122. /* patsiz - returns size of pattern entry at pat(n) */
  123. patsiz(pat, n)
  124. char    pat[];
  125. int    n;
  126.  
  127. {
  128.     switch (pat[n]) {
  129.         case BPAT :
  130.         case EPAT :
  131.         case CHAR :
  132.               return(2);
  133.         case BOL :
  134.         case EOL :
  135.         case ANY :
  136.               return(1);
  137.         case CCL :
  138.         case NCCL:
  139.               return (pat[n+1] + 2);
  140.         case CLOSURE :
  141.               return CLOSIZE;
  142.         default  :
  143.               exit(fprintf(STDERR, "Error in patsiz: can't happen.\n"));
  144.     }
  145. }
  146.  
  147. /* omatch - try to match a single pattern at pat(j) */
  148. omatch(lin, i, pat, j)
  149. char    lin[], pat[];
  150. int    *i, j;
  151.  
  152. {
  153.     int    bump;
  154.     char    c;
  155.  
  156.     c = lin[ *i ];
  157.     if (c == '\0')
  158.         return(NO);
  159.     bump = -1;
  160.     switch (pat[j]) {
  161.         case BPAT :
  162.         case EPAT : return(YES);
  163.         case CHAR : if (c == pat[j+1])
  164.                 bump= 1;
  165.                 break;
  166.         case BOL :  if (*i == 0)
  167.                 bump = 0;
  168.                 break;
  169.         case ANY :  if (c != '\n')
  170.                 bump = 1;
  171.                 break;
  172.         case EOL :  if (c == '\n')
  173.                 bump = 0;
  174.                 break;
  175.         case CCL :  if (locate(c, pat, j+1) == YES)
  176.                 bump = 1;
  177.                 break;
  178.         case NCCL:  if (c != '\n' && locate(c, pat, j+1) == NO)
  179.                 bump = 1;
  180.                 break;
  181.         default  :  fprintf(STDERR, "Error in omatch: can't happen.\n");
  182.     }
  183.     if (bump >= 0) {
  184.         *i += bump;
  185.         return(YES);
  186.         }
  187.     return(NO);
  188. }
  189.  
  190. /* locate - look for c in char class at pat(offset) */
  191. locate(c, pat, offset)
  192. char    c, pat[];
  193. int    offset;
  194.  
  195. {
  196.     int    i;
  197.  
  198.     for (i = offset + pat[offset]; i > offset; i--)
  199.         if (c == pat[i])  return YES;
  200.     return NO;
  201. }
  202.