* Added ".c.o" rule to Makefile
[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.3  1999/06/08 02:01:29  ajc
40  *         * Session no longer locks up when an express message is cancelled
41  *         * The default Citadel server is now "localhost" instead of uncnsrd
42  *         * Added some documentation
43  *
44  * Revision 1.2  1999/06/03 03:48:52  ajc
45  *         * Ditched the frames mode completely.  It wasn't working properly in,
46  *           among other places, IE 5.  Die, Bill, Die.
47  *
48  * Revision 1.1  1999/03/07 03:09:55  ajc
49  *         * wildmat.c, braindamage.c: added
50  *
51  * Revision 1.1  88/12/23  18:02:41  mark
52  * Initial revision
53  * 
54  */
55
56 /* Includes */
57
58 #include <stdlib.h>
59 #include <unistd.h>
60 #include <stdio.h>
61
62
63
64 /* Function Prototypes */
65
66 #ifdef __STDC__
67 static int star(char *, char *);
68 #else                           /* !__STDC__ */
69 static int star();
70 #endif                          /* __STDC__ */
71
72
73 /*
74  * star - handle trailing * in a regular expression 
75  *
76  * DESCRIPTION
77  *
78  *     Star is used to match filename expansions containing a trailing
79  *     asterisk ('*').  Star call wildmat() to determine if the substring
80  *     passed to it is matches the regular expression.
81  *
82  * PARAMETERS 
83  *
84  *     char *source    - The source string which is to be compared to the 
85  *                       regular expression pattern. 
86  *     char *pattern   - The regular expression which we are supposed to 
87  *                       match to. 
88  *
89  * RETURNS 
90  *
91  *     Returns non-zero if the entire source string is completely matched by 
92  *     the regular expression pattern, returns 0 otherwise. This is used to 
93  *     see if *'s in a pattern matched the entire source string. 
94  *
95  */
96
97 #ifdef __STDC__
98
99 static int star(char *source, char *pattern)
100 #else
101
102 static int star(source, pattern)
103 char *source;                   /* source operand */
104 char *pattern;                  /* regular expression to match */
105
106 #endif
107 {
108         while (!wildmat(source, pattern)) {
109                 if (*++source == '\0') {
110                         return (0);
111                 }
112         }
113         return (1);
114 }
115
116
117 /*
118  * wildmat - match a regular expression 
119  *
120  * DESCRIPTION
121  *
122  *     Wildmat attempts to match the string pointed to by source to the 
123  *     regular expression pointed to by pattern.  The subset of regular 
124  *     expression syntax which is supported is defined by POSIX P1003.2 
125  *     FILENAME EXPANSION rules.
126  *
127  * PARAMETERS 
128  *
129  *     char *source    - The source string which is to be compared to the 
130  *                       regular expression pattern. 
131  *     char *pattern   - The regular expression which we are supposed to 
132  *                       match to. 
133  *
134  * RETURNS 
135  *
136  *     Returns non-zero if the source string matches the regular expression 
137  *     pattern specified, returns 0 otherwise. 
138  *
139  */
140
141 #ifdef __STDC__
142
143 int wildmat(char *pattern, char *source)
144 #else
145
146 int wildmat(pattern, source)
147 char *pattern;                  /* regular expression to match */
148 char *source;                   /* source operand */
149
150 #endif
151 {
152         int last;               /* last character matched */
153         int matched;            /* !0 if a match occurred */
154         int reverse;            /* !0 if sense of match is reversed */
155
156         for (; *pattern; source++, pattern++) {
157                 switch (*pattern) {
158                 case '\\':
159                         /* Literal match with following character */
160                         pattern++;
161                         /* FALLTHRU */
162                 default:
163                         if (*source != *pattern) {
164                                 return (0);
165                         }
166                         continue;
167                 case '?':
168                         /* Match anything. */
169                         if (*source == '\0') {
170                                 return (0);
171                         }
172                         continue;
173                 case '*':
174                         /* Trailing star matches everything. */
175                         return (*++pattern ? star(source, pattern) : 1);
176                 case '[':
177                         /* [^....] means inverse character class. */
178                         if ((reverse = pattern[1]) == '^') {
179                                 pattern++;
180                         }
181                         for (last = 0400, matched = 0;
182                         *++pattern && *pattern != ']'; last = *pattern) {
183                                 /* This next line requires a good C compiler. */
184                                 if (*pattern == '-'
185                                 ? *source <= *++pattern && *source >= last
186                                     : *source == *pattern) {
187                                         matched = 1;
188                                 }
189                         }
190                         if (matched == reverse) {
191                                 return (0);
192                         }
193                         continue;
194                 }
195         }
196
197         /*
198          * For "tar" use, matches that end at a slash also work. --hoptoad!gnu 
199          */
200         return (*source == '\0' || *source == '/');
201 }