summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2021-07-03 16:06:17 -0700
committerKaz Kylheku <kaz@kylheku.com>2021-07-03 16:06:17 -0700
commitccb998581d8ba1e2f8f9c56768d57e32c51777c5 (patch)
treef29a4d79f4dfa91880ca415c85229ea80e83d89b
parentfc4d580aaa4bbd5908507596a429621e560b024b (diff)
downloadtxr-ccb998581d8ba1e2f8f9c56768d57e32c51777c5.tar.gz
txr-ccb998581d8ba1e2f8f9c56768d57e32c51777c5.tar.bz2
txr-ccb998581d8ba1e2f8f9c56768d57e32c51777c5.zip
suffix functions: ignore trailing slashes.
Another requirements tweak to short-suffix and long-suffix: ignore one or more trailing slashes, instead of just one. This harmonizes with base-name, which does same, that requirement being copies from the POSIX basename utility. * stream.c (short_suffix, long_suffix): If sl points to a trailing slash which is the start of a suffix that consists of nothing but trailing slashes, then we pretend it isn't there. * tests/018/path.tl: Adjusted two existing test cases, and added more. * txr.1: Documented.
-rw-r--r--stream.c7
-rw-r--r--tests/018/path.tl18
-rw-r--r--txr.111
3 files changed, 27 insertions, 9 deletions
diff --git a/stream.c b/stream.c
index a2f4baf1..4f4edbe3 100644
--- a/stream.c
+++ b/stream.c
@@ -5042,8 +5042,9 @@ val short_suffix(val name, val alt_in)
const wchar_t *str = c_str(name, self);
const wchar_t *dot = wcsrchr(str, '.');
const wchar_t *sl = if3(dot, wcspbrk(dot + 1, psc), 0);
+ int sl_trail = if3(sl, sl[wcsspn(sl, psc)] == 0, 0);
- if (!dot || (sl && sl[1]) || dot == str || wcschr(psc, dot[-1])) {
+ if (!dot || (sl && sl[1] && !sl_trail) || dot == str || wcschr(psc, dot[-1])) {
return default_null_arg(alt_in);
} else {
wchar_t *suff = chk_strdup(dot);
@@ -5063,7 +5064,7 @@ val long_suffix(val name, val alt_in)
{
const wchar_t *sl;
- while (dot && (sl = wcspbrk(dot, psc)) && sl[1])
+ while (dot && (sl = wcspbrk(dot, psc)) && sl[1] && sl[wcsspn(sl, psc)] != 0)
dot = wcschr(sl + 1, '.');
if (dot && (dot == str || wcschr(psc, dot[-1])))
@@ -5074,7 +5075,7 @@ val long_suffix(val name, val alt_in)
} else {
wchar_t *suff = chk_strdup(dot);
if (sl)
- suff[sl - dot] = 0;
+ suff[sl - dot] = 0;
return string_own(suff);
}
}
diff --git a/tests/018/path.tl b/tests/018/path.tl
index 96298dfd..937d2d6e 100644
--- a/tests/018/path.tl
+++ b/tests/018/path.tl
@@ -49,7 +49,12 @@
(short-suffix ".a/b/.b/") nil
(short-suffix ".a/b/c.b") ".b"
(short-suffix ".a/b/c.b/") ".b"
- (short-suffix ".a/b/c.b//") nil)
+ (short-suffix ".a/b/c.b//") ".b"
+ (short-suffix ".a/b/c.b///") ".b"
+ (short-suffix ".a/b/c.") "."
+ (short-suffix ".a/b/c./") "."
+ (short-suffix ".a/b/c.//") "."
+ (short-suffix ".a/b/c.///") ".")
(mtest
(long-suffix "/") nil
@@ -67,7 +72,16 @@
(long-suffix "a.b/c.d.e/") ".d.e"
(long-suffix "a.b/c.d.e/f") nil
(long-suffix "a.b/c.d.e/f.g.h") ".g.h"
- (long-suffix "a.b/c.d.e//") nil)
+ (long-suffix "a.b/c.d.e//") ".d.e"
+ (long-suffix "a.b/c.d.e///") ".d.e"
+ (long-suffix "a.b/c.d.") ".d."
+ (long-suffix "a.b/c.d./") ".d."
+ (long-suffix "a.b/c.d.//") ".d."
+ (long-suffix "a.b/c.d.///") ".d."
+ (long-suffix "a.b/c.") "."
+ (long-suffix "a.b/c./") "."
+ (long-suffix "a.b/c.//") "."
+ (long-suffix "a.b/c.///") ".")
(mtest
(base-name "") ""
diff --git a/txr.1 b/txr.1
index 4b7e7236..d963097d 100644
--- a/txr.1
+++ b/txr.1
@@ -57406,10 +57406,10 @@ If a suffix delimiter is present, then the long or short suffix is the
substring of
.meta path
which includes the delimiting period and all characters which follow,
-except that if the last character of
+except that if
.meta path
-is a path separator character, that character is omitted from the
-returned suffix.
+ends in a sequence of one or more path separator characters,
+those characters are omitted from the returned suffix.
If multiple periods occur in the last component of the path,
the delimiter for the long suffix is the leftmost period and
@@ -57428,7 +57428,8 @@ For the purpose of identifying the last component of
.metn path ,
if
.meta path
-ends in a path-separator character, then that character is removed.
+ends a sequence of one or more path-separator characters, then those
+characters are removed from consideration.
If the remaining string contains path-separator characters, then
the last component consists of that portion of it which follows
the rightmost path-separator character. Otherwise, the last component
@@ -57446,6 +57447,7 @@ extracted from this last component.
(short-suffix "abc" "") -> ""
(short-suffix "abc.") -> "."
(short-suffix "abc.tar") -> ".tar"
+ (short-suffix "abc.tar///") -> ".tar"
(short-suffix "abc.tar.gz") -> ".gz"
(short-suffix "abc.tar.gz/") -> ".gz"
(short-suffix "x.y.z/abc.tar.gz/") -> ".gz"
@@ -57458,6 +57460,7 @@ extracted from this last component.
(long-suffix "/.abc") -> nil
(long-suffix "abc.") -> "."
(long-suffix "abc.tar") -> ".tar"
+ (long-suffix "abc.tar///") -> ".tar"
(long-suffix "abc.tar.gz") -> ".tar.gz"
(long-suffix "abc.tar.gz/") -> ".tar.gz"
(long-suffix "x.y.z/abc.tar.gz/") -> ".tar.gz"