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/regcache.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/regcache.c')
-rw-r--r-- | usr/src/lib/libast/common/regex/regcache.c | 174 |
1 files changed, 174 insertions, 0 deletions
diff --git a/usr/src/lib/libast/common/regex/regcache.c b/usr/src/lib/libast/common/regex/regcache.c new file mode 100644 index 0000000000..ff9554e904 --- /dev/null +++ b/usr/src/lib/libast/common/regex/regcache.c @@ -0,0 +1,174 @@ +/*********************************************************************** +* * +* 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 + +/* + * regcomp() regex_t cache + * AT&T Research + */ + +#include <ast.h> +#include <regex.h> + +#define CACHE 8 /* # cached re's */ +#define MAXPAT 256 /* max pattern length + 1 */ + +#define KEEP 01 +#define DROP 02 + +typedef struct Cache_s +{ + regex_t re; + unsigned long serial; + regflags_t reflags; + int flags; + char pattern[MAXPAT]; +} Cache_t; + +static struct State_s +{ + Cache_t* cache[CACHE]; + unsigned long serial; + char* locale; +} matchstate; + +/* + * flush the cache + */ + +static void +flushcache(void) +{ + register int i; + + for (i = 0; i < elementsof(matchstate.cache); i++) + if (matchstate.cache[i] && matchstate.cache[i]->flags) + { + matchstate.cache[i]->flags = 0; + regfree(&matchstate.cache[i]->re); + } +} + +/* + * return regcomp() compiled re for pattern and reflags + */ + +regex_t* +regcache(const char* pattern, regflags_t reflags, int* status) +{ + register Cache_t* cp; + register int i; + char* s; + int empty; + int unused; + int old; + + /* + * 0 pattern flushes the cache + */ + + if (!pattern) + { + flushcache(); + if (status) + *status = 0; + return 0; + } + + /* + * flush the cache if the locale changed + * the ast setlocale() intercept maintains + * persistent setlocale() return values + */ + + if ((s = setlocale(LC_CTYPE, NiL)) != matchstate.locale) + { + matchstate.locale = s; + flushcache(); + } + + /* + * check if the pattern is in the cache + */ + + empty = unused = -1; + old = 0; + for (i = 0; i < elementsof(matchstate.cache); i++) + if (!matchstate.cache[i]) + empty = i; + else if (!(matchstate.cache[i]->flags & KEEP)) + { + if (matchstate.cache[i]->flags) + { + matchstate.cache[i]->flags = 0; + regfree(&matchstate.cache[i]->re); + } + unused = i; + } + else if (streq(matchstate.cache[i]->pattern, pattern) && matchstate.cache[i]->reflags == reflags) + break; + else if (!matchstate.cache[old] || matchstate.cache[old]->serial > matchstate.cache[i]->serial) + old = i; + if (i >= elementsof(matchstate.cache)) + { + if (unused < 0) + { + if (empty < 0) + unused = old; + else + unused = empty; + } + if (!(cp = matchstate.cache[unused]) && !(cp = matchstate.cache[unused] = newof(0, Cache_t, 1, 0))) + { + if (status) + *status = REG_ESPACE; + return 0; + } + if (cp->flags) + { + cp->flags = 0; + regfree(&cp->re); + } + cp->reflags = reflags; + if (strlen(pattern) < sizeof(cp->pattern)) + { + strcpy(cp->pattern, pattern); + pattern = (const char*)cp->pattern; + cp->flags = KEEP; + } + else + cp->flags = DROP; + if (i = regcomp(&cp->re, pattern, cp->reflags)) + { + if (status) + *status = i; + cp->flags = 0; + return 0; + } + } + else + cp = matchstate.cache[i]; + cp->serial = ++matchstate.serial; + if (status) + *status = 0; + return &cp->re; +} |