Repository navigation
Expand file tree
/
Copy pathwildmat.c
More file actions
185 lines (159 loc) · 4.72 KB
/
Copy pathwildmat.c
File metadata and controls
185 lines (159 loc) · 4.72 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
/*
**
** Do shell-style pattern matching for ?, \, [], and * characters.
** Might not be robust in face of malformed patterns; e.g., "foo[a-"
** could cause a segmentation violation. It is 8bit clean.
**
** Written by Rich $alz, mirror!rs, Wed Nov 26 19:03:17 EST 1986.
** Special thanks to Lars Mathiesen for the ABORT code. This can greatly
** speed up failing wildcard patterns. For example:
** pattern: -*-*-*-*-*-*-12-*-*-*-m-*-*-*
** text 1: -adobe-courier-bold-o-normal--12-120-75-75-m-70-iso8859-1
** text 2: -adobe-courier-bold-o-normal--12-120-75-75-p-70-iso8859-1
** Text 1 matches with 51 calls, while text 2 fails with 54 calls. Without
** the ABORT, then it takes 22310 calls to fail. Ugh.
**
** bernie 613-01 91/01/04 19:34
** Fixed problem with terminating * not matching with (null)
**
** bernie 597-00 91/01/08 11:24
** Fixed shell glob negate from '^' to '!'
**
** bernie 597-02 91/01/21 13:43
** Fixed . matching * or ? on first char.
**
** jseymour 91/02/05 22:56
** Fixed problems with ill-formed sets in pattern yielding false
** matches. Should now be robust in such cases (not all possibilities
** tested - standard disclaimer). Added stand-alone debug code.
**
** jseymour 91/03/28 20:50
** Re-fixed problems with ill-formed sets in pattern yielding false
** matches - one hopes correctly this time.
**
** jseymour 1998/04/04 17:45 EST
** Before adding this to minicom (as part of my "getsdir()" addition),
** I emailed a request to Rich $alz, asking if I could "GPL" it. Here
** is his reply:
**
** Date: Mon, 30 Mar 1998 10:50:06 -0500 (EST)
** Message-Id: <199803301550.KAA14018@<anonymized>.com>
** From: Rich Salz <salzr@<anonymized>.com>
** To: jseymour@jimsun.LinxNet.com
** Subject: Re: A Little Thing Named "Wildmat"
**
** Wildmat is in the public domain -- enjoy it.
**
** I would rather it not get encumbered with various licenses,
** but since it is in the public domain you can do what you want...
**
** So there you go. (I anonymized his email address as I don't know
** that he was particularly interested in having it "advertised".)
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include "minicom.h"
#ifndef TRUE
#define TRUE 1
#endif
#ifndef FALSE
#define FALSE 0
#endif
#define ABORT -1
static int Star(const char *, const char *);
static int DoMatch(const char *, const char *);
static int Star(const char *s, const char *p)
{
int retval;
while ((retval = DoMatch(s, p)) == FALSE) /* gobble up * match */
if (*++s == '\0')
return ABORT;
return retval;
}
/* match string "s" to pattern "p" */
static int DoMatch(const char *s, const char *p)
{
register int last;
register int matched;
register int reverse;
const char *ss;
int escaped;
for (; *p; s++, p++) { /* parse the string to end */
if (*s == '\0')
return *p == '*' && *++p == '\0' ? TRUE : ABORT;
switch (*p) { /* parse pattern */
case '\\':
/* Literal match with following character. */
p++;
/* FALLTHROUGH */
default: /*literal match*/
if (*s != *p)
return FALSE;
continue;
case '?':
/* Match anything. */
continue;
case '*':
/* Trailing star matches everything. */
return *++p ? Star(s, p) : TRUE;
case '[':
/* [!....] means inverse character class. */
if ((reverse = (p[1] == '!')))
p++;
ss = p + 1; /* set start point */
for (last = 0400, escaped = matched = FALSE; *++p; last = *p) {
if (*p == ']' && !(escaped || p == ss))
break;
if (escaped)
escaped = FALSE;
else if (*p == '\\') {
escaped = TRUE;
continue;
}
/* This next line requires a good C compiler. */
/* range? (in bounds) (equal) */
if ((*p == '-') ? (*s <= *++p && *s >= last) : (*s == *p))
matched = TRUE;
}
if (matched == reverse)
return FALSE;
continue;
}
}
return *s == '\0';
}
/*
* usage: wildmat(string, pattern)
*
* returns: non-0 on match
*/
int wildmat(const char *s, const char *p)
{
if ((*p == '?' || *p == '*') && *s == '.') {
return FALSE;
} else {
return DoMatch(s, p) == TRUE;
}
}
#ifdef STAND_ALONE_TEST
#include <stdio.h>
/*
* usage: wildmat <pattern> <test arg(s)>
*/
int main(int argc, char **argv)
{
int index;
int status = FALSE;
for (index = 2; index < argc; ++index) {
if (wildmat(argv[index], argv[1])) {
if (status)
fputs(" ", stdout);
printf("%s", argv[index]);
status = TRUE;
}
}
printf("%s\n", status ? "" : argv[1]);
return 0;
}
#endif