summaryrefslogtreecommitdiff
path: root/usr/src/lib/libast/common/regex/regcache.c
diff options
context:
space:
mode:
authorApril Chin <April.Chin@Sun.COM>2008-12-27 14:59:38 -0800
committerApril Chin <April.Chin@Sun.COM>2008-12-27 14:59:38 -0800
commit7c2fbfb345896881c631598ee3852ce9ce33fb07 (patch)
tree4b173b5657508562dfc0aa05f7d056d1e9add505 /usr/src/lib/libast/common/regex/regcache.c
parent6071ac1de68fed78e1e10052045bbb5f1732a263 (diff)
downloadillumos-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.c65
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