ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/common/rexpr.c
Revision: 2.8
Committed: Mon Jun 30 14:59:11 2003 UTC (20 years, 10 months ago) by schorsch
Content type: text/plain
Branch: MAIN
Changes since 2.7: +1 -4 lines
Log Message:
Replaced most outdated BSD function calls with their posix equivalents, and cleaned up a few other platform dependencies.

File Contents

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