1 /*********************************************************************** 2 * * 3 * This software is part of the ast package * 4 * Copyright (c) 1985-2008 AT&T Intellectual Property * 5 * and is licensed under the * 6 * Common Public License, Version 1.0 * 7 * by AT&T Intellectual Property * 8 * * 9 * A copy of the License is available at * 10 * http://www.opensource.org/licenses/cpl1.0.txt * 11 * (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) * 12 * * 13 * Information and Software Systems Research * 14 * AT&T Research * 15 * Florham Park NJ * 16 * * 17 * Glenn Fowler <gsf@research.att.com> * 18 * David Korn <dgk@research.att.com> * 19 * Phong Vo <kpv@research.att.com> * 20 * * 21 ***********************************************************************/ 22 #pragma prototyped 23 24 /* 25 * Glenn Fowler 26 * AT&T Research 27 * 28 * return RE expression given strmatch() pattern 29 * 0 returned for invalid RE 30 */ 31 32 #include <ast.h> 33 34 typedef struct Stack_s 35 { 36 char* beg; 37 short len; 38 short min; 39 } Stack_t; 40 41 char* 42 fmtre(const char* as) 43 { 44 register char* s = (char*)as; 45 register int c; 46 register char* t; 47 register Stack_t* p; 48 char* x; 49 int n; 50 int end; 51 char* buf; 52 Stack_t stack[32]; 53 54 end = 1; 55 c = 2 * strlen(s) + 1; 56 t = buf = fmtbuf(c); 57 p = stack; 58 if (*s != '*' || *(s + 1) == '(' || *(s + 1) == '-' && *(s + 2) == '(') 59 *t++ = '^'; 60 else 61 s++; 62 for (;;) 63 { 64 switch (c = *s++) 65 { 66 case 0: 67 break; 68 case '\\': 69 if (!(c = *s++) || c == '{' || c == '}') 70 return 0; 71 *t++ = '\\'; 72 if ((*t++ = c) == '(' && *s == '|') 73 { 74 *t++ = *s++; 75 goto logical; 76 } 77 continue; 78 case '[': 79 *t++ = c; 80 n = 0; 81 if ((c = *s++) == '!') 82 { 83 *t++ = '^'; 84 c = *s++; 85 } 86 else if (c == '^') 87 { 88 if ((c = *s++) == ']') 89 { 90 *(t - 1) = '\\'; 91 *t++ = '^'; 92 continue; 93 } 94 n = '^'; 95 } 96 for (;;) 97 { 98 if (!(*t++ = c)) 99 return 0; 100 if ((c = *s++) == ']') 101 { 102 if (n) 103 *t++ = n; 104 *t++ = c; 105 break; 106 } 107 } 108 continue; 109 case '{': 110 for (x = s; *x && *x != '}'; x++); 111 if (*x++ && (*x == '(' || *x == '-' && *(x + 1) == '(')) 112 { 113 if (p >= &stack[elementsof(stack)]) 114 return 0; 115 p->beg = s - 1; 116 s = x; 117 p->len = s - p->beg; 118 if (p->min = *s == '-') 119 s++; 120 p++; 121 *t++ = *s++; 122 } 123 else 124 *t++ = c; 125 continue; 126 case '*': 127 if (!*s) 128 { 129 end = 0; 130 break; 131 } 132 /*FALLTHROUGH*/ 133 case '?': 134 case '+': 135 case '@': 136 case '!': 137 case '~': 138 if (*s == '(' || c != '~' && *s == '-' && *(s + 1) == '(') 139 { 140 if (p >= &stack[elementsof(stack)]) 141 return 0; 142 p->beg = s - 1; 143 if (c == '~') 144 { 145 if (*(s + 1) == 'E' && *(s + 2) == ')') 146 { 147 for (s += 3; *t = *s; t++, s++); 148 continue; 149 } 150 p->len = 0; 151 p->min = 0; 152 *t++ = *s++; 153 *t++ = '?'; 154 } 155 else 156 { 157 p->len = c != '@'; 158 if (p->min = *s == '-') 159 s++; 160 *t++ = *s++; 161 } 162 p++; 163 } 164 else 165 { 166 switch (c) 167 { 168 case '*': 169 *t++ = '.'; 170 break; 171 case '?': 172 c = '.'; 173 break; 174 case '+': 175 case '!': 176 *t++ = '\\'; 177 break; 178 } 179 *t++ = c; 180 } 181 continue; 182 case '(': 183 if (p >= &stack[elementsof(stack)]) 184 return 0; 185 p->beg = s - 1; 186 p->len = 0; 187 p->min = 0; 188 p++; 189 *t++ = c; 190 continue; 191 case ')': 192 if (p == stack) 193 return 0; 194 *t++ = c; 195 p--; 196 for (c = 0; c < p->len; c++) 197 *t++ = p->beg[c]; 198 if (p->min) 199 *t++ = '?'; 200 continue; 201 case '^': 202 case '.': 203 case '$': 204 *t++ = '\\'; 205 *t++ = c; 206 continue; 207 case '|': 208 if (t == buf || *(t - 1) == '(') 209 return 0; 210 logical: 211 if (!*s || *s == ')') 212 return 0; 213 /*FALLTHROUGH*/ 214 default: 215 *t++ = c; 216 continue; 217 } 218 break; 219 } 220 if (p != stack) 221 return 0; 222 if (end) 223 *t++ = '$'; 224 *t = 0; 225 return buf; 226 } 227