]> code.citadel.org Git - citadel.git/blob - webcit/wildmat.c
c9e1db0a2c65b000d129fffc1095414b14ca81de
[citadel.git] / webcit / wildmat.c
1 /* $Source$
2
3  * $Revision$
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 MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
37  *
38  * $Log$
39  * Revision 1.2  1999/06/03 03:48:52  ajc
40  *         * Ditched the frames mode completely.  It wasn't working properly in,
41  *           among other places, IE 5.  Die, Bill, Die.
42  *
43  * Revision 1.1  1999/03/07 03:09:55  ajc
44  *         * wildmat.c, braindamage.c: added
45  *
46  * Revision 1.1  88/12/23  18:02:41  mark
47  * Initial revision
48  * 
49  */
50
51 /* Includes */
52
53 #include <stdlib.h>
54 #include <unistd.h>
55 #include <stdio.h>
56
57
58
59 /* Function Prototypes */
60
61 #ifdef __STDC__
62 static int star(char *, char *);
63 #else                           /* !__STDC__ */
64 static int star();
65 #endif                          /* __STDC__ */
66
67
68 /*
69  * star - handle trailing * in a regular expression 
70  *
71  * DESCRIPTION
72  *
73  *     Star is used to match filename expansions containing a trailing
74  *     asterisk ('*').  Star call wildmat() to determine if the substring
75  *     passed to it is matches the regular expression.
76  *
77  * PARAMETERS 
78  *
79  *     char *source    - The source string which is to be compared to the 
80  *                       regular expression pattern. 
81  *     char *pattern   - The regular expression which we are supposed to 
82  *                       match to. 
83  *
84  * RETURNS 
85  *
86  *     Returns non-zero if the entire source string is completely matched by 
87  *     the regular expression pattern, returns 0 otherwise. This is used to 
88  *     see if *'s in a pattern matched the entire source string. 
89  *
90  */
91
92 #ifdef __STDC__
93
94 static int star(char *source, char *pattern)
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(source, pattern)) {
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 *source    - The source string which is to be compared to the 
125  *                       regular expression pattern. 
126  *     char *pattern   - The regular expression which we are supposed to 
127  *                       match to. 
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
138 int wildmat(char *pattern, char *source)
139 #else
140
141 int wildmat(pattern, source)
142 char *pattern;                  /* regular expression to match */
143 char *source;                   /* source operand */
144
145 #endif
146 {
147         int last;               /* last character matched */
148         int matched;            /* !0 if a match occurred */
149         int reverse;            /* !0 if sense of match is reversed */
150
151         for (; *pattern; source++, pattern++) {
152                 switch (*pattern) {
153                 case '\\':
154                         /* Literal match with following character */
155                         pattern++;
156                         /* FALLTHRU */
157                 default:
158                         if (*source != *pattern) {
159                                 return (0);
160                         }
161                         continue;
162                 case '?':
163                         /* Match anything. */
164                         if (*source == '\0') {
165                                 return (0);
166                         }
167                         continue;
168                 case '*':
169                         /* Trailing star matches everything. */
170                         return (*++pattern ? star(source, pattern) : 1);
171                 case '[':
172                         /* [^....] means inverse character class. */
173                         if (reverse = pattern[1] == '^') {
174                                 pattern++;
175                         }
176                         for (last = 0400, matched = 0;
177                         *++pattern && *pattern != ']'; last = *pattern) {
178                                 /* This next line requires a good C compiler. */
179                                 if (*pattern == '-'
180                                 ? *source <= *++pattern && *source >= last
181                                     : *source == *pattern) {
182                                         matched = 1;
183                                 }
184                         }
185                         if (matched == reverse) {
186                                 return (0);
187                         }
188                         continue;
189                 }
190         }
191
192         /*
193          * For "tar" use, matches that end at a slash also work. --hoptoad!gnu 
194          */
195         return (*source == '\0' || *source == '/');
196 }