diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2021-06-29 07:36:38 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2021-06-29 07:36:38 -0700 |
commit | d5d2a4c79c2e6203798cf985df5f23964a04817f (patch) | |
tree | a7e7d9451eaba0e99bb8dfb7e7081170ad55db89 | |
parent | 86fd2fab95618f6b097a80002da783f02a799d75 (diff) | |
download | txr-d5d2a4c79c2e6203798cf985df5f23964a04817f.tar.gz txr-d5d2a4c79c2e6203798cf985df5f23964a04817f.tar.bz2 txr-d5d2a4c79c2e6203798cf985df5f23964a04817f.zip |
path-cat: becomes variadic.
* stream.c (path_vcat): New static function.
(stream_init): Register path-cat instrinsic to path_vcat
rather than path_cat.
* tests/018/path.tl: path-cat tests: all examples from
documentation, plus others.
* txr.1: Documented existing behaviors that were not clear,
like when inputs are empty. Documented new variadic semantics.
Examples added.
-rw-r--r-- | stream.c | 21 | ||||
-rw-r--r-- | tests/018/path.tl | 32 | ||||
-rw-r--r-- | txr.1 | 58 |
3 files changed, 103 insertions, 8 deletions
@@ -5116,6 +5116,25 @@ val path_cat(val dir_name, val base_name) return scat(lit("/"), dir_name, base_name, nao); } +static val path_vcat(struct args *args) +{ + cnum ix = 0; + + if (!args_more(args, ix)) { + return lit("."); + } else { + val accum = args_get(args, &ix); + + if (!stringp(accum)) + uw_throwf(file_error_s, lit("path-cat: ~s isn't a string"), accum, nao); + + while (args_more(args, ix)) + accum = path_cat(accum, args_get(args, &ix)); + + return accum; + } +} + val make_byte_input_stream(val obj) { val self = lit("make-byte-input-stream"); @@ -5376,7 +5395,7 @@ void stream_init(void) reg_fun(intern(lit("dir-name"), user_package), func_n1(dir_name)); reg_fun(intern(lit("short-suffix"), user_package), func_n2o(short_suffix, 1)); reg_fun(intern(lit("long-suffix"), user_package), func_n2o(long_suffix, 1)); - reg_fun(intern(lit("path-cat"), user_package), func_n2(path_cat)); + reg_fun(intern(lit("path-cat"), user_package), func_n0v(path_vcat)); reg_varl(intern(lit("path-sep-chars"), user_package), static_str(path_sep_chars)); reg_fun(intern(lit("get-indent-mode"), user_package), func_n1(get_indent_mode)); reg_fun(intern(lit("test-set-indent-mode"), user_package), func_n3(test_set_indent_mode)); diff --git a/tests/018/path.tl b/tests/018/path.tl index 16c44d77..96298dfd 100644 --- a/tests/018/path.tl +++ b/tests/018/path.tl @@ -96,3 +96,35 @@ (base-name "a.b/" ".b") "a" (base-name "a.b/" ".b/") "a.b" (base-name "a.b/" "a.b") "a.b") + +(mtest + (path-cat "" "") "" + (path-cat "" ".") "." + (path-cat "." "") "." + (path-cat "." ".") "." + (path-cat "abc" ".") "abc" + (path-cat "." "abc") "abc" + (path-cat "./" ".") "./" + (path-cat "." "./") "./" + (path-cat "abc/" ".") "abc/" + (path-cat "./" "abc") "abc" + (path-cat "/" ".") "/" + (path-cat "/" "abc") "/abc" + (path-cat "ab/cd" "ef") "ab/cd/ef" + (path-cat "a" "b" "c") "a/b/c" + (path-cat "a" "b" "" "c" "/") "a/b/c/") + +(mtest + (path-cat) "." + (path-cat 3) :error + (path-cat "") "" + (path-cat "/") "/" + (path-cat ".") "." + (path-cat "" "" "") "" + (path-cat "." "" "") "." + (path-cat "" "." "") "." + (path-cat "" "" ".") "." + (path-cat "." "." ".") "." + (path-cat "abc/" "/def/" "g") "abc/def/g" + (path-cat "abc/" "/def/" "g/") "abc/def/g/" + (path-cat "" "abc/" "/def/" "g/") "abc/def/g/") @@ -57365,19 +57365,25 @@ extracted from this last component. .coNP Function @ path-cat .synb -.mets (path-cat < dir-path << rel-path ) +.mets (path-cat >> [ dir-path <> { rel-path }*]) .syne .desc The .code path-cat -function joins the directory pathname given by the character -string argument +joints together zero or more paths, returning the combined path. +All arguments are strings. + +The following description defines the behavior when +.code path-cat +is given exactly two arguments, which are interpreted as .meta dir-path -with the relative pathname given by -.metn rel-path , -returning the joined path. +and +.metn rel-path . +A description of the variable argument semantics follows. -The function is related to the functions +Firstly, the two-argument +.code path-cat +is related to the functions .code dir-name and .code base-name @@ -57422,6 +57428,40 @@ string is .meta dir-name itself. +If +.meta dir-path +is an empty string, then +.code rel-path +is returned, and +.IR "vice versa" . + +The variadic semantics of +.code path-cat +is as follows. + +If +.code path-cat +is called with no arguments at all, it returns the path +.str . +(period) denoting the relative path of the current directory. + +If +.code path-cat +is called with one argument, that argument is returned. + +If +.code path-cat +is called with three or more arguments, a left-associative reduction +takes place using the two-argument semantics. The first two arguments +are catenated into a single path, which is then catenated +with the third argument, and so on. + +The above semantics implies that the following equivalence holds: + +.verb + [reduce-left path-cat list] <--> [apply path-cat list] +.brev + .TP* Examples: .verb @@ -57444,6 +57484,10 @@ itself. (path-cat "/" "abc") --> "/abc" (path-cat "ab/cd" "ef") --> "ab/cd/ef" + + (path-cat "a" "b" "c") --> "a/b/c" + + (path-cat "a" "b" "" "c" "/") --> "a/b/c/" .brev .coNP Function @ rel-path |