diff options
author | Wincent Balin <wincent@rockbox.org> | 2010-06-03 00:39:13 +0000 |
---|---|---|
committer | Wincent Balin <wincent@rockbox.org> | 2010-06-03 00:39:13 +0000 |
commit | c1ae4414d4ac6504992434b949b252c30daf0c48 (patch) | |
tree | 696c5781e9a00cea694117eb3ef404d37f10930e /apps/plugins/pdbox/PDa/extra/OSCroute.c | |
parent | 5edd8cf736232a240e2f4f47eb847e1901d18379 (diff) | |
download | rockbox-c1ae4414d4ac6504992434b949b252c30daf0c48.tar.gz rockbox-c1ae4414d4ac6504992434b949b252c30daf0c48.zip |
pdbox: Source cleanup. Removed unneeded files.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@26497 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps/plugins/pdbox/PDa/extra/OSCroute.c')
-rw-r--r-- | apps/plugins/pdbox/PDa/extra/OSCroute.c | 628 |
1 files changed, 0 insertions, 628 deletions
diff --git a/apps/plugins/pdbox/PDa/extra/OSCroute.c b/apps/plugins/pdbox/PDa/extra/OSCroute.c deleted file mode 100644 index 64edbc777f..0000000000 --- a/apps/plugins/pdbox/PDa/extra/OSCroute.c +++ /dev/null | |||
@@ -1,628 +0,0 @@ | |||
1 | /* | ||
2 | Written by Adrian Freed, The Center for New Music and Audio Technologies, | ||
3 | University of California, Berkeley. Copyright (c) 1992,93,94,95,96,97,98,99,2000,01,02,03,04 | ||
4 | The Regents of the University of California (Regents). | ||
5 | |||
6 | Permission to use, copy, modify, distribute, and distribute modified versions | ||
7 | of this software and its documentation without fee and without a signed | ||
8 | licensing agreement, is hereby granted, provided that the above copyright | ||
9 | notice, this paragraph and the following two paragraphs appear in all copies, | ||
10 | modifications, and distributions. | ||
11 | |||
12 | IN NO EVENT SHALL REGENTS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, | ||
13 | SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING | ||
14 | OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF REGENTS HAS | ||
15 | BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
16 | |||
17 | REGENTS SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, | ||
18 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | ||
19 | PURPOSE. THE SOFTWARE AND ACCOMPANYING DOCUMENTATION, IF ANY, PROVIDED | ||
20 | HEREUNDER IS PROVIDED "AS IS". REGENTS HAS NO OBLIGATION TO PROVIDE | ||
21 | MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. | ||
22 | |||
23 | |||
24 | The OSC webpage is http://cnmat.cnmat.berkeley.edu/OpenSoundControl | ||
25 | */ | ||
26 | |||
27 | /* OSC-route.c | ||
28 | Max object for OSC-style dispatching | ||
29 | |||
30 | To-do: | ||
31 | |||
32 | Match a pattern against a pattern? | ||
33 | Declare outlet types / distinguish leaf nodes from other children | ||
34 | More sophisticated (2-pass?) allmessages scheme | ||
35 | set message? | ||
36 | |||
37 | |||
38 | pd | ||
39 | ------------- | ||
40 | -- tweaks for Win32 www.zeggz.com/raf 13-April-2002 | ||
41 | |||
42 | |||
43 | */ | ||
44 | |||
45 | #ifdef ROCKBOX | ||
46 | #include "plugin.h" | ||
47 | #include "../../pdbox.h" | ||
48 | #else /* ROCKBOX */ | ||
49 | #ifdef WIN32 | ||
50 | #include <stdlib.h> | ||
51 | #include <string.h> | ||
52 | #endif | ||
53 | #ifdef __APPLE__ | ||
54 | #include <stdio.h> | ||
55 | #endif | ||
56 | #ifdef UNIX | ||
57 | #include <stdio.h> | ||
58 | #endif | ||
59 | #endif /* ROCKBOX */ | ||
60 | |||
61 | /* structure definition of your object */ | ||
62 | |||
63 | #define MAX_NUM 20 | ||
64 | #define OSC_ROUTE_VERSION "1.05" | ||
65 | #define OSCWarning(x...) post(x) | ||
66 | |||
67 | /* the required include files */ | ||
68 | #include "../src/m_pd.h" | ||
69 | |||
70 | |||
71 | #ifndef TRUE | ||
72 | typedef int Boolean; | ||
73 | #define TRUE 1 | ||
74 | #define FALSE 0 | ||
75 | #endif | ||
76 | |||
77 | |||
78 | /* Fixed byte width types */ | ||
79 | typedef int int4; /* 4 byte int */ | ||
80 | |||
81 | Boolean PatternMatch (const char *pattern, const char *test); | ||
82 | |||
83 | |||
84 | |||
85 | /* Version 1.04: Allows #1 thru #9 as typed-in arguments | ||
86 | Version 1.05: Allows "list" messages as well as "message" messages. | ||
87 | */ | ||
88 | |||
89 | static t_class *OSCroute_class; | ||
90 | |||
91 | typedef struct _OSCroute | ||
92 | { | ||
93 | t_object x_obj; // required header | ||
94 | t_int x_num; // Number of address prefixes we store | ||
95 | t_int x_complainmode; // Do we print a message if no match? | ||
96 | t_int x_sendmode; // use pd internal sends instead of outlets | ||
97 | char *x_prefixes[MAX_NUM]; | ||
98 | void *x_outlets[MAX_NUM+1]; | ||
99 | } t_OSCroute; | ||
100 | |||
101 | t_symbol *ps_list, *ps_complain, *ps_emptySymbol; | ||
102 | |||
103 | /* prototypes */ | ||
104 | |||
105 | void OSCroute_doanything(t_OSCroute *x, t_symbol *s, int argc, t_atom *argv); | ||
106 | void OSCroute_anything(t_OSCroute *x, t_symbol *s, int argc, t_atom *argv); | ||
107 | void OSCroute_list(t_OSCroute *x, t_symbol *s, int argc, t_atom *argv); | ||
108 | /* //void *OSCroute_new(t_symbol *s, int argc, atom *argv); */ | ||
109 | void *OSCroute_new(t_symbol *s, int argc, t_atom *argv); | ||
110 | void OSCroute_version (t_OSCroute *x); | ||
111 | /* void OSCroute_assist (OSCroute *x, void *box, long msg, long arg, */ | ||
112 | /* char *dstString); */ | ||
113 | void OSCroute_allmessages(t_OSCroute *x, t_symbol *s, int argc, t_atom *argv); | ||
114 | |||
115 | static char *NextSlashOrNull(char *p); | ||
116 | static void StrCopyUntilSlash(char *target, const char *source); | ||
117 | |||
118 | |||
119 | // free | ||
120 | static void OSCroute_free(t_OSCroute *x) | ||
121 | { | ||
122 | #ifdef ROCKBOX | ||
123 | (void) x; | ||
124 | #endif | ||
125 | // freebytes(x->x_vec, x->x_nelement * sizeof(*x->x_vec)); | ||
126 | } | ||
127 | |||
128 | /* initialization routine */ | ||
129 | |||
130 | // setup | ||
131 | #ifdef WIN32 | ||
132 | OSC_API void OSCroute_setup(void) { | ||
133 | #else | ||
134 | void OSCroute_setup(void) { | ||
135 | #endif | ||
136 | OSCroute_class = class_new(gensym("OSCroute"), (t_newmethod)OSCroute_new, | ||
137 | (t_method)OSCroute_free,sizeof(t_OSCroute), 0, A_GIMME, 0); | ||
138 | class_addlist(OSCroute_class, OSCroute_list); | ||
139 | class_addanything(OSCroute_class, OSCroute_anything); | ||
140 | class_addmethod(OSCroute_class, (t_method)OSCroute_version, gensym("version"), A_NULL, 0, 0); | ||
141 | class_sethelpsymbol(OSCroute_class, gensym("OSCroute-help.pd")); | ||
142 | |||
143 | /* | ||
144 | class_addmethod(OSCroute_class, (t_method)OSCroute_connect, | ||
145 | gensym("connect"), A_SYMBOL, A_FLOAT, 0); | ||
146 | class_addmethod(OSCroute_class, (t_method)OSCroute_disconnect, | ||
147 | gensym("disconnect"), 0); | ||
148 | class_addmethod(OSCroute_class, (t_method)OSCroute_send, gensym("send"), | ||
149 | A_GIMME, 0); | ||
150 | */ | ||
151 | /* ps_list = gensym("list"); */ | ||
152 | /* ps_complain = gensym("complain"); */ | ||
153 | ps_emptySymbol = gensym(""); | ||
154 | |||
155 | post("OSCroute object version " OSC_ROUTE_VERSION " by Matt Wright. pd: jdl Win32 raf."); | ||
156 | post("OSCroute Copyright © 1999 Regents of the University of California. All Rights Reserved."); | ||
157 | } | ||
158 | |||
159 | |||
160 | |||
161 | /* instance creation routine */ | ||
162 | |||
163 | void *OSCroute_new(t_symbol *s, int argc, t_atom *argv) | ||
164 | { | ||
165 | #ifdef ROCKBOX | ||
166 | (void) s; | ||
167 | #endif | ||
168 | t_OSCroute *x = (t_OSCroute *)pd_new(OSCroute_class); // get memory for a new object & initialize | ||
169 | |||
170 | int i; //{{raf}} n not used | ||
171 | |||
172 | // EnterCallback(); | ||
173 | |||
174 | if (argc > MAX_NUM) { | ||
175 | post("* OSC-route: too many arguments: %ld (max %ld)", argc, MAX_NUM); | ||
176 | // ExitCallback(); | ||
177 | return 0; | ||
178 | } | ||
179 | |||
180 | x->x_complainmode = 0; | ||
181 | x->x_num = 0; | ||
182 | for (i = 0; i < argc; ++i) { | ||
183 | if (argv[i].a_type == A_SYMBOL) { | ||
184 | if (argv[i].a_w.w_symbol->s_name[0] == '/') { | ||
185 | /* Now that's a nice prefix */ | ||
186 | x->x_prefixes[i] = argv[i].a_w.w_symbol->s_name; | ||
187 | ++(x->x_num); | ||
188 | } else if (argv[i].a_w.w_symbol->s_name[0] == '#' && | ||
189 | argv[i].a_w.w_symbol->s_name[1] >= '1' && | ||
190 | argv[i].a_w.w_symbol->s_name[1] <= '9') { | ||
191 | /* The Max programmer is trying to make a patch that will be | ||
192 | a subpatch with arguments. We have to make an outlet for this | ||
193 | argument. */ | ||
194 | x->x_prefixes[i] = "dummy"; | ||
195 | ++(x->x_num); | ||
196 | } else { | ||
197 | /* Maybe this is an option we support */ | ||
198 | |||
199 | /* if (argv[i].a_w.w_sym == ps_complain) { */ | ||
200 | /* x->x_complainmode = 1; */ | ||
201 | /* } else { */ | ||
202 | /* post("* OSC-route: Unrecognized argument %s", argv[i].a_w.w_sym->s_name); */ | ||
203 | /* } */ | ||
204 | |||
205 | } | ||
206 | |||
207 | // no LONG | ||
208 | |||
209 | /* } else if (argv[i].a_type == A_FLOAD) { */ | ||
210 | /* // Convert to a numeral. Max ints are -2147483648 to 2147483647 */ | ||
211 | /* char *string = getbytes(12); */ | ||
212 | /* // I can't be bothered to plug this 12 byte memory leak */ | ||
213 | /* if (string == 0) { */ | ||
214 | /* post("* OSC-route: out of memory!"); */ | ||
215 | /* // ExitCallback(); */ | ||
216 | /* return 0; */ | ||
217 | /* } */ | ||
218 | /* sprintf(string, "%d", argv[i].a_w.w_long); */ | ||
219 | /* x->x_prefixes[i] = string; */ | ||
220 | /* ++(x->x_num); */ | ||
221 | |||
222 | } else if (argv[i].a_type == A_FLOAT) { | ||
223 | post("* OSC-route: float arguments are not OK."); | ||
224 | // ExitCallback(); | ||
225 | return 0; | ||
226 | } else { | ||
227 | post("* OSC-route: unrecognized argument type!"); | ||
228 | // ExitCallback(); | ||
229 | return 0; | ||
230 | } | ||
231 | } | ||
232 | |||
233 | |||
234 | /* Have to create the outlets in reverse order */ | ||
235 | /* well, not in pd ? */ | ||
236 | // for (i = x->x_num-1; i >= 0; --i) { | ||
237 | // for (i = 0; i <= x->x_num-1; i++) { | ||
238 | for (i = 0; i <= x->x_num; i++) { | ||
239 | // x->x_outlets[i] = listout(x); | ||
240 | x->x_outlets[i] = outlet_new(&x->x_obj, &s_list); | ||
241 | } | ||
242 | |||
243 | // ExitCallback(); | ||
244 | return (x); | ||
245 | } | ||
246 | |||
247 | |||
248 | void OSCroute_version (t_OSCroute *x) { | ||
249 | #ifdef ROCKBOX | ||
250 | (void) x; | ||
251 | #endif | ||
252 | // EnterCallback(); | ||
253 | post("OSCroute Version " OSC_ROUTE_VERSION | ||
254 | ", by Matt Wright. pd jdl, win32: raf.\nOSCroute Compiled " __TIME__ " " __DATE__); | ||
255 | // ExitCallback(); | ||
256 | } | ||
257 | |||
258 | /* I don't know why these aren't defined in some Max #include file. */ | ||
259 | #define ASSIST_INLET 1 | ||
260 | #define ASSIST_OUTLET 2 | ||
261 | |||
262 | void OSCroute_assist (t_OSCroute *x, void *box, long msg, long arg, | ||
263 | char *dstString) { | ||
264 | #ifdef ROCKBOX | ||
265 | (void) box; | ||
266 | #endif | ||
267 | // EnterCallback(); | ||
268 | |||
269 | if (msg==ASSIST_INLET) { | ||
270 | #ifdef ROCKBOX | ||
271 | strcpy(dstString, "Incoming OSC messages"); | ||
272 | #else | ||
273 | sprintf(dstString, "Incoming OSC messages"); | ||
274 | #endif | ||
275 | } else if (msg==ASSIST_OUTLET) { | ||
276 | if (arg < 0 || arg >= x->x_num) { | ||
277 | post("* OSCroute_assist: No outlet corresponds to arg %ld!", arg); | ||
278 | } else { | ||
279 | #ifdef ROCKBOX | ||
280 | strcpy(dstString, "subaddress + args for prefix "); | ||
281 | strcat(dstString, x->x_prefixes[arg]); | ||
282 | #else | ||
283 | sprintf(dstString, "subaddress + args for prefix %s", x->x_prefixes[arg]); | ||
284 | #endif | ||
285 | } | ||
286 | } else { | ||
287 | post("* OSCroute_assist: unrecognized message %ld", msg); | ||
288 | } | ||
289 | |||
290 | // ExitCallback(); | ||
291 | } | ||
292 | |||
293 | void OSCroute_list(t_OSCroute *x, t_symbol *s, int argc, t_atom *argv) { | ||
294 | #ifdef ROCKBOX | ||
295 | (void) s; | ||
296 | #endif | ||
297 | // EnterCallback(); | ||
298 | if (argc > 0 && argv[0].a_type == A_SYMBOL) { | ||
299 | /* Ignore the fact that this is a "list" */ | ||
300 | OSCroute_doanything(x, argv[0].a_w.w_symbol, argc-1, argv+1); | ||
301 | } else { | ||
302 | // post("* OSC-route: invalid list beginning with a number"); | ||
303 | // output on unmatched outlet jdl 20020908 | ||
304 | if (argv[0].a_type == A_FLOAT) { | ||
305 | outlet_float(x->x_outlets[x->x_num], argv[0].a_w.w_float); | ||
306 | } else { | ||
307 | post("* OSC-route: unrecognized atom type!"); | ||
308 | } | ||
309 | } | ||
310 | // ExitCallback(); | ||
311 | } | ||
312 | |||
313 | |||
314 | void OSCroute_anything(t_OSCroute *x, t_symbol *s, int argc, t_atom *argv) { | ||
315 | // EnterCallback(); | ||
316 | OSCroute_doanything(x, s, argc, argv); | ||
317 | // ExitCallback(); | ||
318 | } | ||
319 | |||
320 | |||
321 | |||
322 | |||
323 | void OSCroute_doanything(t_OSCroute *x, t_symbol *s, int argc, t_atom *argv) { | ||
324 | char *pattern, *nextSlash; | ||
325 | int i; | ||
326 | int matchedAnything; | ||
327 | // post("*** OSCroute_anything(s %s, argc %ld)", s->s_name, (long) argc); | ||
328 | |||
329 | pattern = s->s_name; | ||
330 | if (pattern[0] != '/') { | ||
331 | post("* OSC-route: invalid message pattern %s does not begin with /", s->s_name); | ||
332 | outlet_anything(x->x_outlets[x->x_num], s, argc, argv); | ||
333 | return; | ||
334 | } | ||
335 | |||
336 | matchedAnything = 0; | ||
337 | |||
338 | nextSlash = NextSlashOrNull(pattern+1); | ||
339 | if (*nextSlash == '\0') { | ||
340 | /* last level of the address, so we'll output the argument list */ | ||
341 | |||
342 | |||
343 | #ifdef NULL_IS_DIFFERENT_FROM_BANG | ||
344 | if (argc==0) { | ||
345 | post("* OSC-route: why are you matching one level pattern %s with no args?", | ||
346 | pattern); | ||
347 | return; | ||
348 | } | ||
349 | #endif | ||
350 | |||
351 | for (i = 0; i < x->x_num; ++i) { | ||
352 | if (PatternMatch(pattern+1, x->x_prefixes[i]+1)) { | ||
353 | ++matchedAnything; | ||
354 | |||
355 | // I hate stupid Max lists with a special first element | ||
356 | if (argc == 0) { | ||
357 | outlet_bang(x->x_outlets[i]); | ||
358 | } else if (argv[0].a_type == A_SYMBOL) { | ||
359 | // Promote the symbol that was argv[0] to the special symbol | ||
360 | outlet_anything(x->x_outlets[i], argv[0].a_w.w_symbol, argc-1, argv+1); | ||
361 | } else if (argc > 1) { | ||
362 | // Multiple arguments starting with a number, so naturally we have | ||
363 | // to use a special function to output this "list", since it's what | ||
364 | // Max originally meant by "list". | ||
365 | outlet_list(x->x_outlets[i], 0L, argc, argv); | ||
366 | } else { | ||
367 | // There was only one argument, and it was a number, so we output it | ||
368 | // not as a list | ||
369 | /* if (argv[0].a_type == A_LONG) { */ | ||
370 | |||
371 | /* outlet_int(x->x_outlets[i], argv[0].a_w.w_long); */ | ||
372 | // } else | ||
373 | if (argv[0].a_type == A_FLOAT) { | ||
374 | |||
375 | outlet_float(x->x_outlets[i], argv[0].a_w.w_float); | ||
376 | } else { | ||
377 | post("* OSC-route: unrecognized atom type!"); | ||
378 | } | ||
379 | } | ||
380 | } | ||
381 | } | ||
382 | } else { | ||
383 | /* There's more address after this part, so our output list will begin with | ||
384 | the next slash. */ | ||
385 | t_symbol *restOfPattern = 0; /* avoid the gensym unless we have to output */ | ||
386 | char patternBegin[1000]; | ||
387 | |||
388 | |||
389 | /* Get the first level of the incoming pattern to match against all our prefixes */ | ||
390 | StrCopyUntilSlash(patternBegin, pattern+1); | ||
391 | |||
392 | for (i = 0; i < x->x_num; ++i) { | ||
393 | if (PatternMatch(patternBegin, x->x_prefixes[i]+1)) { | ||
394 | ++matchedAnything; | ||
395 | if (restOfPattern == 0) { | ||
396 | restOfPattern = gensym(nextSlash); | ||
397 | } | ||
398 | outlet_anything(x->x_outlets[i], restOfPattern, argc, argv); | ||
399 | } | ||
400 | } | ||
401 | } | ||
402 | |||
403 | if (x->x_complainmode) { | ||
404 | if (!matchedAnything) { | ||
405 | post("* OSC-route: pattern %s did not match any prefixes", pattern); | ||
406 | } | ||
407 | } | ||
408 | |||
409 | // output unmatched data on rightmost outlet a la normal 'route' object, jdl 20020908 | ||
410 | if (!matchedAnything) { | ||
411 | outlet_anything(x->x_outlets[x->x_num], s, argc, argv); | ||
412 | } | ||
413 | |||
414 | |||
415 | } | ||
416 | |||
417 | static char *NextSlashOrNull(char *p) { | ||
418 | while (*p != '/' && *p != '\0') { | ||
419 | p++; | ||
420 | } | ||
421 | return p; | ||
422 | } | ||
423 | |||
424 | static void StrCopyUntilSlash(char *target, const char *source) { | ||
425 | while (*source != '/' && *source != '\0') { | ||
426 | *target = *source; | ||
427 | ++target; | ||
428 | ++source; | ||
429 | } | ||
430 | *target = 0; | ||
431 | } | ||
432 | |||
433 | static int MyStrCopy(char *target, const char *source) { | ||
434 | int i = 0; | ||
435 | while (*source != '\0') { | ||
436 | *target = *source; | ||
437 | ++target; | ||
438 | ++source; | ||
439 | ++i; | ||
440 | } | ||
441 | *target = 0; | ||
442 | return i; | ||
443 | } | ||
444 | |||
445 | |||
446 | |||
447 | void OSCroute_allmessages(t_OSCroute *x, t_symbol *s, int argc, t_atom *argv) { | ||
448 | int i; | ||
449 | t_symbol *prefixSymbol = 0; | ||
450 | char prefixBuf[1000]; | ||
451 | char *endOfPrefix; | ||
452 | t_atom a[1]; | ||
453 | |||
454 | if (argc >= 1 && argv[0].a_type == A_SYMBOL) { | ||
455 | prefixSymbol = argv[0].a_w.w_symbol; | ||
456 | endOfPrefix = prefixBuf + MyStrCopy(prefixBuf, | ||
457 | prefixSymbol->s_name); | ||
458 | } else { | ||
459 | prefixSymbol = ps_emptySymbol; | ||
460 | prefixBuf[0] = '\0'; | ||
461 | endOfPrefix = prefixBuf; | ||
462 | } | ||
463 | |||
464 | |||
465 | for (i = 0; i < x->x_num; ++i) { | ||
466 | post("OSC: %s%s", prefixSymbol->s_name, x->x_prefixes[i]); | ||
467 | MyStrCopy(endOfPrefix, x->x_prefixes[i]); | ||
468 | SETSYMBOL(a, gensym(prefixBuf)); | ||
469 | outlet_anything(x->x_outlets[i], s, 1, a); | ||
470 | } | ||
471 | } | ||
472 | |||
473 | |||
474 | /* --------------------------------------------------- */ | ||
475 | |||
476 | |||
477 | |||
478 | static const char *theWholePattern; /* Just for warning messages */ | ||
479 | |||
480 | static Boolean MatchBrackets (const char *pattern, const char *test); | ||
481 | static Boolean MatchList (const char *pattern, const char *test); | ||
482 | |||
483 | Boolean PatternMatch (const char * pattern, const char * test) { | ||
484 | theWholePattern = pattern; | ||
485 | |||
486 | if (pattern == 0 || pattern[0] == 0) { | ||
487 | return test[0] == 0; | ||
488 | } | ||
489 | |||
490 | if (test[0] == 0) { | ||
491 | if (pattern[0] == '*') | ||
492 | return PatternMatch (pattern+1,test); | ||
493 | else | ||
494 | return FALSE; | ||
495 | } | ||
496 | |||
497 | switch (pattern[0]) { | ||
498 | case 0 : return test[0] == 0; | ||
499 | case '?' : return PatternMatch (pattern + 1, test + 1); | ||
500 | case '*' : | ||
501 | if (PatternMatch (pattern+1, test)) { | ||
502 | return TRUE; | ||
503 | } else { | ||
504 | return PatternMatch (pattern, test+1); | ||
505 | } | ||
506 | case ']' : | ||
507 | case '}' : | ||
508 | OSCWarning("Spurious %c in pattern \".../%s/...\"",pattern[0], theWholePattern); | ||
509 | return FALSE; | ||
510 | case '[' : | ||
511 | return MatchBrackets (pattern,test); | ||
512 | case '{' : | ||
513 | return MatchList (pattern,test); | ||
514 | case '\\' : | ||
515 | if (pattern[1] == 0) { | ||
516 | return test[0] == 0; | ||
517 | } else if (pattern[1] == test[0]) { | ||
518 | return PatternMatch (pattern+2,test+1); | ||
519 | } else { | ||
520 | return FALSE; | ||
521 | } | ||
522 | default : | ||
523 | if (pattern[0] == test[0]) { | ||
524 | return PatternMatch (pattern+1,test+1); | ||
525 | } else { | ||
526 | return FALSE; | ||
527 | } | ||
528 | } | ||
529 | } | ||
530 | |||
531 | |||
532 | /* we know that pattern[0] == '[' and test[0] != 0 */ | ||
533 | |||
534 | static Boolean MatchBrackets (const char *pattern, const char *test) { | ||
535 | Boolean result; | ||
536 | Boolean negated = FALSE; | ||
537 | const char *p = pattern; | ||
538 | |||
539 | if (pattern[1] == 0) { | ||
540 | OSCWarning("Unterminated [ in pattern \".../%s/...\"", theWholePattern); | ||
541 | return FALSE; | ||
542 | } | ||
543 | |||
544 | if (pattern[1] == '!') { | ||
545 | negated = TRUE; | ||
546 | p++; | ||
547 | } | ||
548 | |||
549 | while (*p != ']') { | ||
550 | if (*p == 0) { | ||
551 | OSCWarning("Unterminated [ in pattern \".../%s/...\"", theWholePattern); | ||
552 | return FALSE; | ||
553 | } | ||
554 | if (p[1] == '-' && p[2] != 0) { | ||
555 | if (test[0] >= p[0] && test[0] <= p[2]) { | ||
556 | result = !negated; | ||
557 | goto advance; | ||
558 | } | ||
559 | } | ||
560 | if (p[0] == test[0]) { | ||
561 | result = !negated; | ||
562 | goto advance; | ||
563 | } | ||
564 | p++; | ||
565 | } | ||
566 | |||
567 | result = negated; | ||
568 | |||
569 | advance: | ||
570 | |||
571 | if (!result) | ||
572 | return FALSE; | ||
573 | |||
574 | while (*p != ']') { | ||
575 | if (*p == 0) { | ||
576 | OSCWarning("Unterminated [ in pattern \".../%s/...\"", theWholePattern); | ||
577 | return FALSE; | ||
578 | } | ||
579 | p++; | ||
580 | } | ||
581 | |||
582 | return PatternMatch (p+1,test+1); | ||
583 | } | ||
584 | |||
585 | static Boolean MatchList (const char *pattern, const char *test) { | ||
586 | |||
587 | const char *restOfPattern, *tp = test; | ||
588 | |||
589 | |||
590 | for(restOfPattern = pattern; *restOfPattern != '}'; restOfPattern++) { | ||
591 | if (*restOfPattern == 0) { | ||
592 | OSCWarning("Unterminated { in pattern \".../%s/...\"", theWholePattern); | ||
593 | return FALSE; | ||
594 | } | ||
595 | } | ||
596 | |||
597 | restOfPattern++; /* skip close curly brace */ | ||
598 | |||
599 | |||
600 | pattern++; /* skip open curly brace */ | ||
601 | |||
602 | while (1) { | ||
603 | |||
604 | if (*pattern == ',') { | ||
605 | if (PatternMatch (restOfPattern, tp)) { | ||
606 | return TRUE; | ||
607 | } else { | ||
608 | tp = test; | ||
609 | ++pattern; | ||
610 | } | ||
611 | } else if (*pattern == '}') { | ||
612 | return PatternMatch (restOfPattern, tp); | ||
613 | } else if (*pattern == *tp) { | ||
614 | ++pattern; | ||
615 | ++tp; | ||
616 | } else { | ||
617 | tp = test; | ||
618 | while (*pattern != ',' && *pattern != '}') { | ||
619 | pattern++; | ||
620 | } | ||
621 | if (*pattern == ',') { | ||
622 | pattern++; | ||
623 | } | ||
624 | } | ||
625 | } | ||
626 | |||
627 | } | ||
628 | |||