Skip to content

Commit f2ab873

Browse files
committed
normalize: don't coerce
1 parent 06f46a6 commit f2ab873

File tree

6 files changed

+25
-17
lines changed

6 files changed

+25
-17
lines changed

+stdlib/normalize.m

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,8 @@
99
% * n: normalized path
1010

1111
function n = normalize(apath)
12-
arguments
13-
apath (1,1) string
14-
end
1512

16-
parts = split(apath, ["/", filesep]);
13+
parts = split(string(apath), ["/", filesep]);
1714
i0 = 1;
1815
if startsWith(apath, ["/", filesep])
1916
n = extractBefore(apath, 2);
@@ -29,9 +26,9 @@
2926
if n == ""
3027
n = parts(i);
3128
elseif ismember(n, ["/", filesep])
32-
n = n + parts(i);
29+
n = append(n, parts(i));
3330
else
34-
n = n + "/" + parts(i);
31+
n = append(n, '/', parts(i));
3532
end
3633
end
3734
end
@@ -40,5 +37,8 @@
4037
n = ".";
4138
end
4239

40+
if ischar(apath)
41+
n = char(n);
42+
end
4343

4444
end

AGENTS.md

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,16 @@ To detect if a specific language interface is available, we provide functions st
1414
There is a namespace stdlib.sys defined under +stdlib/+sys/ that provided system() calls using the system shell as a last-restort fallback if no external language interface is available on the end user computer running Matlab.
1515
The namespace stdlib.native and stdlib.legacy use plain Matlab code, and allow switching between "modern" and "legacy" implementations of functions as needed.
1616

17-
The self-test functions under "test/" directory can be used by Matlab >= R2019b as invoked by "test_main.m" at the top level of the project directory.
17+
The self-test functions under "test/" directory can be used by Matlab >= R2019a as invoked by "test_main.m" at the top level of the project directory.
1818
Matlab >= R2022b can alternatively use "buildtool test" to run the self-tests.
1919

20+
The key limitations to minimum Matlab version are:
21+
22+
* R2017b: fileparts() supports string type. fileparts() is used in many places in the code as it's 5-10x faster than regexp() for filename parsing.
23+
* R2019a: append() for string and char types. strcat() has the side effect of trimming whitespace, so we prefer append() for string concatenation in case a user path has trailing whitespace.
24+
* R2019b: function argument validation block "arguments"
25+
26+
2027
## Dev Rules
2128

2229
These rules apply under the namespace "stdlib" (directory +stdlib/) and all its sub-namespaces (subdirectories +stdlib/+*).
@@ -25,6 +32,7 @@ These rules apply under the namespace "stdlib" (directory +stdlib/) and all its
2532
- The code must not require any Matlab toolboxes, only base Matlab functionality
2633
- Prohibited to use Matlab factory function "isMATLABReleaseOlderThan()" as it is slow and not available for Matlab < R2020b. Instead we use stdlib.matlabOlderThan() which is like 200x faster than isMATLABReleaseOlderThan() and works for Matlab >= R2016b
2734
- When an exception is encountered, we generally desire that the code return an "empty" value of the appropriate type. In certain cases we may throw or rethrow an error.
35+
- where the output represents a filesystem path, the output should be a string type if any input is string type, otherwise char type.
2836

2937
## Dev notes
3038

test/TestCanonical.m

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
classdef (SharedTestFixtures={ matlab.unittest.fixtures.PathFixture(fileparts(fileparts(mfilename('fullpath'))))}, ...
2-
TestTags = {'impure'}) ...
2+
TestTags = {'R2019a'}) ...
33
TestCanonical < matlab.unittest.TestCase
44

55
properties (TestParameter)
66
p = {{'', ''}, ...
77
{"", ""}, ...
88
{"not-exist", "not-exist"}, ...
9-
{"a/../b", "a/../b"}, ...
9+
{'a/../b', 'a/../b'}, ...
1010
{append(mfilename("fullpath"), '.m/..'), fileparts(mfilename("fullpath"))}, ...
1111
{"not-exist/a/..", "not-exist/a/.."}, ...
1212
{"./not-exist", "not-exist"}
@@ -20,7 +20,7 @@ function test_dirs(tc)
2020
end
2121

2222

23-
methods (Test, TestTags={'R2019b'})
23+
methods (Test)
2424
function test_canonical(tc, p)
2525
c = stdlib.canonical(p{1}, false);
2626
tc.verifyEqual(c, p{2})

test/TestNormalize.m

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
classdef (SharedTestFixtures={ matlab.unittest.fixtures.PathFixture(fileparts(fileparts(mfilename('fullpath'))))}, ...
2-
TestTags = {'R2019b', 'pure'}) ...
2+
TestTags = {'R2019a', 'pure'}) ...
33
TestNormalize < matlab.unittest.TestCase
44

55
properties (TestParameter)
@@ -8,7 +8,7 @@
88
{"a/..", "a/.."}, ...
99
{"/a/b/", "/a/b"}, ...
1010
{"a/b/", "a/b"}, ...
11-
{"a////b", "a/b"}, ...
11+
{'a////b', 'a/b'}, ...
1212
{".a", ".a"}, ...
1313
{"..a", "..a"}, ...
1414
{"a.", "a."}, ...
@@ -45,7 +45,7 @@ function test_drop_slash(tc, d)
4545
{"/", "/"}, ...
4646
{"a/", "a"}, ...
4747
{"a/b", "a/b"}, ...
48-
{"a/b/", "a/b"}, ...
48+
{'a/b/', 'a/b'}, ...
4949
{"////", "/"}, ...
5050
{"a////b", "a/b"}, ...
5151
{"a//b//", "a/b"}, ...

test/TestResolve.m

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
classdef (SharedTestFixtures={ matlab.unittest.fixtures.PathFixture(fileparts(fileparts(mfilename('fullpath'))))}, ...
2-
TestTags = {'impure'}) ...
2+
TestTags = {'R2019a'}) ...
33
TestResolve < matlab.unittest.TestCase
44

55
properties (TestParameter)
@@ -13,7 +13,7 @@ function test_dirs(tc)
1313
end
1414

1515

16-
methods (Test, TestTags={'R2019b'})
16+
methods (Test)
1717

1818
function test_resolve_relative(tc)
1919
import matlab.unittest.constraints.StartsWithSubstring

test/TestRoot.m

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
classdef (SharedTestFixtures={ matlab.unittest.fixtures.PathFixture(fileparts(fileparts(mfilename('fullpath'))))}, ...
2-
TestTags = {'R2019b', 'pure'}) ...
2+
TestTags = {'R2019a', 'pure'}) ...
33
TestRoot < matlab.unittest.TestCase
44

55
properties (TestParameter)
@@ -80,4 +80,4 @@ function test_root_name(tc, rn)
8080
p{8}{2} = '\';
8181
end
8282

83-
end
83+
end

0 commit comments

Comments
 (0)