summaryrefslogtreecommitdiffstats
path: root/lib.c
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2022-05-17 21:02:21 -0700
committerKaz Kylheku <kaz@kylheku.com>2022-05-17 21:02:21 -0700
commitf255d4cfaf866ced7a5fb2f4af4681d96a069b4b (patch)
tree755ddf6bfcc6ede8f6e8d7d2eabf16bae6e96c4f /lib.c
parentf16a4c07c8dad9d7d144063618cf65c6e076233e (diff)
downloadtxr-f255d4cfaf866ced7a5fb2f4af4681d96a069b4b.tar.gz
txr-f255d4cfaf866ced7a5fb2f4af4681d96a069b4b.tar.bz2
txr-f255d4cfaf866ced7a5fb2f4af4681d96a069b4b.zip
split-str: new count parameter.
* eval.c (eval_init): Fix up registration of split-str to account for new parameter. * lib.c (split_str_keep): Implement new optional count argument. (spl): Pass nil value to split_str_keep for new argument. I'd like this function to benefit from this argument also, but the design isn't settled. (split_str): Pass nil argument to split_str_keep. * lib.h (split_str_keep): Declaration updated. * tests/015/split.tl: New tests. * txr.1: Documented.
Diffstat (limited to 'lib.c')
-rw-r--r--lib.c36
1 files changed, 29 insertions, 7 deletions
diff --git a/lib.c b/lib.c
index 95c1bd6b..050e8889 100644
--- a/lib.c
+++ b/lib.c
@@ -5735,10 +5735,18 @@ val fmt_join(struct args *args)
return join_with(nil, args);
}
-val split_str_keep(val str, val sep, val keep_sep)
+val split_str_keep(val str, val sep, val keep_sep_opt, val count_opt)
{
val self = lit("split-str");
- keep_sep = default_null_arg(keep_sep);
+ val keep_sep = default_null_arg(keep_sep_opt);
+ val count = default_null_arg(count_opt);
+ cnum cnt = c_num(if3(count, count, negone), self);
+
+ if (count && cnt < 0)
+ uw_throwf(error_s, lit("~a: count must be nonnegative"), self, nao);
+
+ if (count == zero)
+ return cons(str, nil);
if (regexp(sep)) {
list_collect_decl (out, iter);
@@ -5758,6 +5766,10 @@ val split_str_keep(val str, val sep, val keep_sep)
pos = plus(pos, len);
if (keep_sep)
iter = list_collect(iter, sub_str(str, new_pos, pos));
+ if (cnt > 0 && --cnt == 0) {
+ iter = list_collect(iter, sub_str(str, pos, t));
+ break;
+ }
continue;
}
break;
@@ -5789,8 +5801,14 @@ val split_str_keep(val str, val sep, val keep_sep)
val piece = mkustring(one);
init_str(piece, cstr, self);
iter = list_collect(iter, piece);
- if (keep_sep && *(cstr+1))
- iter = list_collect(iter, null_string);
+ if (*(cstr + 1)) {
+ if (keep_sep)
+ iter = list_collect(iter, null_string);
+ if (cnt > 0 && --cnt == 0) {
+ iter = list_collect(iter, string(cstr + 1));
+ break;
+ }
+ }
}
gc_hint(str);
@@ -5817,6 +5835,10 @@ val split_str_keep(val str, val sep, val keep_sep)
cstr += len_sep;
if (keep_sep)
iter = list_collect(iter, sep);
+ if (cnt > 0 && --cnt == 0) {
+ iter = list_collect(iter, string(cstr));
+ break;
+ }
continue;
}
break;
@@ -5833,13 +5855,13 @@ val split_str_keep(val str, val sep, val keep_sep)
val spl(val sep, val arg1, val arg2)
{
return if3(missingp(arg2),
- split_str_keep(arg1, sep, arg2),
- split_str_keep(arg2, sep, arg1));
+ split_str_keep(arg1, sep, arg2, nil),
+ split_str_keep(arg2, sep, arg1, nil));
}
val split_str(val str, val sep)
{
- return split_str_keep(str, sep, nil);
+ return split_str_keep(str, sep, nil, nil);
}
val split_str_set(val str, val set)