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