Skip to content

Commit ca3954d

Browse files
committed
relative,proximate: can use .net
1 parent fc9662d commit ca3954d

File tree

7 files changed

+69
-32
lines changed

7 files changed

+69
-32
lines changed

+stdlib/file_checksum.m

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
%% FILE_CHECKSUM compute hash of file
2-
% requires: java
2+
% optional: java
33
%
44
% read in chunks to avoid excessive RAM use
55
%

+stdlib/is_symlink.m

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
switch e.identifier
1313
case "MATLAB:UndefinedFunction"
1414
if stdlib.has_dotnet()
15-
if stdlib.dotnet_api >= 6
15+
if stdlib.dotnet_api() >= 6
1616
ok = ~isempty(System.IO.FileInfo(p).LinkTarget);
1717
else
1818
attr = string(System.IO.File.GetAttributes(p).ToString());

+stdlib/proximate_to.m

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,24 @@
11
%% PROXIMATE_TO relative path to base
2-
% requires: mex
3-
2+
% optional: mex
3+
%
44
%%% Inputs
55
% * base {mustBeTextScalar}
66
% * other {mustBeTextScalar}
77
%%% Outputs
88
% * rel {mustBeTextScalar}
9-
%
10-
% This function is written in C++ using STL <filesystem>
119

12-
function proximate_to(~,~)
13-
error("buildtool mex")
10+
function rel = proximate_to(base, other)
11+
arguments
12+
base {mustBeTextScalar}
13+
other {mustBeTextScalar}
14+
end
15+
16+
rel = stdlib.relative_to(base, other);
17+
if strempty(rel)
18+
rel = fullfile(other);
19+
end
20+
21+
1422
end
1523

1624
%!testif 0

+stdlib/relative_to.m

Lines changed: 33 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,47 @@
11
%% RELATIVE_TO relative path to base
2-
% requires: mex
2+
% optional: mex
33
%
44
%%% Inputs
55
% * base {mustBeTextScalar}
66
% * other {mustBeTextScalar}
77
%%% Outputs
88
% * rel {mustBeTextScalar}
99
%
10-
% This function is written in C++ using STL <filesystem>
11-
%
1210
% Note: Java Path.relativize has an algorithm so different that we choose not to use it.
1311
% https://docs.oracle.com/javase/8/docs/api/java/nio/file/Path.html#relativize-java.nio.file.Path-
1412

15-
function relative_to(~,~)
16-
error("buildtool mex")
13+
function rel = relative_to(base, other)
14+
arguments
15+
base {mustBeTextScalar}
16+
other {mustBeTextScalar}
17+
end
18+
19+
20+
if stdlib.has_dotnet() && stdlib.dotnet_api() >= 5
21+
22+
if strempty(base) && strempty(other), rel = "."; return, end
23+
24+
if strempty(other), rel = base; return, end
25+
if strempty(base), rel = other; return, end
26+
27+
bis = stdlib.is_absolute(base);
28+
ois = stdlib.is_absolute(other);
29+
30+
if bis ~= ois, rel = ""; return, end
31+
32+
base = fullfile(base);
33+
other = fullfile(other);
34+
35+
if bis && ~(startsWith(base, other) || startsWith(other, base))
36+
rel = "";
37+
else
38+
% https://learn.microsoft.com/en-us/dotnet/api/system.io.path.getrelativepath
39+
rel = string(System.IO.Path.GetRelativePath(base, other));
40+
end
41+
else
42+
error('no supported relative path method found, please install .NET or "buildtool mex"')
43+
end
44+
1745
end
1846

1947
%!testif 0

buildfile.m

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -265,8 +265,6 @@ function build_exe(context)
265265
["src/is_admin.cpp", "src/admin_fs.cpp"] ...
266266
"src/is_char_device.cpp", ...
267267
["src/normalize.cpp", normal], ...
268-
"src/relative_to.cpp", ...
269-
"src/proximate_to.cpp", ...
270268
"src/disk_available.cpp", ...
271269
"src/disk_capacity.cpp", ...
272270
"src/set_permissions.cpp", ...

src/relative_to.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ class MexFunction : public matlab::mex::Function {
2828
matlab_2string(inputs, &base, &other);
2929

3030
std::error_code ec;
31-
std::string out = std::filesystem::relative(other, base, ec).generic_string();
31+
std::string out = std::filesystem::relative(other, base, ec).string();
3232

3333
if(ec)
3434
matlabEng->feval(u"error", 0,

test/TestRelative.m

Lines changed: 19 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -5,20 +5,20 @@
55
pp = init_prox()
66
end
77

8-
methods (Test, TestTags = "mex")
8+
methods (Test)
99

1010
function test_relative_to(tc, pr)
11-
tc.assertTrue(stdlib.is_mex_fun("stdlib.relative_to"))
11+
tc.assumeTrue((stdlib.has_dotnet() && stdlib.dotnet_api() >= 5) || stdlib.is_mex_fun("stdlib.relative_to"))
1212

1313
tc.verifyEqual(stdlib.relative_to(pr{1}, pr{2}), pr{3}, ...
1414
"relative_to(" + pr{1} + "," + pr{2}+")")
1515
end
1616

1717
function test_proximate_to(tc, pp)
18-
tc.assertTrue(stdlib.is_mex_fun("stdlib.proximate_to"))
18+
tc.assumeTrue((stdlib.has_dotnet() && stdlib.dotnet_api() >= 5) || stdlib.is_mex_fun("stdlib.proximate_to"))
1919

2020
tc.verifyEqual(stdlib.proximate_to(pp{1}, pp{2}), pp{3}, ...
21-
"proximate_to(" + pp{1} + "," + pp{2}+")")
21+
"proximate_to(" + pp{1} + ", " + pp{2}+")")
2222
end
2323

2424
end
@@ -32,30 +32,32 @@ function test_proximate_to(tc, pp)
3232
{"Hello", "Hello/", "."}, ...
3333
{"a/./b", "a/b", "."}, ...
3434
{"a/b", "a/./b", "."}, ...
35-
{"./a/b", "./a/c", "../c"}, ...
35+
{"./a/b", "./a/c", fullfile("..", "c")}, ...
3636
{"/", "/", "."}, ...
37-
{"a/b/c/d", "a/b", "../.."}, ...
38-
{"a/b", "a/c", "../c"}, ...
39-
{"a/b", "c", "../../c"}, ...
40-
{"c", "a/b", "../a/b"}, ...
37+
{"a/b/c/d", "a/b", fullfile("..", "..")}, ...
38+
{"a/b", "a/c", fullfile("..", "c")}, ...
39+
{"a/b", "c", fullfile("..", "..", "c")}, ...
40+
{"c", "a/b", fullfile("..", "a", "b")}, ...
4141
{"a/b", "a/b", "."}, ...
4242
{"a/b", "a", ".."}
4343
};
4444
% NOTE: ".." in relative_to(base) is ambiguous including for python.pathlib, C++ <filesystem>, etc.
4545

4646
if ispc
4747
p = [p, ...
48-
{{"C:/a/b", "C:/", "../.."}, ...
49-
{"C:/", "C:/a/b", "a/b"}, ...
48+
{{"C:/a/b", "C:/", fullfile("..", "..")}, ...
49+
{"C:/", "C:/a/b", fullfile("a", "b")}, ...
5050
{"c:/a/b", "c:/a/b", "."}, ...
5151
{"c:/a/b", "c:/a", ".."}, ...
52-
{"c:\a/b\c/d", "c:/a\b", "../.."}, ...
53-
{"C:/path", "D:/path", ""}}];
52+
{"c:\a/b\c/d", "c:/a\b", fullfile("..", "..")}, ...
53+
{"C:/path", "D:/path", ""}, ...
54+
{"D:/a/b", "c", ""}}];
5455
% note: on Windows the drive letter should be uppercase!
5556
else
5657
p = [p, ...
5758
{{"", "a", "a"}, ...
58-
{"/dev/null", "/dev/null", "."}}];
59+
{"/dev/null", "/dev/null", "."}, ...
60+
{"/a/b", "c", ""}}];
5961
end
6062

6163
end
@@ -65,9 +67,10 @@ function test_proximate_to(tc, pp)
6567

6668
p = init_rel();
6769

68-
6970
if ispc
70-
p{end}{3} = "D:/path";
71+
p{end-1}{3} = fullfile("D:", "path");
7172
end
7273

74+
p{end}{3} = "c";
75+
7376
end

0 commit comments

Comments
 (0)