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 
166  case '\\':
167 #if (!CABLESECTION)
168  if ((c = *cp++)=='(') {
169  if (nbra >= NBRA)
170  goto cerror;
171  *bracketp++ = nbra;
172  *ep++ = CBRA;
173  *ep++ = nbra++;
174  continue;
175  }
176  if (c == ')') {
177  if (bracketp <= bracket)
178  goto cerror;
179  *ep++ = CKET;
180  *ep++ = *--bracketp;
181  continue;
182  }
183 #endif
184  *ep++ = CCHR;
185  if (c=='\n')
186  goto cerror;
187  *ep++ = c;
188  continue;
189 
190  case '.':
191  *ep++ = CDOT;
192  continue;
193 
194  case '\n':
195  goto cerror;
196 
197  case '*':
198  if (*lastep==CBRA || *lastep==CKET)
199  error(EREGEXP);
200  *lastep |= STAR;
201  continue;
202 
203 #if (!CABLESECTION)
204  case '$':
205  tempc = *cp;
206  if (tempc != eof && tempc != '\n')
207  goto defchar;
208  *ep++ = CDOL;
209  continue;
210 #endif
211 
212 #if CABLESECTION
213  case '{':
214  { char* cp1 = cp;
215  if (int_range_index >= NBRA)
216  goto cerror;
217  *ep++ = INTRANGE;
218  do {
219  if (!(*cp >= '0' && *cp <= '9') && *cp != '-') {
220  error(EREGEXP);
221  }
222  }while (*(++cp) != '}');
223  cp++;
224  if (2 != sscanf(cp1, "%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 (
257  (tempc = *cp++) != ']' &&
258  c == '-' && cclcnt > 1 &&
259  tempc != '\n' &&
260  (c = *(ep-1)) <= tempc
261  ) {
262  while (++c <= tempc) {
263  *ep++ = c;
264  cclcnt++;
265  if (ep >= &expbuf[ESIZE])
266  goto cerror;
267  }
268  }
269 /*
270  * Normal case. Add character to buffer
271  */
272  else {
273  cp--;
274  *ep++ = c;
275  cclcnt++;
276  if (ep >= &expbuf[ESIZE])
277  goto cerror;
278  }
279 #if CABLESECTION
280  } while ((c = *cp++) != '>');
281 #else
282 
283  } while ((c = *cp++) != ']');
284 #endif
285  lastep[1] = cclcnt;
286  continue;
287 
288 #if (!CABLESECTION)
289  defchar:
290 #endif
291  default:
292  *ep++ = CCHR;
293  *ep++ = c;
294  }
295  }
296  cerror:
297  expbuf[0] = 0;
298  error(EREGEXP);
299 }
300 
301 int
302 hoc_regexp_search(const char* tar) { /*return true if target matches pattern*/
303  char *target = (char*)tar;
304  char *p1, *p2, c;
305 
306 #if 1
307  if (target == (char *)0) {
308  return(0);
309  }
310  p1 = target;
311  locs = (char *)0;
312 #else /* in e, apparently for searches within or at begining of string */
313  if (gf) {
314  if (circfl)
315  return(0);
316  p1 = linebuf;
317  p2 = genbuf;
318  while (*p1++ = *p2++);
319  locs = p1 = loc2;
320  } else {
321  if (addr==zero)
322  return(0);
323  p1 = getline(*addr);
324  locs = NULL;
325  }
326 #endif
327  p2 = expbuf;
328  if (circfl) {
329  loc1 = p1;
330  return(advance(p1, p2));
331  }
332  /* fast check for first character */
333  if (*p2==CCHR) {
334  c = p2[1];
335  do {
336  if (*p1!=c)
337  continue;
338  if (advance(p1, p2)) {
339  loc1 = p1;
340  return(1);
341  }
342  } while (*p1++);
343  return(0);
344  }
345  /* regular algorithm */
346  do {
347  if (advance(p1, p2)) {
348  loc1 = p1;
349  return(1);
350  }
351  } while (*p1++);
352  return(0);
353 }
354 
355 static int advance(char* lp, char* ep)
356 {
357  char *curlp;
358 
359  for (;;) switch (*ep++) {
360 
361  case CCHR:
362  if (*ep++ == *lp++)
363  continue;
364  return(0);
365 
366  case CDOT:
367  if (*lp++)
368  continue;
369  return(0);
370 
371  case CDOL:
372  if (*lp==0)
373  continue;
374  return(0);
375 
376  case CEOF:
377  loc2 = lp;
378  return(1);
379 
380 #if CABLESECTION
381  case INTRANGE:
382  { int start, stop, num;
383  start = int_range_start[*ep];
384  stop = int_range_stop[*ep++];
385  num = *lp++ - '0';
386  if (num < 0 || num > 9) {
387  return(0);
388  }
389  while(*lp >= '0' && *lp <= '9') {
390  num = 10*num + *lp - '0';
391  ++lp;
392  }
393  if (num >= start && num <= stop) {
394  continue;
395  }
396  }
397  return(0);
398 #endif
399 
400  case CCL:
401  if (hoc_cclass(ep, *lp++, 1)) {
402  ep += *ep;
403  continue;
404  }
405  return(0);
406 
407  case NCCL:
408  if (hoc_cclass(ep, *lp++, 0)) {
409  ep += *ep;
410  continue;
411  }
412  return(0);
413 
414  case CBRA:
415  braslist[*ep++] = lp;
416  continue;
417 
418  case CKET:
419  braelist[*ep++] = lp;
420  continue;
421 
422  case CDOT|STAR:
423  curlp = lp;
424  /*EMPTY*/
425  while (*lp++);
426  goto star;
427 
428  case CCHR|STAR:
429  curlp = lp;
430  /*EMPTY*/
431  while (*lp++ == *ep);
432  ep++;
433  goto star;
434 
435  case CCL|STAR:
436  case NCCL|STAR:
437  curlp = lp;
438  /*EMPTY*/
439  while (hoc_cclass(ep, *lp++, ep[-1]==(CCL|STAR)));
440  ep += *ep;
441  goto star;
442 
443  star:
444  do {
445  lp--;
446  if (lp==locs)
447  break;
448  if (advance(lp, ep))
449  return(1);
450  } while (lp > curlp);
451  return(0);
452 
453  default:
454  error(EREGEXP);
455  }
456 }
457 
458 static int hoc_cclass(char* set, char c, int af)
459 {
460  int n;
461 
462  if (c == 0)
463  return(0);
464  n = *set++;
465  while (--n)
466  if (*set++ == c)
467  return(af);
468  return(!af);
469 }
470 
471 
static char * locs
Definition: regexp.cpp:85
#define NBRA
Definition: regexp.cpp:78
static char * braslist[NBRA]
Definition: regexp.cpp:86
static char * loc1
Definition: regexp.cpp:83
#define NCCL
Definition: regexp.cpp:71
static char * pattern
Definition: regexp.cpp:82
int hoc_regexp_search(const char *tar)
Definition: regexp.cpp:302
#define CCL
Definition: regexp.cpp:70
static int circfl
Definition: regexp.cpp:88
static int int_range_start[NBRA]
Definition: regexp.cpp:90
#define CCHR
Definition: regexp.cpp:68
#define CEOF
Definition: regexp.cpp:73
void start()
Definition: hel2mos.cpp:205
static char * loc2
Definition: regexp.cpp:84
static int int_range_stop[NBRA]
Definition: regexp.cpp:91
int const size_t const size_t n
Definition: nrngsl.h:12
static char expbuf[ESIZE+4]
Definition: regexp.cpp:81
void stop()
Definition: hel2mos.cpp:209
#define error(enum)
Definition: regexp.cpp:66
#define EREGEXP
Definition: regexp.cpp:65
static int advance(char *lp, char *ep)
Definition: regexp.cpp:355
static int hoc_cclass(char *set, char c, int af)
Definition: regexp.cpp:458
#define STAR
Definition: regexp.cpp:61
#define CDOL
Definition: regexp.cpp:72
#define ESIZE
Definition: regexp.cpp:79
#define c
#define eof
Definition: regexp.cpp:80
#define CKET
Definition: regexp.cpp:74
#define CDOT
Definition: regexp.cpp:69
void hoc_regexp_compile(const char *pat)
Definition: regexp.cpp:97
return NULL
Definition: cabcode.cpp:461
#define INTRANGE
Definition: regexp.cpp:76
static char * braelist[NBRA]
Definition: regexp.cpp:87
#define CBRA
Definition: regexp.cpp:67