From 6d800734b64c92b5bb9979c06c84ed4d29098933 Mon Sep 17 00:00:00 2001 From: Kaz Kylheku Date: Fri, 16 Sep 2016 06:55:59 -0700 Subject: split-str gains ability to keep separating pieces. * eval.c (eval_init): Register split-str to split_str_keep, with optional argument. * lib.c (split_str_keep): New function, formed from split_str, with third argument. (split_str): Reduced to wrapper around split_str_keep. Thus we don't have to update umpteen existing calls with an extra nil parameter. * lib.h (split_str_keep): Declared. * txr.1: Documented new optional argument of split-str. --- eval.c | 2 +- lib.c | 15 ++++++++++++++- lib.h | 1 + txr.1 | 14 +++++++++++++- 4 files changed, 29 insertions(+), 3 deletions(-) diff --git a/eval.c b/eval.c index 89af7232..66b33aa1 100644 --- a/eval.c +++ b/eval.c @@ -5233,7 +5233,7 @@ void eval_init(void) reg_fun(intern(lit("sub-str"), user_package), func_n3o(sub_str, 1)); reg_fun(intern(lit("replace-str"), user_package), func_n4o(replace_str, 2)); reg_fun(intern(lit("cat-str"), user_package), func_n2o(cat_str, 1)); - reg_fun(intern(lit("split-str"), user_package), func_n2(split_str)); + reg_fun(intern(lit("split-str"), user_package), func_n3o(split_str_keep, 2)); reg_fun(intern(lit("split-str-set"), user_package), func_n2(split_str_set)); reg_fun(intern(lit("tok-str"), user_package), func_n3o(tok_str, 1)); reg_fun(intern(lit("tok-where"), user_package), func_n2(tok_where)); diff --git a/lib.c b/lib.c index 7abdb95b..13982b69 100644 --- a/lib.c +++ b/lib.c @@ -3807,8 +3807,10 @@ val scat(val sep, ...) return ret; } -val split_str(val str, val sep) +val split_str_keep(val str, val sep, val keep_sep) { + keep_sep = default_bool_arg(keep_sep); + if (regexp(sep)) { list_collect_decl (out, iter); val pos = zero; @@ -3824,6 +3826,8 @@ val split_str(val str, val sep) if (len) { pos = plus(pos, len); + if (keep_sep) + iter = list_collect(iter, sub_str(str, new_pos, pos)); continue; } break; @@ -3846,6 +3850,8 @@ val split_str(val str, val sep) val piece = mkustring(one); init_str(piece, cstr); iter = list_collect(iter, piece); + if (keep_sep && *(cstr+1)) + iter = list_collect(iter, null_string); } gc_hint(str); @@ -3870,6 +3876,8 @@ val split_str(val str, val sep) cstr += span; if (psep != 0) { cstr += len_sep; + if (keep_sep) + iter = list_collect(iter, sep); continue; } break; @@ -3883,6 +3891,11 @@ val split_str(val str, val sep) } } +val split_str(val str, val sep) +{ + return split_str_keep(str, sep, nil); +} + val split_str_set(val str, val set) { const wchar_t *cstr = c_str(str); diff --git a/lib.h b/lib.h index 179c0c66..0ec09a74 100644 --- a/lib.h +++ b/lib.h @@ -716,6 +716,7 @@ val sub_str(val str_in, val from_num, val to_num); val cat_str(val list, val sep); val scat(val sep, ...); val split_str(val str, val sep); +val split_str_keep(val str, val sep, val keep_sep); val split_str_set(val str, val set); val tok_str(val str, val tok_regex, val keep_sep); val tok_where(val str, val tok_regex); diff --git a/txr.1 b/txr.1 index e524dbce..1cbaff45 100644 --- a/txr.1 +++ b/txr.1 @@ -18436,7 +18436,7 @@ which is interposed between the catenated strings. .coNP Function @ split-str .synb -.mets (split-str < string << sep ) +.mets (split-str < string < sep <> [ keep-between ]) .syne .desc The @@ -18491,6 +18491,18 @@ This operation is nondestructive: .meta string is not modified in any way. +If the optional +.meta keep-between +argument is specified and is not +.codn nil , +If an argument is given and is true, then +.meta split-str +incorporates the matching separating pieces of +.meta string +into the resulting list, such that if the resulting +list is catenated, a string equivalent to the original +string will be produced. + Note: To split a string into pieces of length one such that an empty string produces .code nil -- cgit v1.2.3