xref: /illumos-gate/usr/src/lib/libeti/form/common/regex.c (revision 2a613b5974ae49c8b068a3998ff554f8c6f0f593)
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 }
408