1*b30d1939SAndy Fiddaman /***********************************************************************
2*b30d1939SAndy Fiddaman *                                                                      *
3*b30d1939SAndy Fiddaman *               This software is part of the ast package               *
4*b30d1939SAndy Fiddaman *          Copyright (c) 1985-2011 AT&T Intellectual Property          *
5*b30d1939SAndy Fiddaman *                      and is licensed under the                       *
6*b30d1939SAndy Fiddaman *                 Eclipse Public License, Version 1.0                  *
7*b30d1939SAndy Fiddaman *                    by AT&T Intellectual Property                     *
8*b30d1939SAndy Fiddaman *                                                                      *
9*b30d1939SAndy Fiddaman *                A copy of the License is available at                 *
10*b30d1939SAndy Fiddaman *          http://www.eclipse.org/org/documents/epl-v10.html           *
11*b30d1939SAndy Fiddaman *         (with md5 checksum b35adb5213ca9657e911e9befb180842)         *
12*b30d1939SAndy Fiddaman *                                                                      *
13*b30d1939SAndy Fiddaman *              Information and Software Systems Research               *
14*b30d1939SAndy Fiddaman *                            AT&T Research                             *
15*b30d1939SAndy Fiddaman *                           Florham Park NJ                            *
16*b30d1939SAndy Fiddaman *                                                                      *
17*b30d1939SAndy Fiddaman *                 Glenn Fowler <gsf@research.att.com>                  *
18*b30d1939SAndy Fiddaman *                  David Korn <dgk@research.att.com>                   *
19*b30d1939SAndy Fiddaman *                   Phong Vo <kpv@research.att.com>                    *
20*b30d1939SAndy Fiddaman *                                                                      *
21*b30d1939SAndy Fiddaman ***********************************************************************/
22*b30d1939SAndy Fiddaman #pragma prototyped
23*b30d1939SAndy Fiddaman 
24*b30d1939SAndy Fiddaman /*
25*b30d1939SAndy Fiddaman  * Glenn Fowler
26*b30d1939SAndy Fiddaman  * AT&T Research
27*b30d1939SAndy Fiddaman  *
28*b30d1939SAndy Fiddaman  * return RE expression given strmatch() pattern
29*b30d1939SAndy Fiddaman  * 0 returned for invalid RE
30*b30d1939SAndy Fiddaman  */
31*b30d1939SAndy Fiddaman 
32*b30d1939SAndy Fiddaman #include <ast.h>
33*b30d1939SAndy Fiddaman 
34*b30d1939SAndy Fiddaman typedef struct Stack_s
35*b30d1939SAndy Fiddaman {
36*b30d1939SAndy Fiddaman 	char*		beg;
37*b30d1939SAndy Fiddaman 	short		len;
38*b30d1939SAndy Fiddaman 	short		min;
39*b30d1939SAndy Fiddaman } Stack_t;
40*b30d1939SAndy Fiddaman 
41*b30d1939SAndy Fiddaman char*
fmtre(const char * as)42*b30d1939SAndy Fiddaman fmtre(const char* as)
43*b30d1939SAndy Fiddaman {
44*b30d1939SAndy Fiddaman 	register char*		s = (char*)as;
45*b30d1939SAndy Fiddaman 	register int		c;
46*b30d1939SAndy Fiddaman 	register char*		t;
47*b30d1939SAndy Fiddaman 	register Stack_t*	p;
48*b30d1939SAndy Fiddaman 	char*			x;
49*b30d1939SAndy Fiddaman 	int			n;
50*b30d1939SAndy Fiddaman 	int			end;
51*b30d1939SAndy Fiddaman 	char*			buf;
52*b30d1939SAndy Fiddaman 	Stack_t			stack[32];
53*b30d1939SAndy Fiddaman 
54*b30d1939SAndy Fiddaman 	end = 1;
55*b30d1939SAndy Fiddaman 	c = 2 * strlen(s) + 1;
56*b30d1939SAndy Fiddaman 	t = buf = fmtbuf(c);
57*b30d1939SAndy Fiddaman 	p = stack;
58*b30d1939SAndy Fiddaman 	if (*s != '*' || *(s + 1) == '(' || *(s + 1) == '-' && *(s + 2) == '(')
59*b30d1939SAndy Fiddaman 		*t++ = '^';
60*b30d1939SAndy Fiddaman 	else
61*b30d1939SAndy Fiddaman 		s++;
62*b30d1939SAndy Fiddaman 	for (;;)
63*b30d1939SAndy Fiddaman 	{
64*b30d1939SAndy Fiddaman 		switch (c = *s++)
65*b30d1939SAndy Fiddaman 		{
66*b30d1939SAndy Fiddaman 		case 0:
67*b30d1939SAndy Fiddaman 			break;
68*b30d1939SAndy Fiddaman 		case '\\':
69*b30d1939SAndy Fiddaman 			if (!(c = *s++) || c == '{' || c == '}')
70*b30d1939SAndy Fiddaman 				return 0;
71*b30d1939SAndy Fiddaman 			*t++ = '\\';
72*b30d1939SAndy Fiddaman 			if ((*t++ = c) == '(' && *s == '|')
73*b30d1939SAndy Fiddaman 			{
74*b30d1939SAndy Fiddaman 				*t++ = *s++;
75*b30d1939SAndy Fiddaman 				goto logical;
76*b30d1939SAndy Fiddaman 			}
77*b30d1939SAndy Fiddaman 			continue;
78*b30d1939SAndy Fiddaman 		case '[':
79*b30d1939SAndy Fiddaman 			*t++ = c;
80*b30d1939SAndy Fiddaman 			n = 0;
81*b30d1939SAndy Fiddaman 			if ((c = *s++) == '!')
82*b30d1939SAndy Fiddaman 			{
83*b30d1939SAndy Fiddaman 				*t++ = '^';
84*b30d1939SAndy Fiddaman 				c = *s++;
85*b30d1939SAndy Fiddaman 			}
86*b30d1939SAndy Fiddaman 			else if (c == '^')
87*b30d1939SAndy Fiddaman 			{
88*b30d1939SAndy Fiddaman 				if ((c = *s++) == ']')
89*b30d1939SAndy Fiddaman 				{
90*b30d1939SAndy Fiddaman 					*(t - 1) = '\\';
91*b30d1939SAndy Fiddaman 					*t++ = '^';
92*b30d1939SAndy Fiddaman 					continue;
93*b30d1939SAndy Fiddaman 				}
94*b30d1939SAndy Fiddaman 				n = '^';
95*b30d1939SAndy Fiddaman 			}
96*b30d1939SAndy Fiddaman 			for (;;)
97*b30d1939SAndy Fiddaman 			{
98*b30d1939SAndy Fiddaman 				if (!(*t++ = c))
99*b30d1939SAndy Fiddaman 					return 0;
100*b30d1939SAndy Fiddaman 				if ((c = *s++) == ']')
101*b30d1939SAndy Fiddaman 				{
102*b30d1939SAndy Fiddaman 					if (n)
103*b30d1939SAndy Fiddaman 						*t++ = n;
104*b30d1939SAndy Fiddaman 					*t++ = c;
105*b30d1939SAndy Fiddaman 					break;
106*b30d1939SAndy Fiddaman 				}
107*b30d1939SAndy Fiddaman 			}
108*b30d1939SAndy Fiddaman 			continue;
109*b30d1939SAndy Fiddaman 		case '{':
110*b30d1939SAndy Fiddaman 			for (x = s; *x && *x != '}'; x++);
111*b30d1939SAndy Fiddaman 			if (*x++ && (*x == '(' || *x == '-' && *(x + 1) == '('))
112*b30d1939SAndy Fiddaman 			{
113*b30d1939SAndy Fiddaman 				if (p >= &stack[elementsof(stack)])
114*b30d1939SAndy Fiddaman 					return 0;
115*b30d1939SAndy Fiddaman 				p->beg = s - 1;
116*b30d1939SAndy Fiddaman 				s = x;
117*b30d1939SAndy Fiddaman 				p->len = s - p->beg;
118*b30d1939SAndy Fiddaman 				if (p->min = *s == '-')
119*b30d1939SAndy Fiddaman 					s++;
120*b30d1939SAndy Fiddaman 				p++;
121*b30d1939SAndy Fiddaman 				*t++ = *s++;
122*b30d1939SAndy Fiddaman 			}
123*b30d1939SAndy Fiddaman 			else
124*b30d1939SAndy Fiddaman 				*t++ = c;
125*b30d1939SAndy Fiddaman 			continue;
126*b30d1939SAndy Fiddaman 		case '*':
127*b30d1939SAndy Fiddaman 			if (!*s)
128*b30d1939SAndy Fiddaman 			{
129*b30d1939SAndy Fiddaman 				end = 0;
130*b30d1939SAndy Fiddaman 				break;
131*b30d1939SAndy Fiddaman 			}
132*b30d1939SAndy Fiddaman 			/*FALLTHROUGH*/
133*b30d1939SAndy Fiddaman 		case '?':
134*b30d1939SAndy Fiddaman 		case '+':
135*b30d1939SAndy Fiddaman 		case '@':
136*b30d1939SAndy Fiddaman 		case '!':
137*b30d1939SAndy Fiddaman 		case '~':
138*b30d1939SAndy Fiddaman 			if (*s == '(' || c != '~' && *s == '-' && *(s + 1) == '(')
139*b30d1939SAndy Fiddaman 			{
140*b30d1939SAndy Fiddaman 				if (p >= &stack[elementsof(stack)])
141*b30d1939SAndy Fiddaman 					return 0;
142*b30d1939SAndy Fiddaman 				p->beg = s - 1;
143*b30d1939SAndy Fiddaman 				if (c == '~')
144*b30d1939SAndy Fiddaman 				{
145*b30d1939SAndy Fiddaman 					if (*(s + 1) == 'E' && *(s + 2) == ')')
146*b30d1939SAndy Fiddaman 					{
147*b30d1939SAndy Fiddaman 						for (s += 3; *t = *s; t++, s++);
148*b30d1939SAndy Fiddaman 						continue;
149*b30d1939SAndy Fiddaman 					}
150*b30d1939SAndy Fiddaman 					p->len = 0;
151*b30d1939SAndy Fiddaman 					p->min = 0;
152*b30d1939SAndy Fiddaman 					*t++ = *s++;
153*b30d1939SAndy Fiddaman 					*t++ = '?';
154*b30d1939SAndy Fiddaman 				}
155*b30d1939SAndy Fiddaman 				else
156*b30d1939SAndy Fiddaman 				{
157*b30d1939SAndy Fiddaman 					p->len = c != '@';
158*b30d1939SAndy Fiddaman 					if (p->min = *s == '-')
159*b30d1939SAndy Fiddaman 						s++;
160*b30d1939SAndy Fiddaman 					*t++ = *s++;
161*b30d1939SAndy Fiddaman 				}
162*b30d1939SAndy Fiddaman 				p++;
163*b30d1939SAndy Fiddaman 			}
164*b30d1939SAndy Fiddaman 			else
165*b30d1939SAndy Fiddaman 			{
166*b30d1939SAndy Fiddaman 				switch (c)
167*b30d1939SAndy Fiddaman 				{
168*b30d1939SAndy Fiddaman 				case '*':
169*b30d1939SAndy Fiddaman 					*t++ = '.';
170*b30d1939SAndy Fiddaman 					break;
171*b30d1939SAndy Fiddaman 				case '?':
172*b30d1939SAndy Fiddaman 					c = '.';
173*b30d1939SAndy Fiddaman 					break;
174*b30d1939SAndy Fiddaman 				case '+':
175*b30d1939SAndy Fiddaman 				case '!':
176*b30d1939SAndy Fiddaman 					*t++ = '\\';
177*b30d1939SAndy Fiddaman 					break;
178*b30d1939SAndy Fiddaman 				}
179*b30d1939SAndy Fiddaman 				*t++ = c;
180*b30d1939SAndy Fiddaman 			}
181*b30d1939SAndy Fiddaman 			continue;
182*b30d1939SAndy Fiddaman 		case '(':
183*b30d1939SAndy Fiddaman 			if (p >= &stack[elementsof(stack)])
184*b30d1939SAndy Fiddaman 				return 0;
185*b30d1939SAndy Fiddaman 			p->beg = s - 1;
186*b30d1939SAndy Fiddaman 			p->len = 0;
187*b30d1939SAndy Fiddaman 			p->min = 0;
188*b30d1939SAndy Fiddaman 			p++;
189*b30d1939SAndy Fiddaman 			*t++ = c;
190*b30d1939SAndy Fiddaman 			continue;
191*b30d1939SAndy Fiddaman 		case ')':
192*b30d1939SAndy Fiddaman 			if (p == stack)
193*b30d1939SAndy Fiddaman 				return 0;
194*b30d1939SAndy Fiddaman 			*t++ = c;
195*b30d1939SAndy Fiddaman 			p--;
196*b30d1939SAndy Fiddaman 			for (c = 0; c < p->len; c++)
197*b30d1939SAndy Fiddaman 				*t++ = p->beg[c];
198*b30d1939SAndy Fiddaman 			if (p->min)
199*b30d1939SAndy Fiddaman 				*t++ = '?';
200*b30d1939SAndy Fiddaman 			continue;
201*b30d1939SAndy Fiddaman 		case '^':
202*b30d1939SAndy Fiddaman 		case '.':
203*b30d1939SAndy Fiddaman 		case '$':
204*b30d1939SAndy Fiddaman 			*t++ = '\\';
205*b30d1939SAndy Fiddaman 			*t++ = c;
206*b30d1939SAndy Fiddaman 			continue;
207*b30d1939SAndy Fiddaman 		case '|':
208*b30d1939SAndy Fiddaman 			if (t == buf || *(t - 1) == '(')
209*b30d1939SAndy Fiddaman 				return 0;
210*b30d1939SAndy Fiddaman 		logical:
211*b30d1939SAndy Fiddaman 			if (!*s || *s == ')')
212*b30d1939SAndy Fiddaman 				return 0;
213*b30d1939SAndy Fiddaman 			/*FALLTHROUGH*/
214*b30d1939SAndy Fiddaman 		default:
215*b30d1939SAndy Fiddaman 			*t++ = c;
216*b30d1939SAndy Fiddaman 			continue;
217*b30d1939SAndy Fiddaman 		}
218*b30d1939SAndy Fiddaman 		break;
219*b30d1939SAndy Fiddaman 	}
220*b30d1939SAndy Fiddaman 	if (p != stack)
221*b30d1939SAndy Fiddaman 		return 0;
222*b30d1939SAndy Fiddaman 	if (end)
223*b30d1939SAndy Fiddaman 		*t++ = '$';
224*b30d1939SAndy Fiddaman 	*t = 0;
225*b30d1939SAndy Fiddaman 	return buf;
226*b30d1939SAndy Fiddaman }
227