summaryrefslogtreecommitdiff
path: root/usr/src/lib/libast/common/regex/regcache.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/lib/libast/common/regex/regcache.c')
-rw-r--r--usr/src/lib/libast/common/regex/regcache.c75
1 files changed, 33 insertions, 42 deletions
diff --git a/usr/src/lib/libast/common/regex/regcache.c b/usr/src/lib/libast/common/regex/regcache.c
index f40f31fc09..438f7e79e1 100644
--- a/usr/src/lib/libast/common/regex/regcache.c
+++ b/usr/src/lib/libast/common/regex/regcache.c
@@ -1,7 +1,7 @@
/***********************************************************************
* *
* This software is part of the ast package *
-* Copyright (c) 1985-2009 AT&T Intellectual Property *
+* Copyright (c) 1985-2010 AT&T Intellectual Property *
* and is licensed under the *
* Common Public License, Version 1.0 *
* by AT&T Intellectual Property *
@@ -23,31 +23,25 @@
/*
* regcomp() regex_t cache
- * AT&T Research
+ * at&t research
*/
#include <ast.h>
#include <regex.h>
#define CACHE 8 /* default # cached re's */
-#define MAXPAT 256 /* max pattern length + 1 */
+#define ROUND 64 /* pattern buffer size round */
-#define KEEP 01
-#define DROP 02
-
-typedef union Pattern_u
-{
- unsigned long key;
- char buf[MAXPAT];
-} Pattern_t;
+typedef unsigned long Key_t;
typedef struct Cache_s
{
- Pattern_t pattern;
+ char* pattern;
regex_t re;
unsigned long serial;
regflags_t reflags;
- int flags;
+ int keep;
+ int size;
} Cache_t;
typedef struct State_s
@@ -70,9 +64,9 @@ flushcache(void)
register int i;
for (i = matchstate.size; i--;)
- if (matchstate.cache[i] && matchstate.cache[i]->flags)
+ if (matchstate.cache[i] && matchstate.cache[i]->keep)
{
- matchstate.cache[i]->flags = 0;
+ matchstate.cache[i]->keep = 0;
regfree(&matchstate.cache[i]->re);
}
}
@@ -90,7 +84,7 @@ regcache(const char* pattern, regflags_t reflags, int* status)
int empty;
int unused;
int old;
- Pattern_t head;
+ Key_t key;
/*
* 0 pattern flushes the cache and reflags>0 extends cache
@@ -137,25 +131,18 @@ 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;
+ for (i = 0; i < sizeof(key) && pattern[i]; i++)
+ ((char*)&key)[i] = pattern[i];
+ for (; i < sizeof(key); i++)
+ ((char*)&key)[i] = 0;
empty = unused = -1;
old = 0;
for (i = matchstate.size; 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);
- }
+ else if (!matchstate.cache[i]->keep)
unused = i;
- }
- else if (matchstate.cache[i]->pattern.key == head.key && !strcmp(matchstate.cache[i]->pattern.buf, pattern) && matchstate.cache[i]->reflags == reflags)
+ else if (*(Key_t*)matchstate.cache[i]->pattern == key && !strcmp(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;
@@ -174,29 +161,33 @@ regcache(const char* pattern, regflags_t reflags, int* status)
*status = REG_ESPACE;
return 0;
}
- if (cp->flags)
+ if (cp->keep)
{
- cp->flags = 0;
+ cp->keep = 0;
regfree(&cp->re);
}
- cp->reflags = reflags;
- if ((i = strlen(pattern)) < sizeof(cp->pattern.buf))
+ if ((i = strlen(pattern) + 1) >= cp->size)
{
- 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;
+ cp->size = roundof(i, ROUND);
+ if (!(cp->pattern = newof(cp->pattern, char, cp->size, 0)))
+ {
+ if (status)
+ *status = REG_ESPACE;
+ return 0;
+ }
}
- else
- cp->flags = DROP;
- if (i = regcomp(&cp->re, pattern, cp->reflags))
+ strcpy(cp->pattern, pattern);
+ while (++i < sizeof(Key_t))
+ cp->pattern[i] = 0;
+ pattern = (const char*)cp->pattern;
+ if (i = regcomp(&cp->re, pattern, reflags))
{
if (status)
*status = i;
- cp->flags = 0;
return 0;
}
+ cp->keep = 1;
+ cp->reflags = reflags;
}
else
cp = matchstate.cache[i];