home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 620.lha / WildCard / WILDCARD.C < prev    next >
C/C++ Source or Header  |  1991-10-01  |  4KB  |  93 lines

  1. /* Wildcard.c  by Frank J. Perricone
  2.      Matches (recursively) wildcards * and ? (arbitrary number of them)
  3.  
  4.   This program was written solely to test my algorithm for wildcard matching.
  5.   It is of no use in and of itself, so I release it as source code only to
  6.   the public domain, unless someone has copyrighted this code before, in
  7.   which case, my apologies, no offense intended.
  8. */
  9.  
  10. #include <stdio.h>
  11. #include <stdlib.h>
  12.  
  13. #define TRUE  1
  14. #define FALSE 0
  15.  
  16. /* Prototypes */
  17. int wildcardmatch(char *, char *);
  18. int wcm(char *,char *);
  19.  
  20. int main(int argc, char *argv[]) {
  21.   if (argc!=3) { /* we need two params to compare */
  22.       fprintf(stderr,"Usage: WILDCARD pattern string\n");
  23.       return 20;
  24.       }
  25.   if (wildcardmatch(argv[1],argv[2]))
  26.       printf("%s matches %s.\n",argv[1],argv[2]);
  27.       else
  28.       printf("%s does not match %s.\n",argv[1],argv[2]);
  29.   return 0;
  30.   }
  31.  
  32. int wildcardmatch(char *pattern, char *string) {
  33. /* Strip doubled asterisks, then call wcm which is recursive
  34. ---- That is, this routine simply runs a preparation phase on the pattern,
  35. ---- stripping out double (or more) asterisks (which are really meaningless
  36. ---- and can be reduced to one asterisk) and then calls wcm, which does the
  37. ---- real work.
  38. */
  39.   char newpat[256];   /* build the new stripped pattern in the buffer */
  40.   int i=0;    /* counter in pattern */
  41.   int j=0;    /* counter in newpat */
  42.   while (pattern[i]!='\0') {  /* until we reach the end of the pattern */
  43.     newpat[j]=pattern[i];     /* copy a character */
  44.     if (pattern[i]=='*') {    /* if it was an asterisk, */
  45.         i++;          /*   starting with the next character, */
  46.         while (pattern[i]=='*')   /*   scan past all ensuing asterisks */
  47.           i++;
  48.         }
  49.       else
  50.         i++;          /*   else just go to the next character */
  51.         j++;
  52.         }
  53.   newpat[j]='\0';         /* put end-string marker on newpat */
  54.   return wcm(newpat,string);  /* now call wcm to do the real work */
  55.   }
  56.  
  57. int wcm(char *pattern, char *string) {
  58. /* Actually does matching; very recursive, especially if pattern[0]=='*'
  59. ---- The parameters are a pattern, which can contain an arbitrary number of
  60. ---- characters including wildcards, excepting that it has no doubled
  61. ---- asterisks.  The asterisk matches 0 or more characters.  The question mark
  62. ---- matches exactly one character.  wcm just returns TRUE or FALSE.
  63. ---- It does this by breaking up all possibilities into cases described below.
  64. ---- The order they are shown is important, as many of them assume (and
  65. ---- therefore don't test for) the fact that previous cases didn't apply.
  66. */
  67.   if (pattern[0]=='\0' && string[0]=='\0')   /* both are null */
  68.       return TRUE;
  69.   if (pattern[0]=='\0')          /* pattern null but string isn't */
  70.       return FALSE;
  71.   if (pattern[0]=='*' && pattern[1]=='\0')   /* pattern just an asterisk */
  72.       return TRUE;             /* (this is an optimization) */
  73.   if (string[0]=='\0')           /* string null but pattern isn't */
  74.       return FALSE;
  75.   if (pattern[0]=='?')           /* pattern starts with ? */
  76.       return wcm(&(pattern[1]),&(string[1]));  /* matches if the rest matches.. */
  77.   if (pattern[0]=='*') {         /* the biggie: pattern begins with
  78.                                     an asterisk but has more, and
  79.                                     string isn't null... */
  80.       while (string[0]!='\0') {        /* does it match if * matches 0 */
  81.         if (wcm(&(pattern[1]),string)) /* chars of string?  If not, how */
  82.             return TRUE;               /* about one?  Or two?  Keep */
  83.           else                         /* trying until it does, or */
  84.             string++;                  /* you run out of string... */
  85.         }  /* if we get out, we tried all possibilities without success... */
  86.       return FALSE;
  87.       }
  88.   if (pattern[0]==string[0])         /* normal, matching characters */
  89.       return wcm(&(pattern[1]),&(string[1]));
  90.   /* if we got this far -- normal, nonmatching characters */
  91.   return FALSE;
  92.   }
  93.