ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/common/rexpr.c
Revision: 2.3
Committed: Thu Nov 18 09:27:03 1993 UTC (30 years, 5 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.2: +1 -0 lines
Log Message:
minor compiler warning fixes

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 greg 1.2 #ifdef BSD
28     #define memcpy(to,from,len) bcopy(from,to,len)
29     #endif
30    
31 greg 1.4 static int advance(), cclass();
32    
33 greg 1.1 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 greg 2.2 if (ep == expbuf || ep[-1] != CBRC)
111     *ep++ = CBRC;
112 greg 1.1 continue;
113     }
114     if (c == '>') {
115     *ep++ = CLET;
116     continue;
117     }
118     defchar:
119     default:
120     *ep++ = CCHR;
121     *ep++ = c;
122     }
123     }
124     }
125    
126     char *
127     expsave() /* save compiled string */
128     {
129     extern char *malloc();
130     register char *ep;
131    
132     if (explen == 0)
133     return(NULL);
134     if ((ep = malloc(explen+3)) == NULL)
135     return(NULL);
136     ep[0] = iflag;
137     ep[1] = circf;
138     ep[2] = explen;
139     (void)memcpy(ep+3, expbuf, explen);
140     return(ep);
141     }
142    
143     expset(ep) /* install saved string */
144     register char *ep;
145     {
146     iflag = ep[0];
147     circf = ep[1];
148     (void)memcpy(expbuf, ep+3, ep[2]&0xff);
149     }
150    
151     char *
152 greg 2.2 eindex(sp) /* find the expression in string sp */
153 greg 1.1 register char *sp;
154     {
155 greg 2.2 /* check for match at beginning of line, watch CBRC */
156     if (advance(sp, expbuf[0]==CBRC ? expbuf+1 : expbuf))
157     return(sp);
158     if (circf)
159 greg 1.1 return(NULL);
160     /* fast check for first character */
161     if (expbuf[0]==CCHR) {
162     register c = expbuf[1];
163 greg 2.2 while (*++sp)
164 greg 1.1 if (same(*sp, c) && advance(sp, expbuf))
165     return(sp);
166     return(NULL);
167     }
168     /* regular algorithm */
169 greg 2.2 while (*++sp)
170 greg 1.1 if (advance(sp, expbuf))
171     return(sp);
172     return(NULL);
173     }
174    
175     static int
176     advance(alp, ep)
177     char *alp;
178     register char *ep;
179     {
180     register char *lp;
181     char *curlp;
182    
183     lp = alp;
184     for (;;) switch (*ep++) {
185    
186     case CCHR:
187     if (!same(*ep, *lp))
188     return (0);
189     ep++, lp++;
190     continue;
191    
192     case CDOT:
193     if (*lp++)
194     continue;
195     return(0);
196    
197     case CDOL:
198     if (*lp==0)
199     continue;
200     return(0);
201    
202     case CEOF:
203     explen = lp - alp;
204     return(1);
205    
206     case CCL:
207     if (cclass(ep, *lp++, 1)) {
208     ep += *ep;
209     continue;
210     }
211     return(0);
212    
213     case NCCL:
214     if (cclass(ep, *lp++, 0)) {
215     ep += *ep;
216     continue;
217     }
218     return(0);
219    
220     case CDOT|STAR:
221     curlp = lp;
222     while (*lp++);
223     goto star;
224    
225     case CCHR|STAR:
226     curlp = lp;
227     while (same(*lp, *ep))
228     lp++;
229     lp++;
230     ep++;
231     goto star;
232    
233     case CCL|STAR:
234     case NCCL|STAR:
235     curlp = lp;
236     while (cclass(ep, *lp++, ep[-1]==(CCL|STAR)));
237     ep += *ep;
238     star:
239     do {
240     lp--;
241     if (advance(lp, ep)) {
242     explen += lp - alp;
243     return(1);
244     }
245     } while (lp > curlp);
246     return(0);
247    
248     case CBRC:
249     if ((isalnum(*lp) || *lp == '_') && !(isalnum(lp[-1]) || lp[-1] == '_'))
250     continue;
251     return (0);
252    
253     case CLET:
254     if (!isalnum(*lp) && *lp != '_')
255     continue;
256     return (0);
257    
258     default:
259     fprintf(stderr, "RE botch\n");
260     }
261     }
262    
263     static int
264     cclass(set, c, af)
265     register char *set;
266     register c;
267 greg 2.3 int af;
268 greg 1.1 {
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     }