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
73char	*__braslist[NBRA];
74char	*__braelist[NBRA];
75char	*__loc1;
76intptr_t	__bravar[NBRA];
77intptr_t	*__st[SSIZE + 1];
78intptr_t	*__eptr_, *__lptr_;
79intptr_t	__cflg;
80
81char *
82libform_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
108intptr_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
149intptr_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
340intptr_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
369intptr_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
383intptr_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
392intptr_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