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  * Glenn Fowler
25*b30d1939SAndy Fiddaman  * AT&T Research
26*b30d1939SAndy Fiddaman  *
27*b30d1939SAndy Fiddaman  * return strmatch() expression given REG_AUGMENTED RE
28*b30d1939SAndy Fiddaman  * 0 returned for invalid RE
29*b30d1939SAndy Fiddaman  */
30*b30d1939SAndy Fiddaman 
31*b30d1939SAndy Fiddaman #include <ast.h>
32*b30d1939SAndy Fiddaman 
33*b30d1939SAndy Fiddaman char*
fmtmatch(const char * as)34*b30d1939SAndy Fiddaman fmtmatch(const char* as)
35*b30d1939SAndy Fiddaman {
36*b30d1939SAndy Fiddaman 	register char*	s = (char*)as;
37*b30d1939SAndy Fiddaman 	register int	c;
38*b30d1939SAndy Fiddaman 	register char*	t;
39*b30d1939SAndy Fiddaman 	register char**	p;
40*b30d1939SAndy Fiddaman 	register char*	b;
41*b30d1939SAndy Fiddaman 	char*		x;
42*b30d1939SAndy Fiddaman 	char*		y;
43*b30d1939SAndy Fiddaman 	char*		z;
44*b30d1939SAndy Fiddaman 	int		a;
45*b30d1939SAndy Fiddaman 	int		e;
46*b30d1939SAndy Fiddaman 	int		n;
47*b30d1939SAndy Fiddaman 	char*		buf;
48*b30d1939SAndy Fiddaman 	char*		stack[32];
49*b30d1939SAndy Fiddaman 
50*b30d1939SAndy Fiddaman 	c = 3 * (strlen(s) + 1);
51*b30d1939SAndy Fiddaman 	buf = fmtbuf(c);
52*b30d1939SAndy Fiddaman 	t = b = buf + 3;
53*b30d1939SAndy Fiddaman 	p = stack;
54*b30d1939SAndy Fiddaman 	if (a = *s == '^')
55*b30d1939SAndy Fiddaman 		s++;
56*b30d1939SAndy Fiddaman 	e = 0;
57*b30d1939SAndy Fiddaman 	for (;;)
58*b30d1939SAndy Fiddaman 	{
59*b30d1939SAndy Fiddaman 		switch (c = *s++)
60*b30d1939SAndy Fiddaman 		{
61*b30d1939SAndy Fiddaman 		case 0:
62*b30d1939SAndy Fiddaman 			break;
63*b30d1939SAndy Fiddaman 		case '\\':
64*b30d1939SAndy Fiddaman 			if (!(c = *s++))
65*b30d1939SAndy Fiddaman 				return 0;
66*b30d1939SAndy Fiddaman 			switch (*s)
67*b30d1939SAndy Fiddaman 			{
68*b30d1939SAndy Fiddaman 			case '*':
69*b30d1939SAndy Fiddaman 			case '+':
70*b30d1939SAndy Fiddaman 			case '?':
71*b30d1939SAndy Fiddaman 				*t++ = *s++;
72*b30d1939SAndy Fiddaman 				*t++ = '(';
73*b30d1939SAndy Fiddaman 				*t++ = '\\';
74*b30d1939SAndy Fiddaman 				*t++ = c;
75*b30d1939SAndy Fiddaman 				c = ')';
76*b30d1939SAndy Fiddaman 				break;
77*b30d1939SAndy Fiddaman 			case '|':
78*b30d1939SAndy Fiddaman 			case '&':
79*b30d1939SAndy Fiddaman 				if (c == '(')
80*b30d1939SAndy Fiddaman 				{
81*b30d1939SAndy Fiddaman 					*t++ = c;
82*b30d1939SAndy Fiddaman 					c = *s++;
83*b30d1939SAndy Fiddaman 					goto logical;
84*b30d1939SAndy Fiddaman 				}
85*b30d1939SAndy Fiddaman 				break;
86*b30d1939SAndy Fiddaman 			case '{':
87*b30d1939SAndy Fiddaman 			case '}':
88*b30d1939SAndy Fiddaman 				break;
89*b30d1939SAndy Fiddaman 			default:
90*b30d1939SAndy Fiddaman 				*t++ = '\\';
91*b30d1939SAndy Fiddaman 				break;
92*b30d1939SAndy Fiddaman 			}
93*b30d1939SAndy Fiddaman 			*t++ = c;
94*b30d1939SAndy Fiddaman 			continue;
95*b30d1939SAndy Fiddaman 		case '[':
96*b30d1939SAndy Fiddaman 			x = t;
97*b30d1939SAndy Fiddaman 			*t++ = c;
98*b30d1939SAndy Fiddaman 			if ((c = *s++) == '^')
99*b30d1939SAndy Fiddaman 			{
100*b30d1939SAndy Fiddaman 				*t++ = '!';
101*b30d1939SAndy Fiddaman 				c = *s++;
102*b30d1939SAndy Fiddaman 			}
103*b30d1939SAndy Fiddaman 			else if (c == '!')
104*b30d1939SAndy Fiddaman 			{
105*b30d1939SAndy Fiddaman 				*t++ = '\\';
106*b30d1939SAndy Fiddaman 				*t++ = c;
107*b30d1939SAndy Fiddaman 				c = *s++;
108*b30d1939SAndy Fiddaman 			}
109*b30d1939SAndy Fiddaman 			for (;;)
110*b30d1939SAndy Fiddaman 			{
111*b30d1939SAndy Fiddaman 				if (!(*t++ = c))
112*b30d1939SAndy Fiddaman 					return 0;
113*b30d1939SAndy Fiddaman 				if (c == '\\')
114*b30d1939SAndy Fiddaman 					*t++ = c;
115*b30d1939SAndy Fiddaman 				if ((c = *s++) == ']')
116*b30d1939SAndy Fiddaman 				{
117*b30d1939SAndy Fiddaman 					*t++ = c;
118*b30d1939SAndy Fiddaman 					break;
119*b30d1939SAndy Fiddaman 				}
120*b30d1939SAndy Fiddaman 			}
121*b30d1939SAndy Fiddaman 			switch (*s)
122*b30d1939SAndy Fiddaman 			{
123*b30d1939SAndy Fiddaman 			case '*':
124*b30d1939SAndy Fiddaman 			case '+':
125*b30d1939SAndy Fiddaman 			case '?':
126*b30d1939SAndy Fiddaman 				for (y = t + 2, t--; t >= x; t--)
127*b30d1939SAndy Fiddaman 					*(t + 2) = *t;
128*b30d1939SAndy Fiddaman 				*++t = *s++;
129*b30d1939SAndy Fiddaman 				*++t = '(';
130*b30d1939SAndy Fiddaman 				t = y;
131*b30d1939SAndy Fiddaman 				*t++ = ')';
132*b30d1939SAndy Fiddaman 				break;
133*b30d1939SAndy Fiddaman 			}
134*b30d1939SAndy Fiddaman 			continue;
135*b30d1939SAndy Fiddaman 		case '(':
136*b30d1939SAndy Fiddaman 			if (p >= &stack[elementsof(stack)])
137*b30d1939SAndy Fiddaman 				return 0;
138*b30d1939SAndy Fiddaman 			*p++ = t;
139*b30d1939SAndy Fiddaman 			if (*s == '?')
140*b30d1939SAndy Fiddaman 			{
141*b30d1939SAndy Fiddaman 				s++;
142*b30d1939SAndy Fiddaman 				if (*s == 'K' && *(s + 1) == ')')
143*b30d1939SAndy Fiddaman 				{
144*b30d1939SAndy Fiddaman 					s += 2;
145*b30d1939SAndy Fiddaman 					p--;
146*b30d1939SAndy Fiddaman 					while (*t = *s)
147*b30d1939SAndy Fiddaman 						t++, s++;
148*b30d1939SAndy Fiddaman 					continue;
149*b30d1939SAndy Fiddaman 				}
150*b30d1939SAndy Fiddaman 				*t++ = '~';
151*b30d1939SAndy Fiddaman 			}
152*b30d1939SAndy Fiddaman 			else
153*b30d1939SAndy Fiddaman 				*t++ = '@';
154*b30d1939SAndy Fiddaman 			*t++ = '(';
155*b30d1939SAndy Fiddaman 			continue;
156*b30d1939SAndy Fiddaman 		case ')':
157*b30d1939SAndy Fiddaman 			if (p == stack)
158*b30d1939SAndy Fiddaman 				return 0;
159*b30d1939SAndy Fiddaman 			p--;
160*b30d1939SAndy Fiddaman 			*t++ = c;
161*b30d1939SAndy Fiddaman 			switch (*s)
162*b30d1939SAndy Fiddaman 			{
163*b30d1939SAndy Fiddaman 			case 0:
164*b30d1939SAndy Fiddaman 				break;
165*b30d1939SAndy Fiddaman 			case '*':
166*b30d1939SAndy Fiddaman 			case '+':
167*b30d1939SAndy Fiddaman 			case '?':
168*b30d1939SAndy Fiddaman 			case '!':
169*b30d1939SAndy Fiddaman 				**p = *s++;
170*b30d1939SAndy Fiddaman 				if (*s == '?')
171*b30d1939SAndy Fiddaman 				{
172*b30d1939SAndy Fiddaman 					s++;
173*b30d1939SAndy Fiddaman 					x = *p + 1;
174*b30d1939SAndy Fiddaman 					for (y = ++t; y > x; y--)
175*b30d1939SAndy Fiddaman 						*y = *(y - 1);
176*b30d1939SAndy Fiddaman 					*x = '-';
177*b30d1939SAndy Fiddaman 				}
178*b30d1939SAndy Fiddaman 				continue;
179*b30d1939SAndy Fiddaman 			case '{':
180*b30d1939SAndy Fiddaman 				for (z = s; *z != '}'; z++)
181*b30d1939SAndy Fiddaman 					if (!*z)
182*b30d1939SAndy Fiddaman 						return 0;
183*b30d1939SAndy Fiddaman 				n = z - s;
184*b30d1939SAndy Fiddaman 				if (*++z == '?')
185*b30d1939SAndy Fiddaman 					n++;
186*b30d1939SAndy Fiddaman 				x = *p + n;
187*b30d1939SAndy Fiddaman 				for (y = t += n; y > x; y--)
188*b30d1939SAndy Fiddaman 					*y = *(y - n);
189*b30d1939SAndy Fiddaman 				for (x = *p; s < z; *x++ = *s++);
190*b30d1939SAndy Fiddaman 				if (*s == '?')
191*b30d1939SAndy Fiddaman 				{
192*b30d1939SAndy Fiddaman 					s++;
193*b30d1939SAndy Fiddaman 					*x++ = '-';
194*b30d1939SAndy Fiddaman 				}
195*b30d1939SAndy Fiddaman 				continue;
196*b30d1939SAndy Fiddaman 			default:
197*b30d1939SAndy Fiddaman 				continue;
198*b30d1939SAndy Fiddaman 			}
199*b30d1939SAndy Fiddaman 			break;
200*b30d1939SAndy Fiddaman 		case '.':
201*b30d1939SAndy Fiddaman 			switch (*s)
202*b30d1939SAndy Fiddaman 			{
203*b30d1939SAndy Fiddaman 			case 0:
204*b30d1939SAndy Fiddaman 				*t++ = '?';
205*b30d1939SAndy Fiddaman 				break;
206*b30d1939SAndy Fiddaman 			case '*':
207*b30d1939SAndy Fiddaman 				s++;
208*b30d1939SAndy Fiddaman 				*t++ = '*';
209*b30d1939SAndy Fiddaman 				e = !*s;
210*b30d1939SAndy Fiddaman 				continue;
211*b30d1939SAndy Fiddaman 			case '+':
212*b30d1939SAndy Fiddaman 				s++;
213*b30d1939SAndy Fiddaman 				*t++ = '?';
214*b30d1939SAndy Fiddaman 				*t++ = '*';
215*b30d1939SAndy Fiddaman 				continue;
216*b30d1939SAndy Fiddaman 			case '?':
217*b30d1939SAndy Fiddaman 				s++;
218*b30d1939SAndy Fiddaman 				*t++ = '?';
219*b30d1939SAndy Fiddaman 				*t++ = '(';
220*b30d1939SAndy Fiddaman 				*t++ = '?';
221*b30d1939SAndy Fiddaman 				*t++ = ')';
222*b30d1939SAndy Fiddaman 				continue;
223*b30d1939SAndy Fiddaman 			default:
224*b30d1939SAndy Fiddaman 				*t++ = '?';
225*b30d1939SAndy Fiddaman 				continue;
226*b30d1939SAndy Fiddaman 			}
227*b30d1939SAndy Fiddaman 			break;
228*b30d1939SAndy Fiddaman 		case '*':
229*b30d1939SAndy Fiddaman 		case '+':
230*b30d1939SAndy Fiddaman 		case '?':
231*b30d1939SAndy Fiddaman 		case '{':
232*b30d1939SAndy Fiddaman 			n = *(t - 1);
233*b30d1939SAndy Fiddaman 			if (t == b || n == '(' || n == '|')
234*b30d1939SAndy Fiddaman 				return 0;
235*b30d1939SAndy Fiddaman 			*(t - 1) = c;
236*b30d1939SAndy Fiddaman 			if (c == '{')
237*b30d1939SAndy Fiddaman 			{
238*b30d1939SAndy Fiddaman 				for (z = s; *z != '}'; z++)
239*b30d1939SAndy Fiddaman 					if (!*z)
240*b30d1939SAndy Fiddaman 						return 0;
241*b30d1939SAndy Fiddaman 				for (; s <= z; *t++ = *s++);
242*b30d1939SAndy Fiddaman 			}
243*b30d1939SAndy Fiddaman 			if (*s == '?')
244*b30d1939SAndy Fiddaman 			{
245*b30d1939SAndy Fiddaman 				s++;
246*b30d1939SAndy Fiddaman 				*t++ = '-';
247*b30d1939SAndy Fiddaman 			}
248*b30d1939SAndy Fiddaman 			*t++ = '(';
249*b30d1939SAndy Fiddaman 			*t++ = n;
250*b30d1939SAndy Fiddaman 			*t++ = ')';
251*b30d1939SAndy Fiddaman 			continue;
252*b30d1939SAndy Fiddaman 		case '|':
253*b30d1939SAndy Fiddaman 		case '&':
254*b30d1939SAndy Fiddaman 			if (t == b || *(t - 1) == '(')
255*b30d1939SAndy Fiddaman 				return 0;
256*b30d1939SAndy Fiddaman 		logical:
257*b30d1939SAndy Fiddaman 			if (!*s || *s == ')')
258*b30d1939SAndy Fiddaman 				return 0;
259*b30d1939SAndy Fiddaman 			if (p == stack && b == buf + 3)
260*b30d1939SAndy Fiddaman 			{
261*b30d1939SAndy Fiddaman 				*--b = '(';
262*b30d1939SAndy Fiddaman 				*--b = '@';
263*b30d1939SAndy Fiddaman 			}
264*b30d1939SAndy Fiddaman 			*t++ = c;
265*b30d1939SAndy Fiddaman 			continue;
266*b30d1939SAndy Fiddaman 		case '$':
267*b30d1939SAndy Fiddaman 			if (e = !*s)
268*b30d1939SAndy Fiddaman 				break;
269*b30d1939SAndy Fiddaman 			/*FALLTHROUGH*/
270*b30d1939SAndy Fiddaman 		default:
271*b30d1939SAndy Fiddaman 			*t++ = c;
272*b30d1939SAndy Fiddaman 			continue;
273*b30d1939SAndy Fiddaman 		}
274*b30d1939SAndy Fiddaman 		break;
275*b30d1939SAndy Fiddaman 	}
276*b30d1939SAndy Fiddaman 	if (p != stack)
277*b30d1939SAndy Fiddaman 		return 0;
278*b30d1939SAndy Fiddaman 	if (b != buf + 3)
279*b30d1939SAndy Fiddaman 		*t++ = ')';
280*b30d1939SAndy Fiddaman 	if (!a && (*b != '*' || *(b + 1) == '(' || (*(b + 1) == '-' || *(b + 1) == '~') && *(b + 2) == '('))
281*b30d1939SAndy Fiddaman 		*--b = '*';
282*b30d1939SAndy Fiddaman 	if (!e)
283*b30d1939SAndy Fiddaman 		*t++ = '*';
284*b30d1939SAndy Fiddaman 	*t = 0;
285*b30d1939SAndy Fiddaman 	return b;
286*b30d1939SAndy Fiddaman }
287