CSL
5.2
Main Page
Related Pages
Modules
Namespaces
Classes
Files
File List
File Members
pattern_match.c
Go to the documentation of this file.
1
/* Open SoundControl kit in C++ */
2
/* Copyright (C) 2002-2004 libOSC++ contributors. See AUTHORS */
3
/* */
4
/* This library is free software; you can redistribute it and/or */
5
/* modify it under the terms of the GNU Lesser General Public */
6
/* License as published by the Free Software Foundation; either */
7
/* version 2.1 of the License, or (at your option) any later version. */
8
/* */
9
/* This library is distributed in the hope that it will be useful, */
10
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
11
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
12
/* Lesser General Public License for more details. */
13
/* */
14
/* You should have received a copy of the GNU Lesser General Public */
15
/* License along with this library; if not, write to the Free Software */
16
/* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
17
/* */
18
/* For questions regarding this program contact */
19
/* Daniel Holth <dholth@fastmail.fm> or visit */
20
/* http://wiretap.stetson.edu/ */
21
22
/* In the sprit of the public domain, my modifications to this file are also */
23
/* dedicated to the public domain. Daniel Holth, Oct. 2004 */
24
25
/* ChangeLog:
26
*
27
* 2004-10-29 Import, convert to C++, begin OSC syntax changes. -dwh
28
* OSC syntax changes are now working, needs more testing.
29
*
30
*/
31
32
// Original header and syntax:
33
34
/*
35
* robust glob pattern matcher
36
* ozan s. yigit/dec 1994
37
* public domain
38
*
39
* glob patterns:
40
* * matches zero or more characters
41
* ? matches any single character
42
* [set] matches any character in the set
43
* [^set] matches any character NOT in the set
44
* where a set is a group of characters or ranges. a range
45
* is written as two characters seperated with a hyphen: a-z denotes
46
* all characters between a to z inclusive.
47
* [-set] set matches a literal hypen and any character in the set
48
* []set] matches a literal close bracket and any character in the set
49
*
50
* char matches itself except where char is '*' or '?' or '['
51
* \char matches char, including any pattern character
52
*
53
* examples:
54
* a*c ac abc abbc ...
55
* a?c acc abc aXc ...
56
* a[a-z]c aac abc acc ...
57
* a[-a-z]c a-c aac abc ...
58
*
59
* $Log$
60
* Revision 1.1 2004/11/19 23:00:57 theno23
61
* Added lo_send_timestamped
62
*
63
* Revision 1.3 1995/09/14 23:24:23 oz
64
* removed boring test/main code.
65
*
66
* Revision 1.2 94/12/11 10:38:15 oz
67
* cset code fixed. it is now robust and interprets all
68
* variations of cset [i think] correctly, including [z-a] etc.
69
*
70
* Revision 1.1 94/12/08 12:45:23 oz
71
* Initial revision
72
*/
73
74
#include "
lo/lo.h
"
75
76
#ifndef NEGATE
77
#define NEGATE '!'
78
#endif
79
80
#ifndef true
81
#define true 1
82
#endif
83
#ifndef false
84
#define false 0
85
#endif
86
87
int
lo_pattern_match
(
const
char
*str,
const
char
*p)
88
{
89
int
negate;
90
int
match;
91
char
c;
92
93
while
(*p) {
94
if
(!*str && *p !=
'*'
)
95
return
false
;
96
97
switch
(c = *p++) {
98
99
case
'*'
:
100
while
(*p ==
'*'
&& *p !=
'/'
)
101
p++;
102
103
if
(!*p)
104
return
true
;
105
106
// if (*p != '?' && *p != '[' && *p != '\\')
107
if
(*p !=
'?'
&& *p !=
'['
&& *p !=
'{'
)
108
while
(*str && *p != *str)
109
str++;
110
111
while
(*str) {
112
if
(
lo_pattern_match
(str, p))
113
return
true
;
114
str++;
115
}
116
return
false
;
117
118
case
'?'
:
119
if
(*str)
120
break
;
121
return
false
;
122
/*
123
* set specification is inclusive, that is [a-z] is a, z and
124
* everything in between. this means [z-a] may be interpreted
125
* as a set that contains z, a and nothing in between.
126
*/
127
case
'['
:
128
if
(*p !=
NEGATE
)
129
negate =
false
;
130
else
{
131
negate =
true
;
132
p++;
133
}
134
135
match =
false
;
136
137
while
(!match && (c = *p++)) {
138
if
(!*p)
139
return
false
;
140
if
(*p ==
'-'
) {
/* c-c */
141
if
(!*++p)
142
return
false
;
143
if
(*p !=
']'
) {
144
if
(*str == c || *str == *p ||
145
(*str > c && *str < *p))
146
match =
true
;
147
}
148
else
{
/* c-] */
149
if
(*str >= c)
150
match =
true
;
151
break
;
152
}
153
}
154
else
{
/* cc or c] */
155
if
(c == *str)
156
match =
true
;
157
if
(*p !=
']'
) {
158
if
(*p == *str)
159
match =
true
;
160
}
161
else
162
break
;
163
}
164
}
165
166
if
(negate == match)
167
return
false
;
168
/*
169
* if there is a match, skip past the cset and continue on
170
*/
171
while
(*p && *p !=
']'
)
172
p++;
173
if
(!*p++)
/* oops! */
174
return
false
;
175
break
;
176
177
/*
178
* {astring,bstring,cstring}
179
*/
180
case
'{'
:
181
{
182
// *p is now first character in the {brace list}
183
const
char
*place = str;
// to backtrack
184
const
char
*remainder = p;
// to forwardtrack
185
186
// find the end of the brace list
187
while
(*remainder && *remainder !=
'}'
)
188
remainder++;
189
if
(!*remainder++)
/* oops! */
190
return
false
;
191
192
c = *p++;
193
194
while
(c) {
195
if
(c ==
','
) {
196
if
(
lo_pattern_match
(str, remainder)) {
197
return
true
;
198
}
else
{
199
// backtrack on test string
200
str = place;
201
// continue testing,
202
// skip comma
203
if
(!*p++)
// oops
204
return
false
;
205
}
206
}
207
else
if
(c ==
'}'
) {
208
// continue normal pattern matching
209
if
(!*p && !*str)
return
true
;
210
str--;
// str is incremented again below
211
break
;
212
}
else
if
(c == *str) {
213
str++;
214
if
(!*str && *remainder)
215
return
false
;
216
}
else
{
// skip to next comma
217
str = place;
218
while
(*p !=
','
&& *p !=
'}'
&& *p)
219
p++;
220
if
(*p ==
','
)
221
p++;
222
else
if
(*p ==
'}'
) {
223
return
false
;
224
}
225
}
226
c = *p++;
227
}
228
}
229
230
break
;
231
232
/* Not part of OSC pattern matching
233
case '\\':
234
if (*p)
235
c = *p++;
236
*/
237
238
default
:
239
if
(c != *str)
240
return
false
;
241
break
;
242
243
}
244
str++;
245
}
246
247
return
!*str;
248
}
CSL
liblo-0.26
src
pattern_match.c
Generated on Thu Nov 15 2012 22:01:09 for CSL by
1.8.1.1