diff options
-rw-r--r-- | regex.c | 68 |
1 files changed, 51 insertions, 17 deletions
@@ -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(®m, regex); - if ((ch = get_char(stream))) { - if (regex_machine_feed(®m, c_chr(ch)) == REGM_FAIL) { - out = mkstring(one, ch); + for (;;) { + val ch = get_char(stream); - while (ch && (ch = get_char(stream))) { - regex_machine_reset(®m); - - if (regex_machine_feed(®m, c_chr(ch)) == REGM_FAIL) { - string_extend(out, ch); - continue; + if (!ch) { + switch (regex_machine_feed(®m, 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(®m, c_chr(ch)) == REGM_FAIL) { + switch (regex_machine_feed(®m, 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(®m); + continue; + case REGM_MATCH: + push(ch, &stack); + match = stack; + continue; + case REGM_INCOMPLETE: + push(ch, &stack); + continue; } + + break; } regex_machine_cleanup(®m); |