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

# 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     *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 greg 1.3 if (lp == alp)
251 greg 1.1 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     }