diff options
Diffstat (limited to 'usr/src/lib/libast/common/string/fmtmatch.c')
-rw-r--r-- | usr/src/lib/libast/common/string/fmtmatch.c | 286 |
1 files changed, 286 insertions, 0 deletions
diff --git a/usr/src/lib/libast/common/string/fmtmatch.c b/usr/src/lib/libast/common/string/fmtmatch.c new file mode 100644 index 0000000000..f5b27c71bd --- /dev/null +++ b/usr/src/lib/libast/common/string/fmtmatch.c @@ -0,0 +1,286 @@ +/*********************************************************************** +* * +* This software is part of the ast package * +* Copyright (c) 1985-2007 AT&T Knowledge Ventures * +* and is licensed under the * +* Common Public License, Version 1.0 * +* by AT&T Knowledge Ventures * +* * +* A copy of the License is available at * +* http://www.opensource.org/licenses/cpl1.0.txt * +* (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) * +* * +* Information and Software Systems Research * +* AT&T Research * +* Florham Park NJ * +* * +* Glenn Fowler <gsf@research.att.com> * +* David Korn <dgk@research.att.com> * +* Phong Vo <kpv@research.att.com> * +* * +***********************************************************************/ +#pragma prototyped +/* + * Glenn Fowler + * AT&T Research + * + * return strmatch() expression given REG_AUGMENTED RE + * 0 returned for invalid RE + */ + +#include <ast.h> + +char* +fmtmatch(const char* as) +{ + register char* s = (char*)as; + register int c; + register char* t; + register char** p; + register char* b; + char* x; + char* y; + char* z; + int a; + int e; + int n; + char* buf; + char* stack[32]; + + c = 3 * (strlen(s) + 1); + buf = fmtbuf(c); + t = b = buf + 3; + p = stack; + if (a = *s == '^') + s++; + e = 0; + for (;;) + { + switch (c = *s++) + { + case 0: + break; + case '\\': + if (!(c = *s++)) + return 0; + switch (*s) + { + case '*': + case '+': + case '?': + *t++ = *s++; + *t++ = '('; + *t++ = '\\'; + *t++ = c; + c = ')'; + break; + case '|': + case '&': + if (c == '(') + { + *t++ = c; + c = *s++; + goto logical; + } + break; + case '{': + case '}': + break; + default: + *t++ = '\\'; + break; + } + *t++ = c; + continue; + case '[': + x = t; + *t++ = c; + if ((c = *s++) == '^') + { + *t++ = '!'; + c = *s++; + } + else if (c == '!') + { + *t++ = '\\'; + *t++ = c; + c = *s++; + } + for (;;) + { + if (!(*t++ = c)) + return 0; + if (c == '\\') + *t++ = c; + if ((c = *s++) == ']') + { + *t++ = c; + break; + } + } + switch (*s) + { + case '*': + case '+': + case '?': + for (y = t + 2, t--; t >= x; t--) + *(t + 2) = *t; + *++t = *s++; + *++t = '('; + t = y; + *t++ = ')'; + break; + } + continue; + case '(': + if (p >= &stack[elementsof(stack)]) + return 0; + *p++ = t; + if (*s == '?') + { + s++; + if (*s == 'K' && *(s + 1) == ')') + { + s += 2; + p--; + while (*t = *s) + t++, s++; + continue; + } + *t++ = '~'; + } + else + *t++ = '@'; + *t++ = '('; + continue; + case ')': + if (p == stack) + return 0; + p--; + *t++ = c; + switch (*s) + { + case 0: + break; + case '*': + case '+': + case '?': + case '!': + **p = *s++; + if (*s == '?') + { + s++; + x = *p + 1; + for (y = ++t; y > x; y--) + *y = *(y - 1); + *x = '-'; + } + continue; + case '{': + for (z = s; *z != '}'; z++) + if (!*z) + return 0; + n = z - s; + if (*++z == '?') + n++; + x = *p + n; + for (y = t += n; y > x; y--) + *y = *(y - n); + for (x = *p; s < z; *x++ = *s++); + if (*s == '?') + { + s++; + *x++ = '-'; + } + continue; + default: + continue; + } + break; + case '.': + switch (*s) + { + case 0: + *t++ = '?'; + break; + case '*': + s++; + *t++ = '*'; + e = !*s; + continue; + case '+': + s++; + *t++ = '?'; + *t++ = '*'; + continue; + case '?': + s++; + *t++ = '?'; + *t++ = '('; + *t++ = '?'; + *t++ = ')'; + continue; + default: + *t++ = '?'; + continue; + } + break; + case '*': + case '+': + case '?': + case '{': + n = *(t - 1); + if (t == b || n == '(' || n == '|') + return 0; + *(t - 1) = c; + if (c == '{') + { + for (z = s; *z != '}'; z++) + if (!*z) + return 0; + for (; s <= z; *t++ = *s++); + } + if (*s == '?') + { + s++; + *t++ = '-'; + } + *t++ = '('; + *t++ = n; + *t++ = ')'; + continue; + case '|': + case '&': + if (t == b || *(t - 1) == '(') + return 0; + logical: + if (!*s || *s == ')') + return 0; + if (p == stack && b == buf + 3) + { + *--b = '('; + *--b = '@'; + } + *t++ = c; + continue; + case '$': + if (e = !*s) + break; + /*FALLTHROUGH*/ + default: + *t++ = c; + continue; + } + break; + } + if (p != stack) + return 0; + if (b != buf + 3) + *t++ = ')'; + if (!a && (*b != '*' || *(b + 1) == '(' || (*(b + 1) == '-' || *(b + 1) == '~') && *(b + 2) == '(')) + *--b = '*'; + if (!e) + *t++ = '*'; + *t = 0; + return b; +} |