diff options
-rw-r--r-- | regex.c | 40 | ||||
-rw-r--r-- | regex.h | 2 | ||||
-rw-r--r-- | stream.c | 8 | ||||
-rw-r--r-- | stream.h | 2 | ||||
-rw-r--r-- | txr.1 | 36 |
5 files changed, 50 insertions, 38 deletions
@@ -2519,14 +2519,14 @@ 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) +val read_until_match(val regex, val stream_in, val include_match_in) { regex_machine_t regm; val out = nil; val stack = nil; val match = nil; - - stream = default_arg(stream, std_input); + val stream = default_arg(stream_in, std_input); + val include_match = default_bool_arg(include_match_in); regex_machine_init(®m, regex); @@ -2537,18 +2537,11 @@ val read_until_match(val regex, val stream) 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; - } + if (match) + goto out_match; break; case REGM_MATCH: - if (!out) - out = null_string; - break; + goto out_match; } break; } @@ -2557,13 +2550,8 @@ val read_until_match(val regex, val stream) case REGM_FAIL: unget_char(ch, stream); - if (match) { - while (stack != match) - unget_char(pop(&stack), stream); - if (!out) - out = null_string; - break; - } + if (match) + goto out_match; while (stack) unget_char(pop(&stack), stream); @@ -2589,6 +2577,16 @@ val read_until_match(val regex, val stream) break; } + if (nil) { +out_match: + while (stack != match) + unget_char(pop(&stack), stream); + if (!out) + out = null_string; + if (include_match) + out = cat_str(cons(out, nreverse(stack)), nil); + } + regex_machine_cleanup(®m); return out; } @@ -2674,6 +2672,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)); + reg_fun(intern(lit("read-until-match"), user_package), func_n3o(read_until_match, 1)); init_special_char_sets(); } @@ -39,6 +39,6 @@ val search_regst(val haystack, val needle_regex, val start_num, val from_end); val match_regst(val str, val regex, val pos); val match_regst_right(val str, val regex, val end); val regsub(val regex, val repl, val str); -val read_until_match(val regex, val stream); +val read_until_match(val regex, val stream, val keep_match); int wide_display_char_p(wchar_t ch); void regex_init(void); @@ -2325,6 +2325,7 @@ static val make_delegate_stream(val orig_stream, size_t handle_size, struct record_adapter_base { struct delegate_base db; val regex; + val include_match; }; static void record_adapter_base_mark(struct record_adapter_base *rb) @@ -2344,7 +2345,7 @@ static val record_adapter_get_line(val stream) { struct record_adapter_base *rb = coerce(struct record_adapter_base *, stream->co.handle); - return read_until_match(rb->regex, rb->db.target_stream); + return read_until_match(rb->regex, rb->db.target_stream, rb->include_match); } static struct strm_ops record_adapter_ops = @@ -2362,7 +2363,7 @@ static struct strm_ops record_adapter_ops = delegate_get_error, delegate_get_error_str, delegate_clear_error, delegate_get_fd); -val record_adapter(val regex, val stream) +val record_adapter(val regex, val stream, val include_match) { val rec_adapter = make_delegate_stream(default_arg(stream, std_input), sizeof (struct record_adapter_base), @@ -2371,6 +2372,7 @@ val record_adapter(val regex, val stream) rec_adapter->co.handle); rb->regex = regex; + rb->include_match = tnil(include_match); return rec_adapter; } @@ -3847,7 +3849,7 @@ void stream_init(void) reg_fun(intern(lit("cat-streams"), user_package), func_n1(make_catenated_stream)); reg_fun(intern(lit("catenated-stream-p"), user_package), func_n1(catenated_stream_p)); reg_fun(intern(lit("catenated-stream-push"), user_package), func_n2(catenated_stream_push)); - reg_fun(intern(lit("record-adapter"), user_package), func_n2o(record_adapter, 1)); + reg_fun(intern(lit("record-adapter"), user_package), func_n3o(record_adapter, 1)); reg_fun(intern(lit("open-directory"), user_package), func_n1(open_directory)); reg_fun(intern(lit("open-file"), user_package), func_n2o(open_file, 1)); reg_fun(intern(lit("open-fileno"), user_package), func_n2o(open_fileno, 1)); @@ -152,7 +152,7 @@ val get_string_from_stream(val); val make_strlist_output_stream(void); val get_list_from_stream(val); val make_dir_stream(DIR *); -val record_adapter(val regex, val stream); +val record_adapter(val regex, val stream, val include_match); val streamp(val obj); val real_time_stream_p(val obj); val stream_set_prop(val stream, val ind, val prop); @@ -30574,7 +30574,7 @@ in the resulting string object that is processed by .coNP Function @ read-until-match .synb -.mets (read-until-match < regex <> [ stream ]) +.mets (read-until-match < regex >> [ stream <> [ include-match ]]) .syne .desc The @@ -30589,6 +30589,14 @@ then the .code *std-input* stream is used. +The +.meta include-match +argument is Boolean, indicating whether the delimiting text +matched by +.meta regex +is included in the returned string. It defaults to +.codn nil . + The accumulation of characters is terminated by a match on .metn regex , the end of the stream, or an error. @@ -30608,12 +30616,11 @@ are accumulated, the function returns When the accumulation of characters terminates by a match on .metn regex , -reading characters from the stream continues. The longest -possible prefix of the stream which matches -.meta regex -is read, and discarded. If an error is encountered, the -matching procedure terminates and returns the previously -accumulated string. +the longest possible matching sequence of characters is +removed from the stream. If +.meta include-match +is true, that matching text is included in +the returned string. Otherwise, it is discarded. .SS* Hashing Library .coNP Functions @, make-hash and @ hash @@ -34769,7 +34776,7 @@ terminal to terminate the expression. .coNP Function @ record-adapter .synb -.mets (record-adapter < regex <> [ stream ]) +.mets (record-adapter < regex >> [ stream <> [ include-match ]]) .syne .desc The @@ -34797,11 +34804,16 @@ function is used on the adapter, it behaves differently. A string is extracted from .metn stream , and returned. However, the string isn't a line delimited by a newline -character, but a record delimited by -.metn regex -as if using the +character, but rather a record delimited by +.metn regex . +This record is extracted as if by a call to the .code read-until-match -function. +function, invoked with the +.metn regex , +.meta stream +and +.meta include-match +arguments. All behavior which is built on the .code get-lines |