Skip to content

Commit 8d73f6b

Browse files
committed
parent: handle duplicated slashes
parent: handle Windows root paths join: add tests, correct behavior
1 parent 861082f commit 8d73f6b

File tree

4 files changed

+68
-7
lines changed

4 files changed

+68
-7
lines changed

+stdlib/expanduser.m

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,14 @@
1515

1616
e = p;
1717

18-
if ~all(startsWith(e, "~")) || (all(strlength(e) > 1) && ~all(startsWith(e, "~/")))
18+
if ~startsWith(e, "~") || (strlength(e) > 1 && ~startsWith(e, "~/"))
1919
return
2020
end
2121

2222
home = stdlib.homedir(use_java);
2323

2424
if ~isempty(home)
25-
e = stdlib.join(home, extractAfter(e, 1));
25+
e = stdlib.join(home, strip(extractAfter(e, 1), "left", "/"));
2626
end
2727

2828
end %function

+stdlib/join.m

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,45 @@
1-
function p = join(a, b)
1+
function p = join(a, b, use_java)
22
%% JOIN: join two paths with posix file separator
33
arguments
44
a (1,1) string
55
b (1,1) string
6+
use_java (1,1) logical = false
67
end
78

8-
p = stdlib.posix(fullfile(a, b));
9+
if a == "" && b == ""
10+
p = "";
11+
return
12+
end
13+
14+
a = stdlib.posix(a);
15+
b = stdlib.posix(b);
16+
17+
if a == ""
18+
p = b;
19+
return
20+
end
21+
22+
if b == ""
23+
p = a;
24+
return
25+
end
26+
27+
28+
if use_java
29+
30+
p = java.io.File(a).toPath().resolve(b);
31+
32+
else
33+
34+
if startsWith(b, "/") || (ispc && stdlib.is_absolute(b))
35+
p = b;
36+
return
37+
end
38+
39+
p = a + "/" + b;
40+
41+
end
42+
43+
p = stdlib.normalize(p);
944

1045
end

+stdlib/parent.m

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,15 @@
1010
% java is about 10x slower than intrinsic
1111
p = java.io.File(p).getParent();
1212
else
13+
p = stdlib.posix(p);
14+
% drop duplicated slashes in the parent path
15+
p = regexprep(p, "//+", "/");
16+
17+
if ispc && any(strlength(p) == [2,3]) && isletter(extractBetween(p, 1, 1)) && extractBetween(p, 2, 2) == ":"
18+
% 2 or 3 char drive letter
19+
p = stdlib.root(p);
20+
return
21+
end
1322
% have to drop_slash on input to get expected parent path
1423
p = strip(stdlib.posix(p), "right", "/");
1524
j = strfind(p, "/");

test/TestFilePure.m

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,12 @@
1717
sub_is_subdir
1818
ref_is_subdir
1919

20-
in_parent = {"", ".", "..", "../..", "a/b", "a/b/", "ab/.parent", "ab/.parent.txt", "a/b/../.parent.txt"}
21-
ref_parent = {".", ".", ".", "..", "a", "a", "ab", "ab", "a/b/.."}
20+
in_parent
21+
ref_parent
22+
23+
in_join = {"", "a", "", "a/b/", "/", "", "a", "a//", "a/b/../", "a/b", "a/b", "ab/cd"}
24+
other_join = {"", "", "b", "c/", "", "/", "b//", "b//", "c/d/../", "..", "c/d", "/ef"}
25+
ref_join = {"", "a", "b", "a/b/c", "/", "/", "a/b", "a/b", "a/c", "a", "a/b/c/d", "/ef"}
2226

2327
in_suffix = {"", "/foo/bar/baz", "/foo/bar/baz/", "foo/bar/baz.txt", "foo/bar/baz.txt.gz", ".stat", ".stat.txt"}
2428
ref_suffix = {"", "", "", ".txt", ".gz", ".stat", ".txt"}
@@ -37,11 +41,14 @@
3741
end
3842

3943
methods (TestParameterDefinition, Static)
40-
function [base_relative_to, other_relative_to, ref_relative_to, ref_proximate_to, in_root, ref_root] = init_relative_to(classToTest) %#ok<INUSD>
44+
function [base_relative_to, other_relative_to, ref_relative_to, ref_proximate_to, in_root, ref_root, in_parent, ref_parent] = init_relative_to(classToTest) %#ok<INUSD>
4145

4246
in_root = {"", "a/b", "./a/b", "../a/b", "/etc", "c:/etc"};
4347
ref_root = {"", "", "", "", "/", ""};
4448

49+
in_parent = {"", ".", "..", "../..", "a/", "a/b", "a/b/", "ab/.parent", "ab/.parent.txt", "a/b/../.parent.txt", "a/////b////c", "c:/", "c:\", "c:/a/b", "c:\a/b"};
50+
ref_parent = {".", ".", ".", "..", ".", "a", "a", "ab", "ab", "a/b/..", "a/b", ".", ".", "c:/a", "c:\a"};
51+
4552
if ispc
4653

4754
base_relative_to = {'', 'Hello', 'Hello', ...
@@ -55,6 +62,11 @@
5562
ref_proximate_to = ref_relative_to;
5663
ref_proximate_to{end} = other_relative_to{end};
5764

65+
ref_parent{12} = "c:/";
66+
ref_parent{13} = "c:/";
67+
ref_parent{14} = "c:/a";
68+
ref_parent{15} = "c:/a";
69+
5870
ref_root{5} = "";
5971
ref_root{6} = "c:/";
6072

@@ -158,6 +170,11 @@ function test_posix(tc)
158170
end
159171

160172

173+
function test_join(tc, in_join, other_join, ref_join)
174+
tc.verifyEqual(stdlib.join(in_join, other_join), ref_join)
175+
end
176+
177+
161178
function test_filename(tc, in_filename, ref_filename)
162179
tc.verifyEqual(stdlib.filename(in_filename), string(ref_filename))
163180
end

0 commit comments

Comments
 (0)