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"	/* SVr4.0 1.2	*/
32
33/*LINTLIBRARY*/
34
35#include <sys/types.h>
36#include <stdlib.h>
37#include "utility.h"
38
39/* this code was taken from REGCMP(3X) */
40
41#define	SSIZE	16
42#define	TGRP	48
43#define	A256	02
44#define	ZERO	01
45#define	NBRA	10
46#define	CIRCFL	32;
47#define	SLOP	5
48#define	FEOF	0 /* This was originally EOF but it clashes with the header */
49			/* definition so it was changed to FEOF */
50
51#define	CBRA	60
52#define	GRP	40
53#define	SGRP	56
54#define	PGRP	68
55#define	EGRP	44
56#define	RNGE	03
57#define	CCHR	20
58#define	CDOT	64
59#define	CCL	24
60#define	NCCL	8
61#define	CDOL	28
62#define	FCEOF	52 /* This was originally CEOF but it clashes with the header */
63			/* definition so it was changed to FCEOF */
64#define	CKET	12
65
66#define	STAR	01
67#define	PLUS	02
68#define	MINUS	16
69
70intptr_t	*__sp_;
71intptr_t	*__stmax;
72int	__i_size;
73
74/*ARGSUSED2*/
75char *
76libform_regcmp(char *cs1, char *cs2)
77{
78	char c;
79	char *ep, *sp;
80	int *adx;
81	int i, cflg;
82	char *lastep, *sep, *eptr;
83	int nbra, ngrp;
84	int cclcnt;
85	intptr_t stack[SSIZE];
86
87	__sp_ = stack;
88	*__sp_ = -1;
89	__stmax = &stack[SSIZE];
90
91	adx = (int *)&cs1;
92	i = nbra = ngrp = 0;
93	while (*adx)
94		i += __size((char *)(intptr_t)*adx++);
95	adx = (int *)&cs1;
96	sp = (char *)(intptr_t)*adx++;
97	if ((sep = ep = malloc((unsigned)(2 * i + SLOP))) == NULL)
98		return (NULL);
99	if ((c = *sp++) == FEOF)
100		goto cerror;
101	if (c == '^') {
102		c = *sp++;
103		*ep++ = CIRCFL;
104	}
105	if ((c == '*') || (c == '+') || (c == '{'))
106		goto cerror;
107	sp--;
108	for (;;) {
109		if ((c = *sp++) == FEOF) {
110			if (*adx) {
111				sp = (char *)(intptr_t)*adx++;
112				continue;
113			}
114			*ep++ = FCEOF;
115			if (--nbra > NBRA || *__sp_ != -1)
116				goto cerror;
117			__i_size = (int) (ep - sep);
118			return (sep);
119		}
120		if ((c != '*') && (c != '{') && (c != '+'))
121			lastep = ep;
122		switch (c) {
123
124		case '(':
125			if (!__rpush(ep)) goto cerror;
126			*ep++ = CBRA;
127			*ep++ = -1;
128			continue;
129		case ')':
130			if (!(eptr = (char *)__rpop())) goto cerror;
131			if ((c = *sp++) == '$') {
132				if ('0' > (c = *sp++) || c > '9')
133					goto cerror;
134				*ep++ = CKET;
135				*ep++ = *++eptr = nbra++;
136				*ep++ = (c-'0');
137				continue;
138			}
139			*ep++ = EGRP;
140			*ep++ = ngrp++;
141			sp--;
142			switch (c) {
143			case '+':
144				*eptr = PGRP;
145				break;
146			case '*':
147				*eptr = SGRP;
148				break;
149			case '{':
150				*eptr = TGRP;
151				break;
152			default:
153				*eptr = GRP;
154				continue;
155			}
156			i = (int) (ep - eptr - 2);
157			for (cclcnt = 0; i >= 256; cclcnt++)
158				i -= 256;
159			if (cclcnt > 3) goto cerror;
160			*eptr |= cclcnt;
161			*++eptr = (char) i;
162			continue;
163
164		case '\\':
165			*ep++ = CCHR;
166			if ((c = *sp++) == FEOF)
167				goto cerror;
168			*ep++ = c;
169			continue;
170
171		case '{':
172			*lastep |= RNGE;
173			cflg = 0;
174		nlim:
175			if ((c = *sp++) == '}') goto cerror;
176			i = 0;
177			do {
178				if ('0' <= c && c <= '9')
179					i = (i*10+(c-'0'));
180				else goto cerror;
181			} while (((c = *sp++) != '}') && (c != ','));
182			if (i > 255) goto cerror;
183			*ep++ = (char) i;
184			if (c == ',') {
185				if (cflg++) goto cerror;
186				if ((c = *sp++) == '}') {
187					*ep++ = -1;
188					continue;
189				} else {
190					sp--;
191					goto nlim;
192				}
193			}
194			if (!cflg)
195				*ep++ = (char) i;
196			else if ((ep[-1]&0377) < (ep[-2]&0377))
197				goto cerror;
198			continue;
199
200		case '.':
201			*ep++ = CDOT;
202			continue;
203
204		case '+':
205			if (*lastep == CBRA || *lastep == CKET)
206				goto cerror;
207			*lastep |= PLUS;
208			continue;
209
210		case '*':
211			if (*lastep == CBRA || *lastep == CKET)
212			goto cerror;
213			*lastep |= STAR;
214			continue;
215
216		case '$':
217			if ((*sp != FEOF) || (*adx))
218				goto defchar;
219			*ep++ = CDOL;
220			continue;
221
222		case '[':
223			*ep++ = CCL;
224			*ep++ = 0;
225			cclcnt = 1;
226			if ((c = *sp++) == '^') {
227				c = *sp++;
228				ep[-2] = NCCL;
229			}
230			do {
231				if (c == FEOF)
232					goto cerror;
233				if ((c == '-') && (cclcnt > 1) &&
234				    (*sp != ']')) {
235					*ep = ep[-1];
236					ep++;
237					ep[-2] = MINUS;
238					cclcnt++;
239					continue;
240				}
241				*ep++ = c;
242				cclcnt++;
243			} while ((c = *sp++) != ']');
244			lastep[1] = (char) cclcnt;
245			continue;
246
247		defchar:
248		default:
249			*ep++ = CCHR;
250			*ep++ = c;
251		}
252	}
253cerror:
254	free(sep);
255	return (0);
256}
257
258int
259__size(char *strg)
260{
261	int	i;
262
263	i = 1;
264	while (*strg++)
265		i++;
266	return (i);
267}
268
269intptr_t
270__rpop(void)
271{
272	return ((*__sp_ == -1)?0:*__sp_--);
273}
274
275int
276__rpush(char *ptr)
277{
278	if (__sp_ >= __stmax)
279		return (0);
280	*++__sp_ = (intptr_t)ptr;
281	return (1);
282}
283