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 * Glenn Fowler 254887Schin * AT&T Research 264887Schin * 274887Schin * return strmatch() expression given REG_AUGMENTED RE 284887Schin * 0 returned for invalid RE 294887Schin */ 304887Schin 314887Schin #include <ast.h> 324887Schin 334887Schin char* fmtmatch(const char * as)344887Schinfmtmatch(const char* as) 354887Schin { 364887Schin register char* s = (char*)as; 374887Schin register int c; 384887Schin register char* t; 394887Schin register char** p; 404887Schin register char* b; 414887Schin char* x; 424887Schin char* y; 434887Schin char* z; 444887Schin int a; 454887Schin int e; 464887Schin int n; 474887Schin char* buf; 484887Schin char* stack[32]; 494887Schin 504887Schin c = 3 * (strlen(s) + 1); 514887Schin buf = fmtbuf(c); 524887Schin t = b = buf + 3; 534887Schin p = stack; 544887Schin if (a = *s == '^') 554887Schin s++; 564887Schin e = 0; 574887Schin for (;;) 584887Schin { 594887Schin switch (c = *s++) 604887Schin { 614887Schin case 0: 624887Schin break; 634887Schin case '\\': 644887Schin if (!(c = *s++)) 654887Schin return 0; 664887Schin switch (*s) 674887Schin { 684887Schin case '*': 694887Schin case '+': 704887Schin case '?': 714887Schin *t++ = *s++; 724887Schin *t++ = '('; 734887Schin *t++ = '\\'; 744887Schin *t++ = c; 754887Schin c = ')'; 764887Schin break; 774887Schin case '|': 784887Schin case '&': 794887Schin if (c == '(') 804887Schin { 814887Schin *t++ = c; 824887Schin c = *s++; 834887Schin goto logical; 844887Schin } 854887Schin break; 864887Schin case '{': 874887Schin case '}': 884887Schin break; 894887Schin default: 904887Schin *t++ = '\\'; 914887Schin break; 924887Schin } 934887Schin *t++ = c; 944887Schin continue; 954887Schin case '[': 964887Schin x = t; 974887Schin *t++ = c; 984887Schin if ((c = *s++) == '^') 994887Schin { 1004887Schin *t++ = '!'; 1014887Schin c = *s++; 1024887Schin } 1034887Schin else if (c == '!') 1044887Schin { 1054887Schin *t++ = '\\'; 1064887Schin *t++ = c; 1074887Schin c = *s++; 1084887Schin } 1094887Schin for (;;) 1104887Schin { 1114887Schin if (!(*t++ = c)) 1124887Schin return 0; 1134887Schin if (c == '\\') 1144887Schin *t++ = c; 1154887Schin if ((c = *s++) == ']') 1164887Schin { 1174887Schin *t++ = c; 1184887Schin break; 1194887Schin } 1204887Schin } 1214887Schin switch (*s) 1224887Schin { 1234887Schin case '*': 1244887Schin case '+': 1254887Schin case '?': 1264887Schin for (y = t + 2, t--; t >= x; t--) 1274887Schin *(t + 2) = *t; 1284887Schin *++t = *s++; 1294887Schin *++t = '('; 1304887Schin t = y; 1314887Schin *t++ = ')'; 1324887Schin break; 1334887Schin } 1344887Schin continue; 1354887Schin case '(': 1364887Schin if (p >= &stack[elementsof(stack)]) 1374887Schin return 0; 1384887Schin *p++ = t; 1394887Schin if (*s == '?') 1404887Schin { 1414887Schin s++; 1424887Schin if (*s == 'K' && *(s + 1) == ')') 1434887Schin { 1444887Schin s += 2; 1454887Schin p--; 1464887Schin while (*t = *s) 1474887Schin t++, s++; 1484887Schin continue; 1494887Schin } 1504887Schin *t++ = '~'; 1514887Schin } 1524887Schin else 1534887Schin *t++ = '@'; 1544887Schin *t++ = '('; 1554887Schin continue; 1564887Schin case ')': 1574887Schin if (p == stack) 1584887Schin return 0; 1594887Schin p--; 1604887Schin *t++ = c; 1614887Schin switch (*s) 1624887Schin { 1634887Schin case 0: 1644887Schin break; 1654887Schin case '*': 1664887Schin case '+': 1674887Schin case '?': 1684887Schin case '!': 1694887Schin **p = *s++; 1704887Schin if (*s == '?') 1714887Schin { 1724887Schin s++; 1734887Schin x = *p + 1; 1744887Schin for (y = ++t; y > x; y--) 1754887Schin *y = *(y - 1); 1764887Schin *x = '-'; 1774887Schin } 1784887Schin continue; 1794887Schin case '{': 1804887Schin for (z = s; *z != '}'; z++) 1814887Schin if (!*z) 1824887Schin return 0; 1834887Schin n = z - s; 1844887Schin if (*++z == '?') 1854887Schin n++; 1864887Schin x = *p + n; 1874887Schin for (y = t += n; y > x; y--) 1884887Schin *y = *(y - n); 1894887Schin for (x = *p; s < z; *x++ = *s++); 1904887Schin if (*s == '?') 1914887Schin { 1924887Schin s++; 1934887Schin *x++ = '-'; 1944887Schin } 1954887Schin continue; 1964887Schin default: 1974887Schin continue; 1984887Schin } 1994887Schin break; 2004887Schin case '.': 2014887Schin switch (*s) 2024887Schin { 2034887Schin case 0: 2044887Schin *t++ = '?'; 2054887Schin break; 2064887Schin case '*': 2074887Schin s++; 2084887Schin *t++ = '*'; 2094887Schin e = !*s; 2104887Schin continue; 2114887Schin case '+': 2124887Schin s++; 2134887Schin *t++ = '?'; 2144887Schin *t++ = '*'; 2154887Schin continue; 2164887Schin case '?': 2174887Schin s++; 2184887Schin *t++ = '?'; 2194887Schin *t++ = '('; 2204887Schin *t++ = '?'; 2214887Schin *t++ = ')'; 2224887Schin continue; 2234887Schin default: 2244887Schin *t++ = '?'; 2254887Schin continue; 2264887Schin } 2274887Schin break; 2284887Schin case '*': 2294887Schin case '+': 2304887Schin case '?': 2314887Schin case '{': 2324887Schin n = *(t - 1); 2334887Schin if (t == b || n == '(' || n == '|') 2344887Schin return 0; 2354887Schin *(t - 1) = c; 2364887Schin if (c == '{') 2374887Schin { 2384887Schin for (z = s; *z != '}'; z++) 2394887Schin if (!*z) 2404887Schin return 0; 2414887Schin for (; s <= z; *t++ = *s++); 2424887Schin } 2434887Schin if (*s == '?') 2444887Schin { 2454887Schin s++; 2464887Schin *t++ = '-'; 2474887Schin } 2484887Schin *t++ = '('; 2494887Schin *t++ = n; 2504887Schin *t++ = ')'; 2514887Schin continue; 2524887Schin case '|': 2534887Schin case '&': 2544887Schin if (t == b || *(t - 1) == '(') 2554887Schin return 0; 2564887Schin logical: 2574887Schin if (!*s || *s == ')') 2584887Schin return 0; 2594887Schin if (p == stack && b == buf + 3) 2604887Schin { 2614887Schin *--b = '('; 2624887Schin *--b = '@'; 2634887Schin } 2644887Schin *t++ = c; 2654887Schin continue; 2664887Schin case '$': 2674887Schin if (e = !*s) 2684887Schin break; 2694887Schin /*FALLTHROUGH*/ 2704887Schin default: 2714887Schin *t++ = c; 2724887Schin continue; 2734887Schin } 2744887Schin break; 2754887Schin } 2764887Schin if (p != stack) 2774887Schin return 0; 2784887Schin if (b != buf + 3) 2794887Schin *t++ = ')'; 2804887Schin if (!a && (*b != '*' || *(b + 1) == '(' || (*(b + 1) == '-' || *(b + 1) == '~') && *(b + 2) == '(')) 2814887Schin *--b = '*'; 2824887Schin if (!e) 2834887Schin *t++ = '*'; 2844887Schin *t = 0; 2854887Schin return b; 2864887Schin } 287