1da2e3ebdSchin /*********************************************************************** 2da2e3ebdSchin * * 3da2e3ebdSchin * This software is part of the ast package * 4*3e14f97fSRoger A. Faulkner * Copyright (c) 1985-2010 AT&T Intellectual Property * 5da2e3ebdSchin * and is licensed under the * 6da2e3ebdSchin * Common Public License, Version 1.0 * 77c2fbfb3SApril Chin * by AT&T Intellectual Property * 8da2e3ebdSchin * * 9da2e3ebdSchin * A copy of the License is available at * 10da2e3ebdSchin * http://www.opensource.org/licenses/cpl1.0.txt * 11da2e3ebdSchin * (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) * 12da2e3ebdSchin * * 13da2e3ebdSchin * Information and Software Systems Research * 14da2e3ebdSchin * AT&T Research * 15da2e3ebdSchin * Florham Park NJ * 16da2e3ebdSchin * * 17da2e3ebdSchin * Glenn Fowler <gsf@research.att.com> * 18da2e3ebdSchin * David Korn <dgk@research.att.com> * 19da2e3ebdSchin * Phong Vo <kpv@research.att.com> * 20da2e3ebdSchin * * 21da2e3ebdSchin ***********************************************************************/ 22da2e3ebdSchin #pragma prototyped 23da2e3ebdSchin /* 24da2e3ebdSchin * Glenn Fowler 25da2e3ebdSchin * AT&T Research 26da2e3ebdSchin * 27da2e3ebdSchin * return strmatch() expression given REG_AUGMENTED RE 28da2e3ebdSchin * 0 returned for invalid RE 29da2e3ebdSchin */ 30da2e3ebdSchin 31da2e3ebdSchin #include <ast.h> 32da2e3ebdSchin 33da2e3ebdSchin char* fmtmatch(const char * as)34da2e3ebdSchinfmtmatch(const char* as) 35da2e3ebdSchin { 36da2e3ebdSchin register char* s = (char*)as; 37da2e3ebdSchin register int c; 38da2e3ebdSchin register char* t; 39da2e3ebdSchin register char** p; 40da2e3ebdSchin register char* b; 41da2e3ebdSchin char* x; 42da2e3ebdSchin char* y; 43da2e3ebdSchin char* z; 44da2e3ebdSchin int a; 45da2e3ebdSchin int e; 46da2e3ebdSchin int n; 47da2e3ebdSchin char* buf; 48da2e3ebdSchin char* stack[32]; 49da2e3ebdSchin 50da2e3ebdSchin c = 3 * (strlen(s) + 1); 51da2e3ebdSchin buf = fmtbuf(c); 52da2e3ebdSchin t = b = buf + 3; 53da2e3ebdSchin p = stack; 54da2e3ebdSchin if (a = *s == '^') 55da2e3ebdSchin s++; 56da2e3ebdSchin e = 0; 57da2e3ebdSchin for (;;) 58da2e3ebdSchin { 59da2e3ebdSchin switch (c = *s++) 60da2e3ebdSchin { 61da2e3ebdSchin case 0: 62da2e3ebdSchin break; 63da2e3ebdSchin case '\\': 64da2e3ebdSchin if (!(c = *s++)) 65da2e3ebdSchin return 0; 66da2e3ebdSchin switch (*s) 67da2e3ebdSchin { 68da2e3ebdSchin case '*': 69da2e3ebdSchin case '+': 70da2e3ebdSchin case '?': 71da2e3ebdSchin *t++ = *s++; 72da2e3ebdSchin *t++ = '('; 73da2e3ebdSchin *t++ = '\\'; 74da2e3ebdSchin *t++ = c; 75da2e3ebdSchin c = ')'; 76da2e3ebdSchin break; 77da2e3ebdSchin case '|': 78da2e3ebdSchin case '&': 79da2e3ebdSchin if (c == '(') 80da2e3ebdSchin { 81da2e3ebdSchin *t++ = c; 82da2e3ebdSchin c = *s++; 83da2e3ebdSchin goto logical; 84da2e3ebdSchin } 85da2e3ebdSchin break; 86da2e3ebdSchin case '{': 87da2e3ebdSchin case '}': 88da2e3ebdSchin break; 89da2e3ebdSchin default: 90da2e3ebdSchin *t++ = '\\'; 91da2e3ebdSchin break; 92da2e3ebdSchin } 93da2e3ebdSchin *t++ = c; 94da2e3ebdSchin continue; 95da2e3ebdSchin case '[': 96da2e3ebdSchin x = t; 97da2e3ebdSchin *t++ = c; 98da2e3ebdSchin if ((c = *s++) == '^') 99da2e3ebdSchin { 100da2e3ebdSchin *t++ = '!'; 101da2e3ebdSchin c = *s++; 102da2e3ebdSchin } 103da2e3ebdSchin else if (c == '!') 104da2e3ebdSchin { 105da2e3ebdSchin *t++ = '\\'; 106da2e3ebdSchin *t++ = c; 107da2e3ebdSchin c = *s++; 108da2e3ebdSchin } 109da2e3ebdSchin for (;;) 110da2e3ebdSchin { 111da2e3ebdSchin if (!(*t++ = c)) 112da2e3ebdSchin return 0; 113da2e3ebdSchin if (c == '\\') 114da2e3ebdSchin *t++ = c; 115da2e3ebdSchin if ((c = *s++) == ']') 116da2e3ebdSchin { 117da2e3ebdSchin *t++ = c; 118da2e3ebdSchin break; 119da2e3ebdSchin } 120da2e3ebdSchin } 121da2e3ebdSchin switch (*s) 122da2e3ebdSchin { 123da2e3ebdSchin case '*': 124da2e3ebdSchin case '+': 125da2e3ebdSchin case '?': 126da2e3ebdSchin for (y = t + 2, t--; t >= x; t--) 127da2e3ebdSchin *(t + 2) = *t; 128da2e3ebdSchin *++t = *s++; 129da2e3ebdSchin *++t = '('; 130da2e3ebdSchin t = y; 131da2e3ebdSchin *t++ = ')'; 132da2e3ebdSchin break; 133da2e3ebdSchin } 134da2e3ebdSchin continue; 135da2e3ebdSchin case '(': 136da2e3ebdSchin if (p >= &stack[elementsof(stack)]) 137da2e3ebdSchin return 0; 138da2e3ebdSchin *p++ = t; 139da2e3ebdSchin if (*s == '?') 140da2e3ebdSchin { 141da2e3ebdSchin s++; 142da2e3ebdSchin if (*s == 'K' && *(s + 1) == ')') 143da2e3ebdSchin { 144da2e3ebdSchin s += 2; 145da2e3ebdSchin p--; 146da2e3ebdSchin while (*t = *s) 147da2e3ebdSchin t++, s++; 148da2e3ebdSchin continue; 149da2e3ebdSchin } 150da2e3ebdSchin *t++ = '~'; 151da2e3ebdSchin } 152da2e3ebdSchin else 153da2e3ebdSchin *t++ = '@'; 154da2e3ebdSchin *t++ = '('; 155da2e3ebdSchin continue; 156da2e3ebdSchin case ')': 157da2e3ebdSchin if (p == stack) 158da2e3ebdSchin return 0; 159da2e3ebdSchin p--; 160da2e3ebdSchin *t++ = c; 161da2e3ebdSchin switch (*s) 162da2e3ebdSchin { 163da2e3ebdSchin case 0: 164da2e3ebdSchin break; 165da2e3ebdSchin case '*': 166da2e3ebdSchin case '+': 167da2e3ebdSchin case '?': 168da2e3ebdSchin case '!': 169da2e3ebdSchin **p = *s++; 170da2e3ebdSchin if (*s == '?') 171da2e3ebdSchin { 172da2e3ebdSchin s++; 173da2e3ebdSchin x = *p + 1; 174da2e3ebdSchin for (y = ++t; y > x; y--) 175da2e3ebdSchin *y = *(y - 1); 176da2e3ebdSchin *x = '-'; 177da2e3ebdSchin } 178da2e3ebdSchin continue; 179da2e3ebdSchin case '{': 180da2e3ebdSchin for (z = s; *z != '}'; z++) 181da2e3ebdSchin if (!*z) 182da2e3ebdSchin return 0; 183da2e3ebdSchin n = z - s; 184da2e3ebdSchin if (*++z == '?') 185da2e3ebdSchin n++; 186da2e3ebdSchin x = *p + n; 187da2e3ebdSchin for (y = t += n; y > x; y--) 188da2e3ebdSchin *y = *(y - n); 189da2e3ebdSchin for (x = *p; s < z; *x++ = *s++); 190da2e3ebdSchin if (*s == '?') 191da2e3ebdSchin { 192da2e3ebdSchin s++; 193da2e3ebdSchin *x++ = '-'; 194da2e3ebdSchin } 195da2e3ebdSchin continue; 196da2e3ebdSchin default: 197da2e3ebdSchin continue; 198da2e3ebdSchin } 199da2e3ebdSchin break; 200da2e3ebdSchin case '.': 201da2e3ebdSchin switch (*s) 202da2e3ebdSchin { 203da2e3ebdSchin case 0: 204da2e3ebdSchin *t++ = '?'; 205da2e3ebdSchin break; 206da2e3ebdSchin case '*': 207da2e3ebdSchin s++; 208da2e3ebdSchin *t++ = '*'; 209da2e3ebdSchin e = !*s; 210da2e3ebdSchin continue; 211da2e3ebdSchin case '+': 212da2e3ebdSchin s++; 213da2e3ebdSchin *t++ = '?'; 214da2e3ebdSchin *t++ = '*'; 215da2e3ebdSchin continue; 216da2e3ebdSchin case '?': 217da2e3ebdSchin s++; 218da2e3ebdSchin *t++ = '?'; 219da2e3ebdSchin *t++ = '('; 220da2e3ebdSchin *t++ = '?'; 221da2e3ebdSchin *t++ = ')'; 222da2e3ebdSchin continue; 223da2e3ebdSchin default: 224da2e3ebdSchin *t++ = '?'; 225da2e3ebdSchin continue; 226da2e3ebdSchin } 227da2e3ebdSchin break; 228da2e3ebdSchin case '*': 229da2e3ebdSchin case '+': 230da2e3ebdSchin case '?': 231da2e3ebdSchin case '{': 232da2e3ebdSchin n = *(t - 1); 233da2e3ebdSchin if (t == b || n == '(' || n == '|') 234da2e3ebdSchin return 0; 235da2e3ebdSchin *(t - 1) = c; 236da2e3ebdSchin if (c == '{') 237da2e3ebdSchin { 238da2e3ebdSchin for (z = s; *z != '}'; z++) 239da2e3ebdSchin if (!*z) 240da2e3ebdSchin return 0; 241da2e3ebdSchin for (; s <= z; *t++ = *s++); 242da2e3ebdSchin } 243da2e3ebdSchin if (*s == '?') 244da2e3ebdSchin { 245da2e3ebdSchin s++; 246da2e3ebdSchin *t++ = '-'; 247da2e3ebdSchin } 248da2e3ebdSchin *t++ = '('; 249da2e3ebdSchin *t++ = n; 250da2e3ebdSchin *t++ = ')'; 251da2e3ebdSchin continue; 252da2e3ebdSchin case '|': 253da2e3ebdSchin case '&': 254da2e3ebdSchin if (t == b || *(t - 1) == '(') 255da2e3ebdSchin return 0; 256da2e3ebdSchin logical: 257da2e3ebdSchin if (!*s || *s == ')') 258da2e3ebdSchin return 0; 259da2e3ebdSchin if (p == stack && b == buf + 3) 260da2e3ebdSchin { 261da2e3ebdSchin *--b = '('; 262da2e3ebdSchin *--b = '@'; 263da2e3ebdSchin } 264da2e3ebdSchin *t++ = c; 265da2e3ebdSchin continue; 266da2e3ebdSchin case '$': 267da2e3ebdSchin if (e = !*s) 268da2e3ebdSchin break; 269da2e3ebdSchin /*FALLTHROUGH*/ 270da2e3ebdSchin default: 271da2e3ebdSchin *t++ = c; 272da2e3ebdSchin continue; 273da2e3ebdSchin } 274da2e3ebdSchin break; 275da2e3ebdSchin } 276da2e3ebdSchin if (p != stack) 277da2e3ebdSchin return 0; 278da2e3ebdSchin if (b != buf + 3) 279da2e3ebdSchin *t++ = ')'; 280da2e3ebdSchin if (!a && (*b != '*' || *(b + 1) == '(' || (*(b + 1) == '-' || *(b + 1) == '~') && *(b + 2) == '(')) 281da2e3ebdSchin *--b = '*'; 282da2e3ebdSchin if (!e) 283da2e3ebdSchin *t++ = '*'; 284da2e3ebdSchin *t = 0; 285da2e3ebdSchin return b; 286da2e3ebdSchin } 287