ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/common/rexpr.c
Revision: 1.3
Committed: Thu Sep 5 15:03:48 1991 UTC (32 years, 8 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 1.2: +1 -1 lines
Log Message:
fixed bug in \< match to beginning of line

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.1 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 greg 1.3 if (lp == alp)
249 greg 1.1 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     }