1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
7 * with the License.
8 *
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
13 *
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
19 *
20 * CDDL HEADER END
21 */
22 /* Copyright (c) 1988 AT&T */
23 /* All Rights Reserved */
24
25
26 /*
27 * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
28 * Use is subject to license terms.
29 */
30
31 /*LINTLIBRARY*/
32
33 #include <sys/types.h>
34 #include <stdlib.h>
35 #include <unistd.h>
36 #include "utility.h"
37
38 /*
39 * this code was taken from REGCMP(3X)
40 */
41 /*VARARGS*/
42 /*ARGSUSED*/
43
44 #define SSIZE 50
45 #define TGRP 48
46 #define A256 01
47 #define A512 02
48 #define A768 03
49 #define NBRA 10
50 #define CIRCFL 32
51
52 #define CBRA 60
53 #define GRP 40
54 #define SGRP 56
55 #define PGRP 68
56 #define EGRP 44
57 #define RNGE 03
58 #define CCHR 20
59 #define CDOT 64
60 #define CCL 24
61 #define NCCL 8
62 #define CDOL 28
63 #define FCEOF 52 /* This was originally CEOF but it clashes with the header */
64 /* definition so it was changed to FCEOF */
65 #define CKET 12
66
67 #define STAR 01
68 #define PLUS 02
69 #define MINUS 16
70
71 char *__braslist[NBRA];
72 char *__braelist[NBRA];
73 char *__loc1;
74 intptr_t __bravar[NBRA];
75 intptr_t *__st[SSIZE + 1];
76 intptr_t *__eptr_, *__lptr_;
77 intptr_t __cflg;
78
79 char *
80 libform_regex(char *addrc, char *addrl, char *a1)
81 {
82 intptr_t cur, in;
83 intptr_t *adx;
84 char *p1, *p2;
85
86 for (in = 0; in < NBRA; in++) {
87 __braslist[in] = 0;
88 __bravar[in] = -1;
89 }
90 __cflg = 0;
91 cur = __execute(addrc, addrl);
92 adx = (intptr_t *)&a1;
93 for (in = 0; in < NBRA; in++) {
94 if (((p1 = __braslist[in]) != 0) && (__bravar[in] >= 0)) {
95 p2 = (char *)adx[__bravar[in]];
96 while (p1 < __braelist[in]) *p2++ = *p1++;
97 *p2 = '\0';
98 }
99 }
100 if (!__cflg)
101 return ((addrl == (char *)cur) ? (char *)0 : (char *)cur);
102 else
103 return ((char *)cur);
104 }
105
106 intptr_t
107 __execute(char *addrc, char *addrl)
108 {
109 char *p1, *p2, c;
110 intptr_t i;
111
112 p1 = addrl;
113 p2 = addrc;
114 __eptr_ = (intptr_t *)&__st[SSIZE];
115 __lptr_ = (intptr_t *)&__st[0];
116 if (*p2 == CIRCFL) {
117 __loc1 = p1;
118 return ((i = __advance(p1, ++p2)) ? i : (intptr_t)addrl);
119 }
120 /* fast check for first character */
121 if (*p2 == CCHR) {
122 c = p2[1];
123 do {
124 if (*p1 != c)
125 continue;
126 __eptr_ = (intptr_t *)&__st[SSIZE];
127 __lptr_ = (intptr_t *)&__st[0];
128 if (i = __advance(p1, p2)) {
129 __loc1 = p1;
130 return (i);
131 }
132 } while (*p1++);
133 return ((intptr_t)addrl);
134 }
135 /* regular algorithm */
136 do {
137 __eptr_ = (intptr_t *)&__st[SSIZE];
138 __lptr_ = (intptr_t *)&__st[0];
139 if (i = __advance(p1, p2)) {
140 __loc1 = p1;
141 return (i);
142 }
143 } while (*p1++);
144 return ((intptr_t)addrl);
145 }
146
147 intptr_t
148 __advance(char *alp, char *aep)
149 {
150 char *lp, *ep, *curlp;
151 char *sep, *dp;
152 intptr_t i, lcnt, dcnt, gflg;
153
154 lp = alp;
155 ep = aep;
156 gflg = 0;
157 for (; ; ) {
158 switch (*ep++) {
159
160 case CCHR:
161 if (*ep++ == *lp++)
162 continue;
163 return (0);
164
165 case EGRP|RNGE:
166 return ((intptr_t)lp);
167 case EGRP:
168 case GRP:
169 ep++;
170 continue;
171
172 case EGRP|STAR:
173 (void) __xpop(0);
174 /* FALLTHROUGH */
175 case EGRP|PLUS:
176 (void) __xpush(0, ++ep);
177 return ((intptr_t)lp);
178
179 case CDOT:
180 if (*lp++)
181 continue;
182 return (0);
183
184 case CDOL:
185 if (*lp == 0)
186 continue;
187 lp++;
188 return (0);
189
190 case FCEOF:
191 __cflg = 1;
192 return ((intptr_t)lp);
193
194 case TGRP:
195 case TGRP|A768:
196 case TGRP|A512:
197 case TGRP|A256:
198 i = (((ep[-1] & 03) << 8) + (*ep) & 0377);
199 ep++;
200 (void) __xpush(0, ep + i + 2);
201 (void) __xpush(0, ++ep);
202 (void) __xpush(0, ++ep);
203 gflg = 1;
204 (void) __getrnge(&lcnt, &dcnt, &ep[i]);
205 while (lcnt--)
206 if (!(lp = (char *)__advance(lp, ep)))
207 return (0);
208 (void) __xpush(1, curlp = lp);
209 while (dcnt--)
210 if (!(dp = (char *)__advance(lp, ep))) break;
211 else
212 (void) __xpush(1, lp = dp);
213 ep = (char *)__xpop(0);
214 goto star;
215 case CCHR|RNGE:
216 sep = ep++;
217 (void) __getrnge(&lcnt, &dcnt, ep);
218 while (lcnt--)
219 if (*lp++ != *sep)
220 return (0);
221 curlp = lp;
222 while (dcnt--)
223 if (*lp++ != *sep) break;
224 if (dcnt < 0) lp++;
225 ep += 2;
226 goto star;
227 case CDOT|RNGE:
228 (void) __getrnge(&lcnt, &dcnt, ep);
229 while (lcnt--)
230 if (*lp++ == '\0')
231 return (0);
232 curlp = lp;
233 while (dcnt--)
234 if (*lp++ == '\0') break;
235 if (dcnt < 0) lp++;
236 ep += 2;
237 goto star;
238 case CCL|RNGE:
239 case NCCL|RNGE:
240 (void) __getrnge(&lcnt, &dcnt, (ep + (*ep & 0377)));
241 while (lcnt--)
242 if (!__cclass(ep, *lp++, ep[-1] == (CCL | RNGE)))
243 return (0);
244 curlp = lp;
245 while (dcnt--)
246 if (!__cclass(ep, *lp++, ep[-1] == (CCL|RNGE)))
247 break;
248 if (dcnt < 0) lp++;
249 ep += (*ep + 2);
250 goto star;
251 case CCL:
252 if (__cclass(ep, *lp++, 1)) {
253 ep += *ep;
254 continue;
255 }
256 return (0);
257
258 case NCCL:
259 if (__cclass(ep, *lp++, 0)) {
260 ep += *ep;
261 continue;
262 }
263 return (0);
264
265 case CBRA:
266 __braslist[*ep++] = lp;
267 continue;
268
269 case CKET:
270 __braelist[*ep] = lp;
271 __bravar[*ep] = ep[1];
272 ep += 2;
273 continue;
274
275 case CDOT|PLUS:
276 if (*lp++ == '\0')
277 return (0);
278 /* FALLTHROUGH */
279 case CDOT|STAR:
280 curlp = lp;
281 while (*lp++)
282 ;
283 goto star;
284
285 case CCHR|PLUS:
286 if (*lp++ != *ep)
287 return (0);
288 /* FALLTHROUGH */
289 case CCHR|STAR:
290 curlp = lp;
291 while (*lp++ == *ep)
292 ;
293 ep++;
294 goto star;
295
296 case PGRP:
297 case PGRP|A256:
298 case PGRP|A512:
299 case PGRP|A768:
300 if (!(lp = (char *)__advance(lp, ep+1)))
301 return (0);
302 /* FALLTHROUGH */
303 case SGRP|A768:
304 case SGRP|A512:
305 case SGRP|A256:
306 case SGRP:
307 i = (((ep[-1]&03) << 8) + (*ep & 0377));
308 ep++;
309 (void) __xpush(0, ep + i);
310 (void) __xpush(1, curlp = lp);
311 while (i = __advance(lp, ep))
312 (void) __xpush(1, lp = (char *)i);
313 ep = (char *)__xpop(0);
314 gflg = 1;
315 goto star;
316
317 case CCL|PLUS:
318 case NCCL|PLUS:
319 if (!__cclass(ep, *lp++, ep[-1] == (CCL | PLUS)))
320 return (0);
321 /* FALLTHROUGH */
322 case CCL|STAR:
323 case NCCL|STAR:
324 curlp = lp;
325 while (__cclass(ep, *lp++, ((ep[-1] == (CCL | STAR)) ||
326 (ep[-1] == (CCL | PLUS)))))
327 ;
328 ep += *ep;
329 goto star;
330
331 star:
332 do {
333 if (!gflg) lp--;
334 else if (!(lp = (char *)__xpop(1))) break;
335 if (i = __advance(lp, ep))
336 return (i);
337 } while (lp > curlp);
338 return (0);
339
340 default:
341 return (0);
342 }
343 }
344 }
345
346 intptr_t
347 __cclass(char *aset, char ac, intptr_t af)
348 {
349 char *set, c;
350 intptr_t n;
351
352 set = (char *)aset;
353 if ((c = ac) == 0)
354 return (0);
355 n = *set++;
356 while (--n) {
357 if (*set == MINUS) {
358 if ((set[2] - set[1]) < 0)
359 return (0);
360 if (*++set <= c) {
361 if (c <= *++set)
362 return (af);
363 } else
364 ++set;
365 ++set;
366 n -= 2;
367 continue;
368 }
369 if (*set++ == c)
370 return (af);
371 }
372 return (!af);
373 }
374
375 intptr_t
376 __xpush(intptr_t i, char *p)
377 {
378 if (__lptr_ >= __eptr_) {
379 (void) write(2, "stack overflow\n", 15);
380 (void) exit(1);
381 }
382 if (i)
383 *__lptr_++ = (intptr_t)p;
384 else
385 *__eptr_-- = (intptr_t)p;
386 return (1);
387 }
388
389 intptr_t
390 __xpop(intptr_t i)
391 {
392 if (i)
393 return ((__lptr_ < (intptr_t *)&__st[0]) ? 0 : *--__lptr_);
394 else
395 return ((__eptr_ > (intptr_t *)&__st[SSIZE]) ? 0 : *++__eptr_);
396 }
397
398 intptr_t
399 __getrnge(intptr_t *i, intptr_t *j, char *k)
400 {
401 *i = (*k++&0377);
402 if (*k == (char)-1)
403 *j = 20000;
404 else
405 *j = ((*k&0377) - *i);
406 return (1);
407 }