NEURON
regexp.cpp
Go to the documentation of this file.
1 #include <../../nrnconf.h>
2 /* /local/src/master/nrn/src/oc/regexp.cpp,v 1.1.1.1 1994/10/12 17:22:13 hines Exp */
3 /*
4 regexp.cpp,v
5  * Revision 1.1.1.1 1994/10/12 17:22:13 hines
6  * NEURON 3.0 distribution
7  *
8  * Revision 2.19 93/02/02 10:34:37 hines
9  * static functions declared before used
10  *
11  * Revision 1.3 92/07/31 12:11:31 hines
12  * following merged from hoc
13  * The regular expression has been augmented with
14  * {istart-iend} where istart and iend are integers. The expression matches
15  * any integer that falls in this range.
16  *
17  * Revision 1.2 92/01/30 08:17:19 hines
18  * bug fixes found in hoc incorporated. if()return, no else, objectcenter
19  * warnings.
20  *
21  * Revision 1.1 91/10/11 11:12:16 hines
22  * Initial revision
23  *
24  * Revision 3.108 90/10/24 09:44:14 hines
25  * saber warnings gone
26  *
27  * Revision 3.58 90/05/17 16:30:52 jamie
28  * changed global functions to start with hoc_
29  * moved regexp.cpp from project 'neuron' to 'hoc'
30  *
31  * Revision 1.25 89/08/31 10:28:46 mlh
32  * regular expressions for issection()
33  * differences between standard regular expressions are:
34  * allways match from beginning to end of target (implicit ^ and $)
35  * change [] to <>
36  * eliminate \‍(
37  *
38  * Revision 1.2 89/08/31 09:22:17 mlh
39  * works as in e.cpp and lint free
40  *
41  * Revision 1.1 89/08/31 08:24:59 mlh
42  * Initial revision
43  *
44 */
45 
46 /* regular expression match for section names
47  grabbed prototype from e.cpp
48  Use by first compiling the search string with hoc_regexp_compile(pattern)
49  Then checking target strings one at a time with hoc_regexp_search(target)
50 */
51 
52 #include <stdio.h>
53 #include "hocdec.h"
54 #define CABLESECTION 1
55 /* Always match from beginning of string (implicit ^),
56  Always match end of string (implicit $),
57  change [] to <>,
58  eliminate \‍(
59 */
60 
61 #define STAR 01
62 #define SUFF '.'
63 #define TILDE '~'
64 
65 #define EREGEXP 24
66 #define error(enum) hoc_execerror("search string format error", pattern)
67 #define CBRA 1
68 #define CCHR 2
69 #define CDOT 4
70 #define CCL 6
71 #define NCCL 8
72 #define CDOL 10
73 #define CEOF 11
74 #define CKET 12
75 #if CABLESECTION
76 #define INTRANGE 14
77 #endif
78 #define NBRA 5
79 #define ESIZE 256
80 #define eof '\0'
81 static char expbuf[ESIZE + 4];
82 static char* pattern = "";
83 static char* loc1;
84 static char* loc2;
85 static char* locs;
86 static char* braslist[NBRA];
87 static char* braelist[NBRA];
88 static int circfl;
89 #if CABLESECTION
90 static int int_range_start[NBRA];
91 static int int_range_stop[NBRA];
92 #endif
93 
94 static int advance(char* lp, char* ep);
95 static int hoc_cclass(char* set, char c, int af);
96 
97 void hoc_regexp_compile(const char* pat) {
98  char* cp = (char*) pat;
99  int c;
100  char* ep;
101  char* lastep = 0;
102 #if (!CABLESECTION)
103  char bracket[NBRA], *bracketp;
104  int nbra;
105 #else
106  int int_range_index = 0;
107 #endif
108  int cclcnt;
109  int tempc;
110 
111 
112  if (!cp) {
113  pattern = "";
114  error(EREGEXP);
115  }
116  if (pattern == cp && strcmp(pattern, cp)) {
117  /* if previous pattern != cp then may have been freed */
118  return;
119  }
120  pattern = cp;
121  ep = expbuf;
122 #if (!CABLESECTION)
123  bracketp = bracket;
124  nbra = 0;
125 #endif
126  if ((c = *cp++) == '\n') {
127  cp--;
128  c = eof;
129  }
130  if (c == eof) {
131  if (*ep == 0)
132  error(EREGEXP);
133  return;
134  }
135 #if CABLESECTION
136  circfl = 1;
137 #else
138  circfl = 0;
139  if (c == '^') {
140  c = *cp++;
141  circfl++;
142  }
143 #endif
144  if (c == '*')
145  goto cerror;
146  cp--;
147  for (;;) {
148  if (ep >= &expbuf[ESIZE])
149  goto cerror;
150  c = *cp++;
151  if (c == '\n') {
152  cp--;
153  c = eof;
154  }
155  if (c == eof) {
156 #if CABLESECTION
157  *ep++ = CDOL;
158 #endif
159  *ep++ = CEOF;
160  return;
161  }
162  if (c != '*')
163  lastep = ep;
164  switch (c) {
165  case '\\':
166 #if (!CABLESECTION)
167  if ((c = *cp++) == '(') {
168  if (nbra >= NBRA)
169  goto cerror;
170  *bracketp++ = nbra;
171  *ep++ = CBRA;
172  *ep++ = nbra++;
173  continue;
174  }
175  if (c == ')') {
176  if (bracketp <= bracket)
177  goto cerror;
178  *ep++ = CKET;
179  *ep++ = *--bracketp;
180  continue;
181  }
182 #endif
183  *ep++ = CCHR;
184  if (c == '\n')
185  goto cerror;
186  *ep++ = c;
187  continue;
188 
189  case '.':
190  *ep++ = CDOT;
191  continue;
192 
193  case '\n':
194  goto cerror;
195 
196  case '*':
197  if (*lastep == CBRA || *lastep == CKET)
198  error(EREGEXP);
199  *lastep |= STAR;
200  continue;
201 
202 #if (!CABLESECTION)
203  case '$':
204  tempc = *cp;
205  if (tempc != eof && tempc != '\n')
206  goto defchar;
207  *ep++ = CDOL;
208  continue;
209 #endif
210 
211 #if CABLESECTION
212  case '{': {
213  char* cp1 = cp;
214  if (int_range_index >= NBRA)
215  goto cerror;
216  *ep++ = INTRANGE;
217  do {
218  if (!(*cp >= '0' && *cp <= '9') && *cp != '-') {
219  error(EREGEXP);
220  }
221  } while (*(++cp) != '}');
222  cp++;
223  if (2 != sscanf(cp1,
224  "%d-%d",
225  int_range_start + int_range_index,
226  int_range_stop + int_range_index)) {
227  error(EREGEXP);
228  }
229  *ep++ = int_range_index++;
230  }
231  continue;
232 #endif
233 #if CABLESECTION
234  case '<':
235 #else
236  case '[':
237 #endif
238  *ep++ = CCL;
239  *ep++ = 0;
240  cclcnt = 1;
241  if ((c = *cp++) == '^') {
242  c = *cp++;
243  ep[-2] = NCCL;
244  }
245  do {
246  if (c == '\n')
247  goto cerror;
248  /*
249  * Handle the escaped '-'
250  */
251  if (c == '-' && *(ep - 1) == '\\')
252  *(ep - 1) = '-';
253  /*
254  * Handle ranges of characters (e.g. a-z)
255  */
256  else if ((tempc = *cp++) != ']' && c == '-' && cclcnt > 1 && tempc != '\n' &&
257  (c = *(ep - 1)) <= tempc) {
258  while (++c <= tempc) {
259  *ep++ = c;
260  cclcnt++;
261  if (ep >= &expbuf[ESIZE])
262  goto cerror;
263  }
264  }
265  /*
266  * Normal case. Add character to buffer
267  */
268  else {
269  cp--;
270  *ep++ = c;
271  cclcnt++;
272  if (ep >= &expbuf[ESIZE])
273  goto cerror;
274  }
275 #if CABLESECTION
276  } while ((c = *cp++) != '>');
277 #else
278 
279  } while ((c = *cp++) != ']');
280 #endif
281  lastep[1] = cclcnt;
282  continue;
283 
284 #if (!CABLESECTION)
285  defchar:
286 #endif
287  default:
288  *ep++ = CCHR;
289  *ep++ = c;
290  }
291  }
292 cerror:
293  expbuf[0] = 0;
294  error(EREGEXP);
295 }
296 
297 int hoc_regexp_search(const char* tar) { /*return true if target matches pattern*/
298  char* target = (char*) tar;
299  char *p1, *p2, c;
300 
301 #if 1
302  if (target == (char*) 0) {
303  return (0);
304  }
305  p1 = target;
306  locs = (char*) 0;
307 #else /* in e, apparently for searches within or at begining of string */
308  if (gf) {
309  if (circfl)
310  return (0);
311  p1 = linebuf;
312  p2 = genbuf;
313  while (*p1++ = *p2++)
314  ;
315  locs = p1 = loc2;
316  } else {
317  if (addr == zero)
318  return (0);
319  p1 = getline(*addr);
320  locs = NULL;
321  }
322 #endif
323  p2 = expbuf;
324  if (circfl) {
325  loc1 = p1;
326  return (advance(p1, p2));
327  }
328  /* fast check for first character */
329  if (*p2 == CCHR) {
330  c = p2[1];
331  do {
332  if (*p1 != c)
333  continue;
334  if (advance(p1, p2)) {
335  loc1 = p1;
336  return (1);
337  }
338  } while (*p1++);
339  return (0);
340  }
341  /* regular algorithm */
342  do {
343  if (advance(p1, p2)) {
344  loc1 = p1;
345  return (1);
346  }
347  } while (*p1++);
348  return (0);
349 }
350 
351 static int advance(char* lp, char* ep) {
352  char* curlp;
353 
354  for (;;)
355  switch (*ep++) {
356  case CCHR:
357  if (*ep++ == *lp++)
358  continue;
359  return (0);
360 
361  case CDOT:
362  if (*lp++)
363  continue;
364  return (0);
365 
366  case CDOL:
367  if (*lp == 0)
368  continue;
369  return (0);
370 
371  case CEOF:
372  loc2 = lp;
373  return (1);
374 
375 #if CABLESECTION
376  case INTRANGE: {
377  int start, stop, num;
378  start = int_range_start[*ep];
379  stop = int_range_stop[*ep++];
380  num = *lp++ - '0';
381  if (num < 0 || num > 9) {
382  return (0);
383  }
384  while (*lp >= '0' && *lp <= '9') {
385  num = 10 * num + *lp - '0';
386  ++lp;
387  }
388  if (num >= start && num <= stop) {
389  continue;
390  }
391  }
392  return (0);
393 #endif
394 
395  case CCL:
396  if (hoc_cclass(ep, *lp++, 1)) {
397  ep += *ep;
398  continue;
399  }
400  return (0);
401 
402  case NCCL:
403  if (hoc_cclass(ep, *lp++, 0)) {
404  ep += *ep;
405  continue;
406  }
407  return (0);
408 
409  case CBRA:
410  braslist[*ep++] = lp;
411  continue;
412 
413  case CKET:
414  braelist[*ep++] = lp;
415  continue;
416 
417  case CDOT | STAR:
418  curlp = lp;
419  /*EMPTY*/
420  while (*lp++)
421  ;
422  goto star;
423 
424  case CCHR | STAR:
425  curlp = lp;
426  /*EMPTY*/
427  while (*lp++ == *ep)
428  ;
429  ep++;
430  goto star;
431 
432  case CCL | STAR:
433  case NCCL | STAR:
434  curlp = lp;
435  /*EMPTY*/
436  while (hoc_cclass(ep, *lp++, ep[-1] == (CCL | STAR)))
437  ;
438  ep += *ep;
439  goto star;
440 
441  star:
442  do {
443  lp--;
444  if (lp == locs)
445  break;
446  if (advance(lp, ep))
447  return (1);
448  } while (lp > curlp);
449  return (0);
450 
451  default:
452  error(EREGEXP);
453  }
454 }
455 
456 static int hoc_cclass(char* set, char c, int af) {
457  int n;
458 
459  if (c == 0)
460  return (0);
461  n = *set++;
462  while (--n)
463  if (*set++ == c)
464  return (af);
465  return (!af);
466 }
#define c
int hoc_regexp_search(const char *tar)
Definition: regexp.cpp:297
void hoc_regexp_compile(const char *pat)
Definition: regexp.cpp:97
void start()
Definition: hel2mos.cpp:204
void stop()
Definition: hel2mos.cpp:212
int const size_t const size_t n
Definition: nrngsl.h:11
#define error(enum)
Definition: regexp.cpp:66
static int int_range_stop[NBRA]
Definition: regexp.cpp:91
static int advance(char *lp, char *ep)
Definition: regexp.cpp:351
static int circfl
Definition: regexp.cpp:88
static char * braslist[NBRA]
Definition: regexp.cpp:86
#define NBRA
Definition: regexp.cpp:78
#define CDOL
Definition: regexp.cpp:72
#define eof
Definition: regexp.cpp:80
#define NCCL
Definition: regexp.cpp:71
#define INTRANGE
Definition: regexp.cpp:76
static char * loc2
Definition: regexp.cpp:84
#define CEOF
Definition: regexp.cpp:73
static int int_range_start[NBRA]
Definition: regexp.cpp:90
static char * loc1
Definition: regexp.cpp:83
static char * locs
Definition: regexp.cpp:85
#define STAR
Definition: regexp.cpp:61
#define CCL
Definition: regexp.cpp:70
static int hoc_cclass(char *set, char c, int af)
Definition: regexp.cpp:456
#define CCHR
Definition: regexp.cpp:68
#define EREGEXP
Definition: regexp.cpp:65
#define CBRA
Definition: regexp.cpp:67
#define ESIZE
Definition: regexp.cpp:79
static char * braelist[NBRA]
Definition: regexp.cpp:87
static char expbuf[ESIZE+4]
Definition: regexp.cpp:81
#define CKET
Definition: regexp.cpp:74
static char * pattern
Definition: regexp.cpp:82
#define CDOT
Definition: regexp.cpp:69
#define NULL
Definition: sptree.h:16