home *** CD-ROM | disk | FTP | other *** search
/ rtsi.com / 2014.01.www.rtsi.com.tar / www.rtsi.com / OS9 / OSK / CMDS / mtools_3.6.src.lzh / MTOOLS_3.6 / match.c < prev    next >
Text File  |  1997-11-12  |  2KB  |  140 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. static int casecmp(char a,char b)
  11. {
  12.     return toupper(a) == toupper(b);
  13. }
  14.  
  15. static int exactcmp(char a,char b)
  16. {
  17.     return a == b;
  18. }
  19.  
  20.  
  21. static int parse_range(const char **p, const char *s, char *out, 
  22.                int (*compfn)(char a, char b))
  23. {
  24.     char table[256];
  25.     int reverse;
  26.     int i;
  27.     short first, last;
  28.  
  29.     if (**p == '^') {
  30.         reverse = 1;
  31.         (*p)++;
  32.     } else
  33.         reverse=0;    
  34.     for(i=0; i<256; i++)
  35.         table[i]=0;
  36.     while(**p != ']') {
  37.         if(!**p)
  38.             return 0;
  39.         if((*p)[1] == '-') {
  40.             first = **p;
  41.             (*p)+=2;
  42.             if(**p == ']')
  43.                 last = 256;
  44.             else
  45.                 last = *((*p)++);                
  46.             for(i=first; i<last; i++)
  47.                 table[i] = 1;
  48.         } else
  49.             table[(int) *((*p)++)] = 1;
  50.     }
  51.     if(out)
  52.         *out = *s;
  53.     if(table[(int) *s])
  54.         return 1 ^ reverse;
  55.     if(compfn == exactcmp)
  56.         return reverse;
  57.     if(table[tolower(*s)]) {
  58.         if(out)
  59.             *out = tolower(*s);
  60.         return 1 ^ reverse;
  61.     }
  62.     if(table[toupper(*s)]) {
  63.         if(out)
  64.             *out = toupper(*s);
  65.         return 1 ^ reverse;
  66.     }
  67.     return reverse;
  68. }
  69.  
  70.  
  71. static int _match(const char *s, const char *p, char *out, int Case,
  72.           int (*compfn) (char a, char b))
  73. {
  74.     for (; *p != '\0'; ) {
  75.         switch (*p) {
  76.             case '?':    /* match any one character */
  77.                 if (*s == '\0')
  78.                     return(0);
  79.                 if(out)
  80.                     *(out++) = *s;
  81.                 break;
  82.             case '*':    /* match everything */
  83.                 while (*p == '*')
  84.                     p++;
  85.  
  86.                     /* search for next char in pattern */
  87.                 while(*s) {
  88.                     if(_match(s, p, out, Case, compfn))
  89.                         return 1;
  90.                     if(out)
  91.                         *out++ = *s;
  92.                     s++;
  93.                 }
  94.                 continue;
  95.             case '[':     /* match range of characters */
  96.                 p++;
  97.                 if(!parse_range(&p, s, out++, compfn))
  98.                     return 0;
  99.                 break;
  100.             case '\\':    /* Literal match with next character */
  101.                 p++;
  102.                 /* fall thru */
  103.             default:
  104.                 if (!compfn(*s,*p))
  105.                     return(0);
  106.                 if(out)
  107.                     *(out++) = *p;
  108.                 break;
  109.         }
  110.         p++;
  111.         s++;
  112.     }
  113.     if(out)
  114.         *out = '\0';
  115.  
  116.                     /* string ended prematurely ? */
  117.     if (*s != '\0')
  118.         return(0);
  119.     else
  120.         return(1);
  121. }
  122.  
  123.  
  124. int match(const char *s, const char *p, char *out, int Case)
  125. {
  126.     int (*compfn)(char a, char b);
  127.  
  128.     if(Case)
  129.         compfn = casecmp;
  130.     else
  131.         /*compfn = exactcmp;*/
  132.         compfn = casecmp;
  133.     return _match(s, p, out, Case, compfn);
  134. }
  135.  
  136. int hasWildcards(const char *string)
  137. {
  138.     return (int) strpbrk(string, "?*");
  139. }
  140.