comparison src/wildmat.c @ 43:2842f50feb55 noffle

[svn] * client.c, client.h, common.h, config.c, config.h, content.c, content.h, control.c, control.h, database.c, database.h, dynamicstring.c, dynamicstring.h, fetch.c, fetch.h, fetchlist.c, fetchlist.h, group.c, group.h, itemlist.c, itemlist.h, lock.c, lock.h, log.c, log.h, noffle.c, online.c, online.h, outgoing.c, outgoing.h, over.c, over.h, post.c, post.h, protocol.c, protocol.h, pseudo.c, pseudo.h, request.c, request.h, server.c, server.h, util.c, util.h, wildmat.c, wildmat.h: Moved files to the subdirectory src/ * Makefile.am, acconfig.h, configure.in, docs/Makefile.am, src/Makefile.am, Makefile.in, aclocal.m4, config.h.in, configure, install-sh, missing, mkinstalldirs, stamp-h.in, docs/Makefile.in, src/Makefile.in: Added files. They are used by aclocal, autoheader, autoconf and automake. * src/config.c, src/config.h: Renamed to configfile.c and configfile.h, because configure will generate a config.h file itself. * src/client.c, src/content.c, src/database.c, src/fetch.c, src/fetchlist.c, src/group.c, src/lock.c, src/noffle.c, src/online.c, src/outgoing.c, src/over.c, src/pseudo.c, src/request.c, src/server.c, src/util.c: Changed '#include "config.h"' to '#include "configfile.h"'. * src/client.c, src/content.c, src/database.c, src/fetch.c, src/fetchlist.c, src/group.c, src/lock.c, src/online.c, src/outgoing.c, src/post.c, src/protocol.c, src/request.c, src/server.c: Files now #include <config.h>. Added missing <stdio.h>. This removes the warnings about snprintf() not being declared. * Makefile: Removed. This is now generated by configure.
author uh1763
date Fri, 05 May 2000 22:45:56 +0100
parents
children 62b9392bceca
comparison
equal deleted inserted replaced
42:2467ff423c15 43:2842f50feb55
1 /*
2 wildmat.c
3
4 Taken from the INN 2.2 distribution and slightly altered to fit the
5 Noffle environment. Changes are:
6 o Rename wildmat() to Wld_match().
7 o Adjust includes.
8
9 $Id: wildmat.c 49 2000-05-05 21:45:56Z uh1763 $
10
11 The entire INN distribution is covered by the following copyright
12 notice. As this file originated in the INN distribution is it
13 subject to the conditions of this notice.
14
15 Copyright 1991 Rich Salz.
16 All rights reserved.
17 $Revision: 49 $
18
19 Redistribution and use in any form are permitted provided that the
20 following restrictions are are met:
21 1. Source distributions must retain this entire copyright notice
22 and comment.
23 2. Binary distributions must include the acknowledgement ``This
24 product includes software developed by Rich Salz'' in the
25 documentation or other materials provided with the
26 distribution. This must not be represented as an endorsement
27 or promotion without specific prior written permission.
28 3. The origin of this software must not be misrepresented, either
29 by explicit claim or by omission. Credits must appear in the
30 source and documentation.
31 4. Altered versions must be plainly marked as such in the source
32 and documentation and must not be misrepresented as being the
33 original software.
34 THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
35 WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
36 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
37
38 */
39
40 /* $Revision: 49 $
41 **
42 ** Do shell-style pattern matching for ?, \, [], and * characters.
43 ** Might not be robust in face of malformed patterns; e.g., "foo[a-"
44 ** could cause a segmentation violation. It is 8bit clean.
45 **
46 ** Written by Rich $alz, mirror!rs, Wed Nov 26 19:03:17 EST 1986.
47 ** Rich $alz is now <rsalz@osf.org>.
48 ** April, 1991: Replaced mutually-recursive calls with in-line code
49 ** for the star character.
50 **
51 ** Special thanks to Lars Mathiesen <thorinn@diku.dk> for the ABORT code.
52 ** This can greatly speed up failing wildcard patterns. For example:
53 ** pattern: -*-*-*-*-*-*-12-*-*-*-m-*-*-*
54 ** text 1: -adobe-courier-bold-o-normal--12-120-75-75-m-70-iso8859-1
55 ** text 2: -adobe-courier-bold-o-normal--12-120-75-75-X-70-iso8859-1
56 ** Text 1 matches with 51 calls, while text 2 fails with 54 calls. Without
57 ** the ABORT code, it takes 22310 calls to fail. Ugh. The following
58 ** explanation is from Lars:
59 ** The precondition that must be fulfilled is that DoMatch will consume
60 ** at least one character in text. This is true if *p is neither '*' nor
61 ** '\0'.) The last return has ABORT instead of FALSE to avoid quadratic
62 ** behaviour in cases like pattern "*a*b*c*d" with text "abcxxxxx". With
63 ** FALSE, each star-loop has to run to the end of the text; with ABORT
64 ** only the last one does.
65 **
66 ** Once the control of one instance of DoMatch enters the star-loop, that
67 ** instance will return either TRUE or ABORT, and any calling instance
68 ** will therefore return immediately after (without calling recursively
69 ** again). In effect, only one star-loop is ever active. It would be
70 ** possible to modify the code to maintain this context explicitly,
71 ** eliminating all recursive calls at the cost of some complication and
72 ** loss of clarity (and the ABORT stuff seems to be unclear enough by
73 ** itself). I think it would be unwise to try to get this into a
74 ** released version unless you have a good test data base to try it out
75 ** on.
76 */
77 #include <stdio.h>
78 #include <sys/types.h>
79 #include "common.h"
80 #include "log.h"
81
82 #define ABORT (-1)
83
84 /* What character marks an inverted character class? */
85 #define NEGATE_CLASS '^'
86 /* Is "*" a common pattern? */
87 #define OPTIMIZE_JUST_STAR
88 /* Do tar(1) matching rules, which ignore a trailing slash? */
89 #undef MATCH_TAR_PATTERN
90
91
92 /*
93 ** Match text and p, return TRUE, FALSE, or ABORT.
94 */
95 static int DoMatch(const char *text, const char *p)
96 {
97 int last;
98 int matched;
99 int reverse;
100
101 for ( ; *p; text++, p++) {
102 if (*text == '\0' && *p != '*')
103 return ABORT;
104 switch (*p) {
105 case '\\':
106 /* Literal match with following character. */
107 p++;
108 /* FALLTHROUGH */
109 default:
110 if (*text != *p)
111 return FALSE;
112 continue;
113 case '?':
114 /* Match anything. */
115 continue;
116 case '*':
117 while (*++p == '*')
118 /* Consecutive stars act just like one. */
119 continue;
120 if (*p == '\0')
121 /* Trailing star matches everything. */
122 return TRUE;
123 while (*text)
124 if ((matched = DoMatch(text++, p)) != FALSE)
125 return matched;
126 return ABORT;
127 case '[':
128 reverse = p[1] == NEGATE_CLASS ? TRUE : FALSE;
129 if (reverse)
130 /* Inverted character class. */
131 p++;
132 matched = FALSE;
133 if (p[1] == ']' || p[1] == '-')
134 if (*++p == *text)
135 matched = TRUE;
136 for (last = *p; *++p && *p != ']'; last = *p)
137 /* This next line requires a good C compiler. */
138 if (*p == '-' && p[1] != ']'
139 ? *text <= *++p && *text >= last : *text == *p)
140 matched = TRUE;
141 if (matched == reverse)
142 return FALSE;
143 continue;
144 }
145 }
146
147 #ifdef MATCH_TAR_PATTERN
148 if (*text == '/')
149 return TRUE;
150 #endif /* MATCH_TAR_ATTERN */
151 return *text == '\0';
152 }
153
154
155 /*
156 ** User-level routine. Returns TRUE or FALSE.
157 */
158 Bool
159 Wld_match(const char *text, const char *pattern)
160 {
161 #ifdef OPTIMIZE_JUST_STAR
162 if (pattern[0] == '*' && pattern[1] == '\0')
163 return TRUE;
164 #endif /* OPTIMIZE_JUST_STAR */
165 return DoMatch(text, pattern) == TRUE;
166 }
167
168
169
170 #if defined(WILDMAT_TEST)
171
172 /* Yes, we use gets not fgets. Sue me. */
173 extern char *gets();
174
175
176 int
177 main()
178 {
179 char p[80];
180 char text[80];
181
182 printf("Wildmat tester. Enter pattern, then strings to test.\n");
183 printf("A blank line gets prompts for a new pattern; a blank pattern\n");
184 printf("exits the program.\n");
185
186 for ( ; ; ) {
187 printf("\nEnter pattern: ");
188 (void)fflush(stdout);
189 if (gets(p) == NULL || p[0] == '\0')
190 break;
191 for ( ; ; ) {
192 printf("Enter text: ");
193 (void)fflush(stdout);
194 if (gets(text) == NULL)
195 exit(0);
196 if (text[0] == '\0')
197 /* Blank line; go back and get a new pattern. */
198 break;
199 printf(" %s\n", Wld_match(text, p) ? "YES" : "NO");
200 }
201 }
202
203 exit(0);
204 /* NOTREACHED */
205 }
206 #endif /* defined(TEST) */