ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/common/rexpr.c
Revision: 1.2
Committed: Tue Jul 16 10:51:42 1991 UTC (32 years, 9 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 1.1: +4 -0 lines
Log Message:
added define for BSD bcopy

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