summaryrefslogtreecommitdiffstats
path: root/regex.c
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2016-04-19 21:14:48 -0700
committerKaz Kylheku <kaz@kylheku.com>2016-04-19 21:14:48 -0700
commit04575dff348209315fb24e3c809a93343f39783b (patch)
tree2a524abd08ba91e394812b596cd03a2ef2e4a924 /regex.c
parent97476a28d8aa0c1403d4ba4815f8f07a7caa7b4e (diff)
downloadtxr-04575dff348209315fb24e3c809a93343f39783b.tar.gz
txr-04575dff348209315fb24e3c809a93343f39783b.tar.bz2
txr-04575dff348209315fb24e3c809a93343f39783b.zip
Fix broken read_until_match.
* regex.c (read_until_match): Completely rewrite broken, unsalvageable, garbage logic.
Diffstat (limited to 'regex.c')
-rw-r--r--regex.c68
1 files changed, 51 insertions, 17 deletions
diff --git a/regex.c b/regex.c
index 4dd61610..b0464746 100644
--- a/regex.c
+++ b/regex.c
@@ -2523,36 +2523,70 @@ val read_until_match(val regex, val stream)
{
regex_machine_t regm;
val out = nil;
- val ch;
+ val stack = nil;
+ val match = nil;
stream = default_arg(stream, std_input);
regex_machine_init(&regm, regex);
- if ((ch = get_char(stream))) {
- if (regex_machine_feed(&regm, c_chr(ch)) == REGM_FAIL) {
- out = mkstring(one, ch);
+ for (;;) {
+ val ch = get_char(stream);
- while (ch && (ch = get_char(stream))) {
- regex_machine_reset(&regm);
-
- if (regex_machine_feed(&regm, c_chr(ch)) == REGM_FAIL) {
- string_extend(out, ch);
- continue;
+ if (!ch) {
+ switch (regex_machine_feed(&regm, 0)) {
+ case REGM_FAIL:
+ case REGM_INCOMPLETE:
+ if (match) {
+ while (stack != match)
+ unget_char(pop(&stack), stream);
+ if (!out)
+ out = null_string;
+ break;
}
-
+ break;
+ case REGM_MATCH:
+ if (!out)
+ out = null_string;
break;
}
- } else {
- out = mkstring(zero, ch);
+ break;
}
- }
- while (ch && (ch = get_char(stream))) {
- if (regex_machine_feed(&regm, c_chr(ch)) == REGM_FAIL) {
+ switch (regex_machine_feed(&regm, c_chr(ch))) {
+ case REGM_FAIL:
unget_char(ch, stream);
- break;
+
+ if (match) {
+ while (stack != match)
+ unget_char(pop(&stack), stream);
+ if (!out)
+ out = null_string;
+ break;
+ }
+
+ while (stack)
+ unget_char(pop(&stack), stream);
+
+ ch = get_char(stream);
+
+ if (!out)
+ out = mkstring(one, ch);
+ else
+ string_extend(out, ch);
+
+ regex_machine_reset(&regm);
+ continue;
+ case REGM_MATCH:
+ push(ch, &stack);
+ match = stack;
+ continue;
+ case REGM_INCOMPLETE:
+ push(ch, &stack);
+ continue;
}
+
+ break;
}
regex_machine_cleanup(&regm);