xref: /onnv-gate/usr/src/lib/libast/common/string/fmtre.c (revision 12068:08a39a083754)
14887Schin /***********************************************************************
24887Schin *                                                                      *
34887Schin *               This software is part of the ast package               *
4*12068SRoger.Faulkner@Oracle.COM *          Copyright (c) 1985-2010 AT&T Intellectual Property          *
54887Schin *                      and is licensed under the                       *
64887Schin *                  Common Public License, Version 1.0                  *
78462SApril.Chin@Sun.COM *                    by AT&T Intellectual Property                     *
84887Schin *                                                                      *
94887Schin *                A copy of the License is available at                 *
104887Schin *            http://www.opensource.org/licenses/cpl1.0.txt             *
114887Schin *         (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9)         *
124887Schin *                                                                      *
134887Schin *              Information and Software Systems Research               *
144887Schin *                            AT&T Research                             *
154887Schin *                           Florham Park NJ                            *
164887Schin *                                                                      *
174887Schin *                 Glenn Fowler <gsf@research.att.com>                  *
184887Schin *                  David Korn <dgk@research.att.com>                   *
194887Schin *                   Phong Vo <kpv@research.att.com>                    *
204887Schin *                                                                      *
214887Schin ***********************************************************************/
224887Schin #pragma prototyped
234887Schin 
244887Schin /*
254887Schin  * Glenn Fowler
264887Schin  * AT&T Research
274887Schin  *
284887Schin  * return RE expression given strmatch() pattern
294887Schin  * 0 returned for invalid RE
304887Schin  */
314887Schin 
324887Schin #include <ast.h>
334887Schin 
344887Schin typedef struct Stack_s
354887Schin {
364887Schin 	char*		beg;
374887Schin 	short		len;
384887Schin 	short		min;
394887Schin } Stack_t;
404887Schin 
414887Schin char*
fmtre(const char * as)424887Schin fmtre(const char* as)
434887Schin {
444887Schin 	register char*		s = (char*)as;
454887Schin 	register int		c;
464887Schin 	register char*		t;
474887Schin 	register Stack_t*	p;
484887Schin 	char*			x;
494887Schin 	int			n;
504887Schin 	int			end;
514887Schin 	char*			buf;
524887Schin 	Stack_t			stack[32];
534887Schin 
544887Schin 	end = 1;
554887Schin 	c = 2 * strlen(s) + 1;
564887Schin 	t = buf = fmtbuf(c);
574887Schin 	p = stack;
584887Schin 	if (*s != '*' || *(s + 1) == '(' || *(s + 1) == '-' && *(s + 2) == '(')
594887Schin 		*t++ = '^';
604887Schin 	else
614887Schin 		s++;
624887Schin 	for (;;)
634887Schin 	{
644887Schin 		switch (c = *s++)
654887Schin 		{
664887Schin 		case 0:
674887Schin 			break;
684887Schin 		case '\\':
694887Schin 			if (!(c = *s++) || c == '{' || c == '}')
704887Schin 				return 0;
714887Schin 			*t++ = '\\';
724887Schin 			if ((*t++ = c) == '(' && *s == '|')
734887Schin 			{
744887Schin 				*t++ = *s++;
754887Schin 				goto logical;
764887Schin 			}
774887Schin 			continue;
784887Schin 		case '[':
794887Schin 			*t++ = c;
804887Schin 			n = 0;
814887Schin 			if ((c = *s++) == '!')
824887Schin 			{
834887Schin 				*t++ = '^';
844887Schin 				c = *s++;
854887Schin 			}
864887Schin 			else if (c == '^')
874887Schin 			{
884887Schin 				if ((c = *s++) == ']')
894887Schin 				{
904887Schin 					*(t - 1) = '\\';
914887Schin 					*t++ = '^';
924887Schin 					continue;
934887Schin 				}
944887Schin 				n = '^';
954887Schin 			}
964887Schin 			for (;;)
974887Schin 			{
984887Schin 				if (!(*t++ = c))
994887Schin 					return 0;
1004887Schin 				if ((c = *s++) == ']')
1014887Schin 				{
1024887Schin 					if (n)
1034887Schin 						*t++ = n;
1044887Schin 					*t++ = c;
1054887Schin 					break;
1064887Schin 				}
1074887Schin 			}
1084887Schin 			continue;
1094887Schin 		case '{':
1104887Schin 			for (x = s; *x && *x != '}'; x++);
1114887Schin 			if (*x++ && (*x == '(' || *x == '-' && *(x + 1) == '('))
1124887Schin 			{
1134887Schin 				if (p >= &stack[elementsof(stack)])
1144887Schin 					return 0;
1154887Schin 				p->beg = s - 1;
1164887Schin 				s = x;
1174887Schin 				p->len = s - p->beg;
1184887Schin 				if (p->min = *s == '-')
1194887Schin 					s++;
1204887Schin 				p++;
1214887Schin 				*t++ = *s++;
1224887Schin 			}
1234887Schin 			else
1244887Schin 				*t++ = c;
1254887Schin 			continue;
1264887Schin 		case '*':
1274887Schin 			if (!*s)
1284887Schin 			{
1294887Schin 				end = 0;
1304887Schin 				break;
1314887Schin 			}
1324887Schin 			/*FALLTHROUGH*/
1334887Schin 		case '?':
1344887Schin 		case '+':
1354887Schin 		case '@':
1364887Schin 		case '!':
1374887Schin 		case '~':
1384887Schin 			if (*s == '(' || c != '~' && *s == '-' && *(s + 1) == '(')
1394887Schin 			{
1404887Schin 				if (p >= &stack[elementsof(stack)])
1414887Schin 					return 0;
1424887Schin 				p->beg = s - 1;
1434887Schin 				if (c == '~')
1444887Schin 				{
1454887Schin 					if (*(s + 1) == 'E' && *(s + 2) == ')')
1464887Schin 					{
1474887Schin 						for (s += 3; *t = *s; t++, s++);
1484887Schin 						continue;
1494887Schin 					}
1504887Schin 					p->len = 0;
1518462SApril.Chin@Sun.COM 					p->min = 0;
1524887Schin 					*t++ = *s++;
1534887Schin 					*t++ = '?';
1544887Schin 				}
1554887Schin 				else
1564887Schin 				{
1574887Schin 					p->len = c != '@';
1584887Schin 					if (p->min = *s == '-')
1594887Schin 						s++;
1604887Schin 					*t++ = *s++;
1614887Schin 				}
1624887Schin 				p++;
1634887Schin 			}
1644887Schin 			else
1654887Schin 			{
1664887Schin 				switch (c)
1674887Schin 				{
1684887Schin 				case '*':
1694887Schin 					*t++ = '.';
1704887Schin 					break;
1714887Schin 				case '?':
1724887Schin 					c = '.';
1734887Schin 					break;
1744887Schin 				case '+':
1754887Schin 				case '!':
1764887Schin 					*t++ = '\\';
1774887Schin 					break;
1784887Schin 				}
1794887Schin 				*t++ = c;
1804887Schin 			}
1814887Schin 			continue;
1824887Schin 		case '(':
1834887Schin 			if (p >= &stack[elementsof(stack)])
1844887Schin 				return 0;
1854887Schin 			p->beg = s - 1;
1864887Schin 			p->len = 0;
1874887Schin 			p->min = 0;
1884887Schin 			p++;
1894887Schin 			*t++ = c;
1904887Schin 			continue;
1914887Schin 		case ')':
1924887Schin 			if (p == stack)
1934887Schin 				return 0;
1944887Schin 			*t++ = c;
1954887Schin 			p--;
1964887Schin 			for (c = 0; c < p->len; c++)
1974887Schin 				*t++ = p->beg[c];
1984887Schin 			if (p->min)
1994887Schin 				*t++ = '?';
2004887Schin 			continue;
2014887Schin 		case '^':
2024887Schin 		case '.':
2034887Schin 		case '$':
2044887Schin 			*t++ = '\\';
2054887Schin 			*t++ = c;
2064887Schin 			continue;
2074887Schin 		case '|':
2084887Schin 			if (t == buf || *(t - 1) == '(')
2094887Schin 				return 0;
2104887Schin 		logical:
2114887Schin 			if (!*s || *s == ')')
2124887Schin 				return 0;
2134887Schin 			/*FALLTHROUGH*/
2144887Schin 		default:
2154887Schin 			*t++ = c;
2164887Schin 			continue;
2174887Schin 		}
2184887Schin 		break;
2194887Schin 	}
2204887Schin 	if (p != stack)
2214887Schin 		return 0;
2224887Schin 	if (end)
2234887Schin 		*t++ = '$';
2244887Schin 	*t = 0;
2254887Schin 	return buf;
2264887Schin }
227