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
47 #ifndef lint
48 static char *ident = "$Id: wildmat.c,v 1.2 89/02/12 10:06:20 mark Exp $";
49 static char *copyright = "Copyright (c) 1989 Mark H. Colburn.\nAll rights reserved.\n";
50 #endif /* ! lint */
51
52
53 /* Headers */
54
55 #include "pax.h"
56
57
58 /* Function Prototypes */
59
60 #ifdef __STDC__
61 static int star(char *, char *);
62 #else /* !__STDC__ */
63 static int star();
64 #endif /* __STDC__ */
65
66
67 /*
68 * star - handle trailing * in a regular expression
69 *
70 * DESCRIPTION
71 *
72 * Star is used to match filename expansions containing a trailing
73 * asterisk ('*'). Star call wildmat() to determine if the substring
74 * passed to it is matches the regular expression.
75 *
76 * PARAMETERS
77 *
78 * char *source - The source string which is to be compared to the
79 * regular expression pattern.
80 * char *pattern - The regular expression which we are supposed to
81 * match to.
82 *
83 * RETURNS
84 *
85 * Returns non-zero if the entire source string is completely matched by
86 * the regular expression pattern, returns 0 otherwise. This is used to
87 * see if *'s in a pattern matched the entire source string.
88 *
89 */
90
91 #ifdef __STDC__
92
star(char * source,char * pattern)93 static int star(char *source, char *pattern)
94
95 #else
96
97 static int star(source, pattern)
98 char *source; /* source operand */
99 char *pattern; /* regular expression to match */
100
101 #endif
102 {
103 while (!wildmat(pattern, source)) {
104 if (*++source == '\0') {
105 return (0);
106 }
107 }
108 return (1);
109 }
110
111
112 /*
113 * wildmat - match a regular expression
114 *
115 * DESCRIPTION
116 *
117 * Wildmat attempts to match the string pointed to by source to the
118 * regular expression pointed to by pattern. The subset of regular
119 * expression syntax which is supported is defined by POSIX P1003.2
120 * FILENAME EXPANSION rules.
121 *
122 * PARAMETERS
123 *
124 * char *pattern - The regular expression which we are supposed to
125 * match to.
126 * char *source - The source string which is to be compared to the
127 * regular expression pattern.
128 *
129 * RETURNS
130 *
131 * Returns non-zero if the source string matches the regular expression
132 * pattern specified, returns 0 otherwise.
133 *
134 */
135
136 #ifdef __STDC__
137
wildmat(char * pattern,char * source)138 int wildmat(char *pattern, char *source)
139
140 #else
141
142 int wildmat(pattern, source)
143 char *pattern; /* regular expression to match */
144 char *source; /* source operand */
145
146 #endif
147 {
148 int last; /* last character matched */
149 int matched; /* !0 if a match occurred */
150 int reverse; /* !0 if sense of match is reversed */
151
152 for (; *pattern; source++, pattern++) {
153 switch (*pattern) {
154 case '\\':
155 /* Literal match with following character */
156 pattern++;
157 /* FALLTHRU */
158 default:
159 if (*source != *pattern) {
160 return (0);
161 }
162 continue;
163 case '?':
164 /* Match anything. */
165 if (*source == '\0') {
166 return (0);
167 }
168 continue;
169 case '*':
170 /* Trailing star matches everything. */
171 return (*++pattern ? star(source, pattern) : 1);
172 case '[':
173 /* [^....] means inverse character class. */
174 if (reverse = pattern[1] == '^') {
175 pattern++;
176 }
177 for (last = 0400, matched = 0;
178 *++pattern && *pattern != ']'; last = *pattern) {
179 /* This next line requires a good C compiler. */
180 if (*pattern == '-'
181 ? *source <= *++pattern && *source >= last
182 : *source == *pattern) {
183 matched = 1;
184 }
185 }
186 if (matched == reverse) {
187 return (0);
188 }
189 continue;
190 }
191 }
192
193 /*
194 * For "tar" use, matches that end at a slash also work. --hoptoad!gnu
195 */
196 return (*source == '\0' || *source == '/');
197 }
198