home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 3: Developer Tools / Linux Cubed Series 3 - Developer Tools.iso / utils / disk-man / mtools-3.000 / mtools-3 / mtools-3.0 / match.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-04-30  |  2.5 KB  |  148 lines

  1. /*
  2.  * Do shell-style pattern matching for '?', '\', '[..]', and '*' wildcards.
  3.  * Returns 1 if match, 0 if not.
  4.  */
  5.  
  6. #include "sysincludes.h"
  7. #include "mtools.h"
  8.  
  9.  
  10. int casecmp(char a,char b)
  11. {
  12.     return toupper(a) == toupper(b);
  13. }
  14.  
  15. int exactcmp(char a,char b)
  16. {
  17.     return a == b;
  18. }
  19.  
  20.  
  21.  
  22. int match(__const char *s, __const char *p, char *out, int Case)
  23. {
  24.     int matched, reverse;
  25.     char first, last;
  26.  
  27.     int (*compfn)(char a, char b);
  28.  
  29.     if(Case)
  30.         compfn = casecmp;
  31.     else
  32.         /*compfn = exactcmp;*/
  33.         compfn = casecmp;
  34.  
  35.     for (; *p != '\0'; ) {
  36.         switch (*p) {
  37.             case '?':    /* match any one character */
  38.                 if (*s == '\0')
  39.                     return(0);
  40.                 if(out)
  41.                     *(out++) = *p;
  42.                 break;
  43.             case '*':    /* match everything */
  44.                 while (*p == '*')
  45.                     p++;
  46.  
  47.  
  48.                     /* search for next char in pattern */
  49.                 matched = 0;
  50.                 while (*s != '\0') {
  51.                     if(out)
  52.                         *(out++) = *s;
  53.                     if (compfn(*s,*p)) {
  54.                         matched = 1;
  55.                         break;
  56.                     }
  57.                     s++;
  58.                 }
  59.                 /* if last char in pattern */
  60.                 if (*p == '\0')
  61.                     continue;
  62.  
  63.                 if (!matched)
  64.                     return(0);
  65.                 break;
  66.             case '[':     /* match range of characters */
  67.                 first = '\0';
  68.                 matched = 0;
  69.                 reverse = 0;
  70.                 while (*++p != ']') {
  71.                     if (*p == '^') {
  72.                         reverse = 1;
  73.                         p++;
  74.                     }
  75.                     first = *p;
  76.                     if (first == ']' || first == '\0')
  77.                         return(0);
  78.  
  79.                     /* if 2nd char is '-' */
  80.                     if (*(p + 1) == '-') {
  81.                         p++;
  82.                     /* set last to 3rd char ... */
  83.                         last = *++p;
  84.                         if (last == ']' || last == '\0')
  85.                             return(0);
  86.                     /* test the range of values */
  87.                         if (*s >= first &&
  88.                             *s <= last) {
  89.                             if(out)
  90.                                 *(out++) = *s;
  91.                             matched = 1;
  92.                             p++;
  93.                             break;
  94.                         }
  95.                         if(Case &&
  96.                            toupper(*s) >= first &&
  97.                            toupper(*s) <= last){
  98.                             if(out)
  99.                                 *(out++) = toupper(*s);
  100.                             matched = 1;
  101.                             p++;
  102.                             break;
  103.                         }
  104.                         if(Case &&
  105.                            tolower(*s) >= first &&
  106.                            tolower(*s) <= last){
  107.                             if(out)
  108.                                 *(out++) = tolower(*s);
  109.                             matched = 1;
  110.                             p++;
  111.                             break;
  112.                         }
  113.                         return(0);
  114.                     }
  115.                     if (compfn(*s,*p)){
  116.                         if(out)
  117.                             *(out++) = *p;
  118.                         matched = 1;
  119.                     }
  120.                 }
  121.                 if (matched && reverse)
  122.                     return(0);
  123.                 if (!matched)
  124.                     return(0);
  125.                 break;
  126.             case '\\':    /* Literal match with next character */
  127.                 p++;
  128.                 /* fall thru */
  129.             default:
  130.                 if (!compfn(*s,*p))
  131.                     return(0);
  132.                 if(out)
  133.                     *(out++) = *p;
  134.                 break;
  135.         }
  136.         p++;
  137.         s++;
  138.     }
  139.     if(out)
  140.         *out = '\0';
  141.  
  142.                     /* string ended prematurely ? */
  143.     if (*s != '\0')
  144.         return(0);
  145.     else
  146.         return(1);
  147. }
  148.