class library: SynthDef - lazy implementation of removeUGen
[supercollider.git] / include / lang / PyrSymbol.h
blob5be6af8d565822473b3e1e5e88fed1886acb927a
1 /*
2 SuperCollider real time audio synthesis system
3 Copyright (c) 2002 James McCartney. All rights reserved.
4 http://www.audiosynth.com
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 A PyrSymbol is a unique string that resides in a global hash table.
26 #ifndef _PYRSYMBOL_H_
27 #define _PYRSYMBOL_H_
29 #include "SC_Types.h"
31 struct PyrSymbol {
32 char *name;
33 long hash;
34 short specialIndex;
35 uint8 flags;
36 uint8 length;
37 union {
38 long index; // index in row table or primitive table
39 struct PyrClass *classobj; // pointer to class with this name.
40 char *source; // source code for sym_Filename; used only during compilation.
41 } u;
42 struct classdep *classdep;
45 enum {
46 sym_Selector = 1,
47 sym_Class = 2,
48 sym_Compiled = 4,
49 sym_Called = 8,
50 sym_Primitive = 16,
51 sym_Setter = 32,
52 sym_MetaClass = 64,
53 sym_Filename = 128
56 // following function lifted from liblo: http://sourceforge.net/projects/liblo/
58 /* Open SoundControl kit in C++ */
59 /* Copyright (C) 2002-2004 libOSC++ contributors. See AUTHORS */
60 /* */
61 /* This library is free software; you can redistribute it and/or */
62 /* modify it under the terms of the GNU Lesser General Public */
63 /* License as published by the Free Software Foundation; either */
64 /* version 2.1 of the License, or (at your option) any later version. */
65 /* */
66 /* This library is distributed in the hope that it will be useful, */
67 /* but WITHOUT ANY WARRANTY; without even the implied warranty of */
68 /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
69 /* Lesser General Public License for more details. */
70 /* */
71 /* You should have received a copy of the GNU Lesser General Public */
72 /* License along with this library; if not, write to the Free Software */
73 /* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
74 /* */
75 /* For questions regarding this program contact */
76 /* Daniel Holth <dholth@fastmail.fm> or visit */
77 /* http://wiretap.stetson.edu/ */
79 /* In the sprit of the public domain, my modifications to this file are also */
80 /* dedicated to the public domain. Daniel Holth, Oct. 2004 */
82 /* ChangeLog:
84 * 2004-10-29 Import, convert to C++, begin OSC syntax changes. -dwh
85 * OSC syntax changes are now working, needs more testing.
89 // Original header and syntax:
92 * robust glob pattern matcher
93 * ozan s. yigit/dec 1994
94 * public domain
96 * glob patterns:
97 * * matches zero or more characters
98 * ? matches any single character
99 * [set] matches any character in the set
100 * [^set] matches any character NOT in the set
101 * where a set is a group of characters or ranges. a range
102 * is written as two characters seperated with a hyphen: a-z denotes
103 * all characters between a to z inclusive.
104 * [-set] set matches a literal hypen and any character in the set
105 * []set] matches a literal close bracket and any character in the set
107 * char matches itself except where char is '*' or '?' or '['
108 * \char matches char, including any pattern character
110 * examples:
111 * a*c ac abc abbc ...
112 * a?c acc abc aXc ...
113 * a[a-z]c aac abc acc ...
114 * a[-a-z]c a-c aac abc ...
116 * $Log$
117 * Revision 1.1 2004/11/19 23:00:57 theno23
118 * Added lo_send_timestamped
120 * Revision 1.3 1995/09/14 23:24:23 oz
121 * removed boring test/main code.
123 * Revision 1.2 94/12/11 10:38:15 oz
124 * cset code fixed. it is now robust and interprets all
125 * variations of cset [i think] correctly, including [z-a] etc.
127 * Revision 1.1 94/12/08 12:45:23 oz
128 * Initial revision
132 #ifndef lo_NEGATE
133 #define lo_NEGATE '!'
134 #endif
136 #ifndef lo_true
137 #define lo_true 1
138 #endif
139 #ifndef lo_false
140 #define lo_false 0
141 #endif
143 inline int lo_pattern_match(const char *str, const char *p)
145 int negate;
146 int match;
147 char c;
149 while (*p) {
150 if (!*str && *p != '*')
151 return lo_false;
153 switch (c = *p++) {
155 case '*':
156 while (*p == '*' && *p != '/')
157 p++;
159 if (!*p)
160 return lo_true;
162 // if (*p != '?' && *p != '[' && *p != '\\')
163 if (*p != '?' && *p != '[' && *p != '{')
164 while (*str && *p != *str)
165 str++;
167 while (*str) {
168 if (lo_pattern_match(str, p))
169 return lo_true;
170 str++;
172 return lo_false;
174 case '?':
175 if (*str)
176 break;
177 return lo_false;
179 * set specification is inclusive, that is [a-z] is a, z and
180 * everything in between. this means [z-a] may be interpreted
181 * as a set that contains z, a and nothing in between.
183 case '[':
184 if (*p != lo_NEGATE)
185 negate = lo_false;
186 else {
187 negate = lo_true;
188 p++;
191 match = lo_false;
193 while (!match && (c = *p++)) {
194 if (!*p)
195 return lo_false;
196 if (*p == '-') { /* c-c */
197 if (!*++p)
198 return lo_false;
199 if (*p != ']') {
200 if (*str == c || *str == *p ||
201 (*str > c && *str < *p))
202 match = lo_true;
203 } else { /* c-] */
204 if (*str >= c)
205 match = lo_true;
206 break;
208 } else { /* cc or c] */
209 if (c == *str)
210 match = lo_true;
211 if (*p != ']') {
212 if (*p == *str)
213 match = lo_true;
214 } else
215 break;
219 if (negate == match)
220 return lo_false;
222 * if there is a match, skip past the cset and continue on
224 while (*p && *p != ']')
225 p++;
226 if (!*p++) /* oops! */
227 return lo_false;
228 break;
231 * {astring,bstring,cstring}
233 case '{':
235 // *p is now first character in the {brace list}
236 const char *place = str; // to backtrack
237 const char *remainder = p; // to forwardtrack
239 // find the end of the brace list
240 while (*remainder && *remainder != '}')
241 remainder++;
242 if (!*remainder++) /* oops! */
243 return lo_false;
245 c = *p++;
247 while (c) {
248 if (c == ',') {
249 if (lo_pattern_match(str, remainder)) {
250 return lo_true;
251 } else {
252 // backtrack on test string
253 str = place;
254 // continue testing,
255 // skip comma
256 if (!*p++) // oops
257 return lo_false;
259 } else if (c == '}') {
260 // continue normal pattern matching
261 if (!*p && !*str)
262 return lo_true;
263 str--; // str is incremented again below
264 break;
265 } else if (c == *str) {
266 str++;
267 if (!*str && *remainder)
268 return lo_false;
269 } else { // skip to next comma
270 str = place;
271 while (*p != ',' && *p != '}' && *p)
272 p++;
273 if (*p == ',')
274 p++;
275 else if (*p == '}') {
276 return lo_false;
279 c = *p++;
283 break;
285 /* Not part of OSC pattern matching
286 case '\\':
287 if (*p)
288 c = *p++;
291 default:
292 if (c != *str)
293 return lo_false;
294 break;
297 str++;
300 return !*str;
303 #endif