aboutsummaryrefslogtreecommitdiff
path: root/jimregexp.c
diff options
context:
space:
mode:
authorSteve Bennett <steveb@workware.net.au>2011-11-09 10:05:10 +1000
committerSteve Bennett <steveb@workware.net.au>2011-11-10 07:40:04 +1000
commit87507cd2fc4106bb77a487443ea20abf82a92502 (patch)
tree1c81018a0a0aae1384dc947c5203d7efbc2291eb /jimregexp.c
parentc337e92c74561ffa788dcea71cc45dc85da17817 (diff)
downloadjimtcl-87507cd2fc4106bb77a487443ea20abf82a92502.zip
jimtcl-87507cd2fc4106bb77a487443ea20abf82a92502.tar.gz
jimtcl-87507cd2fc4106bb77a487443ea20abf82a92502.tar.bz2
regex: counts were not all being cleared
If a cached regex containing counts was reused, the result may have been incorrect. Signed-off-by: Steve Bennett <steveb@workware.net.au>
Diffstat (limited to 'jimregexp.c')
-rw-r--r--jimregexp.c31
1 files changed, 25 insertions, 6 deletions
diff --git a/jimregexp.c b/jimregexp.c
index dbb49e9..0c5a4dd 100644
--- a/jimregexp.c
+++ b/jimregexp.c
@@ -191,7 +191,7 @@ static int prefix_cmp(const int *prog, int proglen, const char *string, int noca
/*#define DEBUG*/
#ifdef DEBUG
-int regnarrate = 0;
+static int regnarrate = 0;
static void regdump(regex_t *preg);
static const char *regprop( int op );
#endif
@@ -246,13 +246,11 @@ int regcomp(regex_t *preg, const char *exp, int cflags)
preg->program = NULL;
preg->proglen = 0;
-#if 1
/* Allocate space. */
preg->proglen = (strlen(exp) + 1) * 5;
preg->program = malloc(preg->proglen * sizeof(int));
if (preg->program == NULL)
FAIL(preg, REG_ERR_NOMEM);
-#endif
/* Note that since we store a magic value as the first item in the program,
* program offsets will never be 0
@@ -1031,13 +1029,30 @@ int regexec(regex_t *preg, const char *string, size_t nmatch, regmatch_t pmat
preg->start = string; /* All offsets are computed from here */
/* Must clear out the embedded repeat counts */
- for (scan = OPERAND(1); scan != 0; scan = regnext(preg, scan)) {
+ for (scan = OPERAND(1); scan != 0; ) {
switch (OP(preg, scan)) {
case REP:
case REPMIN:
case REPX:
case REPXMIN:
preg->program[scan + 4] = 0;
+ scan += 5;
+ break;
+
+ case ANYOF:
+ case ANYBUT:
+ case EXACTLY:
+ scan += 2;
+ while (preg->program[scan++]) {
+ }
+ break;
+
+ case END:
+ scan = 0;
+ break;
+
+ default:
+ scan += 2;
break;
}
}
@@ -1598,8 +1613,8 @@ static void regdump(regex_t *preg)
int i;
for (i = 1; i < preg->p; i++) {
- printf("%02x ", preg->program[i]);
- if (i % 16 == 15) {
+ printf("%02x ", (unsigned char)preg->program[i]);
+ if (i % 16 == 0) {
printf("\n");
}
}
@@ -1715,6 +1730,10 @@ static const char *regprop( int op )
return "WORDA";
case WORDZ:
return "WORDZ";
+ case OPENNC:
+ return "OPEN";
+ case CLOSENC:
+ return "CLOSE";
default:
if (op >= OPEN && op < CLOSE) {
snprintf(buf, sizeof(buf), "OPEN%d", op-OPEN);