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)424887Schinfmtre(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