wildmat.c 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. /* $Source: /u/mark/src/pax/RCS/wildmat.c,v $
  2. *
  3. * $Revision: 1.2 $
  4. *
  5. * wildmat.c - simple regular expression pattern matching routines
  6. *
  7. * DESCRIPTION
  8. *
  9. * These routines provide simple UNIX style regular expression matching.
  10. * They were originally written by Rich Salz, the comp.sources.unix
  11. * moderator for inclusion in some of his software. These routines
  12. * were released into the public domain and used by John Gilmore in
  13. * USTAR.
  14. *
  15. * AUTHORS
  16. *
  17. * Mark H. Colburn, NAPS International (mark@jhereg.mn.org)
  18. * John Gilmore (gnu@hoptoad)
  19. * Rich Salz (rs@uunet.uu.net)
  20. *
  21. *
  22. * Sponsored by The USENIX Association for public distribution.
  23. *
  24. * Copyright (c) 1989 Mark H. Colburn.
  25. * All rights reserved.
  26. *
  27. * Redistribution and use in source and binary forms are permitted
  28. * provided that the above copyright notice is duplicated in all such
  29. * forms and that any documentation, advertising materials, and other
  30. * materials related to such distribution and use acknowledge that the
  31. * software was developed * by Mark H. Colburn and sponsored by The
  32. * USENIX Association.
  33. *
  34. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  35. * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  36. * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  37. *
  38. * $Log: wildmat.c,v $
  39. * Revision 1.2 89/02/12 10:06:20 mark
  40. * 1.2 release fixes
  41. *
  42. * Revision 1.1 88/12/23 18:02:41 mark
  43. * Initial revision
  44. *
  45. */
  46. #ifndef lint
  47. static char *ident = "$Id: wildmat.c,v 1.2 89/02/12 10:06:20 mark Exp $";
  48. static char *copyright = "Copyright (c) 1989 Mark H. Colburn.\nAll rights reserved.\n";
  49. #endif /* ! lint */
  50. /* Headers */
  51. #include "pax.h"
  52. /* Function Prototypes */
  53. #ifdef __STDC__
  54. static int star(char *, char *);
  55. #else /* !__STDC__ */
  56. static int star();
  57. #endif /* __STDC__ */
  58. /*
  59. * star - handle trailing * in a regular expression
  60. *
  61. * DESCRIPTION
  62. *
  63. * Star is used to match filename expansions containing a trailing
  64. * asterisk ('*'). Star call wildmat() to determine if the substring
  65. * passed to it is matches the regular expression.
  66. *
  67. * PARAMETERS
  68. *
  69. * char *source - The source string which is to be compared to the
  70. * regular expression pattern.
  71. * char *pattern - The regular expression which we are supposed to
  72. * match to.
  73. *
  74. * RETURNS
  75. *
  76. * Returns non-zero if the entire source string is completely matched by
  77. * the regular expression pattern, returns 0 otherwise. This is used to
  78. * see if *'s in a pattern matched the entire source string.
  79. *
  80. */
  81. #ifdef __STDC__
  82. static int star(char *source, char *pattern)
  83. #else
  84. static int star(source, pattern)
  85. char *source; /* source operand */
  86. char *pattern; /* regular expression to match */
  87. #endif
  88. {
  89. while (!wildmat(pattern, source)) {
  90. if (*++source == '\0') {
  91. return (0);
  92. }
  93. }
  94. return (1);
  95. }
  96. /*
  97. * wildmat - match a regular expression
  98. *
  99. * DESCRIPTION
  100. *
  101. * Wildmat attempts to match the string pointed to by source to the
  102. * regular expression pointed to by pattern. The subset of regular
  103. * expression syntax which is supported is defined by POSIX P1003.2
  104. * FILENAME EXPANSION rules.
  105. *
  106. * PARAMETERS
  107. *
  108. * char *pattern - The regular expression which we are supposed to
  109. * match to.
  110. * char *source - The source string which is to be compared to the
  111. * regular expression pattern.
  112. *
  113. * RETURNS
  114. *
  115. * Returns non-zero if the source string matches the regular expression
  116. * pattern specified, returns 0 otherwise.
  117. *
  118. */
  119. #ifdef __STDC__
  120. int wildmat(char *pattern, char *source)
  121. #else
  122. int wildmat(pattern, source)
  123. char *pattern; /* regular expression to match */
  124. char *source; /* source operand */
  125. #endif
  126. {
  127. int last; /* last character matched */
  128. int matched; /* !0 if a match occurred */
  129. int reverse; /* !0 if sense of match is reversed */
  130. for (; *pattern; source++, pattern++) {
  131. switch (*pattern) {
  132. case '\\':
  133. /* Literal match with following character */
  134. pattern++;
  135. /* FALLTHRU */
  136. default:
  137. if (*source != *pattern) {
  138. return (0);
  139. }
  140. continue;
  141. case '?':
  142. /* Match anything. */
  143. if (*source == '\0') {
  144. return (0);
  145. }
  146. continue;
  147. case '*':
  148. /* Trailing star matches everything. */
  149. return (*++pattern ? star(source, pattern) : 1);
  150. case '[':
  151. /* [^....] means inverse character class. */
  152. if (reverse = pattern[1] == '^') {
  153. pattern++;
  154. }
  155. for (last = 0400, matched = 0;
  156. *++pattern && *pattern != ']'; last = *pattern) {
  157. /* This next line requires a good C compiler. */
  158. if (*pattern == '-'
  159. ? *source <= *++pattern && *source >= last
  160. : *source == *pattern) {
  161. matched = 1;
  162. }
  163. }
  164. if (matched == reverse) {
  165. return (0);
  166. }
  167. continue;
  168. }
  169. }
  170. /*
  171. * For "tar" use, matches that end at a slash also work. --hoptoad!gnu
  172. */
  173. return (*source == '\0' || *source == '/');
  174. }