ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/common/rexpr.c
Revision: 2.10
Committed: Sat Dec 28 18:05:14 2019 UTC (4 years, 4 months ago) by greg
Content type: text/plain
Branch: MAIN
CVS Tags: rad5R4, rad5R3, HEAD
Changes since 2.9: +1 -3 lines
Log Message:
Removed redundant include files

File Contents

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