xref: /plan9/sys/src/ape/cmd/pax/wildmat.c (revision 9a747e4fd48b9f4522c70c07e8f882a15030f964)
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