diff options
author | chin <none@none> | 2007-08-17 12:01:52 -0700 |
---|---|---|
committer | chin <none@none> | 2007-08-17 12:01:52 -0700 |
commit | da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968 (patch) | |
tree | 5280d3b78e289fe9551371ab6e7f15ef9944ea14 /usr/src/lib/libast/common/regex/regsubcomp.c | |
parent | 073dbf9103ef2a2b05d8a16e2d26db04e0374b0e (diff) | |
download | illumos-gate-da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968.tar.gz |
6437624 RFE: Add ksh93 (as /usr/bin/ksh93) and libshell.so to OS/Net
6505835 AST tools and library (libpp) required for creating l10n messages for ksh93
PSARC/2006/550 Korn Shell 93 Integration
PSARC/2006/587 /etc/ksh.kshrc for ksh93
PSARC/2007/035 ksh93 Amendments
Contributed by Roland Mainz <roland.mainz@nrubsig.org>
--HG--
rename : usr/src/lib/libcmd/common/mapfile-vers => deleted_files/usr/src/lib/libcmd/common/mapfile-vers
rename : usr/src/lib/libcmd/common/placeholder.c => deleted_files/usr/src/lib/libcmd/common/placeholder.c
Diffstat (limited to 'usr/src/lib/libast/common/regex/regsubcomp.c')
-rw-r--r-- | usr/src/lib/libast/common/regex/regsubcomp.c | 452 |
1 files changed, 452 insertions, 0 deletions
diff --git a/usr/src/lib/libast/common/regex/regsubcomp.c b/usr/src/lib/libast/common/regex/regsubcomp.c new file mode 100644 index 0000000000..f8806a2544 --- /dev/null +++ b/usr/src/lib/libast/common/regex/regsubcomp.c @@ -0,0 +1,452 @@ +/*********************************************************************** +* * +* 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 + +/* + * posix regex ed(1) style substitute compile + */ + +#include "reglib.h" + +static const regflags_t submap[] = +{ + 'g', REG_SUB_ALL, + 'l', REG_SUB_LOWER, + 'n', REG_SUB_NUMBER, + 'p', REG_SUB_PRINT, + 's', REG_SUB_STOP, + 'u', REG_SUB_UPPER, + 'w', REG_SUB_WRITE|REG_SUB_LAST, + 0, 0 +}; + +int +regsubflags(regex_t* p, register const char* s, char** e, int delim, register const regflags_t* map, int* pm, regflags_t* pf) +{ + register int c; + register const regflags_t* m; + regflags_t flags; + int minmatch; + regdisc_t* disc; + + flags = pf ? *pf : 0; + minmatch = pm ? *pm : 0; + if (!map) + map = submap; + while (!(flags & REG_SUB_LAST)) + { + if (!(c = *s++) || c == delim) + { + s--; + break; + } + else if (c >= '0' && c <= '9') + { + if (minmatch) + { + disc = p->env->disc; + regfree(p); + return fatal(disc, REG_EFLAGS, s - 1); + } + minmatch = c - '0'; + while (*s >= '0' && *s <= '9') + minmatch = minmatch * 10 + *s++ - '0'; + } + else + { + for (m = map; *m; m++) + if (*m++ == c) + { + if (flags & *m) + { + disc = p->env->disc; + regfree(p); + return fatal(disc, REG_EFLAGS, s - 1); + } + flags |= *m--; + break; + } + if (!*m) + { + s--; + break; + } + } + } + if (pf) + *pf = flags; + if (pm) + *pm = minmatch; + if (e) + *e = (char*)s; + return 0; +} + +/* + * compile substitute rhs and optional flags + */ + +int +regsubcomp(regex_t* p, register const char* s, const regflags_t* map, int minmatch, regflags_t flags) +{ + register regsub_t* sub; + register int c; + register int d; + register char* t; + register regsubop_t* op; + char* e; + const char* r; + int sre; + int f; + int g; + int n; + int nops; + const char* o; + regdisc_t* disc; + + disc = p->env->disc; + if (p->env->flags & REG_NOSUB) + { + regfree(p); + return fatal(disc, REG_BADPAT, NiL); + } + if (!(sub = (regsub_t*)alloc(p->env->disc, 0, sizeof(regsub_t) + strlen(s))) || !(sub->re_ops = (regsubop_t*)alloc(p->env->disc, 0, (nops = 8) * sizeof(regsubop_t)))) + { + if (sub) + alloc(p->env->disc, sub, 0); + regfree(p); + return fatal(disc, REG_ESPACE, s); + } + sub->re_buf = sub->re_end = 0; + p->re_sub = sub; + p->env->sub = 1; + op = sub->re_ops; + o = s; + if (!(p->env->flags & REG_DELIMITED)) + d = 0; + else + switch (d = *(s - 1)) + { + case '\\': + case '\n': + case '\r': + regfree(p); + return fatal(disc, REG_EDELIM, s); + } + sre = p->env->flags & REG_SHELL; + t = sub->re_rhs; + if (d) + { + r = s; + for (;;) + { + if (!*s) + { + if (p->env->flags & REG_MUSTDELIM) + { + regfree(p); + return fatal(disc, REG_EDELIM, r); + } + break; + } + else if (*s == d) + { + flags |= REG_SUB_FULL; + s++; + break; + } + else if (*s++ == '\\' && !*s++) + { + regfree(p); + return fatal(disc, REG_EESCAPE, r); + } + } + if (*s) + { + if (n = regsubflags(p, s, &e, d, map, &minmatch, &flags)) + return n; + s = (const char*)e; + } + p->re_npat = s - o; + s = r; + } + else + p->re_npat = 0; + op->op = f = g = flags & (REG_SUB_LOWER|REG_SUB_UPPER); + op->off = 0; + while ((c = *s++) != d) + { + again: + if (!c) + { + p->re_npat = s - o - 1; + break; + } + else if (c == '~') + { + if (!sre || *s != '(') + { + *t++ = c; + continue; + } + r = s - 1; + s++; + c = *s++; + } + else if (c == '\\') + { + if (*s == c) + { + *t++ = *s++; + continue; + } + if ((c = *s++) == d) + goto again; + if (!c) + { + regfree(p); + return fatal(disc, REG_EESCAPE, s - 2); + } + if (sre) + { + *t++ = chresc(s - 2, &e); + s = (const char*)e; + continue; + } + if (c == '&') + { + *t++ = c; + continue; + } + } + else if (c == '&') + { + if (sre) + { + *t++ = c; + continue; + } + } + else + { + switch (op->op) + { + case REG_SUB_UPPER: + if (islower(c)) + c = toupper(c); + break; + case REG_SUB_LOWER: + if (isupper(c)) + c = tolower(c); + break; + case REG_SUB_UPPER|REG_SUB_LOWER: + if (isupper(c)) + c = tolower(c); + else if (islower(c)) + c = toupper(c); + break; + } + *t++ = c; + continue; + } + switch (c) + { + case 0: + s--; + continue; + case '&': + c = 0; + break; + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + c -= '0'; + if (sre) + while (isdigit(*s)) + c = c * 10 + *s++ - '0'; + else if (isdigit(*s) && (p->env->flags & REG_MULTIREF)) + c = c * 10 + *s++ - '0'; + break; + case 'l': + if (sre) + { + if (*s != ')') + { + c = -1; + break; + } + s++; + } + if (c = *s) + { + s++; + if (isupper(c)) + c = tolower(c); + *t++ = c; + } + continue; + case 'u': + if (sre) + { + if (*s != ')') + { + c = -1; + break; + } + s++; + } + if (c = *s) + { + s++; + if (islower(c)) + c = toupper(c); + *t++ = c; + } + continue; + case 'E': + if (sre) + { + if (*s != ')') + { + c = -1; + break; + } + s++; + } + f = g; + set: + if ((op->len = (t - sub->re_rhs) - op->off) && (n = ++op - sub->re_ops) >= nops) + { + if (!(sub->re_ops = (regsubop_t*)alloc(p->env->disc, sub->re_ops, (nops *= 2) * sizeof(regsubop_t)))) + { + regfree(p); + return fatal(disc, REG_ESPACE, NiL); + } + op = sub->re_ops + n; + } + op->op = f; + op->off = t - sub->re_rhs; + continue; + case 'L': + if (sre) + { + if (*s != ')') + { + c = -1; + break; + } + s++; + } + g = f; + f = REG_SUB_LOWER; + goto set; + case 'U': + if (sre) + { + if (*s != ')') + { + c = -1; + break; + } + s++; + } + g = f; + f = REG_SUB_UPPER; + goto set; + default: + if (!sre) + { + *t++ = chresc(s - 2, &e); + s = (const char*)e; + continue; + } + s--; + c = -1; + break; + } + if (sre) + { + if (c < 0 || *s != ')') + { + while (r < s) + *t++ = *r++; + continue; + } + s++; + } + if (c > p->re_nsub) + { + regfree(p); + return fatal(disc, REG_ESUBREG, s - 1); + } + if ((n = op - sub->re_ops) >= (nops - 2)) + { + if (!(sub->re_ops = (regsubop_t*)alloc(p->env->disc, sub->re_ops, (nops *= 2) * sizeof(regsubop_t)))) + { + regfree(p); + return fatal(disc, REG_ESPACE, NiL); + } + op = sub->re_ops + n; + } + if (op->len = (t - sub->re_rhs) - op->off) + op++; + op->op = f; + op->off = c; + op->len = 0; + op++; + op->op = f; + op->off = t - sub->re_rhs; + } + if ((op->len = (t - sub->re_rhs) - op->off) && (n = ++op - sub->re_ops) >= nops) + { + if (!(sub->re_ops = (regsubop_t*)alloc(p->env->disc, sub->re_ops, (nops *= 2) * sizeof(regsubop_t)))) + { + regfree(p); + return fatal(disc, REG_ESPACE, NiL); + } + op = sub->re_ops + n; + } + op->len = -1; + sub->re_flags = flags; + sub->re_min = minmatch; + return 0; +} + +void +regsubfree(regex_t* p) +{ + Env_t* env; + regsub_t* sub; + + if (p && (env = p->env) && env->sub && (sub = p->re_sub)) + { + env->sub = 0; + p->re_sub = 0; + if (!(env->disc->re_flags & REG_NOFREE)) + { + if (sub->re_buf) + alloc(env->disc, sub->re_buf, 0); + if (sub->re_ops) + alloc(env->disc, sub->re_ops, 0); + alloc(env->disc, sub, 0); + } + } +} |