home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / altsrcs / 1 / 1707 / nomagic.c < prev    next >
Encoding:
Text File  |  1990-12-28  |  2.8 KB  |  146 lines

  1. /* nomagic.c */
  2.  
  3. /* This contains versions of the regcomp() and regexec() functions which
  4.  * do not recognize any metacharacters except ^ $ and \.  They use the same
  5.  * data structure Henry Spencer's package, so they can continue to use his
  6.  * regsub() function.
  7.  *
  8.  * This file is meant to be #included in regexp.c; it should *NOT* be
  9.  * compiled separately.  The regexp.c file will check to see if NO_MAGIC
  10.  * is defined, and if so then this file is used; if not, then the real
  11.  * regexp functions are used.
  12.  */
  13.  
  14.  
  15. regexp *regcomp(exp)
  16.     char    *exp;
  17. {
  18.     char    *src;
  19.     char    *dest;
  20.     regexp    *re;
  21.     int    i;
  22.  
  23.     /* allocate a big enough regexp structure */
  24.     re = (regexp *)malloc(strlen(exp) + 1 + sizeof(struct regexp));
  25.     if (!re)
  26.     {
  27.         regerror("could not malloc a regexp structure");
  28.         return (regexp *)0;
  29.     }
  30.  
  31.     /* initialize all fields of the structure */
  32.     for (i = 0; i < NSUBEXP; i++)
  33.     {
  34.         re->startp[i] = (char *)0;
  35.         re->endp[i] = (char *)0;
  36.     }
  37.     re->regstart = 0;
  38.     re->reganch = 0;
  39.     re->regmust = &re->program[1];
  40.     re->regmlen = 0;
  41.     re->program[0] = MAGIC;
  42.  
  43.     /* copy the string into it, translating ^ and $ as needed */
  44.     for (src = exp, dest = re->program + 1; *src; src++)
  45.     {
  46.         switch (*src)
  47.         {
  48.           case '^':
  49.             if (src == exp)
  50.                 re->regstart = 1;
  51.             else
  52.                 *dest++ = '^';
  53.             break;
  54.  
  55.           case '$':
  56.             if (!src[1])
  57.                 re->reganch = 1;
  58.             else
  59.                 *dest++ = '$';
  60.             break;
  61.  
  62.           case '\\':
  63.             if (src[1])
  64.                 *dest++ = *++src;
  65.             else
  66.             {
  67.                 regerror("extra \\ at end of regular expression");
  68.             }
  69.             break;
  70.  
  71.           default:
  72.             *dest++ = *src;
  73.         }
  74.     }
  75.     *dest = '\0';
  76.     re->regmlen = strlen(&re->program[1]);
  77.  
  78.     return re;
  79. }
  80.  
  81.  
  82. /* This "helper" function checks for a match at a given location.  It returns
  83.  * 1 if it matches, 0 if it doesn't match here but might match later on in the
  84.  * string, or -1 if it could not possibly match
  85.  */
  86. static int reghelp(prog, string, bolflag)
  87.     struct regexp    *prog;
  88.     char        *string;
  89.     int        bolflag;
  90. {
  91.     char        *scan;
  92.     char        *str;
  93.  
  94.     /* if ^, then require bolflag */
  95.     if (prog->regstart && !bolflag)
  96.     {
  97.         return -1;
  98.     }
  99.  
  100.     /* if it matches, then it will start here */
  101.     prog->startp[0] = string;
  102.  
  103.     /* compare, possibly ignoring case */
  104.     if (*o_ignorecase)
  105.     {
  106.         for (scan = &prog->program[1]; *scan; scan++, string++)
  107.             if (tolower(*scan) != tolower(*string))
  108.                 return *string ? 0 : -1;
  109.     }
  110.     else
  111.     {
  112.         for (scan = &prog->program[1]; *scan; scan++, string++)
  113.             if (*scan != *string)
  114.                 return *string ? 0 : -1;
  115.     }
  116.  
  117.     /* if $, then require string to end here, too */
  118.     if (prog->reganch && *string)
  119.     {
  120.         return 0;
  121.     }
  122.  
  123.     /* if we get to here, it matches */
  124.     prog->endp[0] = string;
  125.     return 1;
  126. }
  127.  
  128.  
  129.  
  130. int regexec(prog, string, bolflag)
  131.     struct regexp    *prog;
  132.     char        *string;
  133.     int        bolflag;
  134. {
  135.     int        rc;
  136.  
  137.     /* keep trying to match it */
  138.     for (rc = reghelp(prog, string, bolflag); rc == 0; rc = reghelp(prog, string, 0))
  139.     {
  140.         string++;
  141.     }
  142.  
  143.     /* did we match? */
  144.     return rc == 1;
  145. }
  146.