We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
There was an error while loading. Please reload this page.
1 parent 6d6b137 commit 81d20d0Copy full SHA for 81d20d0
+stdlib/parent.m
@@ -1,5 +1,11 @@
1
%% PARENT parent directory of path
2
+% optional: mex
3
%
4
+%% Examples:
5
+% parent("a/b/c") == "a/b"
6
+% parent("a/b/c/") == "a/b"
7
+%
8
+% MEX is about 10x faster than plain Matlab for this function
9
10
function p = parent(pth)
11
arguments
buildfile.m
@@ -97,6 +97,7 @@ function publishTask(context)
97
srcs = {
98
["src/is_admin.cpp", "src/admin_fs.cpp"] ...
99
"src/is_char_device.cpp", ...
100
+["src/parent.cpp", "src/parent_fs.cpp", normal], ...
101
"src/relative_to.cpp", ...
102
"src/proximate_to.cpp", ...
103
["src/is_wsl.cpp", linux], ...
example/bench_parent.m
@@ -1,13 +1,7 @@
f = mfilename("fullpath") + ".m";
-%f = tempname;
-fno = @() stdlib.parent(f, false);
-fjava = @() stdlib.parent(f, true);
+fno = @() stdlib.parent(f);
t_no = timeit(fno);
-t_java = timeit(fjava);
disp("No Java: " + t_no + " s")
-disp("Java: " + t_java + " s")
12
-
13
-disp("Java is " + t_no/t_java + " times faster")
octave_build.m
@@ -15,6 +15,7 @@ function octave_build(overwrite)
15
fullfile(d, "is_wsl.cpp"), ...
16
fullfile(d, "is_rosetta.cpp"), ...
17
fullfile(d, "is_admin.cpp"), ...
18
+fullfile(d, "parent.cpp"), ...
19
fullfile(d, "proximate_to.cpp"), ...
20
fullfile(d, "relative_to.cpp"), ...
21
};
@@ -24,11 +25,13 @@ function octave_build(overwrite)
24
25
for s = srcs
26
src = s{1};
27
[~, n] = fileparts(src);
28
+ bin = fullfile(t, [n, ".oct"]);
29
- if ~overwrite && isfile(fullfile(t, [n, ".oct"]))
30
+ if ~overwrite && stdlib.get_modtime(src) < stdlib.get_modtime(bin)
31
continue
32
end
33
- disp(["mkoctfile: ", src, " => ", n, ".oct"])
- mkoctfile(src, ["-I", inc], "--output", fullfile(t, n))
34
+ disp(["mkoctfile: ", src, " => ", bin])
35
+ delete(bin)
36
+ mkoctfile(src, ["-I", inc], "--output", bin)
37
src/ffilesystem.h
@@ -16,5 +16,8 @@ bool fs_is_symlink(std::string_view);
bool fs_create_symlink(std::string_view, std::string_view);
std::string fs_read_symlink(std::string_view);
+std::string fs_parent(std::string_view);
+std::string fs_root_name(std::string_view);
+
22
bool fs_win32_is_symlink(std::string_view);
23
std::string fs_shortname(std::string_view);
src/normalize.cpp
@@ -10,8 +10,6 @@
std::string fs_drop_slash(std::string_view in)
{
// drop all trailing "/" and duplicated internal "/"
- if (fs_is_url(in))
14
- return {};
std::filesystem::path p(in);
src/octave/parent.cpp
@@ -0,0 +1,21 @@
+#include <octave/oct.h>
+#include <string>
+#include <filesystem>
+#include "pure.cpp"
+#include "normalize.cpp"
+DEFUN_DLD (parent, args, nargout,
+ "get parent directory")
+{
+ if (args.length() != 1){
+ octave_stdout << "Oct: One input required\n";
+ return octave_value("");
+ }
+ std::string out = std::filesystem::path(fs_drop_slash(args(0).string_value())).parent_path().generic_string();
+ return octave_value(out);
+}
src/parent.cpp
@@ -0,0 +1,44 @@
+#include "mex.hpp"
+#include "mexAdapter.hpp"
+#include <vector>
+#include <memory>
+#include "ffilesystem.h"
+class MexFunction : public matlab::mex::Function {
+public:
+ void operator()(matlab::mex::ArgumentList outputs, matlab::mex::ArgumentList inputs) {
+// boilerplate engine & ArrayFactory setup
+ std::shared_ptr<matlab::engine::MATLABEngine> matlabEng = getEngine();
+ matlab::data::ArrayFactory factory;
+// wrangle inputs
+ std::string in;
+ if (inputs.size() != 1) {
+ matlabEng->feval(u"error", 0,
+ std::vector<matlab::data::Array>({ factory.createScalar("Mex: One input required") }));
+ if ((inputs[0].getType() == matlab::data::ArrayType::MATLAB_STRING && inputs[0].getNumberOfElements() == 1)){
+ matlab::data::TypedArray<matlab::data::MATLABString> stringArr = inputs[0];
+ in = stringArr[0];
+ } else if (inputs[0].getType() == matlab::data::ArrayType::CHAR){
+ matlab::data::CharArray charArr = inputs[0];
+ in.assign(charArr.begin(), charArr.end());
+ } else {
+ std::vector<matlab::data::Array>({ factory.createScalar("Mex: First input must be a scalar string or char vector") }));
38
39
+// actual function algorithm / computation
40
+ std::string out = fs_parent(in);
41
42
+ outputs[0] = factory.createScalar(out);
43
44
+};
src/parent_fs.cpp
@@ -0,0 +1,27 @@
+#include <string_view>
+std::string fs_parent(std::string_view in)
+ std::string out;
+ if(in.empty())
+ out = ".";
+ else
+ out = std::filesystem::path(fs_drop_slash(in)).parent_path().generic_string();
+ // handle "/" and other no parent cases
+ if (out.empty()){
+ if (!in.empty() && in.front() == '/')
+ out = "/";
+ // make x: x:/
+ if (fs_is_windows() && out.length() == 2 && !fs_root_name(out).empty())
+ out.push_back('/');
src/pure.cpp
@@ -46,6 +46,11 @@ std::string fs_as_posix(std::string_view path)
46
return p.generic_string();
47
}
48
49
+std::string fs_root_name(std::string_view path)
50
51
+ return std::filesystem::path(path).root_name().generic_string();
52
53
54
55
bool fs_is_url(std::string_view path)
56
0 commit comments