Mercurial > octave
changeset 27609:51d26dd80828
Use canonical paths in list of load paths (bug #56267).
* load-path.cc:
(octave::maybe_canonicalize): New static function.
(load_path::set, load_path::add): Canonicalize paths if possible before setting
the load path.
(load_path::find_dir, load_path::find_matching_dirs, load_path::find_dir_info):
Canonicalize input path if possible.
(Faddpath): Revert change from 5a0543de1e47.
(Frmpath): Revert change from 1397742ea0fe.
author | Markus Mützel <markus.muetzel@gmx.de> |
---|---|
date | Fri, 01 Nov 2019 21:57:03 +0100 |
parents | 994db4a60d10 |
children | 8586eb41abf5 |
files | libinterp/corefcn/load-path.cc |
diffstat | 1 files changed, 48 insertions(+), 27 deletions(-) [+] |
line wrap: on
line diff
--- a/libinterp/corefcn/load-path.cc Fri Nov 01 21:31:42 2019 +0100 +++ b/libinterp/corefcn/load-path.cc Fri Nov 01 21:57:03 2019 +0100 @@ -48,10 +48,41 @@ namespace octave { + // Canonicalize file name (keeping the path relative) if it exists. + // Return it unmodified otherwise. + + static std::string + maybe_canonicalize (const std::string& dir_arg) + { + bool is_absolute_path = octave::sys::env::absolute_pathname (dir_arg); + + std::string canonical_dir = octave::sys::canonicalize_file_name (dir_arg); + std::string dir; + if (canonical_dir.empty ()) + dir = dir_arg; + else + { + dir = canonical_dir; + + if (! is_absolute_path) + { + // Remove current path from absolute path generated by + // canonicalize_file_name. + std::string cwd = octave::sys::canonicalize_file_name ("."); + if (dir.compare (0, cwd.length (), cwd) == 0) + dir.erase (0, cwd.length ()+1); + if (dir.empty ()) + dir = "."; + } + } + + return dir; + } + static void maybe_add_path_elts (std::string& path, const std::string& dir) { - std::string tpath = genpath (dir); + std::string tpath = genpath (maybe_canonicalize (dir)); if (! tpath.empty ()) { @@ -254,6 +285,9 @@ // Use a list when we need to preserve order. std::list<std::string> elts = split_path (p); + for (auto& elt : elts) + elt = maybe_canonicalize (elt); + // Use a set when we need to search and order is not important. std::set<std::string> elts_set (elts.begin (), elts.end ()); @@ -568,6 +602,7 @@ } else { + std::string canon_dir = maybe_canonicalize (dir); for (const auto& di : dir_info_list) { std::string dname = sys::env::make_absolute (di.dir_name); @@ -581,11 +616,11 @@ dname_len--; } - size_t dir_len = dir.length (); + size_t dir_len = canon_dir.length (); if (dname_len > dir_len && sys::file_ops::is_dir_sep (dname[dname_len - dir_len - 1]) - && dir == dname.substr (dname_len - dir_len)) + && canon_dir == dname.substr (dname_len - dir_len)) { sys::file_stat fs (di.dir_name); @@ -614,6 +649,7 @@ } else { + std::string canon_dir = maybe_canonicalize (dir); for (const auto& di : dir_info_list) { std::string dname = sys::env::make_absolute (di.dir_name); @@ -627,11 +663,11 @@ dname_len--; } - size_t dir_len = dir.length (); + size_t dir_len = canon_dir.length (); if (dname_len > dir_len && sys::file_ops::is_dir_sep (dname[dname_len - dir_len - 1]) - && dir == dname.substr (dname_len - dir_len)) + && canon_dir == dname.substr (dname_len - dir_len)) { sys::file_stat fs (di.dir_name); @@ -941,6 +977,8 @@ { std::string dir = sys::file_ops::tilde_expand (dir_arg); + dir = maybe_canonicalize (dir); + auto retval = dir_info_list.cbegin (); while (retval != dir_info_list.cend ()) @@ -959,6 +997,8 @@ { std::string dir = sys::file_ops::tilde_expand (dir_arg); + dir = maybe_canonicalize (dir); + auto retval = dir_info_list.begin (); while (retval != dir_info_list.end ()) @@ -1029,6 +1069,8 @@ dir = strip_trailing_separators (dir); + dir = maybe_canonicalize (dir); + auto i = find_dir_info (dir); if (i != dir_info_list.end ()) @@ -2544,23 +2586,6 @@ }), dir.end ()); - bool is_absolute_path = octave::sys::env::absolute_pathname (dir); - - std::string canonical_dir = octave::sys::canonicalize_file_name (dir); - if (! canonical_dir.empty ()) - dir = canonical_dir; - - if (! is_absolute_path) - { - // Remove current path from absolute path generated by - // canonicalize_file_name. - std::string cwd = octave::sys::canonicalize_file_name ("."); - if (dir.compare (0, cwd.length (), cwd) == 0) - dir.erase (0, cwd.length ()+1); - if (dir.empty ()) - dir = "."; - } - auto pos = dir.find_last_of (octave::sys::file_ops::dir_sep_chars ()); if (pos == std::string::npos) { @@ -2633,15 +2658,11 @@ std::string arg = args(i).xstring_value ("rmpath: all arguments must be strings"); std::list<std::string> dir_elts = octave::split_path (arg); - for (auto dir : dir_elts) + for (const auto dir : dir_elts) { //dir = regexprep (dir_elts{j}, '//+', "/"); //dir = regexprep (dir, '/$', ""); - std::string canonical_dir = octave::sys::canonicalize_file_name (dir); - if (! canonical_dir.empty ()) - dir = canonical_dir; - if (! lp.remove (dir)) warning ("rmpath: %s: not found", dir.c_str ()); else