-
Notifications
You must be signed in to change notification settings - Fork 7
/
globmatch.c
173 lines (154 loc) · 4.27 KB
/
globmatch.c
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
/*
* robust glob pattern matcher
* ozan s. yigit/dec 1994
* public domain
*
* glob patterns:
* * matches zero or more characters
* ? matches any single character
* [set] matches any character in the set
* [^set] matches any character NOT in the set
* where a set is a group of characters or ranges. a range
* is written as two characters seperated with a hyphen: a-z denotes
* all characters between a to z inclusive.
* [-set] set matches a literal hypen and any character in the set
* []set] matches a literal close bracket and any character in the set
*
* char matches itself except where char is '*' or '?' or '['
* \char matches char, including any pattern character
*
* examples:
* a*c ac abc abbc ...
* a?c acc abc aXc ...
* a[a-z]c aac abc acc ...
* a[-a-z]c a-c aac abc ...
*
* $Log: not supported by cvs2svn $
* Revision 1.4sl 2007/06/18 12:47:00 ct
* Rename globmatch to sl_globmatch for integration into libslink.
*
* Revision 1.4 2004/12/26 12:38:00 ct
* Changed function name (amatch -> globmatch), variables and
* formatting for clarity. Also add matching header globmatch.h.
*
* Revision 1.3 1995/09/14 23:24:23 oz
* removed boring test/main code.
*
* Revision 1.2 94/12/11 10:38:15 oz
* charset code fixed. it is now robust and interprets all
* variations of charset [i think] correctly, including [z-a] etc.
*
* Revision 1.1 94/12/08 12:45:23 oz
* Initial revision
*/
#include "globmatch.h"
#define SL_GLOBMATCH_TRUE 1
#define SL_GLOBMATCH_FALSE 0
/******************************************************************/ /**
* @brief Check if a string matches a globbing pattern.
*
* @param string The string to check.
* @param pattern The globbing pattern to match.
*
* @returns 0 if string does not match pattern and non-zero otherwise.
**********************************************************************/
int
sl_globmatch (char *string, char *pattern)
{
int negate;
int match;
int c;
while (*pattern)
{
if (!*string && *pattern != '*')
return SL_GLOBMATCH_FALSE;
switch (c = *pattern++)
{
case '*':
while (*pattern == '*')
pattern++;
if (!*pattern)
return SL_GLOBMATCH_TRUE;
if (*pattern != '?' && *pattern != '[' && *pattern != '\\')
while (*string && *pattern != *string)
string++;
while (*string)
{
if (sl_globmatch (string, pattern))
return SL_GLOBMATCH_TRUE;
string++;
}
return SL_GLOBMATCH_FALSE;
case '?':
if (*string)
break;
return SL_GLOBMATCH_FALSE;
/* set specification is inclusive, that is [a-z] is a, z and
* everything in between. this means [z-a] may be interpreted
* as a set that contains z, a and nothing in between.
*/
case '[':
if (*pattern != SL_GLOBMATCH_NEGATE)
negate = SL_GLOBMATCH_FALSE;
else
{
negate = SL_GLOBMATCH_TRUE;
pattern++;
}
match = SL_GLOBMATCH_FALSE;
while (!match && (c = *pattern++))
{
if (!*pattern)
return SL_GLOBMATCH_FALSE;
if (*pattern == '-') /* c-c */
{
if (!*++pattern)
return SL_GLOBMATCH_FALSE;
if (*pattern != ']')
{
if (*string == c || *string == *pattern ||
(*string > c && *string < *pattern))
match = SL_GLOBMATCH_TRUE;
}
else
{ /* c-] */
if (*string >= c)
match = SL_GLOBMATCH_TRUE;
break;
}
}
else /* cc or c] */
{
if (c == *string)
match = SL_GLOBMATCH_TRUE;
if (*pattern != ']')
{
if (*pattern == *string)
match = SL_GLOBMATCH_TRUE;
}
else
break;
}
}
if (negate == match)
return SL_GLOBMATCH_FALSE;
/*
* if there is a match, skip past the charset and continue on
*/
while (*pattern && *pattern != ']')
pattern++;
if (!*pattern++) /* oops! */
return SL_GLOBMATCH_FALSE;
break;
case '\\':
if (*pattern)
c = *pattern++;
default:
if (c != *string)
return SL_GLOBMATCH_FALSE;
break;
}
string++;
}
return !*string;
}