summaryrefslogtreecommitdiffstats
path: root/regex.c
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2016-09-22 06:14:27 -0700
committerKaz Kylheku <kaz@kylheku.com>2016-09-22 06:14:27 -0700
commite3d17617a33941fea6c2f365151e93201aaf152d (patch)
tree67898edda2983dda7283a4a4d42e037dc0b9f384 /regex.c
parentcbe8ab16302c0224c2e90dc0dd28e64e80b3fe2b (diff)
downloadtxr-e3d17617a33941fea6c2f365151e93201aaf152d.tar.gz
txr-e3d17617a33941fea6c2f365151e93201aaf152d.tar.bz2
txr-e3d17617a33941fea6c2f365151e93201aaf152d.zip
Support functional argument in regsub.
* regex.c (regsub): Allow the second argument to be a function, which is called with str as an argument, and returns a range which indicates what part of the string is to be replaced, or else nil. * txr.1: Documented functional argument of regsub.
Diffstat (limited to 'regex.c')
-rw-r--r--regex.c64
1 files changed, 41 insertions, 23 deletions
diff --git a/regex.c b/regex.c
index c7a5e132..ba63132c 100644
--- a/regex.c
+++ b/regex.c
@@ -2523,34 +2523,52 @@ val match_regex_right(val str, val regex, val end)
val regsub(val regex, val repl, val str)
{
- list_collect_decl (out, ptail);
- val pos = zero;
val isfunc = functionp(repl);
- do {
- cons_bind (find, len, search_regex(str, regex, pos, nil));
- if (!find) {
- if (pos == zero)
- return str;
- ptail = list_collect(ptail, sub_str(str, pos, nil));
- break;
+ if (functionp(regex)) {
+ val range = funcall1(regex, str);
+
+ if (!range)
+ return str;
+
+ {
+ val rf = from(range);
+ val rt = to(range);
+
+ return replace_str(str, if3(isfunc,
+ funcall1(repl, sub_str(str, rf, rt)),
+ repl),
+ rf, rt);
}
- ptail = list_collect(ptail, sub_str(str, pos, find));
- ptail = list_collect(ptail, if3(isfunc,
- funcall1(repl, sub_str(str, find,
- plus(find, len))),
- repl));
- if (len == zero && eql(find, pos)) {
- if (lt(pos, length_str(str))) {
- ptail = list_collect(ptail, chr_str(str, pos));
- pos = plus(pos, one);
+ } else {
+ list_collect_decl (out, ptail);
+ val pos = zero;
+
+ do {
+ cons_bind (find, len, search_regex(str, regex, pos, nil));
+ if (!find) {
+ if (pos == zero)
+ return str;
+ ptail = list_collect(ptail, sub_str(str, pos, nil));
+ break;
}
- } else {
- pos = plus(find, len);
- }
- } while (lt(pos, length_str(str)));
+ ptail = list_collect(ptail, sub_str(str, pos, find));
+ ptail = list_collect(ptail, if3(isfunc,
+ funcall1(repl, sub_str(str, find,
+ plus(find, len))),
+ repl));
+ if (len == zero && eql(find, pos)) {
+ if (lt(pos, length_str(str))) {
+ ptail = list_collect(ptail, chr_str(str, pos));
+ pos = plus(pos, one);
+ }
+ } else {
+ pos = plus(find, len);
+ }
+ } while (lt(pos, length_str(str)));
- return cat_str(out, nil);
+ return cat_str(out, nil);
+ }
}
val search_regst(val haystack, val needle_regex, val start_num, val from_end)