home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 35 Internet / 35-Internet.zip / snews-20.zip / AMATCH.C < prev    next >
C/C++ Source or Header  |  1990-01-03  |  4KB  |  184 lines

  1. /*****************************************************************
  2.  | amatch - match a string against a wildcard pattern
  3.  |----------------------------------------------------------------
  4.  |  Compares a data string against a test pattern using Bourne shell
  5.  |  wildcard rules (*not* regular expression rules).
  6.  |
  7.  |  This routine is ugly and not well structured.
  8.  |
  9.  |  Author: Bill Davidsen (davidsen@crdos1.crd.ge.com) Mar 24, 1985
  10.  |        with helpful suggestions from Andy Robinson
  11.  |----------------------------------------------------------------
  12.  |  Copyright:
  13.  |    Copyright (c) 1985, 1989 by Bill Davidsen. This program may be
  14.  |    freely given, bartered, traded or sold by anyone for any
  15.  |    purpose. The supplier assumes all risk for any consequences of
  16.  |    malfunction. All other rights reserved.
  17.  |----------------------------------------------------------------
  18.  |  Arguments:
  19.  |   1 - address of wildcard pattern
  20.  |   2 - address of string to test
  21.  ****************************************************************/
  22.  
  23. #include <string.h>
  24.  
  25. #ifndef TRUE
  26. #define TRUE    1
  27. #define FALSE   0
  28. #endif
  29.  
  30. int amatch(register char *ts, register char *cs)
  31. {
  32.     int low, hi, notf;
  33.  
  34.     while (1) { /* keep going until done */
  35.  
  36.         if (*cs == '\0') { /* out of string */
  37.             for (; *ts == '*'; ++ts)
  38.                 ; /* get rid of extra '*' */
  39.             return(*ts == '\0');
  40.         }
  41.  
  42.         switch (*ts) {
  43.  
  44.         case '\0':
  45.             return(FALSE);
  46.  
  47.         case '[': /* the hardest case (see '*' below) */
  48.  
  49.                /* is the not flag set? */
  50.             if (notf = (*(ts + 1) == '!'))
  51.                 ++ts; /* ! flag set */
  52.  
  53.                /* loop through the bracket */
  54.             while (*++ts != ']' && *ts != '\0') {
  55.  
  56.                 if (*ts == '-') { /* a range of values */
  57.  
  58.                         /* get lower limit */
  59.                     if ((*--ts == '[' || *ts == '!')
  60.                                && *(ts - 1) != '\\')
  61.                         low = '\0';
  62.                     else
  63.                         low = *ts;
  64.  
  65.                         /* get upper limit */
  66.                     if (*(ts += 2) == ']' || *ts == '\0') {
  67.                         hi = '\377';
  68.                         --ts;
  69.                     }
  70.                     else {
  71.                         if (*ts == '\\' &&
  72.                                 *++ts == '\0') {
  73.                             --ts;
  74.                             hi = '\377';
  75.                         }
  76.                         else
  77.                             hi = *ts;
  78.                     }
  79.  
  80.                          /* and compare */
  81.                     if (*cs > (char) low && *cs <= (char) hi)
  82.                         goto foo;
  83.  
  84.                     continue; /* in bracket loop */
  85.                 }
  86.  
  87.                     /* process wildcard */
  88.                 if (*ts == '\\' && *++ts == '\0')
  89.                     break; /* bump and check for \0 */
  90.  
  91.                 /* check if they are the same */
  92.                 if (*cs == *ts)
  93.                     goto foo;
  94.  
  95.             } /* while */
  96.  
  97.             /* get here if no match (out of ts or reached ]) */
  98.             if (!notf)
  99.                 return(FALSE);
  100.             if (*ts)
  101.                 ++ts;
  102.             break;
  103.  
  104.             /* come here if a match */
  105.         foo:    if (notf)
  106.                 return(FALSE);
  107.             ++ts;
  108.             while (*ts != '\0' && *ts++ != ']')
  109.                 ; /* get to end of bracket */
  110.             break;
  111.  
  112.         case '*': /* a chicken way out! my only recursive part */
  113.             while (*++ts == '*')
  114.                 ; /* get rid of extra '*' */
  115.  
  116.             if (!*ts) /* trailing '*' matches anything */
  117.                 return(TRUE);
  118.  
  119.             do
  120.                 if (amatch(ts, cs))
  121.                     return(TRUE);
  122.             while (*++cs);
  123.             return(*ts == '\0');
  124.  
  125.         case '?': /* just bump the pointers */
  126.             ++ts;
  127.             break;
  128.  
  129.         case '\\': /* this drops through to next one */
  130.             ++ts;
  131.  
  132.         default: /* if they ain't the same here forget it */
  133.             if (*cs != *ts++)
  134.                 return(FALSE);
  135.         } /* switch */
  136.  
  137.         ++cs;
  138.  
  139.     } /* while (1) */
  140.  
  141. } /* match */
  142.  
  143. /*****************************************************************
  144.  |  test program for amatch
  145.  |----------------------------------------------------------------
  146.  |  Reads patterns and paths until none given.
  147.  ****************************************************************/
  148.  
  149. #ifdef    TEST
  150. #include <stdio.h>
  151.  
  152. static void getline(char *buffer, int len);
  153.  
  154. void main(void)
  155. {
  156.     char data[80], pattern[80];
  157.     int match;
  158.  
  159.     do {
  160.         /* read wildcard patterns */
  161.         printf("Enter pattern: ");
  162.         getline(pattern, 80);
  163.         if (strlen(pattern)) {
  164.             /* read test cases */
  165.             do {
  166.                 printf("  Enter test data: ");
  167.                 getline(data, 80);
  168.                 if (strlen(data)) {
  169.                     match = amatch(pattern, data);
  170.                     printf("\t%s\n", (match ? "YES" : "NO"));
  171.                 }
  172.             } while (strlen(data));
  173.         }
  174.     } while (strlen(pattern));
  175. }
  176.  
  177. static void getline(char *buffer, int len)
  178. {
  179.     fgets(buffer, len, stdin);
  180.     len = strlen(buffer) - 1;
  181.     if (buffer[len] == '\n') buffer[len] = 0;
  182. }
  183. #endif
  184.