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 /* 25da2e3ebdSchin * Glenn Fowler 26da2e3ebdSchin * AT&T Research 27da2e3ebdSchin * 28da2e3ebdSchin * return RE expression given strmatch() pattern 29da2e3ebdSchin * 0 returned for invalid RE 30da2e3ebdSchin */ 31da2e3ebdSchin 32da2e3ebdSchin #include <ast.h> 33da2e3ebdSchin 34da2e3ebdSchin typedef struct Stack_s 35da2e3ebdSchin { 36da2e3ebdSchin char* beg; 37da2e3ebdSchin short len; 38da2e3ebdSchin short min; 39da2e3ebdSchin } Stack_t; 40da2e3ebdSchin 41da2e3ebdSchin char* fmtre(const char * as)42da2e3ebdSchinfmtre(const char* as) 43da2e3ebdSchin { 44da2e3ebdSchin register char* s = (char*)as; 45da2e3ebdSchin register int c; 46da2e3ebdSchin register char* t; 47da2e3ebdSchin register Stack_t* p; 48da2e3ebdSchin char* x; 49da2e3ebdSchin int n; 50da2e3ebdSchin int end; 51da2e3ebdSchin char* buf; 52da2e3ebdSchin Stack_t stack[32]; 53da2e3ebdSchin 54da2e3ebdSchin end = 1; 55da2e3ebdSchin c = 2 * strlen(s) + 1; 56da2e3ebdSchin t = buf = fmtbuf(c); 57da2e3ebdSchin p = stack; 58da2e3ebdSchin if (*s != '*' || *(s + 1) == '(' || *(s + 1) == '-' && *(s + 2) == '(') 59da2e3ebdSchin *t++ = '^'; 60da2e3ebdSchin else 61da2e3ebdSchin s++; 62da2e3ebdSchin for (;;) 63da2e3ebdSchin { 64da2e3ebdSchin switch (c = *s++) 65da2e3ebdSchin { 66da2e3ebdSchin case 0: 67da2e3ebdSchin break; 68da2e3ebdSchin case '\\': 69da2e3ebdSchin if (!(c = *s++) || c == '{' || c == '}') 70da2e3ebdSchin return 0; 71da2e3ebdSchin *t++ = '\\'; 72da2e3ebdSchin if ((*t++ = c) == '(' && *s == '|') 73da2e3ebdSchin { 74da2e3ebdSchin *t++ = *s++; 75da2e3ebdSchin goto logical; 76da2e3ebdSchin } 77da2e3ebdSchin continue; 78da2e3ebdSchin case '[': 79da2e3ebdSchin *t++ = c; 80da2e3ebdSchin n = 0; 81da2e3ebdSchin if ((c = *s++) == '!') 82da2e3ebdSchin { 83da2e3ebdSchin *t++ = '^'; 84da2e3ebdSchin c = *s++; 85da2e3ebdSchin } 86da2e3ebdSchin else if (c == '^') 87da2e3ebdSchin { 88da2e3ebdSchin if ((c = *s++) == ']') 89da2e3ebdSchin { 90da2e3ebdSchin *(t - 1) = '\\'; 91da2e3ebdSchin *t++ = '^'; 92da2e3ebdSchin continue; 93da2e3ebdSchin } 94da2e3ebdSchin n = '^'; 95da2e3ebdSchin } 96da2e3ebdSchin for (;;) 97da2e3ebdSchin { 98da2e3ebdSchin if (!(*t++ = c)) 99da2e3ebdSchin return 0; 100da2e3ebdSchin if ((c = *s++) == ']') 101da2e3ebdSchin { 102da2e3ebdSchin if (n) 103da2e3ebdSchin *t++ = n; 104da2e3ebdSchin *t++ = c; 105da2e3ebdSchin break; 106da2e3ebdSchin } 107da2e3ebdSchin } 108da2e3ebdSchin continue; 109da2e3ebdSchin case '{': 110da2e3ebdSchin for (x = s; *x && *x != '}'; x++); 111da2e3ebdSchin if (*x++ && (*x == '(' || *x == '-' && *(x + 1) == '(')) 112da2e3ebdSchin { 113da2e3ebdSchin if (p >= &stack[elementsof(stack)]) 114da2e3ebdSchin return 0; 115da2e3ebdSchin p->beg = s - 1; 116da2e3ebdSchin s = x; 117da2e3ebdSchin p->len = s - p->beg; 118da2e3ebdSchin if (p->min = *s == '-') 119da2e3ebdSchin s++; 120da2e3ebdSchin p++; 121da2e3ebdSchin *t++ = *s++; 122da2e3ebdSchin } 123da2e3ebdSchin else 124da2e3ebdSchin *t++ = c; 125da2e3ebdSchin continue; 126da2e3ebdSchin case '*': 127da2e3ebdSchin if (!*s) 128da2e3ebdSchin { 129da2e3ebdSchin end = 0; 130da2e3ebdSchin break; 131da2e3ebdSchin } 132da2e3ebdSchin /*FALLTHROUGH*/ 133da2e3ebdSchin case '?': 134da2e3ebdSchin case '+': 135da2e3ebdSchin case '@': 136da2e3ebdSchin case '!': 137da2e3ebdSchin case '~': 138da2e3ebdSchin if (*s == '(' || c != '~' && *s == '-' && *(s + 1) == '(') 139da2e3ebdSchin { 140da2e3ebdSchin if (p >= &stack[elementsof(stack)]) 141da2e3ebdSchin return 0; 142da2e3ebdSchin p->beg = s - 1; 143da2e3ebdSchin if (c == '~') 144da2e3ebdSchin { 145da2e3ebdSchin if (*(s + 1) == 'E' && *(s + 2) == ')') 146da2e3ebdSchin { 147da2e3ebdSchin for (s += 3; *t = *s; t++, s++); 148da2e3ebdSchin continue; 149da2e3ebdSchin } 150da2e3ebdSchin p->len = 0; 1517c2fbfb3SApril Chin p->min = 0; 152da2e3ebdSchin *t++ = *s++; 153da2e3ebdSchin *t++ = '?'; 154da2e3ebdSchin } 155da2e3ebdSchin else 156da2e3ebdSchin { 157da2e3ebdSchin p->len = c != '@'; 158da2e3ebdSchin if (p->min = *s == '-') 159da2e3ebdSchin s++; 160da2e3ebdSchin *t++ = *s++; 161da2e3ebdSchin } 162da2e3ebdSchin p++; 163da2e3ebdSchin } 164da2e3ebdSchin else 165da2e3ebdSchin { 166da2e3ebdSchin switch (c) 167da2e3ebdSchin { 168da2e3ebdSchin case '*': 169da2e3ebdSchin *t++ = '.'; 170da2e3ebdSchin break; 171da2e3ebdSchin case '?': 172da2e3ebdSchin c = '.'; 173da2e3ebdSchin break; 174da2e3ebdSchin case '+': 175da2e3ebdSchin case '!': 176da2e3ebdSchin *t++ = '\\'; 177da2e3ebdSchin break; 178da2e3ebdSchin } 179da2e3ebdSchin *t++ = c; 180da2e3ebdSchin } 181da2e3ebdSchin continue; 182da2e3ebdSchin case '(': 183da2e3ebdSchin if (p >= &stack[elementsof(stack)]) 184da2e3ebdSchin return 0; 185da2e3ebdSchin p->beg = s - 1; 186da2e3ebdSchin p->len = 0; 187da2e3ebdSchin p->min = 0; 188da2e3ebdSchin p++; 189da2e3ebdSchin *t++ = c; 190da2e3ebdSchin continue; 191da2e3ebdSchin case ')': 192da2e3ebdSchin if (p == stack) 193da2e3ebdSchin return 0; 194da2e3ebdSchin *t++ = c; 195da2e3ebdSchin p--; 196da2e3ebdSchin for (c = 0; c < p->len; c++) 197da2e3ebdSchin *t++ = p->beg[c]; 198da2e3ebdSchin if (p->min) 199da2e3ebdSchin *t++ = '?'; 200da2e3ebdSchin continue; 201da2e3ebdSchin case '^': 202da2e3ebdSchin case '.': 203da2e3ebdSchin case '$': 204da2e3ebdSchin *t++ = '\\'; 205da2e3ebdSchin *t++ = c; 206da2e3ebdSchin continue; 207da2e3ebdSchin case '|': 208da2e3ebdSchin if (t == buf || *(t - 1) == '(') 209da2e3ebdSchin return 0; 210da2e3ebdSchin logical: 211da2e3ebdSchin if (!*s || *s == ')') 212da2e3ebdSchin return 0; 213da2e3ebdSchin /*FALLTHROUGH*/ 214da2e3ebdSchin default: 215da2e3ebdSchin *t++ = c; 216da2e3ebdSchin continue; 217da2e3ebdSchin } 218da2e3ebdSchin break; 219da2e3ebdSchin } 220da2e3ebdSchin if (p != stack) 221da2e3ebdSchin return 0; 222da2e3ebdSchin if (end) 223da2e3ebdSchin *t++ = '$'; 224da2e3ebdSchin *t = 0; 225da2e3ebdSchin return buf; 226da2e3ebdSchin } 227