summaryrefslogtreecommitdiffstats
path: root/regex.c
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2019-02-16 09:46:14 -0800
committerKaz Kylheku <kaz@kylheku.com>2019-02-16 09:46:14 -0800
commitf16aaf441c112f0e6382b77ebdcd585d8c531580 (patch)
treece3041d1395f7260bd698230098beffc778ca952 /regex.c
parent338f97b5a32a038a7cb21b8045a72412dbe4bfd6 (diff)
downloadtxr-f16aaf441c112f0e6382b77ebdcd585d8c531580.tar.gz
txr-f16aaf441c112f0e6382b77ebdcd585d8c531580.tar.bz2
txr-f16aaf441c112f0e6382b77ebdcd585d8c531580.zip
scan-until-match, count-until-match: new functions.
* regex.c (scan_until_common): New static function, made from read_until_match. (read_until_match): Now just wrapper for scan_until_common. (scan_until_match, count_until_match): New functions. (regex_init): Registered new intrinsics scan-until-match and count-until-match. * regex.h (read_until_match, scan_until_match): Declared. * txr.1: Documented.
Diffstat (limited to 'regex.c')
-rw-r--r--regex.c42
1 files changed, 35 insertions, 7 deletions
diff --git a/regex.c b/regex.c
index 99be57e1..47f1e0c3 100644
--- a/regex.c
+++ b/regex.c
@@ -43,6 +43,7 @@
#include "gc.h"
#include "eval.h"
#include "cadr.h"
+#include "itypes.h"
#include "regex.h"
#include "txr.h"
@@ -3113,11 +3114,12 @@ val regex_range_search_fun(val regex, val start, val from_end)
return curry_1234_1(func_n4(range_regex), regex, start, from_end);
}
-val read_until_match(val regex, val stream_in, val include_match_in)
+static val scan_until_common(val self, val regex, val stream_in,
+ val include_match_in, val accum)
{
- val self = lit("read-until-match");
regex_machine_t regm;
val out = nil;
+ u64_t count = 0;
val stack = nil;
val match = nil;
val stream = default_arg(stream_in, std_input);
@@ -3153,10 +3155,14 @@ val read_until_match(val regex, val stream_in, val include_match_in)
ch = get_char(stream);
- if (!out)
- out = mkstring(one, ch);
- else
- string_extend(out, ch);
+ if (accum) {
+ if (!out)
+ out = mkstring(one, ch);
+ else
+ string_extend(out, ch);
+ } else {
+ count++;
+ }
regex_machine_reset(&regm);
continue;
@@ -3176,10 +3182,14 @@ val read_until_match(val regex, val stream_in, val include_match_in)
out_match:
while (stack && stack != match)
unget_char(rcyc_pop(&stack), stream);
- if (!out)
+ if (accum && !out)
out = null_string;
if (include_match)
out = cat_str(cons(out, stack = nreverse(stack)), nil);
+ if (!accum && match) {
+ val c = unum_64(count);
+ out = if3(include_match, cons(c, out), c);
+ }
}
regex_machine_cleanup(&regm);
@@ -3190,6 +3200,22 @@ out_match:
return out;
}
+val read_until_match(val regex, val stream_in, val include_match_in)
+{
+ return scan_until_common(lit("read-until-match"), regex, stream_in,
+ include_match_in, t);
+}
+
+val scan_until_match(val regex, val stream_in)
+{
+ return scan_until_common(lit("scan-until-match"), regex, stream_in, t, nil);
+}
+
+val count_until_match(val regex, val stream_in)
+{
+ return scan_until_common(lit("count-until-match"), regex, stream_in, nil, nil);
+}
+
static char_set_t *create_wide_cs(void)
{
#ifdef FULL_UNICODE
@@ -3293,6 +3319,8 @@ void regex_init(void)
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_n3o(read_until_match, 1));
+ reg_fun(intern(lit("scan-until-match"), user_package), func_n2(scan_until_match));
+ reg_fun(intern(lit("count-until-match"), user_package), func_n2(count_until_match));
reg_fun(intern(lit("f^$"), user_package), func_n2o(regex_match_full_fun, 1));
reg_fun(intern(lit("f^"), user_package), func_n2o(regex_match_left_fun, 1));
reg_fun(intern(lit("f$"), user_package), func_n2o(regex_match_right_fun, 1));