ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/common/rexpr.c
Revision: 2.9
Committed: Thu Jul 17 09:21:29 2003 UTC (20 years, 8 months ago) by schorsch
Content type: text/plain
Branch: MAIN
CVS Tags: rad5R2, rad4R2P2, rad5R0, rad5R1, rad3R7P2, rad3R7P1, rad4R2, rad4R1, rad4R0, rad3R6, rad3R6P1, rad3R8, rad3R9, rad4R2P1
Changes since 2.8: +10 -7 lines
Log Message:
Added prototypes and includes from patch by Randolph Fritz.
Added more required includes and reduced other compile warnings.

File Contents

# Content
1 #ifndef lint
2 static const char RCSid[] = "$Id: rexpr.c,v 2.8 2003/06/30 14:59:11 schorsch Exp $";
3 #endif
4 /*
5 * Regular expression parsing routines.
6 *
7 * External symbols declared in standard.h
8 */
9
10 #include "copyright.h"
11
12 #include <stdio.h>
13 #include <stdlib.h>
14 #include <ctype.h>
15 #include <string.h>
16
17 #include "rtio.h"
18
19 /*
20 * rexpr.c - regular expression parser (ala grep)
21 */
22
23 #define CCHR 2
24 #define CDOT 4
25 #define CCL 6
26 #define NCCL 8
27 #define CDOL 10
28 #define CEOF 11
29 #define CBRC 14
30 #define CLET 15
31 #define STAR 01
32
33 #define ESIZE 255
34
35 #define same(a,b) (a==b || (iflag && (a^b)==' ' && isalpha(a)))
36
37
38 static int advance(char *, char *);
39 static int cclass(char *, int c, int af);
40
41 static char expbuf[ESIZE];
42 static int iflag;
43 static int circf;
44
45 int explen; /* length of the last expression found */
46
47 int
48 ecompile(sp, iflg, wflag) /* compile the expression */
49 register char *sp;
50 int iflg, wflag;
51 {
52 register int c;
53 register char *ep;
54 char *lastep = NULL;
55 int cclcnt;
56
57 iflag = iflg;
58 ep = expbuf;
59 explen = 0;
60 if (*sp == '^') {
61 circf = 1;
62 sp++;
63 } else
64 circf = 0;
65 if (wflag)
66 *ep++ = CBRC;
67 for (;;) {
68 if (ep >= &expbuf[ESIZE])
69 return(-1);
70 if ((c = *sp++) != '*')
71 lastep = ep;
72 switch (c) {
73
74 case '\0':
75 if (wflag)
76 *ep++ = CLET;
77 *ep++ = CEOF;
78 explen = ep - expbuf;
79 return(0);
80
81 case '.':
82 *ep++ = CDOT;
83 continue;
84
85 case '*':
86 if (lastep==0)
87 goto defchar;
88 *lastep |= STAR;
89 continue;
90
91 case '$':
92 if (*sp != '\0')
93 goto defchar;
94 *ep++ = CDOL;
95 continue;
96
97 case '[':
98 *ep++ = CCL;
99 *ep++ = 0;
100 cclcnt = 1;
101 if ((c = *sp++) == '^') {
102 c = *sp++;
103 ep[-2] = NCCL;
104 }
105 do {
106 *ep++ = c;
107 cclcnt++;
108 if (c=='\0' || ep >= &expbuf[ESIZE])
109 return(-1);
110 } while ((c = *sp++) != ']');
111 lastep[1] = cclcnt;
112 continue;
113
114 case '\\':
115 if ((c = *sp++) == '\0')
116 return(-1);
117 if (c == '<') {
118 if (ep == expbuf || ep[-1] != CBRC)
119 *ep++ = CBRC;
120 continue;
121 }
122 if (c == '>') {
123 *ep++ = CLET;
124 continue;
125 }
126 defchar:
127 default:
128 *ep++ = CCHR;
129 *ep++ = c;
130 }
131 }
132 }
133
134 char *
135 expsave() /* save compiled string */
136 {
137 register char *ep;
138
139 if (explen == 0)
140 return(NULL);
141 if ((ep = (char *)malloc(explen+3)) == NULL)
142 return(NULL);
143 ep[0] = iflag;
144 ep[1] = circf;
145 ep[2] = explen;
146 (void)memcpy(ep+3, expbuf, explen);
147 return(ep);
148 }
149
150 void
151 expset(ep) /* install saved string */
152 register char *ep;
153 {
154 iflag = ep[0];
155 circf = ep[1];
156 (void)memcpy(expbuf, ep+3, ep[2]&0xff);
157 }
158
159 char *
160 eindex(sp) /* find the expression in string sp */
161 register char *sp;
162 {
163 /* check for match at beginning of line, watch CBRC */
164 if (advance(sp, expbuf[0]==CBRC ? expbuf+1 : expbuf))
165 return(sp);
166 if (circf)
167 return(NULL);
168 /* fast check for first character */
169 if (expbuf[0]==CCHR) {
170 register int c = expbuf[1];
171 while (*++sp)
172 if (same(*sp, c) && advance(sp, expbuf))
173 return(sp);
174 return(NULL);
175 }
176 /* regular algorithm */
177 while (*++sp)
178 if (advance(sp, expbuf))
179 return(sp);
180 return(NULL);
181 }
182
183 static int
184 advance(alp, ep)
185 char *alp;
186 register char *ep;
187 {
188 register char *lp;
189 char *curlp;
190
191 lp = alp;
192 for (;;) switch (*ep++) {
193
194 case CCHR:
195 if (!same(*ep, *lp))
196 return (0);
197 ep++, lp++;
198 continue;
199
200 case CDOT:
201 if (*lp++)
202 continue;
203 return(0);
204
205 case CDOL:
206 if (*lp==0)
207 continue;
208 return(0);
209
210 case CEOF:
211 explen = lp - alp;
212 return(1);
213
214 case CCL:
215 if (cclass(ep, *lp++, 1)) {
216 ep += *ep;
217 continue;
218 }
219 return(0);
220
221 case NCCL:
222 if (cclass(ep, *lp++, 0)) {
223 ep += *ep;
224 continue;
225 }
226 return(0);
227
228 case CDOT|STAR:
229 curlp = lp;
230 while (*lp++);
231 goto star;
232
233 case CCHR|STAR:
234 curlp = lp;
235 while (same(*lp, *ep))
236 lp++;
237 lp++;
238 ep++;
239 goto star;
240
241 case CCL|STAR:
242 case NCCL|STAR:
243 curlp = lp;
244 while (cclass(ep, *lp++, ep[-1]==(CCL|STAR)));
245 ep += *ep;
246 star:
247 do {
248 lp--;
249 if (advance(lp, ep)) {
250 explen += lp - alp;
251 return(1);
252 }
253 } while (lp > curlp);
254 return(0);
255
256 case CBRC:
257 if ((isalnum(*lp) || *lp == '_') && !(isalnum(lp[-1]) || lp[-1] == '_'))
258 continue;
259 return (0);
260
261 case CLET:
262 if (!isalnum(*lp) && *lp != '_')
263 continue;
264 return (0);
265
266 default:
267 fprintf(stderr, "RE botch\n");
268 }
269 }
270
271 static int
272 cclass(set, c, af)
273 register char *set;
274 register int c;
275 int af;
276 {
277 register int n;
278
279 if (c == 0)
280 return(0);
281 n = *set++;
282 while (--n)
283 if (n > 2 && set[1] == '-') {
284 if (c >= set[0] && c <= set[2])
285 return (af);
286 set += 3;
287 n -= 2;
288 } else
289 if (*set++ == c)
290 return(af);
291 return(!af);
292 }