ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/common/rexpr.c
Revision: 2.6
Committed: Tue May 13 17:58:32 2003 UTC (20 years, 11 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.5: +0 -0 lines
Log Message:
Changed (char *) casts for memory copies to (void *) and other fixes

File Contents

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