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