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/regsubexec.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/regsubexec.c')
-rw-r--r-- | usr/src/lib/libast/common/regex/regsubexec.c | 190 |
1 files changed, 190 insertions, 0 deletions
diff --git a/usr/src/lib/libast/common/regex/regsubexec.c b/usr/src/lib/libast/common/regex/regsubexec.c new file mode 100644 index 0000000000..9682e69f5d --- /dev/null +++ b/usr/src/lib/libast/common/regex/regsubexec.c @@ -0,0 +1,190 @@ +/*********************************************************************** +* * +* 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 execute + */ + +#include "reglib.h" + +#define NEED(p,b,n,r) \ + do \ + { \ + if (((b)->re_end - (b)->re_cur) < (n)) \ + { \ + size_t o = (b)->re_cur - (b)->re_buf; \ + size_t a = ((b)->re_end - (b)->re_buf); \ + if (a < n) \ + a = roundof(n, 128); \ + a *= 2; \ + if (!((b)->re_buf = alloc(p->env->disc, (b)->re_buf, a))) \ + { \ + (b)->re_buf = (b)->re_cur = (b)->re_end = 0; \ + c = REG_ESPACE; \ + r; \ + } \ + (b)->re_cur = (b)->re_buf + o; \ + (b)->re_end = (b)->re_buf + a; \ + } \ + } while (0) + +#define PUTC(p,b,x,r) \ + do \ + { \ + NEED(p, b, 1, r); \ + *(b)->re_cur++ = (x); \ + } while (0) + +#define PUTS(p,b,x,z,r) \ + do if (z) \ + { \ + NEED(p, b, z, r); \ + memcpy((b)->re_cur, x, z); \ + (b)->re_cur += (z); \ + } while (0) + +/* + * do a single substitution + */ + +static int +sub(const regex_t* p, register regsub_t* b, const char* ss, register regsubop_t* op, size_t nmatch, register regmatch_t* match) +{ + register char* s; + register char* e; + register int c; + + for (;; op++) + { + switch (op->len) + { + case -1: + break; + case 0: + if (op->off >= nmatch) + return REG_ESUBREG; + if ((c = match[op->off].rm_so) < 0) + continue; + s = (char*)ss + c; + if ((c = match[op->off].rm_eo) < 0) + continue; + e = (char*)ss + c; + NEED(p, b, e - s, return c); + switch (op->op) + { + case REG_SUB_UPPER: + while (s < e) + { + c = *s++; + if (islower(c)) + c = toupper(c); + *b->re_cur++ = c; + } + break; + case REG_SUB_LOWER: + while (s < e) + { + c = *s++; + if (isupper(c)) + c = tolower(c); + *b->re_cur++ = c; + } + break; + case REG_SUB_UPPER|REG_SUB_LOWER: + while (s < e) + { + c = *s++; + if (isupper(c)) + c = tolower(c); + else if (islower(c)) + c = toupper(c); + *b->re_cur++ = c; + } + break; + default: + while (s < e) + *b->re_cur++ = *s++; + break; + } + continue; + default: + NEED(p, b, op->len, return c); + s = b->re_rhs + op->off; + e = s + op->len; + while (s < e) + *b->re_cur++ = *s++; + continue; + } + break; + } + return 0; +} + +/* + * ed(1) style substitute using matches from last regexec() + */ + +int +regsubexec(const regex_t* p, const char* s, size_t nmatch, regmatch_t* match) +{ + register int c; + register regsub_t* b; + const char* e; + int m; + + if (!p->env->sub || (p->env->flags & REG_NOSUB) || !nmatch) + return fatal(p->env->disc, REG_BADPAT, NiL); + b = p->re_sub; + m = b->re_min; + b->re_cur = b->re_buf; + e = (const char*)p->env->end; + for (;;) + { + if (--m > 0) + PUTS(p, b, s, match->rm_eo, return fatal(p->env->disc, c, NiL)); + else + { + PUTS(p, b, s, match->rm_so, return fatal(p->env->disc, c, NiL)); + if (c = sub(p, b, s, b->re_ops, nmatch, match)) + return fatal(p->env->disc, c, NiL); + } + s += match->rm_eo; + if (m <= 0 && !(b->re_flags & REG_SUB_ALL)) + break; + if (c = regnexec(p, s, e - s, nmatch, match, p->env->flags|(match->rm_so == match->rm_eo ? REG_ADVANCE : 0))) + { + if (c != REG_NOMATCH) + return fatal(p->env->disc, c, NiL); + break; + } + } + while (s < e) + { + c = *s++; + PUTC(p, b, c, return fatal(p->env->disc, c, NiL)); + } + NEED(p, b, 1, return fatal(p->env->disc, c, NiL)); + *b->re_cur = 0; + b->re_len = b->re_cur - b->re_buf; + return 0; +} |