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

  1. /* [FIND1.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. /* find1 - find patterns in text */
  15.  
  16. #include "stdio.h"
  17.  
  18. #define    BDS        1
  19.  
  20. /*
  21. #define    DEBUG        1
  22. */
  23.  
  24. #ifdef    BDS
  25.  
  26. #include <dio.h>
  27.  
  28. #define    stderr        STDERR
  29. #define    stdin        STDIN
  30.  
  31. #endif
  32.  
  33.  
  34. #define    MAXLINE        256
  35. #define    TAB        0x09
  36. #define    YES        0
  37. #define    NO        -1
  38.  
  39. #define    NOT_CHAR    '!'
  40. #define    NOT        0x00800
  41. #define    NMASK        0x0FEFF
  42. #define    BOL_CHAR    '%'
  43. #define    BOL        0x00125
  44. #define    ANY_CHAR    '?'
  45. #define    ANY        0x0013F
  46. #define    EOL_CHAR    '$'
  47. #define    EOL        0x00124
  48. #define    PCLOSURE_CHAR    '+'
  49. #define    CLOSURE_CHAR    '*'
  50. #define    CLOSURE        0x04000
  51. #define    CMASK        0x0BFFF
  52. #define    CCL_CHAR    '['
  53. #define    CCL        0x02000
  54. #define    NCL        0x01000
  55. #define    ECL_CHAR    ']'
  56. #define    GROUP        '-'
  57. #define    UC        '\\'
  58.  
  59. int    np;
  60. int    spat[16][64];
  61.  
  62. main(argc, argv)
  63. int    argc;
  64. char *argv[];
  65.  
  66. {
  67.     char    line[MAXLINE];
  68.     int    pat[256];
  69.  
  70. #ifdef    DEBUG
  71.     int    i, j;
  72. #endif
  73.  
  74. #ifdef    BDS
  75.     dioinit(&argc, argv);
  76. #endif
  77.  
  78.     np = 0;
  79.     if (argc < 2) {
  80.         fprintf(stderr, "Usage: find1 pattern <infile >outfile\n");
  81.         exit();
  82.     }
  83.     makpat(pat, argv[1]);
  84.  
  85. #ifdef    DEBUG
  86.  
  87.     printf("PAT[ ]");
  88.     for (j = 0; pat[j] != '\0'; j++)
  89.         printf("%04x", pat[j]);
  90.     putchar('\n');
  91.     for (i = 0; i < np; i++) {
  92.         printf("PAT[%1d]", i);
  93.         for (j = 0; spat[i][j] != '\0'; j++)
  94.             printf("%04x", spat[i][j]);
  95.         putchar('\n');
  96.     }
  97. #endif
  98.  
  99.     while (getline(line, MAXLINE) > 0)
  100.         if (match(line, pat) >= 0)
  101.             printf("%s", line);
  102. #ifdef    BDS
  103.     dioflush();
  104. #endif
  105.  
  106. }
  107.  
  108. /* makpat -make pattern from arg(from), terminates atdelim */
  109. makpat(s, t)
  110. int    *s;
  111. char    *t;
  112.  
  113. {
  114.     register    char    *tt;
  115.  
  116.     tt = t;
  117.     if (*t == BOL_CHAR) {
  118.         *s++ = BOL;
  119.         t++;
  120.     }
  121.     for (; *t != '\0'; t++) {
  122.         if (*t == ANY_CHAR)
  123.             *s++ = ANY;
  124.         else if (*t == EOL_CHAR && *(t+1) == '\0')
  125.             *s++ = EOL;
  126.         else if (*t == CLOSURE_CHAR && t > tt)
  127.             *(s-1) |= CLOSURE;
  128.         else if (*t == PCLOSURE_CHAR && t > tt)
  129.             *s++ = *(s-1) | CLOSURE;
  130.         else if (*t == CCL_CHAR && *(t+1) != '\0')
  131.             getccl(np++,&s,&t);
  132.         else if (*t == NOT_CHAR && *t != '\0') {
  133.             t++;
  134.             *s++ = esc(&t) | NOT;
  135.         }
  136.         else
  137.             *s++ = esc(&t) ;
  138.     }
  139.     *s = '\0';
  140. }
  141.  
  142. /* getccl - expand char class at arg(i) into pat(j) */
  143. getccl(np,x,y)
  144. register int  **x;
  145. register char **y;
  146.  
  147. {
  148.     char    ss, st, ch;
  149.     int    i;
  150. #define    s    (*x)
  151. #define    t    (*y)
  152.  
  153.     t++;
  154.     if (*t == NOT_CHAR) {
  155.         *s++ = NCL + np;
  156.         t++;
  157.     }
  158.     else
  159.         *s++ = CCL + np;
  160.     for (i = 0; *t != ECL_CHAR && *t != '\0'; i++, t++) {
  161.         if (*t != GROUP)
  162.             spat[np][i] = esc(y);
  163.         else {
  164.             t++;
  165.             ss = esc(y);
  166.             st = spat[np][i-1];
  167.             if ((isdigit(st) && isdigit(ss) ||
  168.                  islower(st) && islower(ss) ||
  169.                  isupper(st) && isupper(ss)) &&
  170.                  st < ss) {
  171.                 i--;
  172.                 for (ch = st; ch <= ss; ch++)
  173.                     spat[np][i++] = ch;
  174.                 i--;
  175.             }
  176.             else {
  177.                 spat[np][i++] = GROUP;
  178.                 spat[np][i]   = ss;
  179.             }
  180.         }
  181.     }
  182.     spat[np][i] = '\0';
  183.     t--;
  184.     if (*t != '\0')
  185.         t++;
  186.  
  187. #undef t
  188. #undef s
  189. }
  190.  
  191. /* esc - map aray(i) into escaped character if appropriate */
  192. esc(x)
  193. register char **x;
  194. {
  195. #define    t    (*x)
  196.  
  197.     if (*t == '@' && *(t+1) != '\0')
  198.         switch (*++t) {
  199.             case 'n' :
  200.             case 'N' :    return ('\n');
  201.             case 's' :
  202.             case 'S' :    return (' ');
  203.             case 't' :
  204.             case 'T' :    return ('\t');
  205.             default  :    return (*t);
  206.         }
  207.     else if (*t == UC && *(t+1) != '\0')
  208.         return toupper(*++t);
  209.     else
  210.         return tolower(*t);
  211.  
  212. #undef    s
  213. }
  214.  
  215.  
  216. getline(s,lim)
  217. char *s;
  218.  
  219. {
  220.     register int    c;
  221.     register char    *p;
  222.  
  223.     p = s;
  224.     while (--lim > 0 && (c = getchar()) != EOF && c != '\n')
  225.         *p++ = c;
  226.     if (c == '\n')
  227.         *p++ = '\n';
  228.     *p = '\0';
  229.     return (p-s);
  230. }
  231.  
  232. /* match - find character anywhere on line */
  233. match(text,pattarn)
  234. int    *pattarn;
  235. char    *text;
  236.  
  237. {
  238.     int    i;
  239.     char    *ss;
  240.  
  241.     for (ss = text; *text != '\0'; text++) {
  242.         if ((i = amatch(text,pattarn,ss)) >= 0)
  243.             return i;
  244.     }
  245.     return -1;
  246. }
  247.  
  248. /* amatch (non-recursive) - look for match starting at lin(from) */
  249. amatch(text,pattarn,tp)
  250. register char *text, *tp;
  251. register int  *pattarn;
  252. {
  253.     char    *temp, *tmp2;
  254.     int    k, *newpat;
  255.  
  256.     for (temp = text; *pattarn != '\0';pattarn++) {
  257.         if ((*pattarn & CLOSURE) == CLOSURE) {
  258.             for (tmp2 = temp; *tmp2 != '\0';) {
  259.                 if (omatch(&tmp2,*pattarn & CMASK,tp) == NO)
  260.                     break;
  261.             }
  262.             for (newpat = pattarn+1; tmp2 >= temp; tmp2--) {
  263.                 if ((k = amatch(tmp2,newpat,tp)) >= 0)
  264.                     break;
  265.             }
  266.             temp = tmp2 + k;
  267.             break;
  268.         }
  269.         else if (omatch(&temp,*pattarn,tp) == NO)
  270.             return -1;
  271.     }
  272.     return (temp-text);
  273. }
  274.  
  275. /* omatch - try to match a single pattern at pat(j */
  276. omatch(ln, pattarn, s)
  277. register char **ln, *s;
  278. register int  pattarn;
  279. {
  280.     int    retv;
  281.  
  282.     if (**ln == '\0')
  283.         retv =  (NO);
  284.     else if (pattarn == ANY && **ln != '\n') {
  285.         (*ln)++;
  286.         retv =  (YES);
  287.         }
  288.     else if (pattarn == BOL && *ln == s)
  289.         retv =  (YES);
  290.     else if (pattarn == EOL && **ln == '\n')
  291.         retv =  (YES);
  292.     else if ((pattarn & NOT) == NOT)
  293.         retv =  (*(*ln)++ == (pattarn & NMASK) ? NO : YES);
  294.     else if ((pattarn & CCL) == CCL)
  295.         retv = iindex(spat[pattarn & 255],*(*ln)++);
  296.     else if ((pattarn & NCL) == NCL)
  297.         retv=(iindex(spat[pattarn & 255],*(*ln)++) == YES ? NO : YES);
  298.     else
  299.         retv =  (*(*ln)++ == pattarn ? YES : NO);
  300.     return retv;
  301. }
  302.  
  303.  
  304. iindex(pat,c)
  305. register int *pat;
  306. register char c;
  307.  
  308. {
  309.     pat--;
  310.     while (*++pat)
  311.         if (*pat == c)
  312.             return YES;
  313.     return NO;
  314. }
  315.