summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--regex.c40
-rw-r--r--regex.h2
-rw-r--r--stream.c8
-rw-r--r--stream.h2
-rw-r--r--txr.136
5 files changed, 50 insertions, 38 deletions
diff --git a/regex.c b/regex.c
index b0464746..e8de118c 100644
--- a/regex.c
+++ b/regex.c
@@ -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(&regm, regex);
@@ -2537,18 +2537,11 @@ val read_until_match(val regex, val stream)
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;
- }
+ 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(&regm);
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();
}
diff --git a/regex.h b/regex.h
index ac84af26..75bad120 100644
--- a/regex.h
+++ b/regex.h
@@ -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);
diff --git a/stream.c b/stream.c
index 24dc79d2..31a3accc 100644
--- a/stream.c
+++ b/stream.c
@@ -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));
diff --git a/stream.h b/stream.h
index 920cdf3e..192f7bbb 100644
--- a/stream.h
+++ b/stream.h
@@ -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);
diff --git a/txr.1 b/txr.1
index c07ca2c8..42558296 100644
--- a/txr.1
+++ b/txr.1
@@ -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