wildmat.c
上传用户:tianjinjs
上传日期:2007-01-05
资源大小:309k
文件大小:5k
源码类别:

Modem编程

开发平台:

Unix_Linux

  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. **  jseymour  91/02/05 22:56 
  25. ** Fixed problems with ill-formed sets in pattern yielding false
  26. ** matches.  Should now be robust in such cases (not all possibilities
  27. ** tested - standard disclaimer).  Added stand-alone debug code.
  28. **
  29. **  jseymour  91/03/28 20:50
  30. ** Re-fixed problems with ill-formed sets in pattern yielding false
  31. ** matches - one hopes correctly this time.
  32. **
  33. **  jseymour  1998/04/04 17:45 EST
  34. ** Before adding this to minicom (as part of my "getsdir()" addition),
  35. ** I emailed a request to Rich $alz, asking if I could "GPL" it.  Here
  36. ** is his reply:
  37. **
  38. **     Date: Mon, 30 Mar 1998 10:50:06 -0500 (EST)
  39. **     Message-Id: <199803301550.KAA14018@<anonymized>.com>
  40. **     From: Rich Salz <salzr@<anonymized>.com>
  41. **     To: jseymour@jimsun.LinxNet.com
  42. **     Subject: Re: A Little Thing Named "Wildmat"
  43. **
  44. **     Wildmat is in the public domain -- enjoy it.
  45. **
  46. **     I would rather it not get encumbered with various licenses,
  47. **     but since it is in the public domain you can do what you want...
  48. **
  49. ** So there you go.  (I anonymized his email address as I don't know
  50. ** that he was particularly interested in having it "advertised".)
  51. */
  52. #include "port.h" /* from minicom: for needed for _PROTO macro only */
  53. #ifndef TRUE
  54. #define TRUE  1
  55. #endif
  56. #ifndef FALSE
  57. #define FALSE  0
  58. #endif
  59. #define ABORT -1
  60. _PROTO(static int Star, (char *, char *));
  61. _PROTO(static int DoMatch, (char *, char *));
  62. _PROTO(extern int wildmat, (char *, char *)); /* pattern matcher */
  63. static int
  64. Star(s, p)
  65. register char *s;
  66. register char *p;
  67. {
  68.     int retval;
  69.     while ((retval = DoMatch(s, p)) == FALSE) /* gobble up * match */
  70. if (*++s == '')
  71.     return ABORT;
  72.     return retval;
  73. }
  74. static int
  75. DoMatch(s, p) /* match string "s" to pattern "p" */
  76. register char *s;
  77. register char *p;
  78. {
  79.     register int last;
  80.     register int matched;
  81.     register int reverse;
  82.     char *ss;
  83.     int escaped;
  84.     for (; *p; s++, p++)
  85.     { /* parse the string to end */
  86. if (*s == '')
  87.     return *p == '*' && *++p == '' ? TRUE : ABORT;
  88. switch (*p)
  89. { /* parse pattern */
  90.     case '\':
  91. /* Literal match with following character. */
  92. p++;
  93. /* FALLTHROUGH */
  94.     default: /*literal match*/
  95. if (*s != *p)
  96.     return FALSE;
  97. continue;
  98.     case '?':
  99. /* Match anything. */
  100. continue;
  101.     case '*':
  102. /* Trailing star matches everything. */
  103. return (*++p ? Star(s, p) : TRUE);
  104.     case '[':
  105. /* [!....] means inverse character class. */
  106. if ((reverse = (p[1] == '!')))
  107.     p++;
  108. ss = p + 1; /* set start point */
  109. for (last = 0400, escaped = matched = FALSE; *++p; last = *p)
  110. {
  111.     if (*p == ']' && !(escaped || p == ss))
  112. break;
  113.     if (escaped)
  114. escaped = FALSE;
  115.     else if (*p == '\')
  116.     {
  117. escaped = TRUE;
  118. continue;
  119.     }
  120.     /* This next line requires a good C compiler.     */
  121.     /*     range? (in bounds)                 (equal) */
  122.     if ((*p == '-') ? (*s <= *++p && *s >= last) : (*s == *p))
  123. matched = TRUE;
  124. }
  125. if (matched == reverse)
  126.     return FALSE;
  127. continue;
  128. }
  129.     }
  130.     return *s == '';
  131. }
  132. /*
  133.  * usage: wildmat(string, pattern)
  134.  *
  135.  * returns: non-0 on match
  136.  */
  137. int 
  138. wildmat(s, p)
  139. char *s;
  140. char *p;
  141. {
  142.     if ((*p == '?' || *p == '*') && *s == '.')
  143.     {
  144. return FALSE;
  145.     }
  146.     else
  147.     {
  148. return DoMatch(s, p) == TRUE;
  149.     }
  150. }
  151. #ifdef STAND_ALONE_TEST
  152. #include <stdio.h>
  153. /*
  154.  * usage: wildmat <pattern> <test arg(s)>
  155.  */
  156. void
  157. main(argc, argv)
  158. int argc;
  159. char *argv[];
  160. {
  161.     int index;
  162.     int status = FALSE;
  163.     for (index = 2; index < argc; ++index)
  164.     {
  165. if (wildmat(argv[index], argv[1]))
  166. {
  167.     if (status)
  168. fputs(" ", stdout);
  169.     printf("%s", argv[index]);
  170.     status = TRUE;
  171. }
  172.     }
  173.     printf("%sn", status ? "" : argv[1]);
  174. }
  175. #endif