diff options
-rw-r--r-- | eval.c | 1 | ||||
-rw-r--r-- | lib.c | 20 | ||||
-rw-r--r-- | lib.h | 1 | ||||
-rw-r--r-- | tests/015/esc.tl | 39 | ||||
-rw-r--r-- | txr.1 | 37 |
5 files changed, 98 insertions, 0 deletions
@@ -7597,6 +7597,7 @@ void eval_init(void) reg_fun(intern(lit("tok-where"), user_package), func_n2(tok_where)); reg_fun(intern(lit("list-str"), user_package), func_n1(list_str)); reg_fun(intern(lit("trim-str"), user_package), func_n1(trim_str)); + reg_fun(intern(lit("str-esc"), user_package), func_n3(str_esc)); reg_fun(intern(lit("cmp-str"), user_package), func_n2(cmp_str)); reg_fun(intern(lit("string-lt"), user_package), func_n2(str_lt)); reg_fun(intern(lit("str="), user_package), func_n2(str_eq)); @@ -6400,6 +6400,26 @@ val trim_str(val str) } } +val str_esc(val escset, val escchr, val str) +{ + val self = lit("shell-escape"); + val out = mkstring(zero, chr(' ')); + const wchar_t *s = c_str(str, self); + const wchar_t *es = c_str(escset, self); + wchar_t ch; + + while ((ch = *s++)) { + if (wcschr(es, ch)) { + string_extend(out, escchr, nil); + string_extend(out, chr(ch), nil); + } else { + string_extend(out, chr(ch), nil); + } + } + + return string_finish(out); +} + val cmp_str(val astr, val bstr) { val self = lit("cmp-str"); @@ -1077,6 +1077,7 @@ val tokn(val count, val tok_regex, val arg1, val arg2); val tok_where(val str, val tok_regex); val list_str(val str); val trim_str(val str); +val str_esc(val escset, val escchr, val str); val cmp_str(val astr, val bstr); val str_eq(val astr, val bstr); val str_lt(val astr, val bstr); diff --git a/tests/015/esc.tl b/tests/015/esc.tl new file mode 100644 index 00000000..cf3619c8 --- /dev/null +++ b/tests/015/esc.tl @@ -0,0 +1,39 @@ +(load "../common") + +(mtest + (str-esc "$*." "~" "") "" + (str-esc "$*." "~" "a") "a" + (str-esc "$*." "~" "~") "~" + (str-esc "$*." "~" "*") "~*" + (str-esc "$*." "~" ".") "~.") + +(mtest + (str-esc "$*." "~" "aa") "aa" + (str-esc "$*." "~" "a~") "a~" + (str-esc "$*." "~" "a$") "a~$" + (str-esc "$*." "~" "a*") "a~*" + (str-esc "$*." "~" "a.") "a~.") + +(mtest + (str-esc "$*." "~" "~a") "~a" + (str-esc "$*." "~" "$a") "~$a" + (str-esc "$*." "~" "*a") "~*a" + (str-esc "$*." "~" ".a") "~.a") + +(mtest + (str-esc "$*." "~" "a~b") "a~b" + (str-esc "$*." "~" "a$b") "a~$b" + (str-esc "$*." "~" "a*b") "a~*b" + (str-esc "$*." "~" "a.b") "a~.b") + +(mtest + (str-esc "$*." "~" "~a~") "~a~" + (str-esc "$*." "~" "$a$") "~$a~$" + (str-esc "$*." "~" "*a*") "~*a~*" + (str-esc "$*." "~" ".a.") "~.a~.") + +(test + (str-esc "$*." "~" "$*.a$*.b") "~$~*~.a~$~*~.b") + +(test + (str-esc "<>" "<" "(<<>>)") "(<<<<<><>)") @@ -26480,6 +26480,43 @@ function produces a copy of from which leading and trailing tabs, spaces and newlines are removed. +.coNP Function @ str-esc +.synb +.mets (str-esc < esc-set < esc-tok << str ) +.syne +.desc +The +.code str-esc +function performs a +.I "character escaping" +transformation on the input string +.metn str . + +The argument +.meta esc-set +is a string containing zero or more characters. + +The +.meta esc-tok +argument is a character or string. + +The function returns a transformed version of +.meta str +in which every character of +.meta str +which occurs in +.meta esc-set +is preceded by +.metn esc-tok . + +.TP* Examples; + +.verb + (str-esc "$@#" "$" "$foo @abc #1") -> "$$foo $@abc $#1" + + (str-esc "'" "'\e\e'" "foo 'bar' baz") -> "foo '\e\e''bar'\e\e'' baz" +.brev + .coNP Functions @ string-set-code and @ string-get-code .synb .mets (string-set-code < string << value ) |