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

# User Rev Content
1 greg 1.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     }