Mercurial > octave
changeset 23445:8e310ef0fa97
move load_path class to octave namespace
* load-path.cc, load-path.h: Move load_path classes inside octave
namespace. Change all uses.
author | John W. Eaton <jwe@octave.org> |
---|---|
date | Thu, 27 Apr 2017 12:31:17 -0400 |
parents | d6e81498e7fe |
children | cd4e1ee28716 |
files | libgui/src/octave-qt-link.cc libinterp/corefcn/defaults.cc libinterp/corefcn/dirfns.cc libinterp/corefcn/help.cc libinterp/corefcn/interpreter.cc libinterp/corefcn/load-path.cc libinterp/corefcn/load-path.h libinterp/corefcn/ls-mat5.cc libinterp/corefcn/symtab.cc libinterp/corefcn/utils.cc libinterp/corefcn/variables.cc libinterp/octave-value/ov-class.cc libinterp/octave-value/ov-classdef.cc libinterp/octave-value/ov-fcn-handle.cc |
diffstat | 14 files changed, 2493 insertions(+), 2473 deletions(-) [+] |
line wrap: on
line diff
--- a/libgui/src/octave-qt-link.cc Wed Apr 26 01:32:49 2017 -0400 +++ b/libgui/src/octave-qt-link.cc Thu Apr 27 12:31:17 2017 -0400 @@ -564,7 +564,7 @@ ok = true; else { - load_path& lp = octave::__get_load_path__ ("octave_qt_link::file_in_path"); + octave::load_path& lp = octave::__get_load_path__ ("octave_qt_link::file_in_path"); bool dir_in_load_path = lp.contains_canonical (dir); @@ -610,7 +610,7 @@ case 2: { - load_path& lp = octave::__get_load_path__ ("octave_qt_link::file_in_path"); + octave::load_path& lp = octave::__get_load_path__ ("octave_qt_link::file_in_path"); lp.prepend (dir); ok = true;
--- a/libinterp/corefcn/defaults.cc Wed Apr 26 01:32:49 2017 -0400 +++ b/libinterp/corefcn/defaults.cc Thu Apr 27 12:31:17 2017 -0400 @@ -298,7 +298,7 @@ if (! tpath.empty ()) VIMAGE_PATH += octave::directory_path::path_sep_str () + tpath; - tpath = genpath (Vimage_dir, ""); + tpath = octave::genpath (Vimage_dir, ""); if (! tpath.empty ()) VIMAGE_PATH += octave::directory_path::path_sep_str () + tpath;
--- a/libinterp/corefcn/dirfns.cc Wed Apr 26 01:32:49 2017 -0400 +++ b/libinterp/corefcn/dirfns.cc Thu Apr 27 12:31:17 2017 -0400 @@ -83,7 +83,7 @@ // FIXME: should these actions be handled as a list of functions // to call so users can add their own chdir handlers? - load_path& lp = octave::__get_load_path__ ("octave_change_to_directory"); + octave::load_path& lp = octave::__get_load_path__ ("octave_change_to_directory"); lp.update ();
--- a/libinterp/corefcn/help.cc Wed Apr 26 01:32:49 2017 -0400 +++ b/libinterp/corefcn/help.cc Thu Apr 27 12:31:17 2017 -0400 @@ -193,7 +193,7 @@ const string_vector lcl = symbol_table::variable_names (); const int lcl_len = lcl.numel (); - load_path& lp = octave::__get_load_path__ ("make_name_list"); + octave::load_path& lp = octave::__get_load_path__ ("make_name_list"); const string_vector ffl = lp.fcn_names (); const int ffl_len = ffl.numel (); @@ -734,7 +734,7 @@ { // We might find a file that contains only a doc string. - load_path& lp = octave::__get_load_path__ ("do_which"); + octave::load_path& lp = octave::__get_load_path__ ("do_which"); file = lp.find_fcn_file (name); } @@ -743,7 +743,7 @@ { // File query. - load_path& lp = octave::__get_load_path__ ("do_which"); + octave::load_path& lp = octave::__get_load_path__ ("do_which"); // For compatibility: "file." queries "file". if (name.size () > 1 && name[name.size () - 1] == '.') @@ -844,7 +844,7 @@ { octave_value retval; - load_path& lp = octave::__get_load_path__ ("__list_functions__"); + octave::load_path& lp = octave::__get_load_path__ ("__list_functions__"); if (args.length () == 0) {
--- a/libinterp/corefcn/interpreter.cc Wed Apr 26 01:32:49 2017 -0400 +++ b/libinterp/corefcn/interpreter.cc Thu Apr 27 12:31:17 2017 -0400 @@ -343,7 +343,7 @@ { std::string file_name = octave::sys::file_ops::concat (dir, "PKG_ADD"); - load_path& lp = octave::__get_load_path__ ("execute_pkg_add"); + octave::load_path& lp = octave::__get_load_path__ ("execute_pkg_add"); try {
--- a/libinterp/corefcn/load-path.cc Wed Apr 26 01:32:49 2017 -0400 +++ b/libinterp/corefcn/load-path.cc Thu Apr 27 12:31:17 2017 -0400 @@ -45,13 +45,10 @@ #include "unwind-prot.h" #include "utils.h" -std::string load_path::sys_path; -load_path::abs_dir_cache_type load_path::abs_dir_cache; - static void maybe_add_path_elts (std::string& path, const std::string& dir) { - std::string tpath = genpath (dir); + std::string tpath = octave::genpath (dir); if (! tpath.empty ()) { @@ -190,7 +187,7 @@ static void rehash_internal (void) { - load_path& lp = octave::__get_load_path__ ("rehash_internal"); + octave::load_path& lp = octave::__get_load_path__ ("rehash_internal"); lp.update (); @@ -201,1964 +198,1973 @@ Vlast_prompt_time.stamp (); } -void -load_path::initialize (bool set_initial_path) -{ - sys_path = ""; - - if (set_initial_path) - { - maybe_add_path_elts (sys_path, Vlocal_ver_oct_file_dir); - maybe_add_path_elts (sys_path, Vlocal_api_oct_file_dir); - maybe_add_path_elts (sys_path, Vlocal_oct_file_dir); - maybe_add_path_elts (sys_path, Vlocal_ver_fcn_file_dir); - maybe_add_path_elts (sys_path, Vlocal_api_fcn_file_dir); - maybe_add_path_elts (sys_path, Vlocal_fcn_file_dir); - maybe_add_path_elts (sys_path, Voct_file_dir); - maybe_add_path_elts (sys_path, Vfcn_file_dir); - maybe_add_path_elts (sys_path, Voct_data_dir); - } - - std::string tpath = load_path::m_command_line_path; - - if (tpath.empty ()) - tpath = octave::sys::env::getenv ("OCTAVE_PATH"); - - std::string xpath; - - if (! tpath.empty ()) - { - xpath = tpath; - - if (! sys_path.empty ()) - xpath += octave::directory_path::path_sep_str () + sys_path; - } - else - xpath = sys_path; - - set (xpath, false, true); -} - -void -load_path::clear (void) -{ - dir_info_list.clear (); - - top_level_package.clear (); - - package_map.clear (); -} - -void -load_path::set (const std::string& p, bool warn, bool is_init) -{ - // Use a list when we need to preserve order. - std::list<std::string> elts = split_path (p); - - // Use a set when we need to search and order is not important. - std::set<std::string> elts_set (elts.begin (), elts.end ()); - - if (is_init) - init_dirs = elts_set; - else - { - for (const auto& init_dir : init_dirs) - { - if (elts_set.find (init_dir) == elts_set.end ()) - { - warning_with_id ("Octave:remove-init-dir", - "default load path altered. Some built-in functions may not be found. Try restoredefaultpath() to recover it."); - break; - } - } - } - - // Temporarily disable add hook. - - octave::unwind_protect frame; - frame.protect_var (add_hook); - - add_hook = 0; - - clear (); - - for (const auto& elt : elts) - append (elt, warn); - - // Restore add hook and execute for all newly added directories. - frame.run_first (); - - // FIXME: Shouldn't the test for add_hook be outside the for loop? - // Why not use const here? Does add_hook change dir_info_list? - for (auto& di : dir_info_list) - { - if (add_hook) - add_hook (di.dir_name); - } - - // Always prepend current directory. - prepend (".", warn); -} - -void -load_path::append (const std::string& dir, bool warn) -{ - if (! dir.empty ()) - add (dir, true, warn); -} - -void -load_path::prepend (const std::string& dir, bool warn) -{ - if (! dir.empty ()) - add (dir, false, warn); -} - -bool -load_path::remove (const std::string& dir_arg) -{ - bool retval = false; - - if (! dir_arg.empty ()) - { - if (dir_arg == ".") - { - warning ("rmpath: can't remove \".\" from path"); - - // Avoid additional warnings. - retval = true; - } - else - { - std::string dir = octave::sys::file_ops::tilde_expand (dir_arg); - - dir = strip_trailing_separators (dir); - - dir_info_list_iterator i = find_dir_info (dir); - - if (i != dir_info_list.end ()) - { - retval = true; - - if (remove_hook) - remove_hook (dir); - - dir_info& di = *i; - - remove (di); - - dir_info_list.erase (i); - } - } - } - - return retval; -} - -void -load_path::update (void) const -{ - // I don't see a better way to do this because we need to - // preserve the correct directory ordering for new files that - // have appeared. - - top_level_package.clear (); - - package_map.clear (); - - for (auto& di : dir_info_list) - { - di.update (); - - add (di, true, "", true); - } -} - -bool -load_path::contains_canonical (const std::string& dir) const -{ - bool retval = false; - - for (const auto& d : dir_info_list) - { - if (same_file (dir, d.dir_name)) - { - retval = true; - break; - } - } - - return retval; -} - -std::list<std::string> -load_path::overloads (const std::string& meth) const -{ - std::list<std::string> retval; - - // update (); - - top_level_package.overloads (meth, retval); - - for (const auto& nm_ldr : package_map) - nm_ldr.second.overloads (meth, retval); - - return retval; -} - -std::list<std::string> -load_path::get_all_package_names (bool only_top_level) const -{ - std::list<std::string> retval; - - for (const auto& dir_ldr : package_map) - { - if (! only_top_level || dir_ldr.first.find ('.') == std::string::npos) - retval.push_back (dir_ldr.first); - } - - return retval; -} - -std::string -load_path::find_file (const std::string& file) const -{ - std::string retval; - - if (octave::sys::env::absolute_pathname (file) - || octave::sys::env::rooted_relative_pathname (file)) - { - octave::sys::file_stat fs (file); - - return fs.exists () ? file : retval; - } - else - { - std::string tfile = find_private_file (file); - - if (! tfile.empty ()) - return tfile; - } - - if (file.find_first_of (octave::sys::file_ops::dir_sep_chars ()) - != std::string::npos) - { - // Given name has a directory separator, so append it to each - // element of the load path in turn. - for (const auto& di : dir_info_list) - { - std::string tfile = octave::sys::file_ops::concat (di.dir_name, file); - - octave::sys::file_stat fs (tfile); - - if (fs.exists ()) - return tfile; - } - } - else - { - // Look in cache. - for (const auto & di : dir_info_list) - { - string_vector all_files = di.all_files; - - octave_idx_type len = all_files.numel (); - - for (octave_idx_type i = 0; i < len; i++) - { - if (all_files[i] == file) - return octave::sys::file_ops::concat (di.dir_name, file); - } - } - } - - return retval; -} - -std::string -load_path::find_dir (const std::string& dir) const -{ - std::string retval; - - if (dir.find_first_of (octave::sys::file_ops::dir_sep_chars ()) != std::string::npos - && (octave::sys::env::absolute_pathname (dir) - || octave::sys::env::rooted_relative_pathname (dir))) - { - octave::sys::file_stat fs (dir); - - if (fs.exists () && fs.is_dir ()) - return dir; - } - else - { - for (const auto& di : dir_info_list) - { - std::string dname = octave::sys::env::make_absolute (di.dir_name); - - size_t dname_len = dname.length (); - - if (dname.substr (dname_len - 1) - == octave::sys::file_ops::dir_sep_str ()) - { - dname = dname.substr (0, dname_len - 1); - dname_len--; - } - - size_t dir_len = dir.length (); - - if (dname_len > dir_len - && octave::sys::file_ops::is_dir_sep (dname[dname_len - dir_len - 1]) - && dir == dname.substr (dname_len - dir_len)) - { - octave::sys::file_stat fs (di.dir_name); - - if (fs.exists () && fs.is_dir ()) - return di.dir_name; - } - } - } - - return retval; -} - -string_vector -load_path::find_matching_dirs (const std::string& dir) const -{ - std::list<std::string> retlist; - - if (dir.find_first_of (octave::sys::file_ops::dir_sep_chars ()) != std::string::npos - && (octave::sys::env::absolute_pathname (dir) - || octave::sys::env::rooted_relative_pathname (dir))) - { - octave::sys::file_stat fs (dir); - - if (fs.exists () && fs.is_dir ()) - retlist.push_back (dir); - } - else - { - for (const auto& di : dir_info_list) - { - std::string dname = octave::sys::env::make_absolute (di.dir_name); - - size_t dname_len = dname.length (); - - if (dname.substr (dname_len - 1) - == octave::sys::file_ops::dir_sep_str ()) - { - dname = dname.substr (0, dname_len - 1); - dname_len--; - } - - size_t dir_len = dir.length (); - - if (dname_len > dir_len - && octave::sys::file_ops::is_dir_sep (dname[dname_len - dir_len - 1]) - && dir == dname.substr (dname_len - dir_len)) - { - octave::sys::file_stat fs (di.dir_name); - - if (fs.exists () && fs.is_dir ()) - retlist.push_back (di.dir_name); - } - } - } - - return retlist; -} - -std::string -load_path::find_first_of (const string_vector& flist) const -{ - std::string retval; - - std::string dir_name; - std::string file_name; - - octave_idx_type flen = flist.numel (); - octave_idx_type rel_flen = 0; - - string_vector rel_flist (flen); - - for (octave_idx_type i = 0; i < flen; i++) - { - std::string file = flist[i]; - - if (file.find_first_of (octave::sys::file_ops::dir_sep_chars ()) - != std::string::npos) - { - if (octave::sys::env::absolute_pathname (file) - || octave::sys::env::rooted_relative_pathname (file)) - { - octave::sys::file_stat fs (file); - - if (fs.exists ()) - return file; - } - else - { - for (const auto& di : dir_info_list) - { - std::string tfile; - tfile = octave::sys::file_ops::concat (di.dir_name, file); - - octave::sys::file_stat fs (tfile); - - if (fs.exists ()) - return tfile; - } - } - } - else - rel_flist[rel_flen++] = file; - } - - rel_flist.resize (rel_flen); - - for (const auto& di : dir_info_list) - { - string_vector all_files = di.all_files; - - octave_idx_type len = all_files.numel (); - - for (octave_idx_type i = 0; i < len; i++) - { - for (octave_idx_type j = 0; j < rel_flen; j++) - { - if (all_files[i] == rel_flist[j]) - { - dir_name = di.dir_name; - file_name = rel_flist[j]; - - goto done; - } - } - } - } - - done: - - if (! dir_name.empty ()) - retval = octave::sys::file_ops::concat (dir_name, file_name); - - return retval; -} - -string_vector -load_path::find_all_first_of (const string_vector& flist) const -{ - std::list<std::string> retlist; - - std::string dir_name; - std::string file_name; - - octave_idx_type flen = flist.numel (); - octave_idx_type rel_flen = 0; - - string_vector rel_flist (flen); - - for (octave_idx_type i = 0; i < flen; i++) - { - std::string file = flist[i]; - - if (file.find_first_of (octave::sys::file_ops::dir_sep_chars ()) - != std::string::npos) - { - if (octave::sys::env::absolute_pathname (file) - || octave::sys::env::rooted_relative_pathname (file)) - { - octave::sys::file_stat fs (file); - - if (fs.exists ()) - retlist.push_back (file); - } - else - { - for (const auto& di : dir_info_list) - { - std::string tfile; - tfile = octave::sys::file_ops::concat (di.dir_name, file); - - octave::sys::file_stat fs (tfile); - - if (fs.exists ()) - retlist.push_back (tfile); - } - } - } - else - rel_flist[rel_flen++] = file; - } - - rel_flist.resize (rel_flen); - - for (const auto& di : dir_info_list) - { - string_vector all_files = di.all_files; - - octave_idx_type len = all_files.numel (); - - for (octave_idx_type i = 0; i < len; i++) - { - for (octave_idx_type j = 0; j < rel_flen; j++) - { - if (all_files[i] == rel_flist[j]) - retlist.push_back (octave::sys::file_ops::concat (di.dir_name, - rel_flist[j])); - } - } - } - - return retlist; -} - -string_vector -load_path::dirs (void) const -{ - size_t len = dir_info_list.size (); - - string_vector retval (len); - - octave_idx_type k = 0; - - for (const auto& di : dir_info_list) - retval[k++] = di.dir_name; - - return retval; -} - -std::list<std::string> -load_path::dir_list (void) const -{ - std::list<std::string> retval; - - for (const auto& di : dir_info_list) - retval.push_back (di.dir_name); - - return retval; -} - -string_vector -load_path::files (const std::string& dir, bool omit_exts) const -{ - string_vector retval; - - const_dir_info_list_iterator p = find_dir_info (dir); - - if (p != dir_info_list.end ()) - retval = p->fcn_files; - - if (omit_exts) - { - octave_idx_type len = retval.numel (); - - for (octave_idx_type i = 0; i < len; i++) - { - std::string fname = retval[i]; - - size_t pos = fname.rfind ('.'); - - if (pos != std::string::npos) - retval[i] = fname.substr (0, pos); - } - } - - return retval; -} - -string_vector -load_path::fcn_names (void) const -{ - return top_level_package.fcn_names (); -} - -std::string -load_path::path (void) const -{ - std::string xpath; - - string_vector xdirs = load_path::dirs (); - - octave_idx_type len = xdirs.numel (); - - if (len > 0) - xpath = xdirs[0]; - - for (octave_idx_type i = 1; i < len; i++) - xpath += octave::directory_path::path_sep_str () + xdirs[i]; - - return xpath; -} - -void -load_path::display (std::ostream& os) const +namespace octave { - for (const auto& di : dir_info_list) - { - string_vector fcn_files = di.fcn_files; - - if (! fcn_files.empty ()) - { - os << "\n*** function files in " << di.dir_name << ":\n\n"; - - fcn_files.list_in_columns (os); - } - - const dir_info::method_file_map_type& method_file_map - = di.method_file_map; - - if (! method_file_map.empty ()) - { - for (const auto& cls_ci : method_file_map) - { - os << "\n*** methods in " << di.dir_name - << "/@" << cls_ci.first << ":\n\n"; - - const dir_info::class_info& ci = cls_ci.second; - - string_vector method_files = get_file_list (ci.method_file_map); - - method_files.list_in_columns (os); - } - } - } - - top_level_package.display (os); - - for (const auto& nm_ldr : package_map) - nm_ldr.second.display (os); -} - -void -load_path::execute_pkg_add (const std::string& dir) -{ - execute_pkg_add_or_del (dir, "PKG_ADD"); -} - -void -load_path::execute_pkg_del (const std::string& dir) -{ - execute_pkg_add_or_del (dir, "PKG_DEL"); -} - -// FIXME: maybe we should also maintain a map to speed up this method of access. - -load_path::const_dir_info_list_iterator -load_path::find_dir_info (const std::string& dir_arg) const -{ - std::string dir = octave::sys::file_ops::tilde_expand (dir_arg); - - const_dir_info_list_iterator retval = dir_info_list.begin (); - - while (retval != dir_info_list.end ()) - { - if (retval->dir_name == dir) - break; - - retval++; - } - - return retval; -} - -load_path::dir_info_list_iterator -load_path::find_dir_info (const std::string& dir_arg) -{ - std::string dir = octave::sys::file_ops::tilde_expand (dir_arg); - - dir_info_list_iterator retval = dir_info_list.begin (); - - while (retval != dir_info_list.end ()) - { - if (retval->dir_name == dir) - break; - - retval++; - } - - return retval; -} - -bool -load_path::contains (const std::string& dir) const -{ - return find_dir_info (dir) != dir_info_list.end (); -} - -void -load_path::move (dir_info_list_iterator i, bool at_end) -{ - if (dir_info_list.size () > 1) - { - dir_info di = *i; - - dir_info_list.erase (i); - - if (at_end) - dir_info_list.push_back (di); - else - dir_info_list.push_front (di); - - move (di, at_end); - } -} - -void -load_path::move (const dir_info& di, bool at_end, const std::string& pname) -{ - package_info& l = get_package (pname); - - l.move (di, at_end); - - dir_info::package_dir_map_type package_dir_map = di.package_dir_map; - - for (const auto& pkg_di : package_dir_map) - { - std::string full_name = pkg_di.first; - - if (! pname.empty ()) - full_name = pname + "." + full_name; - - move (pkg_di.second, at_end, full_name); - } -} - -void -load_path::add (const std::string& dir_arg, bool at_end, bool warn) -{ - size_t len = dir_arg.length (); - - if (len > 1 && dir_arg.substr (len-2) == "//") - warning_with_id ("Octave:recursive-path-search", - "trailing '//' is no longer special in search path elements"); - - std::string dir = octave::sys::file_ops::tilde_expand (dir_arg); - - dir = strip_trailing_separators (dir); - - dir_info_list_iterator i = find_dir_info (dir); - - if (i != dir_info_list.end ()) - move (i, at_end); - else - { - octave::sys::file_stat fs (dir); - - if (fs) - { - if (fs.is_dir ()) - { - dir_info di (dir); - - if (at_end) - dir_info_list.push_back (di); - else - dir_info_list.push_front (di); - - add (di, at_end); - - if (add_hook) - add_hook (dir); - } - else if (warn) - warning ("addpath: %s: not a directory", dir_arg.c_str ()); - } - else if (warn) - { - std::string msg = fs.error (); - warning ("addpath: %s: %s", dir_arg.c_str (), msg.c_str ()); - } - } - - // FIXME: is there a better way to do this? - - i = find_dir_info ("."); - - if (i != dir_info_list.end ()) - move (i, false); -} - -void -load_path::remove (const dir_info& di, const std::string& pname) -{ - package_info& l = get_package (pname); - - l.remove (di); - - dir_info::package_dir_map_type package_dir_map = di.package_dir_map; - - for (const auto& pkg_di : package_dir_map) - { - std::string full_name = pkg_di.first; - - if (! pname.empty ()) - full_name = pname + "." + full_name; - - remove (pkg_di.second, full_name); - } -} - -bool -load_path::is_package (const std::string& name) const -{ - for (const auto& di : dir_info_list) - { - if (di.is_package (name)) - return true; - } - - return false; -} - -void -load_path::add (const dir_info& di, bool at_end, - const std::string& pname, bool updating) const -{ - package_info& l = get_package (pname); - - l.add (di, at_end, updating); - - dir_info::package_dir_map_type package_dir_map = di.package_dir_map; - - for (const auto& pkg_di : package_dir_map) - { - std::string full_name = pkg_di.first; - - if (! pname.empty ()) - full_name = pname + "." + full_name; - - add (pkg_di.second, at_end, full_name); - } -} - -string_vector -load_path::get_file_list (const load_path::dir_info::fcn_file_map_type& lst) const -{ - octave_idx_type n = lst.size (); - - string_vector retval (n); - - octave_idx_type count = 0; - - for (const auto& nm_typ : lst) - { - std::string nm = nm_typ.first; - - int types = nm_typ.second; - - if (types & load_path::OCT_FILE) - nm += ".oct"; - else if (types & load_path::MEX_FILE) - nm += ".mex"; - else - nm += ".m"; - - retval[count++] = nm; - } - - return retval; -} - -load_path::dir_info::fcn_file_map_type -get_fcn_files (const std::string& d) -{ - load_path::dir_info::fcn_file_map_type retval; - - octave::sys::dir_entry dir (d); - - if (dir) - { - string_vector flist = dir.read (); - - octave_idx_type len = flist.numel (); - - for (octave_idx_type i = 0; i < len; i++) - { - std::string fname = flist[i]; - - size_t pos = fname.rfind ('.'); - - if (pos != std::string::npos) - { - std::string base = fname.substr (0, pos); - std::string ext = fname.substr (pos); - - if (valid_identifier (base)) - { - int t = 0; - - if (ext == ".m") - t = load_path::M_FILE; - else if (ext == ".oct") - t = load_path::OCT_FILE; - else if (ext == ".mex") - t = load_path::MEX_FILE; - - if (t) - retval[base] = t; - } - } - } - } - else - { - std::string msg = dir.error (); - warning ("load_path: %s: %s", d.c_str (), msg.c_str ()); - } - - return retval; -} - -void -load_path::dir_info::update (void) -{ - octave::sys::file_stat fs (dir_name); - - if (! fs) - { - std::string msg = fs.error (); - warning ("load_path: %s: %s", dir_name.c_str (), msg.c_str ()); - } - else - { - if (is_relative) - { - try - { - std::string abs_name = octave::sys::env::make_absolute (dir_name); - - const_abs_dir_cache_iterator p = abs_dir_cache.find (abs_name); - - if (p != abs_dir_cache.end ()) - { - // The directory is in the cache of all directories we have - // visited (indexed by absolute name). If it is out of date, - // initialize it. Otherwise, copy the info from the cache. - // By doing that, we avoid unnecessary calls to stat that can - // slow things down tremendously for large directories. - const dir_info& di = p->second; - - if (fs.mtime () + fs.time_resolution () - > di.dir_time_last_checked) + std::string load_path::sys_path; + load_path::abs_dir_cache_type load_path::abs_dir_cache; + + void + load_path::initialize (bool set_initial_path) + { + sys_path = ""; + + if (set_initial_path) + { + maybe_add_path_elts (sys_path, Vlocal_ver_oct_file_dir); + maybe_add_path_elts (sys_path, Vlocal_api_oct_file_dir); + maybe_add_path_elts (sys_path, Vlocal_oct_file_dir); + maybe_add_path_elts (sys_path, Vlocal_ver_fcn_file_dir); + maybe_add_path_elts (sys_path, Vlocal_api_fcn_file_dir); + maybe_add_path_elts (sys_path, Vlocal_fcn_file_dir); + maybe_add_path_elts (sys_path, Voct_file_dir); + maybe_add_path_elts (sys_path, Vfcn_file_dir); + maybe_add_path_elts (sys_path, Voct_data_dir); + } + + std::string tpath = load_path::m_command_line_path; + + if (tpath.empty ()) + tpath = octave::sys::env::getenv ("OCTAVE_PATH"); + + std::string xpath; + + if (! tpath.empty ()) + { + xpath = tpath; + + if (! sys_path.empty ()) + xpath += octave::directory_path::path_sep_str () + sys_path; + } + else + xpath = sys_path; + + set (xpath, false, true); + } + + void + load_path::clear (void) + { + dir_info_list.clear (); + + top_level_package.clear (); + + package_map.clear (); + } + + void + load_path::set (const std::string& p, bool warn, bool is_init) + { + // Use a list when we need to preserve order. + std::list<std::string> elts = split_path (p); + + // Use a set when we need to search and order is not important. + std::set<std::string> elts_set (elts.begin (), elts.end ()); + + if (is_init) + init_dirs = elts_set; + else + { + for (const auto& init_dir : init_dirs) + { + if (elts_set.find (init_dir) == elts_set.end ()) + { + warning_with_id ("Octave:remove-init-dir", + "default load path altered. Some built-in functions may not be found. Try restoredefaultpath() to recover it."); + break; + } + } + } + + // Temporarily disable add hook. + + octave::unwind_protect frame; + frame.protect_var (add_hook); + + add_hook = 0; + + clear (); + + for (const auto& elt : elts) + append (elt, warn); + + // Restore add hook and execute for all newly added directories. + frame.run_first (); + + // FIXME: Shouldn't the test for add_hook be outside the for loop? + // Why not use const here? Does add_hook change dir_info_list? + for (auto& di : dir_info_list) + { + if (add_hook) + add_hook (di.dir_name); + } + + // Always prepend current directory. + prepend (".", warn); + } + + void + load_path::append (const std::string& dir, bool warn) + { + if (! dir.empty ()) + add (dir, true, warn); + } + + void + load_path::prepend (const std::string& dir, bool warn) + { + if (! dir.empty ()) + add (dir, false, warn); + } + + bool + load_path::remove (const std::string& dir_arg) + { + bool retval = false; + + if (! dir_arg.empty ()) + { + if (dir_arg == ".") + { + warning ("rmpath: can't remove \".\" from path"); + + // Avoid additional warnings. + retval = true; + } + else + { + std::string dir = octave::sys::file_ops::tilde_expand (dir_arg); + + dir = strip_trailing_separators (dir); + + dir_info_list_iterator i = find_dir_info (dir); + + if (i != dir_info_list.end ()) + { + retval = true; + + if (remove_hook) + remove_hook (dir); + + dir_info& di = *i; + + remove (di); + + dir_info_list.erase (i); + } + } + } + + return retval; + } + + void + load_path::update (void) const + { + // I don't see a better way to do this because we need to + // preserve the correct directory ordering for new files that + // have appeared. + + top_level_package.clear (); + + package_map.clear (); + + for (auto& di : dir_info_list) + { + di.update (); + + add (di, true, "", true); + } + } + + bool + load_path::contains_canonical (const std::string& dir) const + { + bool retval = false; + + for (const auto& d : dir_info_list) + { + if (same_file (dir, d.dir_name)) + { + retval = true; + break; + } + } + + return retval; + } + + std::list<std::string> + load_path::overloads (const std::string& meth) const + { + std::list<std::string> retval; + + // update (); + + top_level_package.overloads (meth, retval); + + for (const auto& nm_ldr : package_map) + nm_ldr.second.overloads (meth, retval); + + return retval; + } + + std::list<std::string> + load_path::get_all_package_names (bool only_top_level) const + { + std::list<std::string> retval; + + for (const auto& dir_ldr : package_map) + { + if (! only_top_level || dir_ldr.first.find ('.') == std::string::npos) + retval.push_back (dir_ldr.first); + } + + return retval; + } + + std::string + load_path::find_file (const std::string& file) const + { + std::string retval; + + if (octave::sys::env::absolute_pathname (file) + || octave::sys::env::rooted_relative_pathname (file)) + { + octave::sys::file_stat fs (file); + + return fs.exists () ? file : retval; + } + else + { + std::string tfile = find_private_file (file); + + if (! tfile.empty ()) + return tfile; + } + + if (file.find_first_of (octave::sys::file_ops::dir_sep_chars ()) + != std::string::npos) + { + // Given name has a directory separator, so append it to each + // element of the load path in turn. + for (const auto& di : dir_info_list) + { + std::string tfile = octave::sys::file_ops::concat (di.dir_name, file); + + octave::sys::file_stat fs (tfile); + + if (fs.exists ()) + return tfile; + } + } + else + { + // Look in cache. + for (const auto & di : dir_info_list) + { + string_vector all_files = di.all_files; + + octave_idx_type len = all_files.numel (); + + for (octave_idx_type i = 0; i < len; i++) + { + if (all_files[i] == file) + return octave::sys::file_ops::concat (di.dir_name, file); + } + } + } + + return retval; + } + + std::string + load_path::find_dir (const std::string& dir) const + { + std::string retval; + + if (dir.find_first_of (octave::sys::file_ops::dir_sep_chars ()) != std::string::npos + && (octave::sys::env::absolute_pathname (dir) + || octave::sys::env::rooted_relative_pathname (dir))) + { + octave::sys::file_stat fs (dir); + + if (fs.exists () && fs.is_dir ()) + return dir; + } + else + { + for (const auto& di : dir_info_list) + { + std::string dname = octave::sys::env::make_absolute (di.dir_name); + + size_t dname_len = dname.length (); + + if (dname.substr (dname_len - 1) + == octave::sys::file_ops::dir_sep_str ()) + { + dname = dname.substr (0, dname_len - 1); + dname_len--; + } + + size_t dir_len = dir.length (); + + if (dname_len > dir_len + && octave::sys::file_ops::is_dir_sep (dname[dname_len - dir_len - 1]) + && dir == dname.substr (dname_len - dir_len)) + { + octave::sys::file_stat fs (di.dir_name); + + if (fs.exists () && fs.is_dir ()) + return di.dir_name; + } + } + } + + return retval; + } + + string_vector + load_path::find_matching_dirs (const std::string& dir) const + { + std::list<std::string> retlist; + + if (dir.find_first_of (octave::sys::file_ops::dir_sep_chars ()) != std::string::npos + && (octave::sys::env::absolute_pathname (dir) + || octave::sys::env::rooted_relative_pathname (dir))) + { + octave::sys::file_stat fs (dir); + + if (fs.exists () && fs.is_dir ()) + retlist.push_back (dir); + } + else + { + for (const auto& di : dir_info_list) + { + std::string dname = octave::sys::env::make_absolute (di.dir_name); + + size_t dname_len = dname.length (); + + if (dname.substr (dname_len - 1) + == octave::sys::file_ops::dir_sep_str ()) + { + dname = dname.substr (0, dname_len - 1); + dname_len--; + } + + size_t dir_len = dir.length (); + + if (dname_len > dir_len + && octave::sys::file_ops::is_dir_sep (dname[dname_len - dir_len - 1]) + && dir == dname.substr (dname_len - dir_len)) + { + octave::sys::file_stat fs (di.dir_name); + + if (fs.exists () && fs.is_dir ()) + retlist.push_back (di.dir_name); + } + } + } + + return retlist; + } + + std::string + load_path::find_first_of (const string_vector& flist) const + { + std::string retval; + + std::string dir_name; + std::string file_name; + + octave_idx_type flen = flist.numel (); + octave_idx_type rel_flen = 0; + + string_vector rel_flist (flen); + + for (octave_idx_type i = 0; i < flen; i++) + { + std::string file = flist[i]; + + if (file.find_first_of (octave::sys::file_ops::dir_sep_chars ()) + != std::string::npos) + { + if (octave::sys::env::absolute_pathname (file) + || octave::sys::env::rooted_relative_pathname (file)) + { + octave::sys::file_stat fs (file); + + if (fs.exists ()) + return file; + } + else + { + for (const auto& di : dir_info_list) + { + std::string tfile; + tfile = octave::sys::file_ops::concat (di.dir_name, file); + + octave::sys::file_stat fs (tfile); + + if (fs.exists ()) + return tfile; + } + } + } + else + rel_flist[rel_flen++] = file; + } + + rel_flist.resize (rel_flen); + + for (const auto& di : dir_info_list) + { + string_vector all_files = di.all_files; + + octave_idx_type len = all_files.numel (); + + for (octave_idx_type i = 0; i < len; i++) + { + for (octave_idx_type j = 0; j < rel_flen; j++) + { + if (all_files[i] == rel_flist[j]) + { + dir_name = di.dir_name; + file_name = rel_flist[j]; + + goto done; + } + } + } + } + + done: + + if (! dir_name.empty ()) + retval = octave::sys::file_ops::concat (dir_name, file_name); + + return retval; + } + + string_vector + load_path::find_all_first_of (const string_vector& flist) const + { + std::list<std::string> retlist; + + std::string dir_name; + std::string file_name; + + octave_idx_type flen = flist.numel (); + octave_idx_type rel_flen = 0; + + string_vector rel_flist (flen); + + for (octave_idx_type i = 0; i < flen; i++) + { + std::string file = flist[i]; + + if (file.find_first_of (octave::sys::file_ops::dir_sep_chars ()) + != std::string::npos) + { + if (octave::sys::env::absolute_pathname (file) + || octave::sys::env::rooted_relative_pathname (file)) + { + octave::sys::file_stat fs (file); + + if (fs.exists ()) + retlist.push_back (file); + } + else + { + for (const auto& di : dir_info_list) + { + std::string tfile; + tfile = octave::sys::file_ops::concat (di.dir_name, file); + + octave::sys::file_stat fs (tfile); + + if (fs.exists ()) + retlist.push_back (tfile); + } + } + } + else + rel_flist[rel_flen++] = file; + } + + rel_flist.resize (rel_flen); + + for (const auto& di : dir_info_list) + { + string_vector all_files = di.all_files; + + octave_idx_type len = all_files.numel (); + + for (octave_idx_type i = 0; i < len; i++) + { + for (octave_idx_type j = 0; j < rel_flen; j++) + { + if (all_files[i] == rel_flist[j]) + retlist.push_back (octave::sys::file_ops::concat (di.dir_name, + rel_flist[j])); + } + } + } + + return retlist; + } + + string_vector + load_path::dirs (void) const + { + size_t len = dir_info_list.size (); + + string_vector retval (len); + + octave_idx_type k = 0; + + for (const auto& di : dir_info_list) + retval[k++] = di.dir_name; + + return retval; + } + + std::list<std::string> + load_path::dir_list (void) const + { + std::list<std::string> retval; + + for (const auto& di : dir_info_list) + retval.push_back (di.dir_name); + + return retval; + } + + string_vector + load_path::files (const std::string& dir, bool omit_exts) const + { + string_vector retval; + + const_dir_info_list_iterator p = find_dir_info (dir); + + if (p != dir_info_list.end ()) + retval = p->fcn_files; + + if (omit_exts) + { + octave_idx_type len = retval.numel (); + + for (octave_idx_type i = 0; i < len; i++) + { + std::string fname = retval[i]; + + size_t pos = fname.rfind ('.'); + + if (pos != std::string::npos) + retval[i] = fname.substr (0, pos); + } + } + + return retval; + } + + string_vector + load_path::fcn_names (void) const + { + return top_level_package.fcn_names (); + } + + std::string + load_path::path (void) const + { + std::string xpath; + + string_vector xdirs = load_path::dirs (); + + octave_idx_type len = xdirs.numel (); + + if (len > 0) + xpath = xdirs[0]; + + for (octave_idx_type i = 1; i < len; i++) + xpath += octave::directory_path::path_sep_str () + xdirs[i]; + + return xpath; + } + + void + load_path::display (std::ostream& os) const + { + for (const auto& di : dir_info_list) + { + string_vector fcn_files = di.fcn_files; + + if (! fcn_files.empty ()) + { + os << "\n*** function files in " << di.dir_name << ":\n\n"; + + fcn_files.list_in_columns (os); + } + + const dir_info::method_file_map_type& method_file_map + = di.method_file_map; + + if (! method_file_map.empty ()) + { + for (const auto& cls_ci : method_file_map) + { + os << "\n*** methods in " << di.dir_name + << "/@" << cls_ci.first << ":\n\n"; + + const dir_info::class_info& ci = cls_ci.second; + + string_vector method_files = get_file_list (ci.method_file_map); + + method_files.list_in_columns (os); + } + } + } + + top_level_package.display (os); + + for (const auto& nm_ldr : package_map) + nm_ldr.second.display (os); + } + + void + load_path::execute_pkg_add (const std::string& dir) + { + execute_pkg_add_or_del (dir, "PKG_ADD"); + } + + void + load_path::execute_pkg_del (const std::string& dir) + { + execute_pkg_add_or_del (dir, "PKG_DEL"); + } + + // FIXME: maybe we should also maintain a map to speed up this method of access. + + load_path::const_dir_info_list_iterator + load_path::find_dir_info (const std::string& dir_arg) const + { + std::string dir = octave::sys::file_ops::tilde_expand (dir_arg); + + const_dir_info_list_iterator retval = dir_info_list.begin (); + + while (retval != dir_info_list.end ()) + { + if (retval->dir_name == dir) + break; + + retval++; + } + + return retval; + } + + load_path::dir_info_list_iterator + load_path::find_dir_info (const std::string& dir_arg) + { + std::string dir = octave::sys::file_ops::tilde_expand (dir_arg); + + dir_info_list_iterator retval = dir_info_list.begin (); + + while (retval != dir_info_list.end ()) + { + if (retval->dir_name == dir) + break; + + retval++; + } + + return retval; + } + + bool + load_path::contains (const std::string& dir) const + { + return find_dir_info (dir) != dir_info_list.end (); + } + + void + load_path::move (dir_info_list_iterator i, bool at_end) + { + if (dir_info_list.size () > 1) + { + dir_info di = *i; + + dir_info_list.erase (i); + + if (at_end) + dir_info_list.push_back (di); + else + dir_info_list.push_front (di); + + move (di, at_end); + } + } + + void + load_path::move (const dir_info& di, bool at_end, const std::string& pname) + { + package_info& l = get_package (pname); + + l.move (di, at_end); + + dir_info::package_dir_map_type package_dir_map = di.package_dir_map; + + for (const auto& pkg_di : package_dir_map) + { + std::string full_name = pkg_di.first; + + if (! pname.empty ()) + full_name = pname + "." + full_name; + + move (pkg_di.second, at_end, full_name); + } + } + + void + load_path::add (const std::string& dir_arg, bool at_end, bool warn) + { + size_t len = dir_arg.length (); + + if (len > 1 && dir_arg.substr (len-2) == "//") + warning_with_id ("Octave:recursive-path-search", + "trailing '//' is no longer special in search path elements"); + + std::string dir = octave::sys::file_ops::tilde_expand (dir_arg); + + dir = strip_trailing_separators (dir); + + dir_info_list_iterator i = find_dir_info (dir); + + if (i != dir_info_list.end ()) + move (i, at_end); + else + { + octave::sys::file_stat fs (dir); + + if (fs) + { + if (fs.is_dir ()) + { + dir_info di (dir); + + if (at_end) + dir_info_list.push_back (di); + else + dir_info_list.push_front (di); + + add (di, at_end); + + if (add_hook) + add_hook (dir); + } + else if (warn) + warning ("addpath: %s: not a directory", dir_arg.c_str ()); + } + else if (warn) + { + std::string msg = fs.error (); + warning ("addpath: %s: %s", dir_arg.c_str (), msg.c_str ()); + } + } + + // FIXME: is there a better way to do this? + + i = find_dir_info ("."); + + if (i != dir_info_list.end ()) + move (i, false); + } + + void + load_path::remove (const dir_info& di, const std::string& pname) + { + package_info& l = get_package (pname); + + l.remove (di); + + dir_info::package_dir_map_type package_dir_map = di.package_dir_map; + + for (const auto& pkg_di : package_dir_map) + { + std::string full_name = pkg_di.first; + + if (! pname.empty ()) + full_name = pname + "." + full_name; + + remove (pkg_di.second, full_name); + } + } + + bool + load_path::is_package (const std::string& name) const + { + for (const auto& di : dir_info_list) + { + if (di.is_package (name)) + return true; + } + + return false; + } + + void + load_path::add (const dir_info& di, bool at_end, + const std::string& pname, bool updating) const + { + package_info& l = get_package (pname); + + l.add (di, at_end, updating); + + dir_info::package_dir_map_type package_dir_map = di.package_dir_map; + + for (const auto& pkg_di : package_dir_map) + { + std::string full_name = pkg_di.first; + + if (! pname.empty ()) + full_name = pname + "." + full_name; + + add (pkg_di.second, at_end, full_name); + } + } + + string_vector + load_path::get_file_list (const load_path::dir_info::fcn_file_map_type& lst) const + { + octave_idx_type n = lst.size (); + + string_vector retval (n); + + octave_idx_type count = 0; + + for (const auto& nm_typ : lst) + { + std::string nm = nm_typ.first; + + int types = nm_typ.second; + + if (types & load_path::OCT_FILE) + nm += ".oct"; + else if (types & load_path::MEX_FILE) + nm += ".mex"; + else + nm += ".m"; + + retval[count++] = nm; + } + + return retval; + } + + load_path::dir_info::fcn_file_map_type + get_fcn_files (const std::string& d) + { + load_path::dir_info::fcn_file_map_type retval; + + octave::sys::dir_entry dir (d); + + if (dir) + { + string_vector flist = dir.read (); + + octave_idx_type len = flist.numel (); + + for (octave_idx_type i = 0; i < len; i++) + { + std::string fname = flist[i]; + + size_t pos = fname.rfind ('.'); + + if (pos != std::string::npos) + { + std::string base = fname.substr (0, pos); + std::string ext = fname.substr (pos); + + if (valid_identifier (base)) + { + int t = 0; + + if (ext == ".m") + t = load_path::M_FILE; + else if (ext == ".oct") + t = load_path::OCT_FILE; + else if (ext == ".mex") + t = load_path::MEX_FILE; + + if (t) + retval[base] = t; + } + } + } + } + else + { + std::string msg = dir.error (); + warning ("load_path: %s: %s", d.c_str (), msg.c_str ()); + } + + return retval; + } + + void + load_path::dir_info::update (void) + { + octave::sys::file_stat fs (dir_name); + + if (! fs) + { + std::string msg = fs.error (); + warning ("load_path: %s: %s", dir_name.c_str (), msg.c_str ()); + } + else + { + if (is_relative) + { + try + { + std::string abs_name = octave::sys::env::make_absolute (dir_name); + + const_abs_dir_cache_iterator p = abs_dir_cache.find (abs_name); + + if (p != abs_dir_cache.end ()) + { + // The directory is in the cache of all directories we have + // visited (indexed by absolute name). If it is out of date, + // initialize it. Otherwise, copy the info from the cache. + // By doing that, we avoid unnecessary calls to stat that can + // slow things down tremendously for large directories. + const dir_info& di = p->second; + + if (fs.mtime () + fs.time_resolution () + > di.dir_time_last_checked) + initialize (); + else + { + // Copy over info from cache, but leave dir_name and + // is_relative unmodified. + this->abs_dir_name = di.abs_dir_name; + this->dir_mtime = di.dir_mtime; + this->dir_time_last_checked = di.dir_time_last_checked; + this->all_files = di.all_files; + this->fcn_files = di.fcn_files; + this->private_file_map = di.private_file_map; + this->method_file_map = di.method_file_map; + this->package_dir_map = di.package_dir_map; + } + } + else + { + // We haven't seen this directory before. initialize (); - else - { - // Copy over info from cache, but leave dir_name and - // is_relative unmodified. - this->abs_dir_name = di.abs_dir_name; - this->dir_mtime = di.dir_mtime; - this->dir_time_last_checked = di.dir_time_last_checked; - this->all_files = di.all_files; - this->fcn_files = di.fcn_files; - this->private_file_map = di.private_file_map; - this->method_file_map = di.method_file_map; - this->package_dir_map = di.package_dir_map; - } - } - else - { - // We haven't seen this directory before. - initialize (); - } - } - catch (const octave::execution_exception&) - { - // Skip updating if we don't know where we are, - // but don't treat it as an error. - octave::interpreter::recover_from_exception (); - } - } - // Absolute path, check timestamp to see whether it requires re-caching - else if (fs.mtime () + fs.time_resolution () > dir_time_last_checked) - initialize (); - } -} - -bool -load_path::dir_info::is_package (const std::string& name) const -{ - size_t pos = name.find ('.'); - - if (pos == std::string::npos) - return package_dir_map.find (name) != package_dir_map.end (); - else - { - std::string name_head = name.substr (0, pos); - std::string name_tail = name.substr (pos + 1); - - const_package_dir_map_iterator it = package_dir_map.find (name_head); - - if (it != package_dir_map.end ()) - return it->second.is_package (name_tail); - else - return false; - } -} - -void -load_path::dir_info::initialize (void) -{ - is_relative = ! octave::sys::env::absolute_pathname (dir_name); - - dir_time_last_checked = octave::sys::time (static_cast<time_t> (0)); - - octave::sys::file_stat fs (dir_name); - - if (fs) - { - method_file_map.clear (); - package_dir_map.clear (); - - dir_mtime = fs.mtime (); - dir_time_last_checked = octave::sys::time (); - - get_file_list (dir_name); - - try - { - std::string abs_name = octave::sys::env::make_absolute (dir_name); - - // FIXME: nothing is ever removed from this cache of - // directory information, so there could be some resource - // problems. Perhaps it should be pruned from time to time. - - abs_dir_cache[abs_name] = *this; - } - catch (const octave::execution_exception&) - { - // Skip updating if we don't know where we are but don't treat - // it as an error. - - octave::interpreter::recover_from_exception (); - } - } - else - { - std::string msg = fs.error (); - warning ("load_path: %s: %s", dir_name.c_str (), msg.c_str ()); - } -} - -void -load_path::dir_info::get_file_list (const std::string& d) -{ - octave::sys::dir_entry dir (d); - - if (dir) - { - string_vector flist = dir.read (); - - octave_idx_type len = flist.numel (); - - all_files.resize (len); - fcn_files.resize (len); - - octave_idx_type all_files_count = 0; - octave_idx_type fcn_files_count = 0; - - for (octave_idx_type i = 0; i < len; i++) - { - std::string fname = flist[i]; - - std::string full_name = octave::sys::file_ops::concat (d, fname); - - octave::sys::file_stat fs (full_name); - - if (fs) - { - if (fs.is_dir ()) - { - if (fname == "private") - get_private_file_map (full_name); - else if (fname[0] == '@') - get_method_file_map (full_name, fname.substr (1)); - else if (fname[0] == '+') - get_package_dir (full_name, fname.substr (1)); - } - else - { - all_files[all_files_count++] = fname; - - size_t pos = fname.rfind ('.'); - - if (pos != std::string::npos) - { - std::string ext = fname.substr (pos); - - if (ext == ".m" || ext == ".oct" || ext == ".mex") - { - std::string base = fname.substr (0, pos); - - if (valid_identifier (base)) - fcn_files[fcn_files_count++] = fname; - } - } - } - } - } - - all_files.resize (all_files_count); - fcn_files.resize (fcn_files_count); - } - else - { - std::string msg = dir.error (); - warning ("load_path: %s: %s", d.c_str (), msg.c_str ()); - } -} - -void -load_path::dir_info::get_private_file_map (const std::string& d) -{ - private_file_map = get_fcn_files (d); -} - -void -load_path::dir_info::get_method_file_map (const std::string& d, - const std::string& class_name) -{ - method_file_map[class_name].method_file_map = get_fcn_files (d); - - std::string pd = octave::sys::file_ops::concat (d, "private"); - - octave::sys::file_stat fs (pd); - - if (fs && fs.is_dir ()) - method_file_map[class_name].private_file_map = get_fcn_files (pd); -} - -void -load_path::dir_info::get_package_dir (const std::string& d, - const std::string& package_name) -{ - package_dir_map[package_name] = dir_info (d); -} - -void -load_path::package_info::move (const dir_info& di, bool at_end) -{ - std::string dir_name = di.dir_name; - - std::list<std::string>::iterator s = - std::find (dir_list.begin (), dir_list.end (), dir_name); - - if (s != dir_list.end ()) - { - dir_list.erase (s); - - if (at_end) - dir_list.push_back (dir_name); - else - dir_list.push_front (dir_name); - } - - move_fcn_map (dir_name, di.fcn_files, at_end); - - // No need to move elements of private function map. - - move_method_map (dir_name, at_end); -} - -void -load_path::package_info::remove (const dir_info& di) -{ - std::string dir = di.dir_name; - - string_vector fcn_files = di.fcn_files; - - dir_list.remove (dir); - - remove_fcn_map (dir, fcn_files); - - remove_private_fcn_map (dir); - - remove_method_map (dir); -} - -void -load_path::package_info::display (std::ostream& os) const -{ - os << "*** package_info: " - << (m_package_name.empty () ? "<top-level>" : m_package_name) - << "\n\n"; - - for (const auto& dir : dir_list) - os << dir << "\n"; - os << "\n"; - - for (const auto& dir_fnlst : private_fcn_map) - { - os << "\n*** private functions in " - << octave::sys::file_ops::concat (dir_fnlst.first, "private") - << ":\n\n"; - - print_fcn_list (os, dir_fnlst.second); - } + } + } + catch (const octave::execution_exception&) + { + // Skip updating if we don't know where we are, + // but don't treat it as an error. + octave::interpreter::recover_from_exception (); + } + } + // Absolute path, check timestamp to see whether it requires re-caching + else if (fs.mtime () + fs.time_resolution () > dir_time_last_checked) + initialize (); + } + } + + bool + load_path::dir_info::is_package (const std::string& name) const + { + size_t pos = name.find ('.'); + + if (pos == std::string::npos) + return package_dir_map.find (name) != package_dir_map.end (); + else + { + std::string name_head = name.substr (0, pos); + std::string name_tail = name.substr (pos + 1); + + const_package_dir_map_iterator it = package_dir_map.find (name_head); + + if (it != package_dir_map.end ()) + return it->second.is_package (name_tail); + else + return false; + } + } + + void + load_path::dir_info::initialize (void) + { + is_relative = ! octave::sys::env::absolute_pathname (dir_name); + + dir_time_last_checked = octave::sys::time (static_cast<time_t> (0)); + + octave::sys::file_stat fs (dir_name); + + if (fs) + { + method_file_map.clear (); + package_dir_map.clear (); + + dir_mtime = fs.mtime (); + dir_time_last_checked = octave::sys::time (); + + get_file_list (dir_name); + + try + { + std::string abs_name = octave::sys::env::make_absolute (dir_name); + + // FIXME: nothing is ever removed from this cache of + // directory information, so there could be some resource + // problems. Perhaps it should be pruned from time to time. + + abs_dir_cache[abs_name] = *this; + } + catch (const octave::execution_exception&) + { + // Skip updating if we don't know where we are but don't treat + // it as an error. + + octave::interpreter::recover_from_exception (); + } + } + else + { + std::string msg = fs.error (); + warning ("load_path: %s: %s", dir_name.c_str (), msg.c_str ()); + } + } + + void + load_path::dir_info::get_file_list (const std::string& d) + { + octave::sys::dir_entry dir (d); + + if (dir) + { + string_vector flist = dir.read (); + + octave_idx_type len = flist.numel (); + + all_files.resize (len); + fcn_files.resize (len); + + octave_idx_type all_files_count = 0; + octave_idx_type fcn_files_count = 0; + + for (octave_idx_type i = 0; i < len; i++) + { + std::string fname = flist[i]; + + std::string full_name = octave::sys::file_ops::concat (d, fname); + + octave::sys::file_stat fs (full_name); + + if (fs) + { + if (fs.is_dir ()) + { + if (fname == "private") + get_private_file_map (full_name); + else if (fname[0] == '@') + get_method_file_map (full_name, fname.substr (1)); + else if (fname[0] == '+') + get_package_dir (full_name, fname.substr (1)); + } + else + { + all_files[all_files_count++] = fname; + + size_t pos = fname.rfind ('.'); + + if (pos != std::string::npos) + { + std::string ext = fname.substr (pos); + + if (ext == ".m" || ext == ".oct" || ext == ".mex") + { + std::string base = fname.substr (0, pos); + + if (valid_identifier (base)) + fcn_files[fcn_files_count++] = fname; + } + } + } + } + } + + all_files.resize (all_files_count); + fcn_files.resize (fcn_files_count); + } + else + { + std::string msg = dir.error (); + warning ("load_path: %s: %s", d.c_str (), msg.c_str ()); + } + } + + void + load_path::dir_info::get_private_file_map (const std::string& d) + { + private_file_map = get_fcn_files (d); + } + + void + load_path::dir_info::get_method_file_map (const std::string& d, + const std::string& class_name) + { + method_file_map[class_name].method_file_map = get_fcn_files (d); + + std::string pd = octave::sys::file_ops::concat (d, "private"); + + octave::sys::file_stat fs (pd); + + if (fs && fs.is_dir ()) + method_file_map[class_name].private_file_map = get_fcn_files (pd); + } + + void + load_path::dir_info::get_package_dir (const std::string& d, + const std::string& package_name) + { + package_dir_map[package_name] = dir_info (d); + } + + void + load_path::package_info::move (const dir_info& di, bool at_end) + { + std::string dir_name = di.dir_name; + + std::list<std::string>::iterator s = + std::find (dir_list.begin (), dir_list.end (), dir_name); + + if (s != dir_list.end ()) + { + dir_list.erase (s); + + if (at_end) + dir_list.push_back (dir_name); + else + dir_list.push_front (dir_name); + } + + move_fcn_map (dir_name, di.fcn_files, at_end); + + // No need to move elements of private function map. + + move_method_map (dir_name, at_end); + } + + void + load_path::package_info::remove (const dir_info& di) + { + std::string dir = di.dir_name; + + string_vector fcn_files = di.fcn_files; + + dir_list.remove (dir); + + remove_fcn_map (dir, fcn_files); + + remove_private_fcn_map (dir); + + remove_method_map (dir); + } + + void + load_path::package_info::display (std::ostream& os) const + { + os << "*** package_info: " + << (m_package_name.empty () ? "<top-level>" : m_package_name) + << "\n\n"; + + for (const auto& dir : dir_list) + os << dir << "\n"; + os << "\n"; + + for (const auto& dir_fnlst : private_fcn_map) + { + os << "\n*** private functions in " + << octave::sys::file_ops::concat (dir_fnlst.first, "private") + << ":\n\n"; + + print_fcn_list (os, dir_fnlst.second); + } #if defined (DEBUG_LOAD_PATH) - for (const auto& nm_filst : fcn_map) - { - os << nm_filst.first << ":\n"; - - const file_info_list_type& file_info_list = nm_filst.second; - - for (const auto& finfo : file_info_list) - { - os << " " << finfo.dir_name << " ("; - - print_types (os, finfo.types); - - os << ")\n"; - } - } - - for (const auto& cls_fnmap : method_map) - { - os << "CLASS " << cls_fnmap.first << ":\n"; - - const fcn_map_type& fm = cls_fnmap.second; - - for (const auto& nm_fnlst : fcn_map) - { - os << " " << nm_fnlst.first << ":\n"; - - const file_info_list_type& file_info_list = nm_fnlst.second; - - for (const auto& finfo : file_info_list) - { - os << " " << finfo.dir_name << " ("; - - print_types (os, finfo.types); - - os << ")\n"; - } - } - } - - os << "\n"; + for (const auto& nm_filst : fcn_map) + { + os << nm_filst.first << ":\n"; + + const file_info_list_type& file_info_list = nm_filst.second; + + for (const auto& finfo : file_info_list) + { + os << " " << finfo.dir_name << " ("; + + print_types (os, finfo.types); + + os << ")\n"; + } + } + + for (const auto& cls_fnmap : method_map) + { + os << "CLASS " << cls_fnmap.first << ":\n"; + + const fcn_map_type& fm = cls_fnmap.second; + + for (const auto& nm_fnlst : fcn_map) + { + os << " " << nm_fnlst.first << ":\n"; + + const file_info_list_type& file_info_list = nm_fnlst.second; + + for (const auto& finfo : file_info_list) + { + os << " " << finfo.dir_name << " ("; + + print_types (os, finfo.types); + + os << ")\n"; + } + } + } + + os << "\n"; #endif -} - -std::string -load_path::package_info::find_fcn (const std::string& fcn, std::string& dir_name, - int type) const -{ - std::string retval; - - // update (); - - if (fcn.length () > 0 && fcn[0] == '@') - { - size_t pos = fcn.find ('/'); - - if (pos != std::string::npos) - { - std::string class_name = fcn.substr (1, pos-1); - std::string meth = fcn.substr (pos+1); - - retval = find_method (class_name, meth, dir_name); - } - else - retval = ""; - } - else - { - dir_name = ""; - - const_fcn_map_iterator p = fcn_map.find (fcn); - - if (p != fcn_map.end ()) - { - const file_info_list_type& file_info_list = p->second; - - for (const auto& fi : file_info_list) - { - retval = octave::sys::file_ops::concat (fi.dir_name, fcn); - - if (check_file_type (retval, type, fi.types, - fcn, "load_path::find_fcn")) - { - dir_name = fi.dir_name; - break; - } - else - retval = ""; - } - } - } - - return retval; -} - -std::string -load_path::package_info::find_private_fcn (const std::string& dir, - const std::string& fcn, int type) const -{ - std::string retval; - - // update (); - - const_private_fcn_map_iterator q = private_fcn_map.find (dir); - - if (q != private_fcn_map.end ()) - { - const dir_info::fcn_file_map_type& m = q->second; - - dir_info::const_fcn_file_map_iterator p = m.find (fcn); - - if (p != m.end ()) - { - std::string fname - = octave::sys::file_ops::concat (octave::sys::file_ops::concat (dir, "private"), fcn); - - if (check_file_type (fname, type, p->second, fcn, - "load_path::find_private_fcn")) - retval = fname; - } - } - - return retval; -} - -std::string -load_path::package_info::find_method (const std::string& class_name, - const std::string& meth, - std::string& dir_name, int type) const -{ - std::string retval; - - // update (); - - dir_name = ""; - - const_method_map_iterator q = method_map.find (class_name); - - if (q != method_map.end ()) - { - const fcn_map_type& m = q->second; - - const_fcn_map_iterator p = m.find (meth); - - if (p != m.end ()) - { - const file_info_list_type& file_info_list = p->second; - - for (const auto& fi : file_info_list) - { - retval = octave::sys::file_ops::concat (fi.dir_name, meth); - - bool found = check_file_type (retval, type, fi.types, - meth, "load_path::find_method"); - - if (found) - { - dir_name = fi.dir_name; + } + + std::string + load_path::package_info::find_fcn (const std::string& fcn, + std::string& dir_name, + int type) const + { + std::string retval; + + // update (); + + if (fcn.length () > 0 && fcn[0] == '@') + { + size_t pos = fcn.find ('/'); + + if (pos != std::string::npos) + { + std::string class_name = fcn.substr (1, pos-1); + std::string meth = fcn.substr (pos+1); + + retval = find_method (class_name, meth, dir_name); + } + else + retval = ""; + } + else + { + dir_name = ""; + + const_fcn_map_iterator p = fcn_map.find (fcn); + + if (p != fcn_map.end ()) + { + const file_info_list_type& file_info_list = p->second; + + for (const auto& fi : file_info_list) + { + retval = octave::sys::file_ops::concat (fi.dir_name, fcn); + + if (check_file_type (retval, type, fi.types, + fcn, "load_path::find_fcn")) + { + dir_name = fi.dir_name; + break; + } + else + retval = ""; + } + } + } + + return retval; + } + + std::string + load_path::package_info::find_private_fcn (const std::string& dir, + const std::string& fcn, + int type) const + { + std::string retval; + + // update (); + + const_private_fcn_map_iterator q = private_fcn_map.find (dir); + + if (q != private_fcn_map.end ()) + { + const dir_info::fcn_file_map_type& m = q->second; + + dir_info::const_fcn_file_map_iterator p = m.find (fcn); + + if (p != m.end ()) + { + std::string fname + = octave::sys::file_ops::concat (octave::sys::file_ops::concat (dir, "private"), fcn); + + if (check_file_type (fname, type, p->second, fcn, + "load_path::find_private_fcn")) + retval = fname; + } + } + + return retval; + } + + std::string + load_path::package_info::find_method (const std::string& class_name, + const std::string& meth, + std::string& dir_name, + int type) const + { + std::string retval; + + // update (); + + dir_name = ""; + + const_method_map_iterator q = method_map.find (class_name); + + if (q != method_map.end ()) + { + const fcn_map_type& m = q->second; + + const_fcn_map_iterator p = m.find (meth); + + if (p != m.end ()) + { + const file_info_list_type& file_info_list = p->second; + + for (const auto& fi : file_info_list) + { + retval = octave::sys::file_ops::concat (fi.dir_name, meth); + + bool found = check_file_type (retval, type, fi.types, + meth, "load_path::find_method"); + + if (found) + { + dir_name = fi.dir_name; + break; + } + else + retval = ""; + } + } + } + + return retval; + } + + std::list<std::string> + load_path::package_info::methods (const std::string& class_name) const + { + std::list<std::string> retval; + + // update (); + + const_method_map_iterator mtd_map_it = method_map.find (class_name); + + if (mtd_map_it != method_map.end ()) + { + for (const auto& nm_filst : mtd_map_it->second) + retval.push_back (nm_filst.first); + } + + if (! retval.empty ()) + retval.sort (); + + return retval; + } + + void + load_path::package_info::overloads (const std::string& meth, + std::list<std::string>& l) const + { + for (const auto& cls_fnmap : method_map) + { + const fcn_map_type& m = cls_fnmap.second; + + if (m.find (meth) != m.end ()) + { + std::string class_name = cls_fnmap.first; + + if (! m_package_name.empty ()) + class_name = m_package_name + "." + class_name; + + l.push_back (class_name); + } + } + } + + string_vector + load_path::package_info::fcn_names (void) const + { + size_t len = fcn_map.size (); + + string_vector retval (len); + + octave_idx_type count = 0; + + for (const auto& nm_filst : fcn_map) + retval[count++] = nm_filst.first; + + return retval; + } + + void + load_path::package_info::add_to_fcn_map (const dir_info& di, + bool at_end, bool updating) + { + std::string dir_name = di.dir_name; + + string_vector fcn_files = di.fcn_files; + + octave_idx_type len = fcn_files.numel (); + + for (octave_idx_type i = 0; i < len; i++) + { + std::string fname = fcn_files[i]; + + std::string ext; + std::string base = fname; + + size_t pos = fname.rfind ('.'); + + if (pos != std::string::npos) + { + base = fname.substr (0, pos); + ext = fname.substr (pos); + } + + file_info_list_type& file_info_list = fcn_map[base]; + + file_info_list_iterator p = file_info_list.begin (); + + while (p != file_info_list.end ()) + { + if (p->dir_name == dir_name) + break; + + p++; + } + + int t = 0; + if (ext == ".m") + t = load_path::M_FILE; + else if (ext == ".oct") + t = load_path::OCT_FILE; + else if (ext == ".mex") + t = load_path::MEX_FILE; + + if (p == file_info_list.end ()) + { + // Warn if a built-in or library function is being shadowed, + // but not if we are just updating (rehashing) the list. + + if (! updating) + { + if (file_info_list.empty ()) + { + if (symbol_table::is_built_in_function_name (base)) + { + std::string fcn_path = octave::sys::file_ops::concat (dir_name, fname); + + warning_with_id ("Octave:shadowed-function", + "function %s shadows a built-in function", + fcn_path.c_str ()); + } + } + else if (! at_end) + { + file_info& old = file_info_list.front (); + + // FIXME: do we need to be more careful about the + // way we look for old.dir_name in sys_path to avoid + // partial matches? + + // Don't warn about Contents.m files since we expect + // more than one to exist in the load path. + + if (fname != "Contents.m" + && sys_path.find (old.dir_name) != std::string::npos + && in_path_list (sys_path, old.dir_name)) + { + std::string fcn_path = octave::sys::file_ops::concat (dir_name, fname); + + warning_with_id ("Octave:shadowed-function", + "function %s shadows a core library function", + fcn_path.c_str ()); + } + } + } + + file_info fi (dir_name, t); + + if (at_end) + file_info_list.push_back (fi); + else + file_info_list.push_front (fi); + } + else + { + file_info& fi = *p; + + fi.types |= t; + } + } + } + + void + load_path::package_info::add_to_private_fcn_map (const dir_info& di) + { + dir_info::fcn_file_map_type private_file_map = di.private_file_map; + + if (! private_file_map.empty ()) + private_fcn_map[di.dir_name] = private_file_map; + } + + void + load_path::package_info::add_to_method_map (const dir_info& di, bool at_end) + { + std::string dir_name = di.dir_name; + + // <CLASS_NAME, CLASS_INFO> + dir_info::method_file_map_type method_file_map = di.method_file_map; + + for (const auto& cls_ci : method_file_map) + { + std::string class_name = cls_ci.first; + + fcn_map_type& fm = method_map[class_name]; + + std::string full_dir_name + = octave::sys::file_ops::concat (dir_name, "@" + class_name); + + const dir_info::class_info& ci = cls_ci.second; + + // <FCN_NAME, TYPES> + const dir_info::fcn_file_map_type& m = ci.method_file_map; + + for (const auto& nm_typ : m) + { + std::string base = nm_typ.first; + int types = nm_typ.second; + + file_info_list_type& file_info_list = fm[base]; + + file_info_list_iterator p2 = file_info_list.begin (); + while (p2 != file_info_list.end ()) + { + if (p2->dir_name == full_dir_name) break; - } - else - retval = ""; - } - } - } - - return retval; -} - -std::list<std::string> -load_path::package_info::methods (const std::string& class_name) const -{ - std::list<std::string> retval; - - // update (); - - const_method_map_iterator mtd_map_it = method_map.find (class_name); - - if (mtd_map_it != method_map.end ()) - { - for (const auto& nm_filst : mtd_map_it->second) - retval.push_back (nm_filst.first); - } - - if (! retval.empty ()) - retval.sort (); - - return retval; -} - -void -load_path::package_info::overloads (const std::string& meth, - std::list<std::string>& l) const -{ - for (const auto& cls_fnmap : method_map) - { - const fcn_map_type& m = cls_fnmap.second; - - if (m.find (meth) != m.end ()) - { - std::string class_name = cls_fnmap.first; - - if (! m_package_name.empty ()) - class_name = m_package_name + "." + class_name; - - l.push_back (class_name); - } - } -} - -string_vector -load_path::package_info::fcn_names (void) const -{ - size_t len = fcn_map.size (); - - string_vector retval (len); - - octave_idx_type count = 0; - - for (const auto& nm_filst : fcn_map) - retval[count++] = nm_filst.first; - - return retval; -} - -void -load_path::package_info::add_to_fcn_map (const dir_info& di, - bool at_end, bool updating) -{ - std::string dir_name = di.dir_name; - - string_vector fcn_files = di.fcn_files; - - octave_idx_type len = fcn_files.numel (); - - for (octave_idx_type i = 0; i < len; i++) - { - std::string fname = fcn_files[i]; - - std::string ext; - std::string base = fname; - - size_t pos = fname.rfind ('.'); - - if (pos != std::string::npos) - { - base = fname.substr (0, pos); - ext = fname.substr (pos); - } - - file_info_list_type& file_info_list = fcn_map[base]; - - file_info_list_iterator p = file_info_list.begin (); - - while (p != file_info_list.end ()) - { - if (p->dir_name == dir_name) - break; - - p++; - } - - int t = 0; - if (ext == ".m") - t = load_path::M_FILE; - else if (ext == ".oct") - t = load_path::OCT_FILE; - else if (ext == ".mex") - t = load_path::MEX_FILE; - - if (p == file_info_list.end ()) - { - // Warn if a built-in or library function is being shadowed, - // but not if we are just updating (rehashing) the list. - - if (! updating) - { - if (file_info_list.empty ()) - { - if (symbol_table::is_built_in_function_name (base)) - { - std::string fcn_path = octave::sys::file_ops::concat (dir_name, fname); - - warning_with_id ("Octave:shadowed-function", - "function %s shadows a built-in function", - fcn_path.c_str ()); - } - } - else if (! at_end) - { - file_info& old = file_info_list.front (); - - // FIXME: do we need to be more careful about the - // way we look for old.dir_name in sys_path to avoid - // partial matches? - - // Don't warn about Contents.m files since we expect - // more than one to exist in the load path. - - if (fname != "Contents.m" - && sys_path.find (old.dir_name) != std::string::npos - && in_path_list (sys_path, old.dir_name)) - { - std::string fcn_path = octave::sys::file_ops::concat (dir_name, fname); - - warning_with_id ("Octave:shadowed-function", - "function %s shadows a core library function", - fcn_path.c_str ()); - } - } - } - - file_info fi (dir_name, t); - - if (at_end) - file_info_list.push_back (fi); - else - file_info_list.push_front (fi); - } - else - { - file_info& fi = *p; - - fi.types |= t; - } - } -} - -void -load_path::package_info::add_to_private_fcn_map (const dir_info& di) -{ - dir_info::fcn_file_map_type private_file_map = di.private_file_map; - - if (! private_file_map.empty ()) - private_fcn_map[di.dir_name] = private_file_map; -} - -void -load_path::package_info::add_to_method_map (const dir_info& di, bool at_end) -{ - std::string dir_name = di.dir_name; - - // <CLASS_NAME, CLASS_INFO> - dir_info::method_file_map_type method_file_map = di.method_file_map; - - for (const auto& cls_ci : method_file_map) - { - std::string class_name = cls_ci.first; - - fcn_map_type& fm = method_map[class_name]; - - std::string full_dir_name - = octave::sys::file_ops::concat (dir_name, "@" + class_name); - - const dir_info::class_info& ci = cls_ci.second; - - // <FCN_NAME, TYPES> - const dir_info::fcn_file_map_type& m = ci.method_file_map; - - for (const auto& nm_typ : m) - { - std::string base = nm_typ.first; - int types = nm_typ.second; - - file_info_list_type& file_info_list = fm[base]; - - file_info_list_iterator p2 = file_info_list.begin (); - while (p2 != file_info_list.end ()) - { - if (p2->dir_name == full_dir_name) + + p2++; + } + + if (p2 == file_info_list.end ()) + { + file_info fi (full_dir_name, types); + + if (at_end) + file_info_list.push_back (fi); + else + file_info_list.push_front (fi); + } + else + { + // FIXME: is this possible? + file_info& fi = *p2; + + fi.types = types; + } + } + + // <FCN_NAME, TYPES> + dir_info::fcn_file_map_type private_file_map = ci.private_file_map; + + if (! private_file_map.empty ()) + private_fcn_map[full_dir_name] = private_file_map; + } + } + + void + load_path::package_info::move_fcn_map (const std::string& dir_name, + const string_vector& fcn_files, bool at_end) + { + octave_idx_type len = fcn_files.numel (); + + for (octave_idx_type k = 0; k < len; k++) + { + std::string fname = fcn_files[k]; + + std::string ext; + std::string base = fname; + + size_t pos = fname.rfind ('.'); + + if (pos != std::string::npos) + { + base = fname.substr (0, pos); + ext = fname.substr (pos); + } + + file_info_list_type& file_info_list = fcn_map[base]; + + if (file_info_list.size () == 1) + continue; + else + { + for (auto fi_it = file_info_list.begin (); + fi_it != file_info_list.end (); + fi_it++) + { + if (fi_it->dir_name == dir_name) + { + file_info fi_tmp = *fi_it; + + file_info_list.erase (fi_it); + + if (at_end) + file_info_list.push_back (fi_tmp); + else + file_info_list.push_front (fi_tmp); + + break; + } + } + } + } + } + + void + load_path::package_info::move_method_map (const std::string& dir_name, bool at_end) + { + for (auto& cls_fnmap : method_map) + { + std::string class_name = cls_fnmap.first; + + fcn_map_type& fn_map = cls_fnmap.second; + + std::string full_dir_name + = octave::sys::file_ops::concat (dir_name, "@" + class_name); + + for (auto& nm_filst : fn_map) + { + file_info_list_type& file_info_list = nm_filst.second; + + if (file_info_list.size () == 1) + continue; + else + { + for (auto fi_it = file_info_list.begin (); + fi_it != file_info_list.end (); fi_it++) + { + if (fi_it->dir_name == full_dir_name) + { + file_info fi_tmp = *fi_it; + + file_info_list.erase (fi_it); + + if (at_end) + file_info_list.push_back (fi_tmp); + else + file_info_list.push_front (fi_tmp); + + break; + } + } + } + } + } + } + + void + load_path::package_info::remove_fcn_map (const std::string& dir, + const string_vector& fcn_files) + { + octave_idx_type len = fcn_files.numel (); + + for (octave_idx_type k = 0; k < len; k++) + { + std::string fname = fcn_files[k]; + + std::string ext; + std::string base = fname; + + size_t pos = fname.rfind ('.'); + + if (pos != std::string::npos) + { + base = fname.substr (0, pos); + ext = fname.substr (pos); + } + + file_info_list_type& file_info_list = fcn_map[base]; + + for (auto fi_it = file_info_list.begin (); + fi_it != file_info_list.end (); + fi_it++) + { + if (fi_it->dir_name == dir) + { + file_info_list.erase (fi_it); + + if (file_info_list.empty ()) + fcn_map.erase (fname); + break; - - p2++; - } - - if (p2 == file_info_list.end ()) - { - file_info fi (full_dir_name, types); - - if (at_end) - file_info_list.push_back (fi); - else - file_info_list.push_front (fi); - } - else - { - // FIXME: is this possible? - file_info& fi = *p2; - - fi.types = types; - } - } - - // <FCN_NAME, TYPES> - dir_info::fcn_file_map_type private_file_map = ci.private_file_map; - - if (! private_file_map.empty ()) - private_fcn_map[full_dir_name] = private_file_map; - } -} - -void -load_path::package_info::move_fcn_map (const std::string& dir_name, - const string_vector& fcn_files, bool at_end) -{ - octave_idx_type len = fcn_files.numel (); - - for (octave_idx_type k = 0; k < len; k++) - { - std::string fname = fcn_files[k]; - - std::string ext; - std::string base = fname; - - size_t pos = fname.rfind ('.'); - - if (pos != std::string::npos) - { - base = fname.substr (0, pos); - ext = fname.substr (pos); - } - - file_info_list_type& file_info_list = fcn_map[base]; - - if (file_info_list.size () == 1) - continue; - else - { - for (auto fi_it = file_info_list.begin (); - fi_it != file_info_list.end (); - fi_it++) - { - if (fi_it->dir_name == dir_name) - { - file_info fi_tmp = *fi_it; - - file_info_list.erase (fi_it); - - if (at_end) - file_info_list.push_back (fi_tmp); - else - file_info_list.push_front (fi_tmp); - - break; - } - } - } - } -} - -void -load_path::package_info::move_method_map (const std::string& dir_name, bool at_end) -{ - for (auto& cls_fnmap : method_map) - { - std::string class_name = cls_fnmap.first; - - fcn_map_type& fn_map = cls_fnmap.second; - - std::string full_dir_name - = octave::sys::file_ops::concat (dir_name, "@" + class_name); - - for (auto& nm_filst : fn_map) - { - file_info_list_type& file_info_list = nm_filst.second; - - if (file_info_list.size () == 1) - continue; - else - { - for (auto fi_it = file_info_list.begin (); - fi_it != file_info_list.end (); fi_it++) - { - if (fi_it->dir_name == full_dir_name) - { - file_info fi_tmp = *fi_it; - - file_info_list.erase (fi_it); - - if (at_end) - file_info_list.push_back (fi_tmp); - else - file_info_list.push_front (fi_tmp); - + } + } + } + } + + void + load_path::package_info::remove_private_fcn_map (const std::string& dir) + { + private_fcn_map_iterator p = private_fcn_map.find (dir); + + if (p != private_fcn_map.end ()) + private_fcn_map.erase (p); + } + + void + load_path::package_info::remove_method_map (const std::string& dir) + { + for (auto& cls_fnmap : method_map) + { + std::string class_name = cls_fnmap.first; + + fcn_map_type& fn_map = cls_fnmap.second; + + std::string full_dir_name + = octave::sys::file_ops::concat (dir, "@" + class_name); + + for (auto& nm_filst : fn_map) + { + file_info_list_type& file_info_list = nm_filst.second; + + if (file_info_list.size () == 1) + continue; + else + { + for (auto fi_it = file_info_list.begin (); + fi_it != file_info_list.end (); fi_it++) + { + if (fi_it->dir_name == full_dir_name) + { + file_info_list.erase (fi_it); + // FIXME: if there are no other elements, we + // should remove this element of fn_map but calling + // erase here would invalidate the iterator fi_it. + + break; + } + } + } + } + } + } + + bool + load_path::package_info::check_file_type (std::string& fname, int type, + int possible_types, + const std::string& fcn, + const char *who) const + { + bool retval = false; + + if (type == load_path::OCT_FILE) + { + if ((type & possible_types) == load_path::OCT_FILE) + { + fname += ".oct"; + retval = true; + } + } + else if (type == load_path::M_FILE) + { + if ((type & possible_types) == load_path::M_FILE) + { + fname += ".m"; + retval = true; + } + } + else if (type == load_path::MEX_FILE) + { + if ((type & possible_types) == load_path::MEX_FILE) + { + fname += ".mex"; + retval = true; + } + } + else if (type == (load_path::M_FILE | load_path::OCT_FILE)) + { + if (possible_types & load_path::OCT_FILE) + { + fname += ".oct"; + retval = true; + } + else if (possible_types & load_path::M_FILE) + { + fname += ".m"; + retval = true; + } + } + else if (type == (load_path::M_FILE | load_path::MEX_FILE)) + { + if (possible_types & load_path::MEX_FILE) + { + fname += ".mex"; + retval = true; + } + else if (possible_types & load_path::M_FILE) + { + fname += ".m"; + retval = true; + } + } + else if (type == (load_path::OCT_FILE | load_path::MEX_FILE)) + { + if (possible_types & load_path::OCT_FILE) + { + fname += ".oct"; + retval = true; + } + else if (possible_types & load_path::MEX_FILE) + { + fname += ".mex"; + retval = true; + } + } + else if (type == (load_path::M_FILE | load_path::OCT_FILE + | load_path::MEX_FILE)) + { + if (possible_types & load_path::OCT_FILE) + { + fname += ".oct"; + retval = true; + } + else if (possible_types & load_path::MEX_FILE) + { + fname += ".mex"; + retval = true; + } + else if (possible_types & load_path::M_FILE) + { + fname += ".m"; + retval = true; + } + } + else + error ("%s: %s: invalid type code = %d", who, fcn.c_str (), type); + + return retval; + } + + void + load_path::package_info::print_types (std::ostream& os, int types) const + { + bool printed_type = false; + + if (types & load_path::OCT_FILE) + { + os << "oct"; + printed_type = true; + } + + if (types & load_path::MEX_FILE) + { + if (printed_type) + os << "|"; + os << "mex"; + printed_type = true; + } + + if (types & load_path::M_FILE) + { + if (printed_type) + os << "|"; + os << "m"; + printed_type = true; + } + } + + void + load_path::package_info::print_fcn_list (std::ostream& os, + const load_path::dir_info::fcn_file_map_type& lst) const + { + for (const auto& nm_typ : lst) + { + os << " " << nm_typ.first << " ("; + + print_types (os, nm_typ.second); + + os << ")\n"; + } + } + + std::string + genpath (const std::string& dirname, const string_vector& skip) + { + std::string retval; + + octave::sys::dir_entry dir (dirname); + + if (dir) + { + retval = dirname; + + string_vector dirlist = dir.read ().sort (false); + + octave_idx_type len = dirlist.numel (); + + for (octave_idx_type i = 0; i < len; i++) + { + std::string elt = dirlist[i]; + + bool skip_p = (elt == "." || elt == ".." || elt[0] == '@' + || elt[0] == '+'); + + if (! skip_p) + { + for (octave_idx_type j = 0; j < skip.numel (); j++) + { + skip_p = (elt == skip[j]); + if (skip_p) break; - } - } - } - } - } -} - -void -load_path::package_info::remove_fcn_map (const std::string& dir, - const string_vector& fcn_files) -{ - octave_idx_type len = fcn_files.numel (); - - for (octave_idx_type k = 0; k < len; k++) - { - std::string fname = fcn_files[k]; - - std::string ext; - std::string base = fname; - - size_t pos = fname.rfind ('.'); - - if (pos != std::string::npos) - { - base = fname.substr (0, pos); - ext = fname.substr (pos); - } - - file_info_list_type& file_info_list = fcn_map[base]; - - for (auto fi_it = file_info_list.begin (); - fi_it != file_info_list.end (); - fi_it++) - { - if (fi_it->dir_name == dir) - { - file_info_list.erase (fi_it); - - if (file_info_list.empty ()) - fcn_map.erase (fname); - - break; - } - } - } -} - -void -load_path::package_info::remove_private_fcn_map (const std::string& dir) -{ - private_fcn_map_iterator p = private_fcn_map.find (dir); - - if (p != private_fcn_map.end ()) - private_fcn_map.erase (p); -} - -void -load_path::package_info::remove_method_map (const std::string& dir) -{ - for (auto& cls_fnmap : method_map) - { - std::string class_name = cls_fnmap.first; - - fcn_map_type& fn_map = cls_fnmap.second; - - std::string full_dir_name - = octave::sys::file_ops::concat (dir, "@" + class_name); - - for (auto& nm_filst : fn_map) - { - file_info_list_type& file_info_list = nm_filst.second; - - if (file_info_list.size () == 1) - continue; - else - { - for (auto fi_it = file_info_list.begin (); - fi_it != file_info_list.end (); fi_it++) - { - if (fi_it->dir_name == full_dir_name) - { - file_info_list.erase (fi_it); - // FIXME: if there are no other elements, we - // should remove this element of fn_map but calling - // erase here would invalidate the iterator fi_it. - - break; - } - } - } - } - } -} - -bool -load_path::package_info::check_file_type (std::string& fname, int type, - int possible_types, - const std::string& fcn, - const char *who) const -{ - bool retval = false; - - if (type == load_path::OCT_FILE) - { - if ((type & possible_types) == load_path::OCT_FILE) - { - fname += ".oct"; - retval = true; - } - } - else if (type == load_path::M_FILE) - { - if ((type & possible_types) == load_path::M_FILE) - { - fname += ".m"; - retval = true; - } - } - else if (type == load_path::MEX_FILE) - { - if ((type & possible_types) == load_path::MEX_FILE) - { - fname += ".mex"; - retval = true; - } - } - else if (type == (load_path::M_FILE | load_path::OCT_FILE)) - { - if (possible_types & load_path::OCT_FILE) - { - fname += ".oct"; - retval = true; - } - else if (possible_types & load_path::M_FILE) - { - fname += ".m"; - retval = true; - } - } - else if (type == (load_path::M_FILE | load_path::MEX_FILE)) - { - if (possible_types & load_path::MEX_FILE) - { - fname += ".mex"; - retval = true; - } - else if (possible_types & load_path::M_FILE) - { - fname += ".m"; - retval = true; - } - } - else if (type == (load_path::OCT_FILE | load_path::MEX_FILE)) - { - if (possible_types & load_path::OCT_FILE) - { - fname += ".oct"; - retval = true; - } - else if (possible_types & load_path::MEX_FILE) - { - fname += ".mex"; - retval = true; - } - } - else if (type == (load_path::M_FILE | load_path::OCT_FILE - | load_path::MEX_FILE)) - { - if (possible_types & load_path::OCT_FILE) - { - fname += ".oct"; - retval = true; - } - else if (possible_types & load_path::MEX_FILE) - { - fname += ".mex"; - retval = true; - } - else if (possible_types & load_path::M_FILE) - { - fname += ".m"; - retval = true; - } - } - else - error ("%s: %s: invalid type code = %d", who, fcn.c_str (), type); - - return retval; -} - -void -load_path::package_info::print_types (std::ostream& os, int types) const -{ - bool printed_type = false; - - if (types & load_path::OCT_FILE) - { - os << "oct"; - printed_type = true; - } - - if (types & load_path::MEX_FILE) - { - if (printed_type) - os << "|"; - os << "mex"; - printed_type = true; - } - - if (types & load_path::M_FILE) - { - if (printed_type) - os << "|"; - os << "m"; - printed_type = true; - } -} - -void -load_path::package_info::print_fcn_list (std::ostream& os, - const load_path::dir_info::fcn_file_map_type& lst) const -{ - for (const auto& nm_typ : lst) - { - os << " " << nm_typ.first << " ("; - - print_types (os, nm_typ.second); - - os << ")\n"; - } -} - -std::string -genpath (const std::string& dirname, const string_vector& skip) -{ - std::string retval; - - octave::sys::dir_entry dir (dirname); - - if (dir) - { - retval = dirname; - - string_vector dirlist = dir.read ().sort (false); - - octave_idx_type len = dirlist.numel (); - - for (octave_idx_type i = 0; i < len; i++) - { - std::string elt = dirlist[i]; - - bool skip_p = (elt == "." || elt == ".." || elt[0] == '@' - || elt[0] == '+'); - - if (! skip_p) - { - for (octave_idx_type j = 0; j < skip.numel (); j++) - { - skip_p = (elt == skip[j]); - if (skip_p) - break; - } - - if (! skip_p) - { - std::string nm = octave::sys::file_ops::concat (dirname, elt); - - octave::sys::file_stat fs (nm); - - if (fs && fs.is_dir ()) - retval += octave::directory_path::path_sep_str () + genpath (nm, skip); - } - } - } - } - - return retval; + } + + if (! skip_p) + { + std::string nm = octave::sys::file_ops::concat (dirname, elt); + + octave::sys::file_stat fs (nm); + + if (fs && fs.is_dir ()) + retval += octave::directory_path::path_sep_str () + genpath (nm, skip); + } + } + } + } + + return retval; + } } DEFUN (genpath, args, , @@ -2182,7 +2188,7 @@ { std::string dirname = args(0).xstring_value ("genpath: DIR must be a string"); - retval = genpath (dirname); + retval = octave::genpath (dirname); } else { @@ -2193,7 +2199,7 @@ for (octave_idx_type i = 1; i < nargin; i++) skip[i-1] = args(i).xstring_value ("genpath: all arguments must be strings"); - retval = genpath (dirname, skip); + retval = octave::genpath (dirname, skip); } return retval; @@ -2221,7 +2227,7 @@ if (! args.empty ()) print_usage (); - load_path& lp = octave::__get_load_path__ ("command_line_path"); + octave::load_path& lp = octave::__get_load_path__ ("command_line_path"); return ovl (lp.get_command_line_path ()); } @@ -2237,7 +2243,7 @@ if (! args.empty ()) print_usage (); - load_path& lp = octave::__get_load_path__ ("restoredefaultpath"); + octave::load_path& lp = octave::__get_load_path__ ("restoredefaultpath"); lp.initialize (true); @@ -2255,7 +2261,7 @@ Undocumented internal function. @end deftypefn */) { - load_path& lp = octave::__get_load_path__ ("__pathorig__"); + octave::load_path& lp = octave::__get_load_path__ ("__pathorig__"); lp.initialize (true); @@ -2287,7 +2293,7 @@ string_vector argv = args.make_argv ("path"); - load_path& lp = octave::__get_load_path__ ("path"); + octave::load_path& lp = octave::__get_load_path__ ("path"); if (nargin > 0) { @@ -2351,7 +2357,7 @@ if (nargin == 0) print_usage (); - load_path& lp = octave::__get_load_path__ ("addpath"); + octave::load_path& lp = octave::__get_load_path__ ("addpath"); octave_value retval; @@ -2459,7 +2465,7 @@ octave_value retval; - load_path& lp = octave::__get_load_path__ ("rmpath"); + octave::load_path& lp = octave::__get_load_path__ ("rmpath"); if (nargout > 0) retval = lp.path (); @@ -2495,7 +2501,7 @@ Undocumented internal function. @end deftypefn */) { - load_path& lp = octave::__get_load_path__ ("__dump_load_path__"); + octave::load_path& lp = octave::__get_load_path__ ("__dump_load_path__"); lp.display (octave_stdout);
--- a/libinterp/corefcn/load-path.h Wed Apr 26 01:32:49 2017 -0400 +++ b/libinterp/corefcn/load-path.h Thu Apr 27 12:31:17 2017 -0400 @@ -36,514 +36,525 @@ #include "pathsearch.h" #include "str-vec.h" -class -OCTINTERP_API -load_path +namespace octave { -public: - - load_path (void) - : package_map (), top_level_package (), dir_info_list (), init_dirs (), - m_command_line_path (), add_hook (load_path::execute_pkg_add), - remove_hook (load_path::execute_pkg_del) - { } - - typedef void (*hook_fcn_ptr) (const std::string& dir); - - load_path (const load_path&) = delete; - - load_path& operator = (const load_path&) = delete; - - ~load_path (void) = default; - - void initialize (bool set_initial_path = false); - - void clear (void); - - void set (const std::string& p, bool warn = false, bool is_init = false); - - void append (const std::string& dir, bool warn = false); - - void prepend (const std::string& dir, bool warn = false); - - bool remove (const std::string& dir); - - void update (void) const; - - bool contains_canonical (const std::string& dir_name) const; - - std::string find_method (const std::string& class_name, - const std::string& meth, - std::string& dir_name, - const std::string& pack_name = "") - { - return get_package (pack_name).find_method (class_name, meth, dir_name); - } - - std::string find_method (const std::string& class_name, - const std::string& meth, - const std::string& pack_name = "") - { - std::string dir_name; - return find_method (class_name, meth, dir_name, pack_name); - } - - std::list<std::string> methods (const std::string& class_name, - const std::string& pack_name = "") - { - return get_package (pack_name).methods (class_name); - } - - std::list<std::string> overloads (const std::string& meth) const; - - bool find_package (const std::string& package_name) const - { - return (package_map.find (package_name) != package_map.end ()); - } - - std::list<std::string> get_all_package_names (bool only_top_level = true) const; - - std::string find_fcn (const std::string& fcn, std::string& dir_name, - const std::string& pack_name = "") - { - return get_package (pack_name).find_fcn (fcn, dir_name); - } - - std::string find_fcn (const std::string& fcn, - const std::string& pack_name = "") - { - std::string dir_name; - return find_fcn (fcn, dir_name, pack_name); - } - - std::string find_private_fcn (const std::string& dir, - const std::string& fcn, - const std::string& pack_name = "") - { - return get_package (pack_name).find_private_fcn (dir, fcn); - } - - std::string find_fcn_file (const std::string& fcn, - const std::string& pack_name = "") - { - std::string dir_name; - return get_package (pack_name).find_fcn (fcn, dir_name, M_FILE); - } - - std::string find_oct_file (const std::string& fcn, - const std::string& pack_name = "") - { - std::string dir_name; - return get_package (pack_name).find_fcn (fcn, dir_name, M_FILE); - } - - std::string find_mex_file (const std::string& fcn, - const std::string& pack_name = "") - { - std::string dir_name; - return get_package (pack_name).find_fcn (fcn, dir_name, M_FILE); - } - - std::string find_file (const std::string& file) const; - - std::string find_dir (const std::string& dir) const; - - string_vector find_matching_dirs (const std::string& dir) const; - - std::string find_first_of (const string_vector& files) const; - - string_vector find_all_first_of (const string_vector& files) const; - - string_vector dirs (void) const; - - std::list<std::string> dir_list (void) const; - - string_vector files (const std::string& dir, bool omit_exts = false) const; - - string_vector fcn_names (void) const; - - std::string path (void) const; - - void display (std::ostream& os) const; - - hook_fcn_ptr get_add_hook (void) { return add_hook; } - hook_fcn_ptr get_remove_hook (void) { return remove_hook; } - - void set_add_hook (hook_fcn_ptr f) { add_hook = f; } - void set_remove_hook (hook_fcn_ptr f) { remove_hook = f; } - - static void execute_pkg_add (const std::string& dir); - static void execute_pkg_del (const std::string& dir); - - void set_command_line_path (const std::string& p) - { - if (m_command_line_path.empty ()) - m_command_line_path = p; - else - m_command_line_path += octave::directory_path::path_sep_str () + p; - } - - std::string get_command_line_path (void) const { return m_command_line_path; } - - std::string system_path (void) const { return sys_path; } - -private: - - static const int M_FILE = 1; - static const int OCT_FILE = 2; - static const int MEX_FILE = 4; - - class dir_info + class + OCTINTERP_API + load_path { public: - // <FCN_NAME, TYPE> - typedef std::map<std::string, int> fcn_file_map_type; - - typedef fcn_file_map_type::const_iterator const_fcn_file_map_iterator; - typedef fcn_file_map_type::iterator fcn_file_map_iterator; - - struct class_info - { - class_info (void) : method_file_map (), private_file_map () { } - - class_info (const class_info& ci) - : method_file_map (ci.method_file_map), - private_file_map (ci.private_file_map) { } - - class_info& operator = (const class_info& ci) - { - if (this != &ci) - { - method_file_map = ci.method_file_map; - private_file_map = ci.private_file_map; - } - return *this; - } - - ~class_info (void) = default; - - fcn_file_map_type method_file_map; - fcn_file_map_type private_file_map; - }; - - // <CLASS_NAME, CLASS_INFO> - typedef std::map<std::string, class_info> method_file_map_type; - - typedef method_file_map_type::const_iterator const_method_file_map_iterator; - typedef method_file_map_type::iterator method_file_map_iterator; - - // <PACKAGE_NAME, DIR_INFO> - typedef std::map<std::string, dir_info> package_dir_map_type; - - typedef package_dir_map_type::const_iterator const_package_dir_map_iterator; - typedef package_dir_map_type::iterator package_dir_map_iterator; - - // This default constructor is only provided so we can create a - // std::map of dir_info objects. You should not use this - // constructor for any other purpose. - dir_info (void) = default; - - dir_info (const std::string& d) - : dir_name (d), abs_dir_name (), is_relative (false), - dir_mtime (), dir_time_last_checked (), all_files (), fcn_files (), - private_file_map (), method_file_map (), package_dir_map () - { - initialize (); - } - - dir_info (const dir_info& di) = default; + load_path (void) + : package_map (), top_level_package (), dir_info_list (), init_dirs (), + m_command_line_path (), add_hook (load_path::execute_pkg_add), + remove_hook (load_path::execute_pkg_del) + { } - ~dir_info (void) = default; - - dir_info& operator = (const dir_info& di) = default; - - void update (void); + typedef void (*hook_fcn_ptr) (const std::string& dir); - std::string dir_name; - std::string abs_dir_name; - bool is_relative; - octave::sys::time dir_mtime; - octave::sys::time dir_time_last_checked; - string_vector all_files; - string_vector fcn_files; - fcn_file_map_type private_file_map; - method_file_map_type method_file_map; - package_dir_map_type package_dir_map; - - bool is_package (const std::string& name) const; - - private: - - void initialize (void); - - void get_file_list (const std::string& d); - - void get_private_file_map (const std::string& d); + load_path (const load_path&) = delete; - void get_method_file_map (const std::string& d, - const std::string& class_name); - - void get_package_dir (const std::string& d, - const std::string& package_name); - - friend fcn_file_map_type get_fcn_files (const std::string& d); - }; - - class file_info - { - public: - - file_info (const std::string& d, int t) : dir_name (d), types (t) { } + load_path& operator = (const load_path&) = delete; - file_info (const file_info& fi) - : dir_name (fi.dir_name), types (fi.types) { } - - ~file_info (void) = default; - - file_info& operator = (const file_info& fi) - { - if (&fi != this) - { - dir_name = fi.dir_name; - types = fi.types; - } - - return *this; - } + ~load_path (void) = default; - std::string dir_name; - int types; - }; + void initialize (bool set_initial_path = false); - // We maintain two ways of looking at the same information. - // - // First, a list of directories and the set of "public" files and - // private files (those found in the special "private" subdirectory) - // in each directory. - // - // Second, a map from filenames (the union of all "public" files for all - // directories, but without filename extensions) to a list of - // corresponding information (directory name and file types). This - // way, we can quickly find shadowed filenames and look up all - // overloaded functions (in the "@" directories used to implement - // classes). - - typedef std::list<dir_info> dir_info_list_type; - - typedef dir_info_list_type::const_iterator const_dir_info_list_iterator; - typedef dir_info_list_type::iterator dir_info_list_iterator; - - typedef std::map<std::string, dir_info> abs_dir_cache_type; - - typedef abs_dir_cache_type::const_iterator const_abs_dir_cache_iterator; - typedef abs_dir_cache_type::iterator abs_dir_cache_iterator; - - typedef std::list<file_info> file_info_list_type; + void clear (void); - typedef file_info_list_type::const_iterator const_file_info_list_iterator; - typedef file_info_list_type::iterator file_info_list_iterator; - - // <FCN_NAME, FILE_INFO_LIST> - typedef std::map<std::string, file_info_list_type> fcn_map_type; - - typedef fcn_map_type::const_iterator const_fcn_map_iterator; - typedef fcn_map_type::iterator fcn_map_iterator; - - // <DIR_NAME, <FCN_NAME, TYPE>> - typedef std::map<std::string, dir_info::fcn_file_map_type> - private_fcn_map_type; + void set (const std::string& p, bool warn = false, bool is_init = false); - typedef private_fcn_map_type::const_iterator const_private_fcn_map_iterator; - typedef private_fcn_map_type::iterator private_fcn_map_iterator; - - // <CLASS_NAME, <FCN_NAME, FILE_INFO_LIST>> - typedef std::map<std::string, fcn_map_type> method_map_type; - - typedef method_map_type::const_iterator const_method_map_iterator; - typedef method_map_type::iterator method_map_iterator; - - class package_info - { - public: - - package_info (const std::string& package_name = "") - : m_package_name (package_name), dir_list (), fcn_map (), private_fcn_map (), - method_map () { } + void append (const std::string& dir, bool warn = false); - package_info (const package_info& l) - : m_package_name (l.m_package_name), dir_list (l.dir_list), - private_fcn_map (l.private_fcn_map), method_map (l.method_map) { } - - ~package_info (void) = default; + void prepend (const std::string& dir, bool warn = false); - package_info& operator = (const package_info& l) - { - if (&l != this) - { - m_package_name = l.m_package_name; - dir_list = l.dir_list; - fcn_map = l.fcn_map; - private_fcn_map = l.private_fcn_map; - method_map = l.method_map; - } - - return *this; - } - - void add (const dir_info& di, bool at_end, bool updating) - { - if (at_end) - dir_list.push_back (di.dir_name); - else - dir_list.push_front (di.dir_name); - - add_to_fcn_map (di, at_end, updating); + bool remove (const std::string& dir); - add_to_private_fcn_map (di); - - add_to_method_map (di, at_end); - } - - void move (const dir_info& di, bool at_end); - - void remove (const dir_info& di); - - void clear (void) - { - dir_list.clear (); - - fcn_map.clear (); + void update (void) const; - private_fcn_map.clear (); - - method_map.clear (); - } - - void display (std::ostream& out) const; - - std::string find_fcn (const std::string& fcn, - std::string& dir_name, - int type = M_FILE | OCT_FILE | MEX_FILE) const; - - std::string find_private_fcn (const std::string& dir, - const std::string& fcn, - int type = M_FILE | OCT_FILE | MEX_FILE) const; + bool contains_canonical (const std::string& dir_name) const; std::string find_method (const std::string& class_name, const std::string& meth, std::string& dir_name, - int type = M_FILE | OCT_FILE | MEX_FILE) const; + const std::string& pack_name = "") + { + return get_package (pack_name).find_method (class_name, meth, dir_name); + } + + std::string find_method (const std::string& class_name, + const std::string& meth, + const std::string& pack_name = "") + { + std::string dir_name; + return find_method (class_name, meth, dir_name, pack_name); + } + + std::list<std::string> methods (const std::string& class_name, + const std::string& pack_name = "") + { + return get_package (pack_name).methods (class_name); + } + + std::list<std::string> overloads (const std::string& meth) const; + + bool find_package (const std::string& package_name) const + { + return (package_map.find (package_name) != package_map.end ()); + } + + std::list<std::string> + get_all_package_names (bool only_top_level = true) const; + + std::string find_fcn (const std::string& fcn, std::string& dir_name, + const std::string& pack_name = "") + { + return get_package (pack_name).find_fcn (fcn, dir_name); + } + + std::string find_fcn (const std::string& fcn, + const std::string& pack_name = "") + { + std::string dir_name; + return find_fcn (fcn, dir_name, pack_name); + } - std::list<std::string> methods (const std::string& class_name) const; + std::string find_private_fcn (const std::string& dir, + const std::string& fcn, + const std::string& pack_name = "") + { + return get_package (pack_name).find_private_fcn (dir, fcn); + } + + std::string find_fcn_file (const std::string& fcn, + const std::string& pack_name = "") + { + std::string dir_name; + return get_package (pack_name).find_fcn (fcn, dir_name, M_FILE); + } + + std::string find_oct_file (const std::string& fcn, + const std::string& pack_name = "") + { + std::string dir_name; + return get_package (pack_name).find_fcn (fcn, dir_name, M_FILE); + } - void overloads (const std::string& meth, std::list<std::string>& l) const; + std::string find_mex_file (const std::string& fcn, + const std::string& pack_name = "") + { + std::string dir_name; + return get_package (pack_name).find_fcn (fcn, dir_name, M_FILE); + } + + std::string find_file (const std::string& file) const; + + std::string find_dir (const std::string& dir) const; + + string_vector find_matching_dirs (const std::string& dir) const; + + std::string find_first_of (const string_vector& files) const; + + string_vector find_all_first_of (const string_vector& files) const; + + string_vector dirs (void) const; + + std::list<std::string> dir_list (void) const; + + string_vector files (const std::string& dir, bool omit_exts = false) const; string_vector fcn_names (void) const; + std::string path (void) const; + + void display (std::ostream& os) const; + + hook_fcn_ptr get_add_hook (void) { return add_hook; } + hook_fcn_ptr get_remove_hook (void) { return remove_hook; } + + void set_add_hook (hook_fcn_ptr f) { add_hook = f; } + void set_remove_hook (hook_fcn_ptr f) { remove_hook = f; } + + static void execute_pkg_add (const std::string& dir); + static void execute_pkg_del (const std::string& dir); + + void set_command_line_path (const std::string& p) + { + if (m_command_line_path.empty ()) + m_command_line_path = p; + else + m_command_line_path += octave::directory_path::path_sep_str () + p; + } + + std::string get_command_line_path (void) const + { + return m_command_line_path; + } + + std::string system_path (void) const { return sys_path; } + private: - void add_to_fcn_map (const dir_info& di, bool at_end, bool updating); + static const int M_FILE = 1; + static const int OCT_FILE = 2; + static const int MEX_FILE = 4; + + class dir_info + { + public: + + // <FCN_NAME, TYPE> + typedef std::map<std::string, int> fcn_file_map_type; + + typedef fcn_file_map_type::const_iterator const_fcn_file_map_iterator; + typedef fcn_file_map_type::iterator fcn_file_map_iterator; + + struct class_info + { + class_info (void) : method_file_map (), private_file_map () { } - void add_to_private_fcn_map (const dir_info& di); + class_info (const class_info& ci) + : method_file_map (ci.method_file_map), + private_file_map (ci.private_file_map) + { } + + class_info& operator = (const class_info& ci) + { + if (this != &ci) + { + method_file_map = ci.method_file_map; + private_file_map = ci.private_file_map; + } + return *this; + } + + ~class_info (void) = default; + + fcn_file_map_type method_file_map; + fcn_file_map_type private_file_map; + }; + + // <CLASS_NAME, CLASS_INFO> + typedef std::map<std::string, class_info> method_file_map_type; - void add_to_method_map (const dir_info& di, bool at_end); + typedef method_file_map_type::const_iterator const_method_file_map_iterator; + typedef method_file_map_type::iterator method_file_map_iterator; + + // <PACKAGE_NAME, DIR_INFO> + typedef std::map<std::string, dir_info> package_dir_map_type; + + typedef package_dir_map_type::const_iterator const_package_dir_map_iterator; + typedef package_dir_map_type::iterator package_dir_map_iterator; + + // This default constructor is only provided so we can create a + // std::map of dir_info objects. You should not use this + // constructor for any other purpose. + dir_info (void) = default; + + dir_info (const std::string& d) + : dir_name (d), abs_dir_name (), is_relative (false), + dir_mtime (), dir_time_last_checked (), all_files (), fcn_files (), + private_file_map (), method_file_map (), package_dir_map () + { + initialize (); + } - void move_fcn_map (const std::string& dir, - const string_vector& fcn_files, bool at_end); + dir_info (const dir_info& di) = default; + + ~dir_info (void) = default; + + dir_info& operator = (const dir_info& di) = default; + + void update (void); + + std::string dir_name; + std::string abs_dir_name; + bool is_relative; + octave::sys::time dir_mtime; + octave::sys::time dir_time_last_checked; + string_vector all_files; + string_vector fcn_files; + fcn_file_map_type private_file_map; + method_file_map_type method_file_map; + package_dir_map_type package_dir_map; + + bool is_package (const std::string& name) const; + + private: - void move_method_map (const std::string& dir, bool at_end); + void initialize (void); + + void get_file_list (const std::string& d); + + void get_private_file_map (const std::string& d); + + void get_method_file_map (const std::string& d, + const std::string& class_name); + + void get_package_dir (const std::string& d, + const std::string& package_name); + + friend fcn_file_map_type get_fcn_files (const std::string& d); + }; + + class file_info + { + public: + + file_info (const std::string& d, int t) : dir_name (d), types (t) { } + + file_info (const file_info& fi) + : dir_name (fi.dir_name), types (fi.types) { } + + ~file_info (void) = default; + + file_info& operator = (const file_info& fi) + { + if (&fi != this) + { + dir_name = fi.dir_name; + types = fi.types; + } + + return *this; + } + + std::string dir_name; + int types; + }; - void remove_fcn_map (const std::string& dir, - const string_vector& fcn_files); + // We maintain two ways of looking at the same information. + // + // First, a list of directories and the set of "public" files and + // private files (those found in the special "private" subdirectory) + // in each directory. + // + // Second, a map from filenames (the union of all "public" files for all + // directories, but without filename extensions) to a list of + // corresponding information (directory name and file types). This + // way, we can quickly find shadowed filenames and look up all + // overloaded functions (in the "@" directories used to implement + // classes). + + typedef std::list<dir_info> dir_info_list_type; + + typedef dir_info_list_type::const_iterator const_dir_info_list_iterator; + typedef dir_info_list_type::iterator dir_info_list_iterator; + + typedef std::map<std::string, dir_info> abs_dir_cache_type; + + typedef abs_dir_cache_type::const_iterator const_abs_dir_cache_iterator; + typedef abs_dir_cache_type::iterator abs_dir_cache_iterator; - void remove_private_fcn_map (const std::string& dir); + typedef std::list<file_info> file_info_list_type; + + typedef file_info_list_type::const_iterator const_file_info_list_iterator; + typedef file_info_list_type::iterator file_info_list_iterator; + + // <FCN_NAME, FILE_INFO_LIST> + typedef std::map<std::string, file_info_list_type> fcn_map_type; + + typedef fcn_map_type::const_iterator const_fcn_map_iterator; + typedef fcn_map_type::iterator fcn_map_iterator; - void remove_method_map (const std::string& dir); + // <DIR_NAME, <FCN_NAME, TYPE>> + typedef std::map<std::string, dir_info::fcn_file_map_type> + private_fcn_map_type; + + typedef private_fcn_map_type::const_iterator const_private_fcn_map_iterator; + typedef private_fcn_map_type::iterator private_fcn_map_iterator; + + // <CLASS_NAME, <FCN_NAME, FILE_INFO_LIST>> + typedef std::map<std::string, fcn_map_type> method_map_type; + + typedef method_map_type::const_iterator const_method_map_iterator; + typedef method_map_type::iterator method_map_iterator; - bool check_file_type (std::string& fname, int type, int possible_types, - const std::string& fcn, const char *who) const; + class package_info + { + public: + + package_info (const std::string& package_name = "") + : m_package_name (package_name), dir_list (), fcn_map (), + private_fcn_map (), + method_map () + { } + + package_info (const package_info& l) + : m_package_name (l.m_package_name), dir_list (l.dir_list), + private_fcn_map (l.private_fcn_map), method_map (l.method_map) + { } + + ~package_info (void) = default; + + package_info& operator = (const package_info& l) + { + if (&l != this) + { + m_package_name = l.m_package_name; + dir_list = l.dir_list; + fcn_map = l.fcn_map; + private_fcn_map = l.private_fcn_map; + method_map = l.method_map; + } + + return *this; + } + + void add (const dir_info& di, bool at_end, bool updating) + { + if (at_end) + dir_list.push_back (di.dir_name); + else + dir_list.push_front (di.dir_name); + + add_to_fcn_map (di, at_end, updating); + + add_to_private_fcn_map (di); - void print_types (std::ostream& os, int types) const; + add_to_method_map (di, at_end); + } + + void move (const dir_info& di, bool at_end); + + void remove (const dir_info& di); + + void clear (void) + { + dir_list.clear (); + + fcn_map.clear (); + + private_fcn_map.clear (); + + method_map.clear (); + } + + void display (std::ostream& out) const; - void print_fcn_list (std::ostream& os, - const dir_info::fcn_file_map_type& lst) const; + std::string + find_fcn (const std::string& fcn, std::string& dir_name, + int type = M_FILE | OCT_FILE | MEX_FILE) const; + + std::string + find_private_fcn (const std::string& dir, const std::string& fcn, + int type = M_FILE | OCT_FILE | MEX_FILE) const; + + std::string + find_method (const std::string& class_name, const std::string& meth, + std::string& dir_name, + int type = M_FILE | OCT_FILE | MEX_FILE) const; + + std::list<std::string> methods (const std::string& class_name) const; + + void overloads (const std::string& meth, std::list<std::string>& l) const; + + string_vector fcn_names (void) const; + + private: + + void add_to_fcn_map (const dir_info& di, bool at_end, bool updating); + + void add_to_private_fcn_map (const dir_info& di); + + void add_to_method_map (const dir_info& di, bool at_end); - std::string m_package_name; + void move_fcn_map (const std::string& dir, + const string_vector& fcn_files, bool at_end); + + void move_method_map (const std::string& dir, bool at_end); + + void remove_fcn_map (const std::string& dir, + const string_vector& fcn_files); + + void remove_private_fcn_map (const std::string& dir); + + void remove_method_map (const std::string& dir); + + bool check_file_type (std::string& fname, int type, int possible_types, + const std::string& fcn, const char *who) const; + + void print_types (std::ostream& os, int types) const; + + void print_fcn_list (std::ostream& os, + const dir_info::fcn_file_map_type& lst) const; + + std::string m_package_name; - std::list<std::string> dir_list; + std::list<std::string> dir_list; + + fcn_map_type fcn_map; + + private_fcn_map_type private_fcn_map; + + method_map_type method_map; + }; + + // <PACKAGE_NAME, PACKAGE_INFO> + typedef std::map<std::string, package_info> package_map_type; + + typedef package_map_type::const_iterator const_package_map_iterator; + typedef package_map_type::iterator package_map_iterator; + + mutable package_map_type package_map; + + mutable package_info top_level_package; + + mutable dir_info_list_type dir_info_list; + + mutable std::set<std::string> init_dirs; - fcn_map_type fcn_map; + std::string m_command_line_path; + + static std::string sys_path; + + static abs_dir_cache_type abs_dir_cache; + + hook_fcn_ptr add_hook; + + hook_fcn_ptr remove_hook; + + const_dir_info_list_iterator find_dir_info (const std::string& dir) const; + dir_info_list_iterator find_dir_info (const std::string& dir); + + bool contains (const std::string& dir) const; + + void move (dir_info_list_iterator i, bool at_end); + + void move (const dir_info& di, bool at_end, const std::string& pname = ""); + + void remove (const dir_info& di, const std::string& pname = ""); + + void add (const std::string& dir, bool at_end, bool warn); - private_fcn_map_type private_fcn_map; + void add (const dir_info& di, bool at_end, const std::string& pname = "", + bool updating = false) const; + + bool is_package (const std::string& name) const; + + package_info& get_package (const std::string& name) const + { + if (! name.empty () && is_package (name)) + { + package_map_iterator l = package_map.find (name); - method_map_type method_map; + if (l == package_map.end ()) + l = package_map.insert (package_map.end (), + package_map_type::value_type (name, package_info (name))); + + return l->second; + } + + return top_level_package; + } + + string_vector get_file_list (const dir_info::fcn_file_map_type& lst) const; + + friend dir_info::fcn_file_map_type get_fcn_files (const std::string& d); }; - // <PACKAGE_NAME, PACKAGE_INFO> - typedef std::map<std::string, package_info> package_map_type; - - typedef package_map_type::const_iterator const_package_map_iterator; - typedef package_map_type::iterator package_map_iterator; - - mutable package_map_type package_map; - - mutable package_info top_level_package; - - mutable dir_info_list_type dir_info_list; - - mutable std::set<std::string> init_dirs; - - std::string m_command_line_path; - - static std::string sys_path; - - static abs_dir_cache_type abs_dir_cache; - - hook_fcn_ptr add_hook; - - hook_fcn_ptr remove_hook; - - const_dir_info_list_iterator find_dir_info (const std::string& dir) const; - dir_info_list_iterator find_dir_info (const std::string& dir); - - bool contains (const std::string& dir) const; - - void move (dir_info_list_iterator i, bool at_end); - - void move (const dir_info& di, bool at_end, const std::string& pname = ""); - - void remove (const dir_info& di, const std::string& pname = ""); - - void add (const std::string& dir, bool at_end, bool warn); - - void add (const dir_info& di, bool at_end, const std::string& pname = "", - bool updating = false) const; - - bool is_package (const std::string& name) const; - - package_info& get_package (const std::string& name) const - { - if (! name.empty () && is_package (name)) - { - package_map_iterator l = package_map.find (name); - - if (l == package_map.end ()) - l = package_map.insert (package_map.end (), - package_map_type::value_type (name, package_info (name))); - - return l->second; - } - - return top_level_package; - } - - string_vector get_file_list (const dir_info::fcn_file_map_type& lst) const; - - friend dir_info::fcn_file_map_type get_fcn_files (const std::string& d); -}; - -extern std::string -genpath (const std::string& dir, const string_vector& skip = "private"); + extern std::string + genpath (const std::string& dir, const string_vector& skip = "private"); +} #endif
--- a/libinterp/corefcn/ls-mat5.cc Wed Apr 26 01:32:49 2017 -0400 +++ b/libinterp/corefcn/ls-mat5.cc Thu Apr 27 12:31:17 2017 -0400 @@ -906,7 +906,7 @@ names.push_back (fname + ".mex"); names.push_back (fname + ".m"); - load_path& lp = octave::__get_load_path__ ("read_mat5_binary_element"); + octave::load_path& lp = octave::__get_load_path__ ("read_mat5_binary_element"); octave::directory_path p (lp.system_path ()); @@ -1208,7 +1208,7 @@ tc = cls; - load_path& lp = octave::__get_load_path__ ("read_mat5_binary_element"); + octave::load_path& lp = octave::__get_load_path__ ("read_mat5_binary_element"); if (lp.find_method (classname, "loadobj") != "") { @@ -2605,7 +2605,7 @@ octave_map m; - load_path& lp = octave::__get_load_path__ ("read_mat5_binary_element"); + octave::load_path& lp = octave::__get_load_path__ ("read_mat5_binary_element"); if (tc.is_object () && lp.find_method (tc.class_name (), "saveobj") != "")
--- a/libinterp/corefcn/symtab.cc Wed Apr 26 01:32:49 2017 -0400 +++ b/libinterp/corefcn/symtab.cc Thu Apr 27 12:31:17 2017 -0400 @@ -265,7 +265,7 @@ if (! dispatch_type.empty ()) { - load_path& lp = octave::__get_load_path__ ("out_of_date_check"); + octave::load_path& lp = octave::__get_load_path__ ("out_of_date_check"); file = lp.find_method (dispatch_type, nm, dir_name, pack); @@ -304,7 +304,7 @@ if (file.empty ()) { - load_path& lp = octave::__get_load_path__ ("out_of_date_check"); + octave::load_path& lp = octave::__get_load_path__ ("out_of_date_check"); file = lp.find_fcn (nm, dir_name, pack); } } @@ -392,7 +392,7 @@ { octave_value retval; - load_path& lp = octave::__get_load_path__ ("symbol_table::fcn_info::fcn_info_rep::load_private_function"); + octave::load_path& lp = octave::__get_load_path__ ("symbol_table::fcn_info::fcn_info_rep::load_private_function"); std::string file_name = lp.find_private_fcn (dir_name, name); @@ -432,7 +432,7 @@ std::string dir_name; - load_path& lp = octave::__get_load_path__ ("symbol_table::fcn_info::fcn_info_rep::load_class_constructor"); + octave::load_path& lp = octave::__get_load_path__ ("symbol_table::fcn_info::fcn_info_rep::load_class_constructor"); std::string file_name = lp.find_method (name, name, dir_name, package_name); @@ -500,7 +500,7 @@ { std::string dir_name; - load_path& lp = octave::__get_load_path__ ("symbol_table::fcn_info::fcn_info_rep::load_class_method"); + octave::load_path& lp = octave::__get_load_path__ ("symbol_table::fcn_info::fcn_info_rep::load_class_method"); std::string file_name = lp.find_method (dispatch_type, name, dir_name); @@ -702,7 +702,7 @@ // the last prompt or chdir, so try updating the load path and // searching again. - load_path& lp = octave::__get_load_path__ ("symbol_table::fcn_info::fcn_info_rep::find"); + octave::load_path& lp = octave::__get_load_path__ ("symbol_table::fcn_info::fcn_info_rep::find"); lp.update (); @@ -904,7 +904,7 @@ // the last prompt or chdir, so try updating the load path and // searching again. - load_path& lp = octave::__get_load_path__ ("symbol_table::fcn_info::fcn_info_rep::builtin_find"); + octave::load_path& lp = octave::__get_load_path__ ("symbol_table::fcn_info::fcn_info_rep::builtin_find"); lp.update (); @@ -1104,7 +1104,7 @@ { std::string dir_name; - load_path& lp = octave::__get_load_path__ ("symbol_table::fcn_info::fcn_info_rep::find_user_function"); + octave::load_path& lp = octave::__get_load_path__ ("symbol_table::fcn_info::fcn_info_rep::find_user_function"); std::string file_name = lp.find_fcn (name, dir_name, package_name);
--- a/libinterp/corefcn/utils.cc Wed Apr 26 01:32:49 2017 -0400 +++ b/libinterp/corefcn/utils.cc Thu Apr 27 12:31:17 2017 -0400 @@ -312,7 +312,7 @@ if (names.empty ()) error ("file_in_loadpath: FILE argument must not be empty"); - load_path& lp = octave::__get_load_path__ ("file_in_loadpath"); + octave::load_path& lp = octave::__get_load_path__ ("file_in_loadpath"); if (nargin == 1) return ovl (octave::sys::env::make_absolute (lp.find_first_of (names))); @@ -428,7 +428,7 @@ if (! suffix.empty ()) nm.append (suffix); - load_path& lp = octave::__get_load_path__ ("file_in_path"); + octave::load_path& lp = octave::__get_load_path__ ("file_in_path"); return octave::sys::env::make_absolute (lp.find_file (nm)); } @@ -453,7 +453,7 @@ if (! local_file_ok) { - load_path& lp = octave::__get_load_path__ ("find_data_file_in_load_path"); + octave::load_path& lp = octave::__get_load_path__ ("find_data_file_in_load_path"); // Not directly found; search load path. std::string tmp @@ -492,7 +492,7 @@ } else if (len > 2 && name[len - 2] == '.' && name[len - 1] == 'm') { - load_path& lp = octave::__get_load_path__ ("fcn_file_in_path"); + octave::load_path& lp = octave::__get_load_path__ ("fcn_file_in_path"); retval = lp.find_fcn_file (name.substr (0, len-2)); } @@ -503,7 +503,7 @@ if (pos != std::string::npos) fname = name.substr (0, pos); - load_path& lp = octave::__get_load_path__ ("fcn_file_in_path"); + octave::load_path& lp = octave::__get_load_path__ ("fcn_file_in_path"); retval = lp.find_fcn_file (fname); } @@ -522,7 +522,7 @@ if (dir.length () > 0) { - load_path& lp = octave::__get_load_path__ ("contents_in_file_path"); + octave::load_path& lp = octave::__get_load_path__ ("contents_in_file_path"); std::string tcontents = octave::sys::file_ops::concat (lp.find_dir (dir), @@ -559,13 +559,13 @@ } else if (len > 4 && name.find (".oct", len-5)) { - load_path& lp = octave::__get_load_path__ ("oct_file_in_path"); + octave::load_path& lp = octave::__get_load_path__ ("oct_file_in_path"); retval = lp.find_oct_file (name.substr (0, len-4)); } else { - load_path& lp = octave::__get_load_path__ ("oct_file_in_path"); + octave::load_path& lp = octave::__get_load_path__ ("oct_file_in_path"); retval = lp.find_oct_file (name); } @@ -596,13 +596,13 @@ } else if (len > 4 && name.find (".mex", len-5)) { - load_path& lp = octave::__get_load_path__ ("mex_file_in_path"); + octave::load_path& lp = octave::__get_load_path__ ("mex_file_in_path"); retval = lp.find_mex_file (name.substr (0, len-4)); } else { - load_path& lp = octave::__get_load_path__ ("mex_file_in_path"); + octave::load_path& lp = octave::__get_load_path__ ("mex_file_in_path"); retval = lp.find_mex_file (name); } @@ -1008,7 +1008,7 @@ dir = args(0).xstring_value ("dir_in_loadpath: DIR must be a directory name"); - load_path& lp = octave::__get_load_path__ ("dir_in_loadpath"); + octave::load_path& lp = octave::__get_load_path__ ("dir_in_loadpath"); if (nargin == 1) return ovl (lp.find_dir (dir));
--- a/libinterp/corefcn/variables.cc Wed Apr 26 01:32:49 2017 -0400 +++ b/libinterp/corefcn/variables.cc Thu Apr 27 12:31:17 2017 -0400 @@ -428,7 +428,7 @@ if (file_name.empty ()) { - load_path& lp = octave::__get_load_path__ ("symbol_exist"); + octave::load_path& lp = octave::__get_load_path__ ("symbol_exist"); file_name = lp.find_fcn (name); }
--- a/libinterp/octave-value/ov-class.cc Wed Apr 26 01:32:49 2017 -0400 +++ b/libinterp/octave-value/ov-class.cc Thu Apr 27 12:31:17 2017 -0400 @@ -1143,7 +1143,7 @@ os << "# classname: " << class_name () << "\n"; octave_map m; - load_path& lp = octave::__get_load_path__ ("octave_class::save_ascii"); + octave::load_path& lp = octave::__get_load_path__ ("octave_class::save_ascii"); if (lp.find_method (class_name (), "saveobj") != "") { @@ -1217,7 +1217,7 @@ if (! reconstruct_parents ()) warning ("load: unable to reconstruct object inheritance"); - load_path& lp = octave::__get_load_path__ ("octave_class::load_ascii"); + octave::load_path& lp = octave::__get_load_path__ ("octave_class::load_ascii"); if (lp.find_method (classname, "loadobj") != "") { @@ -1248,7 +1248,7 @@ octave_map m; - load_path& lp = octave::__get_load_path__ ("octave_class::save_binary"); + octave::load_path& lp = octave::__get_load_path__ ("octave_class::save_binary"); if (lp.find_method (class_name (), "saveobj") != "") { @@ -1337,7 +1337,7 @@ if (! reconstruct_parents ()) warning ("load: unable to reconstruct object inheritance"); - load_path& lp = octave::__get_load_path__ ("octave_class::load_binary"); + octave::load_path& lp = octave::__get_load_path__ ("octave_class::load_binary"); if (lp.find_method (c_name, "loadobj") != "") { @@ -1376,7 +1376,7 @@ octave_map m; octave_map::iterator i; - load_path& lp = octave::__get_load_path__ ("octave_class::save_hdf5"); + octave::load_path& lp = octave::__get_load_path__ ("octave_class::save_hdf5"); #if defined (HAVE_HDF5_18) group_hid = H5Gcreate (loc_id, name, octave_H5P_DEFAULT, octave_H5P_DEFAULT, @@ -1586,7 +1586,7 @@ if (! reconstruct_parents ()) warning ("load: unable to reconstruct object inheritance"); - load_path& lp = octave::__get_load_path__ ("octave_class::load_hdf5"); + octave::load_path& lp = octave::__get_load_path__ ("octave_class::load_hdf5"); if (lp.find_method (c_name, "loadobj") != "") { @@ -1926,7 +1926,7 @@ std::string method = args(1).string_value (); - load_path& lp = octave::__get_load_path__ ("ismethod"); + octave::load_path& lp = octave::__get_load_path__ ("ismethod"); if (lp.find_method (class_name, method) != "") return ovl (true); @@ -1954,7 +1954,7 @@ else if (arg.is_string ()) class_name = arg.string_value (); - load_path& lp = octave::__get_load_path__ ("__methods__"); + octave::load_path& lp = octave::__get_load_path__ ("__methods__"); string_vector sv = lp.methods (class_name);
--- a/libinterp/octave-value/ov-classdef.cc Wed Apr 26 01:32:49 2017 -0400 +++ b/libinterp/octave-value/ov-classdef.cc Thu Apr 27 12:31:17 2017 -0400 @@ -2633,7 +2633,8 @@ std::list<octave::tree_classdef_methods_block *> mb_list = b->methods_list (); - load_path& lp = octave::__get_load_path__ ("cdef_class::make_meta_class"); + octave::load_path& lp + = octave::__get_load_path__ ("cdef_class::make_meta_class"); for (auto& mb_p : mb_list) { @@ -2982,7 +2983,8 @@ { if (is_dummy_method (function)) { - load_path& lp = octave::__get_load_path__ ("cdef_method::cdef_method_rep::check_method"); + octave::load_path& lp + = octave::__get_load_path__ ("cdef_method::cdef_method_rep::check_method"); std::string name = get_name (); std::string cls_name = dispatch_type; @@ -3195,7 +3197,7 @@ { std::map<std::string, cdef_package> toplevel_packages; - load_path& lp = octave::__get_load_path__ ("package_getAllPackages"); + octave::load_path& lp = octave::__get_load_path__ ("package_getAllPackages"); std::list<std::string> names = lp.get_all_package_names (); @@ -3632,7 +3634,8 @@ } else { - load_path& lp = octave::__get_load_path__ ("cdef_manager::do_find_package"); + octave::load_path& lp + = octave::__get_load_path__ ("cdef_manager::do_find_package"); if (load_if_not_found && lp.find_package (name)) {
--- a/libinterp/octave-value/ov-fcn-handle.cc Wed Apr 26 01:32:49 2017 -0400 +++ b/libinterp/octave-value/ov-fcn-handle.cc Thu Apr 27 12:31:17 2017 -0400 @@ -298,7 +298,7 @@ names.push_back (nm + ".mex"); names.push_back (nm + ".m"); - load_path& lp = octave::__get_load_path__ ("octave_fcn_handle::set_fcn"); + octave::load_path& lp = octave::__get_load_path__ ("octave_fcn_handle::set_fcn"); octave::directory_path p (lp.system_path ()); @@ -1587,7 +1587,7 @@ } else { - load_path& lp = octave::__get_load_path__ ("make_fcn_handle"); + octave::load_path& lp = octave::__get_load_path__ ("make_fcn_handle"); // Globally visible (or no match yet). Query overloads. std::list<std::string> classes = lp.overloads (tnm);