ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/common/rexpr.c
Revision: 1.1
Committed: Sat Dec 8 09:28:17 1990 UTC (33 years, 5 months ago) by greg
Content type: text/plain
Branch: MAIN
Log Message:
Initial revision

File Contents

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