aboutsummaryrefslogtreecommitdiff
path: root/src/libregexp
diff options
context:
space:
mode:
Diffstat (limited to 'src/libregexp')
-rw-r--r--src/libregexp/regaux.c105
-rw-r--r--src/libregexp/regcomp.c10
-rw-r--r--src/libregexp/regcomp.h6
-rw-r--r--src/libregexp/regexec.c48
-rw-r--r--src/libregexp/rregexec.c61
5 files changed, 117 insertions, 113 deletions
diff --git a/src/libregexp/regaux.c b/src/libregexp/regaux.c
index b854b5ac..39e67725 100644
--- a/src/libregexp/regaux.c
+++ b/src/libregexp/regaux.c
@@ -23,90 +23,89 @@ _renewmatch(Resub *mp, int ms, Resublist *sp)
}
/*
- * Note optimization in _renewthread:
- * *lp must be pending when _renewthread called; if *l has been looked
- * at already, the optimization is a bug.
+ * Add ip to the list [lp, elp], but only if it is not there already.
+ * These work lists are stored and processed in increasing
+ * order of sp[0], so if the ip is there already, the one that's
+ * there already is a more left match and takes priority.
*/
-extern Relist*
-_renewthread(Relist *lp, /* _relist to add to */
+static Relist*
+_renewthread1(Relist *lp, /* Relist to add to */
+ Relist *elp, /* limit pointer for Relist */
Reinst *ip, /* instruction to add */
int ms,
Resublist *sep) /* pointers to subexpressions */
{
Relist *p;
- for(p=lp; p->inst; p++){
- if(p->inst == ip){
- if(sep->m[0].s.sp < p->se.m[0].s.sp){
- if(ms > 1)
- p->se = *sep;
- else
- p->se.m[0] = sep->m[0];
- }
+ for(p=lp; p->inst; p++)
+ if(p->inst == ip)
return 0;
- }
- }
+
+ if(p == elp) /* refuse to overflow buffer */
+ return elp;
+
p->inst = ip;
if(ms > 1)
p->se = *sep;
else
p->se.m[0] = sep->m[0];
- (++p)->inst = 0;
+ (p+1)->inst = 0;
return p;
}
+extern int
+_renewthread(Relist *lp, Relist *elp, Reinst *ip, int ms, Resublist *sep)
+{
+ Relist *ap;
+
+ ap = _renewthread1(lp, elp, ip, ms, sep);
+ if(ap == 0)
+ return 0;
+ if(ap == elp)
+ return -1;
+
+ /*
+ * Added ip to list at ap.
+ * Expand any ORs right now, so that entire
+ * work list ends up being sorted by increasing m[0].sp.
+ */
+ for(; ap->inst; ap++){
+ if(ap->inst->type == OR){
+ if(_renewthread1(lp, elp, ap->inst->u1.right, ms, &ap->se) == elp)
+ return -1;
+ if(_renewthread1(lp, elp, ap->inst->u2.next, ms, &ap->se) == elp)
+ return -1;
+ }
+ }
+ return 0;
+}
+
/*
* same as renewthread, but called with
* initial empty start pointer.
*/
-extern Relist*
+extern int
_renewemptythread(Relist *lp, /* _relist to add to */
+ Relist *elp,
Reinst *ip, /* instruction to add */
int ms,
char *sp) /* pointers to subexpressions */
{
- Relist *p;
-
- for(p=lp; p->inst; p++){
- if(p->inst == ip){
- if(sp < p->se.m[0].s.sp) {
- if(ms > 1)
- memset(&p->se, 0, sizeof(p->se));
- p->se.m[0].s.sp = sp;
- }
- return 0;
- }
- }
- p->inst = ip;
+ Resublist sep;
+
if(ms > 1)
- memset(&p->se, 0, sizeof(p->se));
- p->se.m[0].s.sp = sp;
- (++p)->inst = 0;
- return p;
+ memset(&sep, 0, sizeof sep);
+ sep.m[0].s.sp = sp;
+ sep.m[0].e.ep = 0;
+ return _renewthread(lp, elp, ip, ms, &sep);
}
-extern Relist*
+extern int
_rrenewemptythread(Relist *lp, /* _relist to add to */
+ Relist *elp,
Reinst *ip, /* instruction to add */
int ms,
Rune *rsp) /* pointers to subexpressions */
{
- Relist *p;
-
- for(p=lp; p->inst; p++){
- if(p->inst == ip){
- if(rsp < p->se.m[0].s.rsp) {
- if(ms > 1)
- memset(&p->se, 0, sizeof(p->se));
- p->se.m[0].s.rsp = rsp;
- }
- return 0;
- }
- }
- p->inst = ip;
- if(ms > 1)
- memset(&p->se, 0, sizeof(p->se));
- p->se.m[0].s.rsp = rsp;
- (++p)->inst = 0;
- return p;
+ return _renewemptythread(lp, elp, ip, ms, (char*)rsp);
}
diff --git a/src/libregexp/regcomp.c b/src/libregexp/regcomp.c
index b8286dc7..ba0175ff 100644
--- a/src/libregexp/regcomp.c
+++ b/src/libregexp/regcomp.c
@@ -232,7 +232,7 @@ optimize(Reprog *pp)
int size;
Reprog *npp;
Reclass *cl;
- int diff;
+ int diff, proglen;
/*
* get rid of NOOP chains
@@ -249,10 +249,13 @@ optimize(Reprog *pp)
* necessary. Reallocate to the actual space used
* and then relocate the code.
*/
- size = sizeof(Reprog) + (freep - pp->firstinst)*sizeof(Reinst);
+ proglen = freep - pp->firstinst;
+ size = sizeof(Reprog) + proglen*sizeof(Reinst);
npp = realloc(pp, size);
- if(npp==0 || npp==pp)
+ if(npp==0 || npp==pp){
+ pp->proglen = proglen;
return pp;
+ }
diff = (char *)npp - (char *)pp;
freep = (Reinst *)((char *)freep + diff);
for(inst=npp->firstinst; inst<freep; inst++){
@@ -273,6 +276,7 @@ optimize(Reprog *pp)
*(char**)(void*)&inst->u2.left += diff;
}
*(char**)(void*)&npp->startinst += diff;
+ npp->proglen = proglen;
return npp;
}
diff --git a/src/libregexp/regcomp.h b/src/libregexp/regcomp.h
index 6c88cd09..fde99f54 100644
--- a/src/libregexp/regcomp.h
+++ b/src/libregexp/regcomp.h
@@ -68,7 +68,7 @@ struct Reljunk
Rune* reol;
};
-extern Relist* _renewthread(Relist*, Reinst*, int, Resublist*);
+extern int _renewthread(Relist*, Relist*, Reinst*, int, Resublist*);
extern void _renewmatch(Resub*, int, Resublist*);
-extern Relist* _renewemptythread(Relist*, Reinst*, int, char*);
-extern Relist* _rrenewemptythread(Relist*, Reinst*, int, Rune*);
+extern int _renewemptythread(Relist*, Relist*, Reinst*, int, char*);
+extern int _rrenewemptythread(Relist*, Relist*, Reinst*, int, Rune*);
diff --git a/src/libregexp/regexec.c b/src/libregexp/regexec.c
index c04182a1..10d93f0c 100644
--- a/src/libregexp/regexec.c
+++ b/src/libregexp/regexec.c
@@ -2,7 +2,6 @@
#include "regexp9.h"
#include "regcomp.h"
-
/*
* return 0 if no match
* >0 if a match
@@ -13,16 +12,14 @@ regexec1(Reprog *progp, /* program to run */
char *bol, /* string to run machine on */
Resub *mp, /* subexpression elements */
int ms, /* number of elements at mp */
- Reljunk *j
-)
+ Reljunk *j)
{
int flag=0;
Reinst *inst;
Relist *tlp;
char *s;
- int i, checkstart;
+ int i, checkstart, n;
Rune r, *rp, *ep;
- int n;
Relist* tl; /* This list, next list */
Relist* nl;
Relist* tle; /* ends of this and next list */
@@ -48,7 +45,7 @@ regexec1(Reprog *progp, /* program to run */
switch(j->starttype) {
case RUNE:
p = utfrune(s, j->startchar);
- if(p == 0 || s == j->eol)
+ if(p == 0 || (j->eol && p >= j->eol))
return match;
s = p;
break;
@@ -56,7 +53,7 @@ regexec1(Reprog *progp, /* program to run */
if(s == bol)
break;
p = utfrune(s, '\n');
- if(p == 0 || s == j->eol)
+ if(p == 0 || (j->eol && p+1 >= j->eol))
return match;
s = p+1;
break;
@@ -77,17 +74,16 @@ regexec1(Reprog *progp, /* program to run */
/* Add first instruction to current list */
if(match == 0)
- _renewemptythread(tl, progp->startinst, ms, s);
+ _renewemptythread(tl, tle, progp->startinst, ms, s);
/* Execute machine until current list is empty */
- for(tlp=tl; tlp->inst; tlp++){ /* assignment = */
+ for(tlp=tl; tlp->inst; tlp++){
for(inst = tlp->inst; ; inst = inst->u2.next){
switch(inst->type){
case RUNE: /* regular character */
- if(inst->u1.r == r){
- if(_renewthread(nl, inst->u2.next, ms, &tlp->se)==nle)
+ if(inst->u1.r == r)
+ if(_renewthread(nl, nle, inst->u2.next, ms, &tlp->se) < 0)
return -1;
- }
break;
case LBRA:
tlp->se.m[inst->u1.subid].s.sp = s;
@@ -97,11 +93,11 @@ regexec1(Reprog *progp, /* program to run */
continue;
case ANY:
if(r != '\n')
- if(_renewthread(nl, inst->u2.next, ms, &tlp->se)==nle)
+ if(_renewthread(nl, nle, inst->u2.next, ms, &tlp->se) < 0)
return -1;
break;
case ANYNL:
- if(_renewthread(nl, inst->u2.next, ms, &tlp->se)==nle)
+ if(_renewthread(nl, nle, inst->u2.next, ms, &tlp->se) < 0)
return -1;
break;
case BOL:
@@ -116,7 +112,7 @@ regexec1(Reprog *progp, /* program to run */
ep = inst->u1.cp->end;
for(rp = inst->u1.cp->spans; rp < ep; rp += 2)
if(r >= rp[0] && r <= rp[1]){
- if(_renewthread(nl, inst->u2.next, ms, &tlp->se)==nle)
+ if(_renewthread(nl, nle, inst->u2.next, ms, &tlp->se) < 0)
return -1;
break;
}
@@ -127,15 +123,12 @@ regexec1(Reprog *progp, /* program to run */
if(r >= rp[0] && r <= rp[1])
break;
if(rp == ep)
- if(_renewthread(nl, inst->u2.next, ms, &tlp->se)==nle)
+ if(_renewthread(nl, nle, inst->u2.next, ms, &tlp->se) < 0)
return -1;
break;
case OR:
- /* evaluate right choice later */
- if(_renewthread(tl, inst->u1.right, ms, &tlp->se) == tle)
- return -1;
- /* efficiency: advance and re-evaluate */
- continue;
+ /* expanded during renewthread; just a place holder */
+ break;
case END: /* Match! */
match = 1;
tlp->se.m[0].e.ep = s;
@@ -165,19 +158,18 @@ regexec2(Reprog *progp, /* program to run */
int rv;
Relist *relist0, *relist1;
- /* mark space */
- relist0 = malloc(BIGLISTSIZE*sizeof(Relist));
+ relist0 = malloc((progp->proglen+1)*sizeof(Relist));
if(relist0 == nil)
return -1;
- relist1 = malloc(BIGLISTSIZE*sizeof(Relist));
+ relist1 = malloc((progp->proglen+1)*sizeof(Relist));
if(relist1 == nil){
free(relist1);
return -1;
}
j->relist[0] = relist0;
j->relist[1] = relist1;
- j->reliste[0] = relist0 + BIGLISTSIZE - 2;
- j->reliste[1] = relist1 + BIGLISTSIZE - 2;
+ j->reliste[0] = relist0 + progp->proglen;
+ j->reliste[1] = relist1 + progp->proglen;
rv = regexec1(progp, bol, mp, ms, j);
free(relist0);
@@ -218,8 +210,8 @@ regexec(Reprog *progp, /* program to run */
/* mark space */
j.relist[0] = relist0;
j.relist[1] = relist1;
- j.reliste[0] = relist0 + nelem(relist0) - 2;
- j.reliste[1] = relist1 + nelem(relist1) - 2;
+ j.reliste[0] = relist0 + nelem(relist0) - 1;
+ j.reliste[1] = relist1 + nelem(relist1) - 1;
rv = regexec1(progp, bol, mp, ms, &j);
if(rv >= 0)
diff --git a/src/libregexp/rregexec.c b/src/libregexp/rregexec.c
index ec7907da..907ddef3 100644
--- a/src/libregexp/rregexec.c
+++ b/src/libregexp/rregexec.c
@@ -9,9 +9,9 @@
*/
static int
rregexec1(Reprog *progp, /* program to run */
- Rune *bol, /* string to run machine on */
- Resub *mp, /* subexpression elements */
- int ms, /* number of elements at mp */
+ Rune *bol, /* string to run machine on */
+ Resub *mp, /* subexpression elements */
+ int ms, /* number of elements at mp */
Reljunk *j)
{
int flag=0;
@@ -28,7 +28,7 @@ rregexec1(Reprog *progp, /* program to run */
Rune *p;
match = 0;
- checkstart = j->startchar;
+ checkstart = j->starttype;
if(mp)
for(i=0; i<ms; i++) {
mp[i].s.rsp = 0;
@@ -46,7 +46,7 @@ rregexec1(Reprog *progp, /* program to run */
switch(j->starttype) {
case RUNE:
p = runestrchr(s, j->startchar);
- if(p == 0 || p == j->reol)
+ if(p == 0 || (j->reol && p >= j->reol))
return match;
s = p;
break;
@@ -54,7 +54,7 @@ rregexec1(Reprog *progp, /* program to run */
if(s == bol)
break;
p = runestrchr(s, '\n');
- if(p == 0 || s == j->reol)
+ if(p == 0 || (j->reol && p+1 >= j->reol))
return match;
s = p+1;
break;
@@ -71,15 +71,16 @@ rregexec1(Reprog *progp, /* program to run */
nl->inst = 0;
/* Add first instruction to current list */
- _rrenewemptythread(tl, progp->startinst, ms, s);
+ if(match == 0)
+ _rrenewemptythread(tl, tle, progp->startinst, ms, s);
/* Execute machine until current list is empty */
for(tlp=tl; tlp->inst; tlp++){
- for(inst=tlp->inst; ; inst = inst->u2.next){
+ for(inst = tlp->inst; ; inst = inst->u2.next){
switch(inst->type){
case RUNE: /* regular character */
if(inst->u1.r == r)
- if(_renewthread(nl, inst->u2.next, ms, &tlp->se)==nle)
+ if(_renewthread(nl, nle, inst->u2.next, ms, &tlp->se) < 0)
return -1;
break;
case LBRA:
@@ -90,11 +91,11 @@ rregexec1(Reprog *progp, /* program to run */
continue;
case ANY:
if(r != '\n')
- if(_renewthread(nl, inst->u2.next, ms, &tlp->se)==nle)
+ if(_renewthread(nl, nle, inst->u2.next, ms, &tlp->se) < 0)
return -1;
break;
case ANYNL:
- if(_renewthread(nl, inst->u2.next, ms, &tlp->se)==nle)
+ if(_renewthread(nl, nle, inst->u2.next, ms, &tlp->se) < 0)
return -1;
break;
case BOL:
@@ -109,7 +110,7 @@ rregexec1(Reprog *progp, /* program to run */
ep = inst->u1.cp->end;
for(rp = inst->u1.cp->spans; rp < ep; rp += 2)
if(r >= rp[0] && r <= rp[1]){
- if(_renewthread(nl, inst->u2.next, ms, &tlp->se)==nle)
+ if(_renewthread(nl, nle, inst->u2.next, ms, &tlp->se) < 0)
return -1;
break;
}
@@ -120,15 +121,12 @@ rregexec1(Reprog *progp, /* program to run */
if(r >= rp[0] && r <= rp[1])
break;
if(rp == ep)
- if(_renewthread(nl, inst->u2.next, ms, &tlp->se)==nle)
+ if(_renewthread(nl, nle, inst->u2.next, ms, &tlp->se) < 0)
return -1;
break;
case OR:
- /* evaluate right choice later */
- if(_renewthread(tl, inst->u1.right, ms, &tlp->se) == tle)
- return -1;
- /* efficiency: advance and re-evaluate */
- continue;
+ /* expanded during renewthread; just a place holder */
+ break;
case END: /* Match! */
match = 1;
tlp->se.m[0].e.rep = s;
@@ -141,7 +139,7 @@ rregexec1(Reprog *progp, /* program to run */
}
if(s == j->reol)
break;
- checkstart = j->startchar && nl->inst==0;
+ checkstart = j->starttype && nl->inst==0;
s++;
}while(r);
return match;
@@ -155,15 +153,26 @@ rregexec2(Reprog *progp, /* program to run */
Reljunk *j
)
{
- Relist relist0[5*LISTSIZE], relist1[5*LISTSIZE];
+ int rv;
+ Relist *relist0, *relist1;
- /* mark space */
+ relist0 = malloc((progp->proglen+1)*sizeof(Relist));
+ if(relist0 == nil)
+ return -1;
+ relist1 = malloc((progp->proglen+1)*sizeof(Relist));
+ if(relist1 == nil){
+ free(relist1);
+ return -1;
+ }
j->relist[0] = relist0;
j->relist[1] = relist1;
- j->reliste[0] = relist0 + nelem(relist0) - 2;
- j->reliste[1] = relist1 + nelem(relist1) - 2;
+ j->reliste[0] = relist0 + progp->proglen;
+ j->reliste[1] = relist1 + progp->proglen;
- return rregexec1(progp, bol, mp, ms, j);
+ rv = rregexec1(progp, bol, mp, ms, j);
+ free(relist0);
+ free(relist1);
+ return rv;
}
extern int
@@ -199,8 +208,8 @@ rregexec(Reprog *progp, /* program to run */
/* mark space */
j.relist[0] = relist0;
j.relist[1] = relist1;
- j.reliste[0] = relist0 + nelem(relist0) - 2;
- j.reliste[1] = relist1 + nelem(relist1) - 2;
+ j.reliste[0] = relist0 + nelem(relist0) - 1;
+ j.reliste[1] = relist1 + nelem(relist1) - 1;
rv = rregexec1(progp, bol, mp, ms, &j);
if(rv >= 0)