ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/common/rexpr.c
Revision: 1.4
Committed: Mon Oct 28 09:47:25 1991 UTC (32 years, 6 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 1.3: +2 -0 lines
Log Message:
compatibility fixes for SGI libraries

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