diff --git a/src/backend/regex/regcomp.c b/src/backend/regex/regcomp.c index b84d0c3af55f04873bc61c8b843af3b99c865b4a..7fd0b07e2c5d45405493247f28fd3aac88883572 100644 --- a/src/backend/regex/regcomp.c +++ b/src/backend/regex/regcomp.c @@ -1623,7 +1623,7 @@ subre(struct vars * v, ret->op = op; ret->flags = flags; - ret->retry = 0; + ret->id = 0; /* will be assigned later */ ret->subno = 0; ret->min = ret->max = 1; ret->left = NULL; @@ -1693,7 +1693,7 @@ optst(struct vars * v, } /* - * numst - number tree nodes (assigning retry indexes) + * numst - number tree nodes (assigning "id" indexes) */ static int /* next number */ numst(struct subre * t, @@ -1704,7 +1704,7 @@ numst(struct subre * t, assert(t != NULL); i = start; - t->retry = (short) i++; + t->id = (short) i++; if (t->left != NULL) i = numst(t->left, i); if (t->right != NULL) @@ -1999,11 +1999,11 @@ stid(struct subre * t, char *buf, size_t bufsize) { - /* big enough for hex int or decimal t->retry? */ - if (bufsize < sizeof(void *) * 2 + 3 || bufsize < sizeof(t->retry) * 3 + 1) + /* big enough for hex int or decimal t->id? */ + if (bufsize < sizeof(void *) * 2 + 3 || bufsize < sizeof(t->id) * 3 + 1) return "unable"; - if (t->retry != 0) - sprintf(buf, "%d", t->retry); + if (t->id != 0) + sprintf(buf, "%d", t->id); else sprintf(buf, "%p", t); return buf; diff --git a/src/backend/regex/regexec.c b/src/backend/regex/regexec.c index ea16e39a6eddfc6267e7c8fc2977afab7cb17e49..55f0c18d14f6af48432638fd95f72dcc27fb0081 100644 --- a/src/backend/regex/regexec.c +++ b/src/backend/regex/regexec.c @@ -112,7 +112,6 @@ struct vars chr *search_start; /* search start of string */ chr *stop; /* just past end of string */ int err; /* error code if any (0 none) */ - regoff_t *mem; /* memory vector for backtracking */ struct smalldfa dfa1; struct smalldfa dfa2; }; @@ -134,8 +133,8 @@ struct vars static int find(struct vars *, struct cnfa *, struct colormap *); static int cfind(struct vars *, struct cnfa *, struct colormap *); static int cfindloop(struct vars *, struct cnfa *, struct colormap *, struct dfa *, struct dfa *, chr **); -static void zapsubs(regmatch_t *, size_t); -static void zapmem(struct vars *, struct subre *); +static void zapallsubs(regmatch_t *, size_t); +static void zaptreesubs(struct vars *, struct subre *); static void subset(struct vars *, struct subre *, chr *, chr *); static int dissect(struct vars *, struct subre *, chr *, chr *); static int condissect(struct vars *, struct subre *, chr *, chr *); @@ -186,9 +185,6 @@ pg_regexec(regex_t *re, #define LOCALMAT 20 regmatch_t mat[LOCALMAT]; -#define LOCALMEM 40 - regoff_t mem[LOCALMEM]; - /* sanity checks */ if (re == NULL || string == NULL || re->re_magic != REMAGIC) return REG_INVARG; @@ -229,24 +225,6 @@ pg_regexec(regex_t *re, v->search_start = (chr *) string + search_start; v->stop = (chr *) string + len; v->err = 0; - if (backref) - { - /* need retry memory */ - assert(v->g->ntree >= 0); - n = (size_t) v->g->ntree; - if (n <= LOCALMEM) - v->mem = mem; - else - v->mem = (regoff_t *) MALLOC(n * sizeof(regoff_t)); - if (v->mem == NULL) - { - if (v->pmatch != pmatch && v->pmatch != mat) - FREE(v->pmatch); - return REG_ESPACE; - } - } - else - v->mem = NULL; /* do it */ assert(v->g->tree != NULL); @@ -258,7 +236,7 @@ pg_regexec(regex_t *re, /* copy (portion of) match vector over if necessary */ if (st == REG_OKAY && v->pmatch != pmatch && nmatch > 0) { - zapsubs(pmatch, nmatch); + zapallsubs(pmatch, nmatch); n = (nmatch < v->nmatch) ? nmatch : v->nmatch; memcpy(VS(pmatch), VS(v->pmatch), n * sizeof(regmatch_t)); } @@ -266,8 +244,6 @@ pg_regexec(regex_t *re, /* clean up */ if (v->pmatch != pmatch && v->pmatch != mat) FREE(v->pmatch); - if (v->mem != NULL && v->mem != mem) - FREE(v->mem); return st; } @@ -354,7 +330,7 @@ find(struct vars * v, return REG_OKAY; /* submatches */ - zapsubs(v->pmatch, v->nmatch); + zapallsubs(v->pmatch, v->nmatch); return dissect(v, v->g->tree, begin, end); } @@ -451,8 +427,7 @@ cfindloop(struct vars * v, if (end == NULL) break; /* NOTE BREAK OUT */ MDEBUG(("tentative end %ld\n", LOFF(end))); - zapsubs(v->pmatch, v->nmatch); - zapmem(v, v->g->tree); + zapallsubs(v->pmatch, v->nmatch); er = cdissect(v, v->g->tree, begin, end); if (er == REG_OKAY) { @@ -490,11 +465,11 @@ cfindloop(struct vars * v, } /* - * zapsubs - initialize the subexpression matches to "no match" + * zapallsubs - initialize all subexpression matches to "no match" */ static void -zapsubs(regmatch_t *p, - size_t n) +zapallsubs(regmatch_t *p, + size_t n) { size_t i; @@ -506,17 +481,12 @@ zapsubs(regmatch_t *p, } /* - * zapmem - initialize the retry memory of a subtree to zeros + * zaptreesubs - initialize subexpressions within subtree to "no match" */ static void -zapmem(struct vars * v, - struct subre * t) +zaptreesubs(struct vars * v, + struct subre * t) { - if (t == NULL) - return; - - assert(v->mem != NULL); - v->mem[t->retry] = 0; if (t->op == '(') { assert(t->subno > 0); @@ -525,9 +495,9 @@ zapmem(struct vars * v, } if (t->left != NULL) - zapmem(v, t->left); + zaptreesubs(v, t->left); if (t->right != NULL) - zapmem(v, t->right); + zaptreesubs(v, t->right); } /* @@ -767,7 +737,7 @@ iterdissect(struct vars * v, FREE(endpts); return v->err; } - MDEBUG(("iter %d\n", t->retry)); + MDEBUG(("iter %d\n", t->id)); /* * Our strategy is to first find a set of sub-match endpoints that are @@ -796,7 +766,7 @@ iterdissect(struct vars * v, goto backtrack; } MDEBUG(("%d: working endpoint %d: %ld\n", - t->retry, k, LOFF(endpts[k]))); + t->id, k, LOFF(endpts[k]))); /* k'th sub-match can no longer be considered verified */ if (nverified >= k) @@ -831,7 +801,7 @@ iterdissect(struct vars * v, if (k < min_matches) goto backtrack; - MDEBUG(("%d: verifying %d..%d\n", t->retry, nverified + 1, k)); + MDEBUG(("%d: verifying %d..%d\n", t->id, nverified + 1, k)); for (i = nverified + 1; i <= k; i++) { @@ -852,7 +822,7 @@ iterdissect(struct vars * v, if (i > k) { /* satisfaction */ - MDEBUG(("%d successful\n", t->retry)); + MDEBUG(("%d successful\n", t->id)); freedfa(d); FREE(endpts); return REG_OKAY; @@ -885,7 +855,7 @@ backtrack: } /* all possibilities exhausted - shouldn't happen in uncomplicated mode */ - MDEBUG(("%d failed\n", t->retry)); + MDEBUG(("%d failed\n", t->id)); freedfa(d); FREE(endpts); return REG_ASSERT; @@ -953,7 +923,7 @@ reviterdissect(struct vars * v, FREE(endpts); return v->err; } - MDEBUG(("reviter %d\n", t->retry)); + MDEBUG(("reviter %d\n", t->id)); /* * Our strategy is to first find a set of sub-match endpoints that are @@ -989,7 +959,7 @@ reviterdissect(struct vars * v, goto backtrack; } MDEBUG(("%d: working endpoint %d: %ld\n", - t->retry, k, LOFF(endpts[k]))); + t->id, k, LOFF(endpts[k]))); /* k'th sub-match can no longer be considered verified */ if (nverified >= k) @@ -1019,7 +989,7 @@ reviterdissect(struct vars * v, if (k < min_matches) goto backtrack; - MDEBUG(("%d: verifying %d..%d\n", t->retry, nverified + 1, k)); + MDEBUG(("%d: verifying %d..%d\n", t->id, nverified + 1, k)); for (i = nverified + 1; i <= k; i++) { @@ -1040,7 +1010,7 @@ reviterdissect(struct vars * v, if (i > k) { /* satisfaction */ - MDEBUG(("%d successful\n", t->retry)); + MDEBUG(("%d successful\n", t->id)); freedfa(d); FREE(endpts); return REG_OKAY; @@ -1066,7 +1036,7 @@ backtrack: } /* all possibilities exhausted - shouldn't happen in uncomplicated mode */ - MDEBUG(("%d failed\n", t->retry)); + MDEBUG(("%d failed\n", t->id)); freedfa(d); FREE(endpts); return REG_ASSERT; @@ -1074,8 +1044,6 @@ backtrack: /* * cdissect - determine subexpression matches (with complications) - * The retry memory stores the offset of the trial midpoint from begin, - * plus 1 so that 0 uniquely means "clean slate". */ static int /* regexec return code */ cdissect(struct vars * v, @@ -1119,8 +1087,6 @@ cdissect(struct vars * v, /* * ccondissect - concatenation subexpression matches (with complications) - * The retry memory stores the offset of the trial midpoint from begin, - * plus 1 so that 0 uniquely means "clean slate". */ static int /* regexec return code */ ccondissect(struct vars * v, @@ -1149,26 +1115,17 @@ ccondissect(struct vars * v, freedfa(d); return v->err; } - MDEBUG(("cconcat %d\n", t->retry)); + MDEBUG(("cconcat %d\n", t->id)); /* pick a tentative midpoint */ - if (v->mem[t->retry] == 0) - { - mid = longest(v, d, begin, end, (int *) NULL); - if (mid == NULL) - { - freedfa(d); - freedfa(d2); - return REG_NOMATCH; - } - MDEBUG(("tentative midpoint %ld\n", LOFF(mid))); - v->mem[t->retry] = (mid - begin) + 1; - } - else + mid = longest(v, d, begin, end, (int *) NULL); + if (mid == NULL) { - mid = begin + (v->mem[t->retry] - 1); - MDEBUG(("working midpoint %ld\n", LOFF(mid))); + freedfa(d); + freedfa(d2); + return REG_NOMATCH; } + MDEBUG(("tentative midpoint %ld\n", LOFF(mid))); /* iterate until satisfaction or failure */ for (;;) @@ -1201,7 +1158,7 @@ ccondissect(struct vars * v, if (mid == begin) { /* all possibilities exhausted */ - MDEBUG(("%d no midpoint\n", t->retry)); + MDEBUG(("%d no midpoint\n", t->id)); freedfa(d); freedfa(d2); return REG_NOMATCH; @@ -1210,15 +1167,14 @@ ccondissect(struct vars * v, if (mid == NULL) { /* failed to find a new one */ - MDEBUG(("%d failed midpoint\n", t->retry)); + MDEBUG(("%d failed midpoint\n", t->id)); freedfa(d); freedfa(d2); return REG_NOMATCH; } - MDEBUG(("%d: new midpoint %ld\n", t->retry, LOFF(mid))); - v->mem[t->retry] = (mid - begin) + 1; - zapmem(v, t->left); - zapmem(v, t->right); + MDEBUG(("%d: new midpoint %ld\n", t->id, LOFF(mid))); + zaptreesubs(v, t->left); + zaptreesubs(v, t->right); } /* can't get here */ @@ -1227,8 +1183,6 @@ ccondissect(struct vars * v, /* * crevdissect - shortest-first concatenation subexpression matches - * The retry memory stores the offset of the trial midpoint from begin, - * plus 1 so that 0 uniquely means "clean slate". */ static int /* regexec return code */ crevdissect(struct vars * v, @@ -1256,26 +1210,17 @@ crevdissect(struct vars * v, freedfa(d); return v->err; } - MDEBUG(("crev %d\n", t->retry)); + MDEBUG(("crev %d\n", t->id)); /* pick a tentative midpoint */ - if (v->mem[t->retry] == 0) - { - mid = shortest(v, d, begin, begin, end, (chr **) NULL, (int *) NULL); - if (mid == NULL) - { - freedfa(d); - freedfa(d2); - return REG_NOMATCH; - } - MDEBUG(("tentative midpoint %ld\n", LOFF(mid))); - v->mem[t->retry] = (mid - begin) + 1; - } - else + mid = shortest(v, d, begin, begin, end, (chr **) NULL, (int *) NULL); + if (mid == NULL) { - mid = begin + (v->mem[t->retry] - 1); - MDEBUG(("working midpoint %ld\n", LOFF(mid))); + freedfa(d); + freedfa(d2); + return REG_NOMATCH; } + MDEBUG(("tentative midpoint %ld\n", LOFF(mid))); /* iterate until satisfaction or failure */ for (;;) @@ -1308,7 +1253,7 @@ crevdissect(struct vars * v, if (mid == end) { /* all possibilities exhausted */ - MDEBUG(("%d no midpoint\n", t->retry)); + MDEBUG(("%d no midpoint\n", t->id)); freedfa(d); freedfa(d2); return REG_NOMATCH; @@ -1317,15 +1262,14 @@ crevdissect(struct vars * v, if (mid == NULL) { /* failed to find a new one */ - MDEBUG(("%d failed midpoint\n", t->retry)); + MDEBUG(("%d failed midpoint\n", t->id)); freedfa(d); freedfa(d2); return REG_NOMATCH; } - MDEBUG(("%d: new midpoint %ld\n", t->retry, LOFF(mid))); - v->mem[t->retry] = (mid - begin) + 1; - zapmem(v, t->left); - zapmem(v, t->right); + MDEBUG(("%d: new midpoint %ld\n", t->id, LOFF(mid))); + zaptreesubs(v, t->left); + zaptreesubs(v, t->right); } /* can't get here */ @@ -1355,7 +1299,7 @@ cbrdissect(struct vars * v, assert(n >= 0); assert((size_t) n < v->nmatch); - MDEBUG(("cbackref n%d %d{%d-%d}\n", t->retry, n, min, max)); + MDEBUG(("cbackref n%d %d{%d-%d}\n", t->id, n, min, max)); /* get the backreferenced string */ if (v->pmatch[n].rm_so == -1) @@ -1363,11 +1307,6 @@ cbrdissect(struct vars * v, brstring = v->start + v->pmatch[n].rm_so; brlen = v->pmatch[n].rm_eo - v->pmatch[n].rm_so; - /* no room to maneuver -- retries are pointless */ - if (v->mem[t->retry]) - return REG_NOMATCH; - v->mem[t->retry] = 1; - /* special cases for zero-length strings */ if (brlen == 0) { @@ -1430,40 +1369,29 @@ caltdissect(struct vars * v, struct dfa *d; int er; -#define UNTRIED 0 /* not yet tried at all */ -#define TRYING 1 /* top matched, trying submatches */ -#define TRIED 2 /* top didn't match or submatches exhausted */ - if (t == NULL) return REG_NOMATCH; - assert(t->op == '|'); - if (v->mem[t->retry] == TRIED) - return caltdissect(v, t->right, begin, end); - MDEBUG(("calt n%d\n", t->retry)); + assert(t->op == '|'); assert(t->left != NULL); - if (v->mem[t->retry] == UNTRIED) + MDEBUG(("calt n%d\n", t->id)); + + d = newdfa(v, &t->left->cnfa, &v->g->cmap, DOMALLOC); + if (ISERR()) + return v->err; + if (longest(v, d, begin, end, (int *) NULL) != end) { - d = newdfa(v, &t->left->cnfa, &v->g->cmap, DOMALLOC); - if (ISERR()) - return v->err; - if (longest(v, d, begin, end, (int *) NULL) != end) - { - freedfa(d); - v->mem[t->retry] = TRIED; - return caltdissect(v, t->right, begin, end); - } freedfa(d); - MDEBUG(("calt matched\n")); - v->mem[t->retry] = TRYING; + return caltdissect(v, t->right, begin, end); } + freedfa(d); + MDEBUG(("calt matched\n")); er = cdissect(v, t->left, begin, end); if (er != REG_NOMATCH) return er; - v->mem[t->retry] = TRIED; return caltdissect(v, t->right, begin, end); } @@ -1531,7 +1459,7 @@ citerdissect(struct vars * v, FREE(endpts); return v->err; } - MDEBUG(("citer %d\n", t->retry)); + MDEBUG(("citer %d\n", t->id)); /* * Our strategy is to first find a set of sub-match endpoints that are @@ -1560,7 +1488,7 @@ citerdissect(struct vars * v, goto backtrack; } MDEBUG(("%d: working endpoint %d: %ld\n", - t->retry, k, LOFF(endpts[k]))); + t->id, k, LOFF(endpts[k]))); /* k'th sub-match can no longer be considered verified */ if (nverified >= k) @@ -1595,11 +1523,11 @@ citerdissect(struct vars * v, if (k < min_matches) goto backtrack; - MDEBUG(("%d: verifying %d..%d\n", t->retry, nverified + 1, k)); + MDEBUG(("%d: verifying %d..%d\n", t->id, nverified + 1, k)); for (i = nverified + 1; i <= k; i++) { - zapmem(v, t->left); + zaptreesubs(v, t->left); er = cdissect(v, t->left, endpts[i - 1], endpts[i]); if (er == REG_OKAY) { @@ -1617,7 +1545,7 @@ citerdissect(struct vars * v, if (i > k) { /* satisfaction */ - MDEBUG(("%d successful\n", t->retry)); + MDEBUG(("%d successful\n", t->id)); freedfa(d); FREE(endpts); return REG_OKAY; @@ -1650,7 +1578,7 @@ backtrack: } /* all possibilities exhausted */ - MDEBUG(("%d failed\n", t->retry)); + MDEBUG(("%d failed\n", t->id)); freedfa(d); FREE(endpts); return REG_NOMATCH; @@ -1718,7 +1646,7 @@ creviterdissect(struct vars * v, FREE(endpts); return v->err; } - MDEBUG(("creviter %d\n", t->retry)); + MDEBUG(("creviter %d\n", t->id)); /* * Our strategy is to first find a set of sub-match endpoints that are @@ -1754,7 +1682,7 @@ creviterdissect(struct vars * v, goto backtrack; } MDEBUG(("%d: working endpoint %d: %ld\n", - t->retry, k, LOFF(endpts[k]))); + t->id, k, LOFF(endpts[k]))); /* k'th sub-match can no longer be considered verified */ if (nverified >= k) @@ -1784,11 +1712,11 @@ creviterdissect(struct vars * v, if (k < min_matches) goto backtrack; - MDEBUG(("%d: verifying %d..%d\n", t->retry, nverified + 1, k)); + MDEBUG(("%d: verifying %d..%d\n", t->id, nverified + 1, k)); for (i = nverified + 1; i <= k; i++) { - zapmem(v, t->left); + zaptreesubs(v, t->left); er = cdissect(v, t->left, endpts[i - 1], endpts[i]); if (er == REG_OKAY) { @@ -1806,7 +1734,7 @@ creviterdissect(struct vars * v, if (i > k) { /* satisfaction */ - MDEBUG(("%d successful\n", t->retry)); + MDEBUG(("%d successful\n", t->id)); freedfa(d); FREE(endpts); return REG_OKAY; @@ -1832,7 +1760,7 @@ backtrack: } /* all possibilities exhausted */ - MDEBUG(("%d failed\n", t->retry)); + MDEBUG(("%d failed\n", t->id)); freedfa(d); FREE(endpts); return REG_NOMATCH; diff --git a/src/include/regex/regguts.h b/src/include/regex/regguts.h index d420ea8316e18f2ff009af5c618027cf3fae8256..bc5419d98e78bf103a0fa54c87292e83c17eb2aa 100644 --- a/src/include/regex/regguts.h +++ b/src/include/regex/regguts.h @@ -409,7 +409,7 @@ struct subre #define PREF(f) ((f)&LOCAL) #define PREF2(f1, f2) ((PREF(f1) != 0) ? PREF(f1) : PREF(f2)) #define COMBINE(f1, f2) (UP((f1)|(f2)) | PREF2(f1, f2)) - short retry; /* index into retry memory */ + short id; /* ID of subre (1..ntree) */ int subno; /* subexpression number (for 'b' and '(') */ short min; /* min repetitions for iteration or backref */ short max; /* max repetitions for iteration or backref */