diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2016-01-01 12:23:00 -0800 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2016-01-01 12:23:00 -0800 |
commit | 27e0a161c083222ef78bcf6192b931aa815583b3 (patch) | |
tree | ebb045f0417307f3c7763ce900cbb4b50781e581 /regex.c | |
parent | bccdfcb523d7b0315c20a41dec43a6b0cf302a73 (diff) | |
download | txr-27e0a161c083222ef78bcf6192b931aa815583b3.tar.gz txr-27e0a161c083222ef78bcf6192b931aa815583b3.tar.bz2 txr-27e0a161c083222ef78bcf6192b931aa815583b3.zip |
Record-delimiting stream adapter.
* regex.c (read_until_match): New function.
(regex_init): Registered read-until-match intrinsic.
* regex.h (read_until_match): Declared.
* stream.c (struct delegate_base): New struct type.
(delegate_base_mark, delegate_put_string, delegate_put_char,
delegate_put_byte, delegate_get_char, delegate_get_byte,
delegate_unget_char, delegate_unget_byte, delegate_close,
delegate_flush, delegate_seek, delegate_truncate,
delegate_get_prop, delegate_set_prop, delegate_get_error,
delegate_get_error_str, delegate_clear_error,
make_delegate_stream): New static functions.
(struct record_adapter_base): New struct type.
(record_adapter_base_mark, record_adapter_mark_op,
record_adapter_get_line): New static functions.
(record_adapter_ops): New static structure.
(record_adapter): New function.
(stream_init): Registered record-adapter intrinsic.
* stream.h (record_adapter): Declared.
* txr.1: Documented read-until-match and record-adapter.
Diffstat (limited to 'regex.c')
-rw-r--r-- | regex.c | 41 |
1 files changed, 41 insertions, 0 deletions
@@ -2502,6 +2502,46 @@ val match_regst_right(val str, val regex, val end) sub_str(str, minus(end, len), end))); } +val read_until_match(val regex, val stream) +{ + regex_machine_t regm; + val out = nil; + val ch; + + 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); + + 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; + } + + break; + } + } else { + out = mkstring(zero, ch); + } + } + + while (ch && (ch = get_char(stream))) { + if (regex_machine_feed(®m, c_chr(ch)) == REGM_FAIL) { + unget_char(ch, stream); + break; + } + } + + regex_machine_cleanup(®m); + return out; +} + static char_set_t *create_wide_cs(void) { #ifdef FULL_UNICODE @@ -2583,5 +2623,6 @@ void regex_init(void) reg_fun(intern(lit("reg-expand-nongreedy"), system_package), func_n1(reg_expand_nongreedy)); reg_fun(intern(lit("reg-optimize"), system_package), func_n1(reg_optimize)); + reg_fun(intern(lit("read-until-match"), user_package), func_n2o(read_until_match, 1)); init_special_char_sets(); } |