Commit Diff


commit - ad0209f094996d7d6bd1ce2319f5b0385f343bd6
commit + 13efde33b7b447d7c224632ab895efd18662dc9e
blob - 7d338fb279442bce81d01c14b97d97734f3c1e4d
blob + 0ac282cf73284d376a6eff871018ae760d015458
--- nfa.c
+++ nfa.c
@@ -494,6 +494,7 @@ struct prep {
 
 	int pos;		/* current input position */
 	int match;		/* length of longest match so far */
+	int active;		/* is the automaton (still) running? */
 
 	struct set act;		/* set of "active" states */
 	struct set next;	/* set of "next active" states */
@@ -547,6 +548,7 @@ nfastart(struct prep *pr, sub_t *sub, out_t *out, void
 	pr->env = env;
 	pr->pos = 0;
 	pr->match = -1;		/* no match */
+	pr->active = 1;
 
 	memset(pr->act.bits, 0, pr->act.sz * sizeof(bunch_t));
 		// XXX is this memset actually necessary?? i.e.: does
@@ -783,22 +785,29 @@ nfacont(struct prep *pr, const char *input, size_t sz)
 {
 	int i, r, x;
 
+	if (!pr->active)
+		return 0;
+
 	for(i = 0; i < sz; i += r) {
 		x = (unsigned char)input[i];
 		r = nfastep(pr, x, &pr->act, &pr->next);
-		if (r == -1)			/* no match */
-			break;
+		if (r == -1)				/* no match? */
+			return (pr->active = 0);	/* we're done */
 		pr->pos += r;
 	}
 
-	return pr->match;
+	return 1;					/* ready for more */
 }
 
 int
 nfaend(struct prep *pr)
 {
-	/* run until output ceases or END matches */
-	while(nfastep(pr, END, &pr->act, &pr->next) == 0);
+	if (pr->active) {
+		/* run until output ceases or END matches */
+		while(nfastep(pr, END, &pr->act, &pr->next) == 0);
+		pr->active = 0;
+	}
+
 	return pr->match;
 }
 
@@ -808,8 +817,7 @@ nfarun_(struct prep *pr,
 {
 	nfastart(pr, sub, out, env);
 	nfacont(pr, inp, sz);
-	nfaend(pr);
-	return pr->match;
+	return nfaend(pr);
 }
 
 int