home *** CD-ROM | disk | FTP | other *** search
/ Languages Around the World / LanguageWorld.iso / language / vietnam / lambai / wildmatc.c < prev   
Encoding:
C/C++ Source or Header  |  1992-05-02  |  2.7 KB  |  111 lines

  1. /*
  2. **  Do shell-style pattern matching for ?, \, [], and * characters.
  3. **  Might not be robust in face of malformed patterns; e.g., "foo[a-"
  4. **  could cause a segmentation violation.  It is 8bit clean.
  5. **
  6. **  Written by Rich $alz, mirror!rs, Wed Nov 26 19:03:17 EST 1986.
  7. **  Special thanks to Lars Mathiesen for the ABORT code.  This can greatly
  8. **  speed up failing wildcard patterns.  For example:
  9. **    pattern: -*-*-*-*-*-*-12-*-*-*-m-*-*-*
  10. **    text 1:     -adobe-courier-bold-o-normal--12-120-75-75-m-70-iso8859-1
  11. **    text 2:     -adobe-courier-bold-o-normal--12-120-75-75-p-70-iso8859-1
  12. **  Text 1 matches with 51 calls, while text 2 fails with 54 calls.  Without
  13. **  the ABORT, then it takes 22310 calls to fail.  Ugh.
  14. **
  15. **  bernie    613-01 91/01/04 19:34 
  16. **  Fixed problem with terminating * not matching with (null)
  17. **
  18. **  bernie    597-00 91/01/08 11:24 
  19. **  Fixed shell glob negate from '^' to '!'
  20. **
  21. **  bernie    597-02 91/01/21 13:43 
  22. **    Fixed . matching * or ? on first char.
  23. **
  24.  *  bernie      1-00 91/02/14 10:28 
  25. **    Fixed Star return on ABORT
  26. */
  27.  
  28. #define TRUE        1
  29. #define FALSE        0
  30. #define ABORT        -1
  31.  
  32. static int count;
  33.  
  34. static int
  35. Star(s, p)
  36.     register char    *s;
  37.     register char    *p;
  38. {
  39.     register int stat;
  40.  
  41.     while ( (stat=DoMatch(s, p)) == FALSE) /* gobble up * match */
  42.     if (*++s == '\0') return ABORT;
  43.     return stat;
  44. }
  45.  
  46.  
  47. static int
  48. DoMatch(s, p)    /* match string "s" to pattern "p" */
  49.     register char    *s;
  50.     register char    *p;
  51. {
  52.     register int      last;
  53.     register int      matched;
  54.     register int      reverse;
  55.  
  56.     count++;
  57.  
  58.     for ( ; *p; s++, p++) { /* parse the string to end */
  59.     if (*s == '\0')
  60.         return *p == '*' && *++p == '\0' ? TRUE : ABORT;
  61.  
  62.     switch (*p) { /* parse pattern */
  63.  
  64.     case '\\':
  65.         /* Literal match with following character. */
  66.         p++;
  67.         /* FALLTHROUGH */
  68.  
  69.     default: /*literal match*/
  70.         if (*s != *p)
  71.         return FALSE;
  72.         continue;
  73.  
  74.     case '?':
  75.         /* Match anything. */
  76.         continue;
  77.  
  78.     case '*':
  79.         /* Trailing star matches everything. */
  80.         return( *++p ? Star(s, p) : TRUE );
  81.  
  82.     case '[':
  83.         /* [!....] means inverse character class. */
  84.         if (reverse = p[1] == '!') p++;
  85.  
  86.         for (last = 0400, matched = FALSE; *++p && *p != ']'; last = *p)
  87.         /* This next line requires a good C compiler. */
  88.         /*     range?        (in bounds)                  (equal) */
  89.         if ( ( *p == '-' ) ? (*s <= *++p && *s >= last ) : (*s == *p) )
  90.             matched = TRUE;
  91.  
  92.         if (matched == reverse) return FALSE;
  93.         continue;
  94.     }
  95.     }
  96.     return *s == '\0';
  97. }
  98.  
  99.  
  100. int wildmat(s, p)
  101.     char    *s;
  102.     char    *p;
  103. {
  104.     if ( (*p == '?' || *p == '*' ) && *s == '.' ) {
  105.         return FALSE;
  106.     } else {
  107.         return DoMatch(s, p) == TRUE;
  108.     }
  109. }
  110.  
  111.