diff options
author | April Chin <April.Chin@Sun.COM> | 2008-12-27 14:59:38 -0800 |
---|---|---|
committer | April Chin <April.Chin@Sun.COM> | 2008-12-27 14:59:38 -0800 |
commit | 7c2fbfb345896881c631598ee3852ce9ce33fb07 (patch) | |
tree | 4b173b5657508562dfc0aa05f7d056d1e9add505 /usr/src/lib/libast/common/regex/regcache.c | |
parent | 6071ac1de68fed78e1e10052045bbb5f1732a263 (diff) | |
download | illumos-gate-7c2fbfb345896881c631598ee3852ce9ce33fb07.tar.gz |
PSARC/2008/094 ksh93 Update 1
PSARC/2008/344 ksh93 Integration Update 1 Amendments 1
PSARC/2008/589 Remove /usr/bin/printf from PSARC case 2008 094
6619428 *ksh93* RFE: Update ksh93 in Solaris to ast-ksh.2008-11-04
6788659 RFE: Update libpp in Solaris to ast-open.2008-07-25
6561901 RFE: Add "shcomp" (shell script compiler) + kernel module to exec binary sh code
6599668 RFE: Move consumers of alias.sh over to ksh93
6595183 *ksh93* RFE: Update ksh93-integration demo code
6775901 *ksh93* no C message catalogs are generated for ksh93
6451262 *sleep* RFE: /usr/bin/sleep should support floating-point values
6687139 *ksh93* command substitution, exec, and stdout redirection cause allocation loop
6703761 *ksh93* crashes in script containing uncommon output redirections
6715496 *ksh93* SEGVs on array reinitialization
6713682 *ksh93* Creating a compound variable in a subshell "bleeds through" to the calling subshell
6672350 *ksh93* causes parent shell to die when child shell is suspended
6745015 *ksh93* VARIABLE=`command substitution` assignment is not reliable on OpenSolaris
6710205 *ksh93* problem with command substitution (within back quotes) containing \$'
6737600 *ksh93* exits debugger when user presses ctrl-c
6748645 *ksh93* fc -l -e - is mis-parsed, outputs wrong error message "-e - requires single argument"
6754020 *ksh93* does weird '[' expansion
6753538 *ksh93* umask modification leaks out of a ksh93 subshell
6766246 *ksh93* bug in pattern matching
6763594 *ksh93* executes command after "command" builtin twice on failure
6762665 *ksh93* Difficult-to-reproduce SIGSEGV in ksh93
Diffstat (limited to 'usr/src/lib/libast/common/regex/regcache.c')
-rw-r--r-- | usr/src/lib/libast/common/regex/regcache.c | 65 |
1 files changed, 49 insertions, 16 deletions
diff --git a/usr/src/lib/libast/common/regex/regcache.c b/usr/src/lib/libast/common/regex/regcache.c index ff9554e904..e306bb0855 100644 --- a/usr/src/lib/libast/common/regex/regcache.c +++ b/usr/src/lib/libast/common/regex/regcache.c @@ -1,10 +1,10 @@ /*********************************************************************** * * * This software is part of the ast package * -* Copyright (c) 1985-2007 AT&T Knowledge Ventures * +* Copyright (c) 1985-2008 AT&T Intellectual Property * * and is licensed under the * * Common Public License, Version 1.0 * -* by AT&T Knowledge Ventures * +* by AT&T Intellectual Property * * * * A copy of the License is available at * * http://www.opensource.org/licenses/cpl1.0.txt * @@ -29,27 +29,36 @@ #include <ast.h> #include <regex.h> -#define CACHE 8 /* # cached re's */ +#define CACHE 8 /* default # cached re's */ #define MAXPAT 256 /* max pattern length + 1 */ #define KEEP 01 #define DROP 02 +typedef union Pattern_u +{ + unsigned long key; + char buf[MAXPAT]; +} Pattern_t; + typedef struct Cache_s { + Pattern_t pattern; regex_t re; unsigned long serial; regflags_t reflags; int flags; - char pattern[MAXPAT]; } Cache_t; -static struct State_s +typedef struct State_s { - Cache_t* cache[CACHE]; + unsigned int size; unsigned long serial; char* locale; -} matchstate; + Cache_t** cache; +} State_t; + +static State_t matchstate; /* * flush the cache @@ -60,7 +69,7 @@ flushcache(void) { register int i; - for (i = 0; i < elementsof(matchstate.cache); i++) + for (i = matchstate.size; i--;) if (matchstate.cache[i] && matchstate.cache[i]->flags) { matchstate.cache[i]->flags = 0; @@ -81,18 +90,36 @@ regcache(const char* pattern, regflags_t reflags, int* status) int empty; int unused; int old; + Pattern_t head; /* - * 0 pattern flushes the cache + * 0 pattern flushes the cache and reflags>0 extends cache */ if (!pattern) { flushcache(); + i = 0; + if (reflags > matchstate.size) + { + if (matchstate.cache = newof(matchstate.cache, Cache_t*, reflags, 0)) + matchstate.size = reflags; + else + { + matchstate.size = 0; + i = 1; + } + } if (status) - *status = 0; + *status = i; return 0; } + if (!matchstate.cache) + { + if (!(matchstate.cache = newof(0, Cache_t*, CACHE, 0))) + return 0; + matchstate.size = CACHE; + } /* * flush the cache if the locale changed @@ -110,9 +137,13 @@ regcache(const char* pattern, regflags_t reflags, int* status) * check if the pattern is in the cache */ + for (i = 0; i < sizeof(unsigned long) && pattern[i]; i++) + head.buf[i] = pattern[i]; + for (; i < sizeof(unsigned long); i++) + head.buf[i] = 0; empty = unused = -1; old = 0; - for (i = 0; i < elementsof(matchstate.cache); i++) + for (i = matchstate.size; i--;) if (!matchstate.cache[i]) empty = i; else if (!(matchstate.cache[i]->flags & KEEP)) @@ -124,11 +155,11 @@ regcache(const char* pattern, regflags_t reflags, int* status) } unused = i; } - else if (streq(matchstate.cache[i]->pattern, pattern) && matchstate.cache[i]->reflags == reflags) + else if (matchstate.cache[i]->pattern.key == head.key && !strcmp(matchstate.cache[i]->pattern.buf, 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 (i < 0) { if (unused < 0) { @@ -149,10 +180,12 @@ regcache(const char* pattern, regflags_t reflags, int* status) regfree(&cp->re); } cp->reflags = reflags; - if (strlen(pattern) < sizeof(cp->pattern)) + if ((i = strlen(pattern)) < sizeof(cp->pattern.buf)) { - strcpy(cp->pattern, pattern); - pattern = (const char*)cp->pattern; + if (i < sizeof(unsigned long)) + memset(cp->pattern.buf, 0, sizeof(unsigned long)); + strcpy(cp->pattern.buf, pattern); + pattern = (const char*)cp->pattern.buf; cp->flags = KEEP; } else |