26#if defined (HAVE_CONFIG_H)
38#if ! defined (OCTAVE_USE_WINDOWS_API)
61maybe_canonicalize (
const std::string& dir_arg)
63 bool is_absolute_path = sys::env::absolute_pathname (dir_arg);
65 std::string canonical_dir = sys::canonicalize_file_name (dir_arg);
67 if (canonical_dir.empty ())
73 if (! is_absolute_path)
77 std::string cwd = sys::canonicalize_file_name (
".");
78 if (dir.compare (0, cwd.length (), cwd) == 0)
79 dir.erase (0, cwd.length ()+1);
89maybe_add_path_elts (std::string& path,
const std::string& dir)
91 std::string tpath =
genpath (maybe_canonicalize (dir));
102static std::list<std::string>
103split_path (
const std::string& p)
105 std::list<std::string> retval;
110 std::size_t
len = p.length ();
112 while (end != std::string::npos)
114 std::string elt = p.substr (beg, end-beg);
117 retval.push_back (elt);
127 std::string elt = p.substr (beg);
130 retval.push_back (elt);
138strip_trailing_separators (
const std::string& dir_arg)
140 std::string dir = dir_arg;
142 std::size_t k = dir.length ();
144 while (k > 1 && sys::file_ops::is_dir_sep (dir[k-1]))
147 if (k < dir.length ())
156in_path_list (
const std::string& path_list,
const std::string& path)
158 std::size_t ps = path.size ();
159 std::size_t pls = path_list.size ();
160 std::size_t pos = path_list.find (path);
162 while (pos != std::string::npos)
164 if ((pos == 0 || path_list[pos-1] == psc)
165 && (pos + ps == pls || path_list[pos + ps] == psc))
168 pos = path_list.find (path, pos + 1);
203subdirs_modified (
const std::string&
d,
const sys::file_time& last_checked)
205 sys::dir_entry dir (
d);
215 std::string fname = flist[i];
217 std::string full_name = sys::file_ops::concat (
d, fname);
221#if defined (OCTAVE_USE_WINDOWS_API)
222 if (sys::dir_exists (full_name)
224 sys::file_stat fs (full_name);
226 if (fs && fs.is_dir ()
228 && (fname[0] ==
'@' || fname[0] ==
'+' || fname ==
"private")
229#
if defined (OCTAVE_USE_WINDOWS_API)
230 && ((sys::file_time (full_name)
232 && ((sys::file_time (fs.mtime ().unix_time ())
234 + sys::file_time::time_resolution () > last_checked)
235 || ((fname[0] ==
'@' || fname[0] ==
'+')
236 && subdirs_modified (full_name, last_checked))))
242 std::string msg = dir.error ();
243 warning (
"load_path: %s: %s",
d.c_str (), msg.c_str ());
249std::string load_path::s_sys_path;
250load_path::abs_dir_cache_type load_path::s_abs_dir_cache;
253 : m_add_hook ([this] (const std::string& dir) { this->
execute_pkg_add (dir); }),
254m_remove_hook ([
this] (
const std::string& dir) { this->
execute_pkg_del (dir); }),
255m_interpreter (interp), m_package_map (), m_top_level_package (),
256m_dir_info_list (), m_init_dirs (), m_command_line_path ()
264 if (set_initial_path)
266 maybe_add_path_elts (s_sys_path, config::local_ver_oct_file_dir ());
267 maybe_add_path_elts (s_sys_path, config::local_api_oct_file_dir ());
268 maybe_add_path_elts (s_sys_path, config::local_oct_file_dir ());
269 maybe_add_path_elts (s_sys_path, config::local_ver_fcn_file_dir ());
270 maybe_add_path_elts (s_sys_path, config::local_api_fcn_file_dir ());
271 maybe_add_path_elts (s_sys_path, config::local_fcn_file_dir ());
272 maybe_add_path_elts (s_sys_path, config::oct_file_dir ());
273 maybe_add_path_elts (s_sys_path, config::fcn_file_dir ());
274 maybe_add_path_elts (s_sys_path, config::oct_data_dir ());
277 std::string tpath = load_path::m_command_line_path;
280 tpath = sys::env::getenv (
"OCTAVE_PATH");
284 if (! tpath.empty ())
288 if (! s_sys_path.empty ())
294 set (xpath,
false,
true);
300 m_dir_info_list.clear ();
302 m_top_level_package.clear ();
304 m_package_map.clear ();
311 std::list<std::string> elts = split_path (p);
313 for (
auto& elt : elts)
314 elt = maybe_canonicalize (elt);
317 std::set<std::string> elts_set (elts.begin (), elts.end ());
320 m_init_dirs = elts_set;
323 for (
const auto& init_dir : m_init_dirs)
325 if (elts_set.find (init_dir) == elts_set.end ())
328 "default load path altered. Some built-in functions may not be found. Try restoredefaultpath() to recover it.");
339 m_add_hook =
nullptr;
343 for (
const auto& elt : elts)
360 for (
auto& di : m_dir_info_list)
363 if (di.dir_name.compare (
"."))
364 m_add_hook (di.dir_name);
373 add (dir,
true, warn);
380 add (dir,
false, warn);
388 if (! dir_arg.empty ())
390 if (sys::same_file (dir_arg,
"."))
392 warning (R
"(rmpath: can't remove "." from path)");
399 std::string dir = sys::file_ops::tilde_expand (dir_arg);
401 dir = strip_trailing_separators (dir);
403 auto i = find_dir_info (dir);
405 if (i != m_dir_info_list.end ())
416 m_dir_info_list.erase (i);
431 m_top_level_package.clear ();
433 m_package_map.clear ();
435 for (dir_info_list_iterator di = m_dir_info_list.begin ();
436 di != m_dir_info_list.end ();)
438 bool ok = di->update ();
443 (
"Octave:load-path:update-failed",
444 "load-path: update failed for '%s', removing from path",
445 di->dir_name.c_str ());
448 m_remove_hook (di->dir_name.c_str ());
452 di = m_dir_info_list.erase (di);
456 add (*di,
true,
"",
true);
467 for (
const auto&
d : m_dir_info_list)
469 if (sys::same_file (dir,
d.dir_name))
481 const std::string& dir)
484 bool addpath_option =
true;
486 std::string curr_dir = sys::env::get_current_directory ();
488 if (sys::same_file (curr_dir, dir))
495 std::string base_file = (file.length () > dir.length ())
496 ? file.substr (dir.length () + 1)
497 : sys::env::base_pathname (file);
499 std::string lp_file =
find_file (base_file);
501 if (dir_in_load_path)
503 if (sys::same_file (lp_file, file))
514 if (sys::same_file (lp_file, base_file))
516 if (sys::same_file (curr_dir, dir))
519 addpath_option =
false;
534 m_interpreter.
chdir (dir);
553std::list<std::string>
556 std::list<std::string> retval;
560 m_top_level_package.overloads (meth, retval);
562 for (
const auto& nm_ldr : m_package_map)
563 nm_ldr.second.overloads (meth, retval);
568std::list<std::string>
571 std::list<std::string> retval;
573 for (
const auto& dir_ldr : m_package_map)
575 if (! only_top_level || dir_ldr.first.find (
'.') == std::string::npos)
576 retval.push_back (dir_ldr.first);
587 if (sys::env::absolute_pathname (file)
588 || sys::env::rooted_relative_pathname (file))
589 return sys::file_exists (file) ? file : retval;
592 std::string tfile = find_private_file (file);
594 if (! tfile.empty ())
598 if (file.find_first_of (sys::file_ops::dir_sep_chars ())
599 != std::string::npos)
603 for (
const auto& di : m_dir_info_list)
605 std::string tfile = sys::file_ops::concat (di.abs_dir_name, file);
607 if (sys::file_exists (tfile))
614 for (
const auto& di : m_dir_info_list)
622 if (all_files[i] == file)
623 return sys::file_ops::concat (di.abs_dir_name, file);
636 if (dir.find_first_of (sys::file_ops::dir_sep_chars ()) != std::string::npos
637 && (sys::env::absolute_pathname (dir)
638 || sys::env::rooted_relative_pathname (dir)))
640 if (sys::dir_exists (dir))
645 std::string canon_dir = maybe_canonicalize (dir);
646 for (
const auto& di : m_dir_info_list)
648 std::string dname = di.abs_dir_name;
650 std::size_t dname_len = dname.length ();
652 if (dname.substr (dname_len - 1)
653 == sys::file_ops::dir_sep_str ())
655 dname = dname.substr (0, dname_len - 1);
659 std::size_t dir_len = canon_dir.length ();
661 if (dname_len > dir_len
662 && sys::file_ops::is_dir_sep (dname[dname_len - dir_len - 1])
663 && canon_dir == dname.substr (dname_len - dir_len)
664 && sys::dir_exists (di.dir_name))
665 return di.abs_dir_name;
675 std::list<std::string> retlist;
677 if (dir.find_first_of (sys::file_ops::dir_sep_chars ()) != std::string::npos
678 && (sys::env::absolute_pathname (dir)
679 || sys::env::rooted_relative_pathname (dir)))
681 if (sys::dir_exists (dir))
682 retlist.push_back (dir);
686 std::string canon_dir = maybe_canonicalize (dir);
687 for (
const auto& di : m_dir_info_list)
689 std::string dname = di.abs_dir_name;
691 std::size_t dname_len = dname.length ();
693 if (dname.substr (dname_len - 1)
694 == sys::file_ops::dir_sep_str ())
696 dname = dname.substr (0, dname_len - 1);
700 std::size_t dir_len = canon_dir.length ();
702 if (dname_len > dir_len
703 && sys::file_ops::is_dir_sep (dname[dname_len - dir_len - 1])
704 && canon_dir == dname.substr (dname_len - dir_len)
705 && sys::dir_exists (di.dir_name))
706 retlist.push_back (di.abs_dir_name);
718 std::string dir_name;
719 std::string file_name;
728 std::string file = flist[i];
730 if (file.find_first_of (sys::file_ops::dir_sep_chars ())
731 != std::string::npos)
733 if (sys::env::absolute_pathname (file)
734 || sys::env::rooted_relative_pathname (file))
736 if (sys::file_exists (file))
741 for (
const auto& di : m_dir_info_list)
744 tfile = sys::file_ops::concat (di.abs_dir_name, file);
746 if (sys::file_exists (tfile))
752 rel_flist[rel_flen++] = file;
755 rel_flist.
resize (rel_flen);
757 for (
const auto& di : m_dir_info_list)
767 if (all_files[i] == rel_flist[j])
769 dir_name = di.abs_dir_name;
770 file_name = rel_flist[j];
780 if (! dir_name.empty ())
781 retval = sys::file_ops::concat (dir_name, file_name);
789 std::list<std::string> retlist;
791 std::string dir_name;
792 std::string file_name;
801 std::string file = flist[i];
803 if (file.find_first_of (sys::file_ops::dir_sep_chars ())
804 != std::string::npos)
806 if (sys::env::absolute_pathname (file)
807 || sys::env::rooted_relative_pathname (file))
809 if (sys::file_exists (file))
810 retlist.push_back (file);
814 for (
const auto& di : m_dir_info_list)
817 tfile = sys::file_ops::concat (di.abs_dir_name, file);
819 if (sys::file_exists (tfile))
820 retlist.push_back (tfile);
825 rel_flist[rel_flen++] = file;
828 rel_flist.
resize (rel_flen);
830 for (
const auto& di : m_dir_info_list)
840 if (all_files[i] == rel_flist[j])
841 retlist.push_back (sys::file_ops::concat (di.abs_dir_name,
853 std::size_t
len = m_dir_info_list.size ();
859 for (
const auto& di : m_dir_info_list)
860 retval[k++] = di.dir_name;
865std::list<std::string>
868 std::list<std::string> retval;
870 for (
const auto& di : m_dir_info_list)
871 retval.push_back (di.dir_name);
881 const_dir_info_list_iterator p = find_dir_info (dir);
883 if (p != m_dir_info_list.end ())
884 retval = p->fcn_files;
892 std::string fname = retval[i];
894 std::size_t pos = fname.rfind (
'.');
896 if (pos != std::string::npos)
897 retval[i] = fname.substr (0, pos);
907 return m_top_level_package.fcn_names ();
931 for (
const auto& di : m_dir_info_list)
935 if (! fcn_files.
empty ())
937 os <<
"\n*** function files in " << di.dir_name <<
":\n\n";
942 const dir_info::method_file_map_type& method_file_map
943 = di.method_file_map;
945 if (! method_file_map.empty ())
947 for (
const auto& cls_ci : method_file_map)
949 os <<
"\n*** methods in " << di.dir_name
950 <<
"/@" << cls_ci.first <<
":\n\n";
961 m_top_level_package.display (os);
963 for (
const auto& nm_ldr : m_package_map)
964 nm_ldr.second.display (os);
970 execute_pkg_add_or_del (dir,
"PKG_ADD");
976 execute_pkg_add_or_del (dir,
"PKG_DEL");
998load_path::execute_pkg_add_or_del (
const std::string& dir,
999 const std::string& script_file)
1004 std::string file = sys::file_ops::concat (dir, script_file);
1006 if (sys::file_exists (file))
1013load_path::const_dir_info_list_iterator
1014load_path::find_dir_info (
const std::string& dir_arg)
const
1016 std::string dir = sys::file_ops::tilde_expand (dir_arg);
1018 dir = maybe_canonicalize (dir);
1020 auto retval = m_dir_info_list.cbegin ();
1022 while (retval != m_dir_info_list.cend ())
1024 if (retval->dir_name == dir)
1033load_path::dir_info_list_iterator
1034load_path::find_dir_info (
const std::string& dir_arg)
1036 std::string dir = sys::file_ops::tilde_expand (dir_arg);
1038 dir = maybe_canonicalize (dir);
1040 auto retval = m_dir_info_list.begin ();
1042 while (retval != m_dir_info_list.end ())
1044 if (retval->dir_name == dir)
1054load_path::contains (
const std::string& dir)
const
1056 return find_dir_info (dir) != m_dir_info_list.end ();
1060load_path::move (dir_info_list_iterator i,
bool at_end)
1062 if (m_dir_info_list.size () > 1)
1066 m_dir_info_list.erase (i);
1069 m_dir_info_list.push_back (di);
1071 m_dir_info_list.push_front (di);
1078load_path::move (
const dir_info& di,
bool at_end,
const std::string& pname)
1080 package_info& l = get_package (pname);
1082 l.move (di, at_end);
1084 dir_info::package_dir_map_type package_dir_map = di.package_dir_map;
1086 for (
const auto& pkg_di : package_dir_map)
1088 std::string full_name = pkg_di.first;
1090 if (! pname.empty ())
1091 full_name = pname +
'.' + full_name;
1093 move (pkg_di.second, at_end, full_name);
1098load_path::add (
const std::string& dir_arg,
bool at_end,
bool warn)
1100 std::size_t
len = dir_arg.length ();
1102 if (
len > 1 && dir_arg.substr (
len-2) ==
"//")
1104 "trailing '//' is no longer special in search path elements");
1106 std::string dir = sys::file_ops::tilde_expand (dir_arg);
1108 dir = strip_trailing_separators (dir);
1110 dir = maybe_canonicalize (dir);
1112 auto i = find_dir_info (dir);
1114 if (i != m_dir_info_list.end ())
1120 if (sys::dir_exists (dir, msg))
1127 m_dir_info_list.push_back (di);
1129 m_dir_info_list.push_front (di);
1133 if (m_add_hook && di.dir_name.compare (
"."))
1137 if (warn && ! msg.empty ())
1138 warning (
"addpath: %s: %s", dir_arg.c_str (), msg.c_str ());
1144 i = find_dir_info (
".");
1146 if (i != m_dir_info_list.end ())
1153 package_info& l = get_package (pname);
1157 dir_info::package_dir_map_type package_dir_map = di.package_dir_map;
1159 for (
const auto& pkg_di : package_dir_map)
1161 std::string full_name = pkg_di.first;
1163 if (! pname.empty ())
1164 full_name = pname +
'.' + full_name;
1166 remove (pkg_di.second, full_name);
1174 const std::string key = sys::canonicalize_file_name (dir);
1178 conf_file = key + sys::file_ops::dir_sep_str () +
".oct-config";
1180 FILE *cfile = sys::fopen (conf_file,
"rb");
1187 std::string enc_val =
"delete";
1196 const std::string enc_prop =
"encoding";
1199 std::string conf_str =
fgets (cfile, eof);
1202 auto it = std::find_if_not (conf_str.begin (), conf_str.end (),
1203 [] (
unsigned char c)
1204 { return std::isblank (c); });
1205 conf_str.erase (conf_str.begin (), it);
1208 if (conf_str.compare (0, enc_prop.size (), enc_prop) == 0)
1211 std::size_t pos = conf_str.find_first_not_of (
" \t=:",
1213 if (pos == std::string::npos)
1216 std::string enc_val = conf_str.substr (pos);
1219 it = std::find_if_not (enc_val.begin (), enc_val.end (),
1220 [] (
unsigned char c)
1221 { return std::isalnum (c) || c ==
'-'; });
1222 enc_val.erase(it, enc_val.end ());
1224 if (enc_val.empty ())
1237 std::string enc_val =
"delete";
1243load_path::is_package (
const std::string& name)
const
1245 for (
const auto& di : m_dir_info_list)
1247 if (di.is_package (name))
1255load_path::add (
const dir_info& di,
bool at_end,
1256 const std::string& pname,
bool updating)
1258 package_info& l = get_package (pname);
1260 l.add (di, at_end, updating);
1262 dir_info::package_dir_map_type package_dir_map = di.package_dir_map;
1264 for (
const auto& pkg_di : package_dir_map)
1266 std::string full_name = pkg_di.first;
1268 if (! pname.empty ())
1269 full_name = pname +
'.' + full_name;
1271 add (pkg_di.second, at_end, full_name);
1276load_path::get_file_list (
const load_path::dir_info::fcn_file_map_type& lst)
const
1284 for (
const auto& nm_typ : lst)
1286 std::string nm = nm_typ.first;
1288 int types = nm_typ.second;
1297 retval[count++] = nm;
1307load_path::find_private_file (
const std::string& fname)
const
1324 std::string dir_name = curr_code->
dir_name ();
1326 if (! dir_name.empty ())
1328 std::string pfname = dir_name + sys::file_ops::dir_sep_str ()
1329 +
"private" + sys::file_ops::dir_sep_str ()
1332 if (sys::file_exists (pfname,
false))
1340load_path::dir_info::fcn_file_map_type
1343 load_path::dir_info::fcn_file_map_type retval;
1348 if (! sys::get_dirlist (
d, flist, msg))
1349 warning (
"load_path: %s: %s",
d.c_str (), msg.c_str ());
1356 std::string fname = flist[i];
1358 std::size_t pos = fname.rfind (
'.');
1360 if (pos != std::string::npos)
1362 std::string base = fname.substr (0, pos);
1363 std::string ext = fname.substr (pos);
1371 else if (ext ==
".oct")
1373 else if (ext ==
".mex")
1378 load_path::dir_info::fcn_file_map_iterator p
1379 = retval.find (base);
1381 if (p == retval.end ())
1395load_path::dir_info::update ()
1397#if defined (OCTAVE_USE_WINDOWS_API)
1400 if (! sys::dir_exists (dir_name, msg))
1403 sys::file_stat fs (dir_name);
1407 std::string msg = fs.error ();
1410 "load_path: %s: %s", dir_name.c_str (), msg.c_str ());
1419 std::string abs_name = sys::canonicalize_file_name (dir_name);
1421 const_abs_dir_cache_iterator p = s_abs_dir_cache.find (abs_name);
1423 if (p != s_abs_dir_cache.end ())
1430 const dir_info& di = p->second;
1432#if defined (OCTAVE_USE_WINDOWS_API)
1433 if ((sys::file_time (dir_name)
1435 if ((sys::file_time (fs.mtime ().unix_time ())
1437 + sys::file_time::time_resolution ()
1438 > di.dir_time_last_checked)
1439 || subdirs_modified (dir_name, dir_time_last_checked))
1445 abs_dir_name = di.abs_dir_name;
1446 dir_mtime = di.dir_mtime;
1447 dir_time_last_checked = di.dir_time_last_checked;
1448 all_files = di.all_files;
1449 fcn_files = di.fcn_files;
1450 private_file_map = di.private_file_map;
1451 method_file_map = di.method_file_map;
1452 package_dir_map = di.package_dir_map;
1472#if defined (OCTAVE_USE_WINDOWS_API)
1473 else if (sys::file_time (dir_name)
1475 else if (sys::file_time (fs.mtime ().unix_time ())
1477 + sys::file_time::time_resolution () > dir_time_last_checked
1478 || subdirs_modified (dir_name, dir_time_last_checked))
1485load_path::dir_info::is_package (
const std::string& name)
const
1487 std::size_t pos = name.find (
'.');
1489 if (pos == std::string::npos)
1490 return package_dir_map.find (name) != package_dir_map.end ();
1493 std::string name_head = name.substr (0, pos);
1494 std::string name_tail = name.substr (pos + 1);
1496 const_package_dir_map_iterator it = package_dir_map.find (name_head);
1498 if (it != package_dir_map.end ())
1499 return it->second.is_package (name_tail);
1506load_path::dir_info::initialize ()
1508 is_relative = ! sys::env::absolute_pathname (dir_name);
1510 dir_time_last_checked = sys::file_time (
static_cast<OCTAVE_TIME_T
> (0));
1512#if defined (OCTAVE_USE_WINDOWS_API)
1515 if (sys::dir_exists (dir_name, msg))
1517 sys::file_stat fs (dir_name);
1522 method_file_map.clear ();
1523 package_dir_map.clear ();
1525#if defined (OCTAVE_USE_WINDOWS_API)
1526 dir_mtime = sys::file_time (dir_name);
1528 dir_mtime = fs.mtime ().unix_time ();
1531 dir_time_last_checked = sys::file_time ();
1533 get_file_list (dir_name);
1537 abs_dir_name = sys::canonicalize_file_name (dir_name);
1543 s_abs_dir_cache[abs_dir_name] = *
this;
1557#if ! defined (OCTAVE_USE_WINDOWS_API)
1558 std::string msg = fs.error ();
1560 warning (
"load_path: %s: %s", dir_name.c_str (), msg.c_str ());
1565load_path::dir_info::get_file_list (
const std::string&
d)
1570 if (! sys::get_dirlist (
d, flist, msg))
1572 warning (
"load_path: %s: %s",
d.c_str (), msg.c_str ());
1578 all_files.resize (
len);
1579 fcn_files.resize (
len);
1586 std::string fname = flist[i];
1588 std::string full_name = sys::file_ops::concat (
d, fname);
1590 if (sys::dir_exists (full_name))
1592 if (fname ==
"private")
1593 get_private_file_map (full_name);
1594 else if (fname[0] ==
'@')
1595 get_method_file_map (full_name, fname.substr (1));
1596 else if (fname[0] ==
'+')
1597 get_package_dir (full_name, fname.substr (1));
1599 else if (sys::file_exists (full_name))
1601 all_files[all_files_count++] = fname;
1603 std::size_t pos = fname.rfind (
'.');
1605 if (pos != std::string::npos)
1607 std::string ext = fname.substr (pos);
1609 if (ext ==
".m" || ext ==
".oct" || ext ==
".mex")
1611 std::string base = fname.substr (0, pos);
1614 fcn_files[fcn_files_count++] = fname;
1620 all_files.resize (all_files_count);
1621 fcn_files.resize (fcn_files_count);
1625load_path::dir_info::get_private_file_map (
const std::string&
d)
1631load_path::dir_info::get_method_file_map (
const std::string&
d,
1632 const std::string& class_name)
1636 std::string pd = sys::file_ops::concat (
d,
"private");
1638 if (sys::dir_exists (pd))
1639 method_file_map[class_name].private_file_map =
get_fcn_files (pd);
1643load_path::dir_info::get_package_dir (
const std::string&
d,
1644 const std::string& package_name)
1646 package_dir_map[package_name] = dir_info (
d);
1650load_path::package_info::move (
const dir_info& di,
bool at_end)
1652 std::string dir_name = di.abs_dir_name;
1654 auto s = std::find (m_dir_list.begin (), m_dir_list.end (), dir_name);
1656 if (s != m_dir_list.end ())
1658 m_dir_list.erase (s);
1661 m_dir_list.push_back (dir_name);
1663 m_dir_list.push_front (dir_name);
1666 move_fcn_map (dir_name, di.fcn_files, at_end);
1670 move_method_map (dir_name, at_end);
1674load_path::package_info::remove (
const dir_info& di)
1676 std::string dir = di.abs_dir_name;
1680 m_dir_list.remove (dir);
1682 remove_fcn_map (dir, fcn_files);
1684 remove_private_fcn_map (dir);
1686 remove_method_map (dir);
1690load_path::package_info::display (std::ostream& os)
const
1692 os <<
"*** package_info: "
1693 << (m_package_name.empty () ?
"<top-level>" : m_package_name)
1696 for (
const auto& dir : m_dir_list)
1700 for (
const auto& dir_fnlst : m_private_fcn_map)
1702 os <<
"\n*** private functions in "
1703 << sys::file_ops::concat (dir_fnlst.first,
"private")
1706 print_fcn_list (os, dir_fnlst.second);
1709#if defined (DEBUG_LOAD_PATH)
1711 for (
const auto& nm_filst : m_fcn_map)
1713 os << nm_filst.first <<
":\n";
1715 const file_info_list_type& file_info_list = nm_filst.second;
1717 for (
const auto& finfo : file_info_list)
1719 os <<
" " << finfo.dir_name <<
" (";
1721 print_types (os, finfo.types);
1727 for (
const auto& cls_fnmap : m_method_map)
1729 os <<
"CLASS " << cls_fnmap.first <<
":\n";
1731 const fcn_map_type& fm = cls_fnmap.second;
1733 for (
const auto& nm_fnlst : m_fcn_map)
1735 os <<
" " << nm_fnlst.first <<
":\n";
1737 const file_info_list_type& file_info_list = nm_fnlst.second;
1739 for (
const auto& finfo : file_info_list)
1741 os <<
" " << finfo.dir_name <<
" (";
1743 print_types (os, finfo.types);
1756load_path::package_info::find_fcn (
const std::string& fcn,
1757 std::string& dir_name,
1764 if (fcn.length () > 0 && fcn[0] ==
'@')
1766 std::size_t pos = fcn.find (
'/');
1768 if (pos != std::string::npos)
1770 std::string class_name = fcn.substr (1, pos-1);
1771 std::string meth = fcn.substr (pos+1);
1773 retval = find_method (class_name, meth, dir_name);
1781 const_fcn_map_iterator p = m_fcn_map.find (fcn);
1783 if (p != m_fcn_map.end ())
1785 const file_info_list_type& file_info_list = p->second;
1787 for (
const auto& fi : file_info_list)
1789 retval = sys::file_ops::concat (fi.dir_name, fcn);
1791 if (check_file_type (retval, type, fi.types,
1792 fcn,
"load_path::find_fcn"))
1794 dir_name = fi.dir_name;
1807load_path::package_info::find_private_fcn (
const std::string& dir,
1808 const std::string& fcn,
1815 const_private_fcn_map_iterator q = m_private_fcn_map.find (dir);
1817 if (q != m_private_fcn_map.end ())
1819 const dir_info::fcn_file_map_type& fcn_file_map = q->second;
1821 dir_info::const_fcn_file_map_iterator p = fcn_file_map.find (fcn);
1823 if (p != fcn_file_map.end ())
1826 = sys::file_ops::concat (sys::file_ops::concat (dir,
"private"),
1829 if (check_file_type (fname, type, p->second, fcn,
1830 "load_path::find_private_fcn"))
1839load_path::package_info::find_method (
const std::string& class_name,
1840 const std::string& meth,
1841 std::string& dir_name,
1851 const_method_map_iterator q = m_method_map.find (class_name);
1853 if (q != m_method_map.end ())
1855 const fcn_map_type& m = q->second;
1857 const_fcn_map_iterator p = m.find (meth);
1861 const file_info_list_type& file_info_list = p->second;
1863 for (
const auto& fi : file_info_list)
1865 retval = sys::file_ops::concat (fi.dir_name, meth);
1867 bool found = check_file_type (retval, type, fi.types,
1868 meth,
"load_path::find_method");
1872 dir_name = fi.dir_name;
1884std::list<std::string>
1885load_path::package_info::methods (
const std::string& class_name)
const
1887 std::list<std::string> retval;
1891 const_method_map_iterator mtd_map_it = m_method_map.find (class_name);
1893 if (mtd_map_it != m_method_map.end ())
1895 for (
const auto& nm_filst : mtd_map_it->second)
1896 retval.push_back (nm_filst.first);
1899 if (! retval.empty ())
1906load_path::package_info::overloads (
const std::string& meth,
1907 std::list<std::string>& l)
const
1909 for (
const auto& cls_fnmap : m_method_map)
1911 const fcn_map_type& m = cls_fnmap.second;
1913 if (m.find (meth) != m.end ())
1915 std::string class_name = cls_fnmap.first;
1917 if (! m_package_name.empty ())
1918 class_name = m_package_name +
'.' + class_name;
1920 l.push_back (class_name);
1926load_path::package_info::fcn_names ()
const
1928 std::size_t
len = m_fcn_map.size ();
1934 for (
const auto& nm_filst : m_fcn_map)
1935 retval[count++] = nm_filst.first;
1941load_path::package_info::add_to_fcn_map (
const dir_info& di,
1942 bool at_end,
bool updating)
1944 std::string dir_name = di.abs_dir_name;
1952 std::string fname = fcn_files[i];
1955 std::string base = fname;
1957 std::size_t pos = fname.rfind (
'.');
1959 if (pos != std::string::npos)
1961 base = fname.substr (0, pos);
1962 ext = fname.substr (pos);
1965 file_info_list_type& file_info_list = m_fcn_map[base];
1967 auto p = file_info_list.begin ();
1969 while (p != file_info_list.end ())
1971 if (p->dir_name == dir_name)
1980 else if (ext ==
".oct")
1982 else if (ext ==
".mex")
1985 if (p == file_info_list.end ())
1992 if (file_info_list.empty ())
1998 std::string fcn_path = sys::file_ops::concat (dir_name,
2002 "function %s shadows a built-in function",
2008 file_info& old = file_info_list.front ();
2017 if (fname !=
"Contents.m"
2018 && s_sys_path.find (old.dir_name) != std::string::npos
2019 && in_path_list (s_sys_path, old.dir_name))
2021 std::string fcn_path = sys::file_ops::concat (dir_name,
2025 "function %s shadows a core library function",
2034 file_info_list.push_back (fi);
2036 file_info_list.push_front (fi);
2048load_path::package_info::add_to_private_fcn_map (
const dir_info& di)
2050 dir_info::fcn_file_map_type private_file_map = di.private_file_map;
2052 if (! private_file_map.empty ())
2053 m_private_fcn_map[di.abs_dir_name] = private_file_map;
2057load_path::package_info::add_to_method_map (
const dir_info& di,
bool at_end)
2059 std::string dir_name = di.abs_dir_name;
2062 dir_info::method_file_map_type method_file_map = di.method_file_map;
2064 for (
const auto& cls_ci : method_file_map)
2066 std::string class_name = cls_ci.first;
2068 fcn_map_type& fm = m_method_map[class_name];
2070 std::string full_dir_name
2071 = sys::file_ops::concat (dir_name,
'@' + class_name);
2073 const dir_info::class_info& ci = cls_ci.second;
2076 const dir_info::fcn_file_map_type& m = ci.method_file_map;
2078 for (
const auto& nm_typ : m)
2080 std::string base = nm_typ.first;
2081 int types = nm_typ.second;
2083 file_info_list_type& file_info_list = fm[base];
2085 auto p2 = file_info_list.begin ();
2086 while (p2 != file_info_list.end ())
2088 if (p2->dir_name == full_dir_name)
2094 if (p2 == file_info_list.end ())
2099 file_info_list.push_back (fi);
2101 file_info_list.push_front (fi);
2113 dir_info::fcn_file_map_type private_file_map = ci.private_file_map;
2115 if (! private_file_map.empty ())
2116 m_private_fcn_map[full_dir_name] = private_file_map;
2121load_path::package_info::move_fcn_map (
const std::string& dir_name,
2129 std::string fname = fcn_files[k];
2132 std::string base = fname;
2134 std::size_t pos = fname.rfind (
'.');
2136 if (pos != std::string::npos)
2138 base = fname.substr (0, pos);
2139 ext = fname.substr (pos);
2142 file_info_list_type& file_info_list = m_fcn_map[base];
2144 if (file_info_list.size () == 1)
2148 for (
auto fi_it = file_info_list.begin ();
2149 fi_it != file_info_list.end ();
2152 if (fi_it->dir_name == dir_name)
2156 file_info_list.erase (fi_it);
2159 file_info_list.push_back (fi_tmp);
2161 file_info_list.push_front (fi_tmp);
2171load_path::package_info::move_method_map (
const std::string& dir_name,
2174 for (
auto& cls_fnmap : m_method_map)
2176 std::string class_name = cls_fnmap.first;
2178 fcn_map_type& fn_map = cls_fnmap.second;
2180 std::string full_dir_name
2181 = sys::file_ops::concat (dir_name,
'@' + class_name);
2183 for (
auto& nm_filst : fn_map)
2185 file_info_list_type& file_info_list = nm_filst.second;
2187 if (file_info_list.size () == 1)
2191 for (
auto fi_it = file_info_list.begin ();
2192 fi_it != file_info_list.end (); fi_it++)
2194 if (fi_it->dir_name == full_dir_name)
2198 file_info_list.erase (fi_it);
2201 file_info_list.push_back (fi_tmp);
2203 file_info_list.push_front (fi_tmp);
2214load_path::package_info::remove_fcn_map (
const std::string& dir,
2221 std::string fname = fcn_files[k];
2224 std::string base = fname;
2226 std::size_t pos = fname.rfind (
'.');
2228 if (pos != std::string::npos)
2230 base = fname.substr (0, pos);
2231 ext = fname.substr (pos);
2234 file_info_list_type& file_info_list = m_fcn_map[base];
2236 for (
auto fi_it = file_info_list.begin ();
2237 fi_it != file_info_list.end ();
2240 if (fi_it->dir_name == dir)
2242 file_info_list.erase (fi_it);
2244 if (file_info_list.empty ())
2245 m_fcn_map.erase (fname);
2254load_path::package_info::remove_private_fcn_map (
const std::string& dir)
2256 auto p = m_private_fcn_map.find (dir);
2258 if (p != m_private_fcn_map.end ())
2259 m_private_fcn_map.erase (p);
2263load_path::package_info::remove_method_map (
const std::string& dir)
2265 for (
auto& cls_fnmap : m_method_map)
2267 std::string class_name = cls_fnmap.first;
2269 fcn_map_type& fn_map = cls_fnmap.second;
2271 std::string full_dir_name
2272 = sys::file_ops::concat (dir,
'@' + class_name);
2274 for (
auto& nm_filst : fn_map)
2276 file_info_list_type& file_info_list = nm_filst.second;
2278 if (file_info_list.size () == 1)
2282 for (
auto fi_it = file_info_list.begin ();
2283 fi_it != file_info_list.end (); fi_it++)
2285 if (fi_it->dir_name == full_dir_name)
2287 file_info_list.erase (fi_it);
2301load_path::package_info::check_file_type (std::string& fname,
int type,
2303 const std::string& fcn,
2304 const char *who)
const
2306 bool retval =
false;
2391 error (
"%s: %s: invalid type code = %d", who, fcn.c_str (), type);
2397load_path::package_info::print_types (std::ostream& os,
int types)
const
2399 bool printed_type =
false;
2404 printed_type =
true;
2412 printed_type =
true;
2420 printed_type =
true;
2425load_path::package_info::print_fcn_list (std::ostream& os,
2426 const load_path::dir_info::fcn_file_map_type& lst)
const
2428 for (
const auto& nm_typ : lst)
2430 os <<
" " << nm_typ.first <<
" (";
2432 print_types (os, nm_typ.second);
2445 if (! sys::get_dirlist (
dirname, dirlist, msg))
2450 dirlist = dirlist.
sort (
false);
2456 std::string elt = dirlist[i];
2458 bool skip_p = (elt ==
"." || elt ==
".." || elt[0] ==
'@'
2465 skip_p = (elt == skip[j]);
2472 std::string nm = sys::file_ops::concat (
dirname, elt);
2474 if (sys::dir_exists (nm))
2499 int nargin = args.length ();
2508 std::string
dirname = args(0).xstring_value (
"genpath: DIR must be a string");
2514 std::string
dirname = args(0).xstring_value (
"genpath: all arguments must be strings");
2519 skip[i-1] = args(i).xstring_value (
"genpath: all arguments must be strings");
2533 load_path& lp = interp.get_load_path ();
2540DEFMETHOD (command_line_path, interp, args, ,
2549 if (! args.empty ())
2552 load_path& lp = interp.get_load_path ();
2557DEFMETHOD (restoredefaultpath, interp, args, ,
2566 if (! args.empty ())
2569 load_path& lp = interp.get_load_path ();
2587 load_path& lp = interp.get_load_path ();
2613 int nargin = args.length ();
2617 load_path& lp = interp.get_load_path ();
2621 std::string path = argv[1];
2623 for (
int i = 2; i <= nargin; i++)
2626 lp.
set (path,
true);
2633 else if (nargin == 0 && nargout == 0)
2636 "\nOctave's search path contains the following directories:\n\n";
2648DEFMETHOD (addpath, interp, args, nargout,
2683 int nargin = args.length ();
2688 load_path& lp = interp.get_load_path ();
2693 retval = lp.
path ();
2695 bool append =
false;
2703 if (option ==
"-end")
2708 else if (option ==
"-begin")
2713 int val = option_arg.
strict_int_value (
"addpath: OPTION must be '-begin'/0 or '-end'/1");
2723 error (
"addpath: OPTION must be '-begin'/0 or '-end'/1");
2726 bool need_to_update =
false;
2732 for (
int i = 0; i < arglist.
length (); i++)
2734 std::string arg = arglist(i).xstring_value (
"addpath: all arguments must be strings");
2736 std::list<std::string> dir_elts = split_path (arg);
2739 std::reverse (dir_elts.begin (), dir_elts.end ());
2741 for (
auto dir : dir_elts)
2744 auto it_start = dir.begin ();
2745#if defined (OCTAVE_HAVE_WINDOWS_FILESYSTEM)
2749 dir.erase (std::unique
2750 (it_start, dir.end (),
2753 return l == r && sys::file_ops::is_dir_sep (l);
2757 auto pos = dir.find_last_of (sys::file_ops::dir_sep_chars ());
2758 if (pos == std::string::npos)
2760 if (! dir.empty () && dir[0] ==
'+')
2762 "addpath: package directories should not be "
2763 "added to path: %s\n", dir.c_str ());
2767 if (pos + 1 < dir.length () && dir[pos+1] ==
'+')
2769 "addpath: package directories should not be "
2770 "added to path: %s\n", dir.c_str ());
2778 need_to_update =
true;
2788DEFMETHOD (rmpath, interp, args, nargout,
2811 int nargin = args.
length ();
2818 load_path& lp = interp.get_load_path ();
2821 retval = lp.
path ();
2823 bool need_to_update =
false;
2825 for (
int i = 0; i < nargin; i++)
2827 std::string arg = args(i).xstring_value (
"rmpath: all arguments must be strings");
2828 std::list<std::string> dir_elts = split_path (arg);
2830 for (
const auto& dir : dir_elts)
2836 warning (
"rmpath: %s: not found", dir.c_str ());
2838 need_to_update =
true;
2848DEFMETHOD (__dump_load_path__, interp, , ,
2854 load_path& lp = interp.get_load_path ();
2861OCTAVE_END_NAMESPACE(octave)
static std::string path_sep_str()
static char path_sep_char()
Provides threadsafe access to octave.
void update_path_dialog()
int debug_cd_or_addpath_error(const std::string &file, const std::string &dir, bool addpath_option)
symbol_scope get_current_scope() const
int chdir(const std::string &dir)
void recover_from_exception()
event_manager & get_event_manager()
std::string find_first_of(const string_vector &files) const
string_vector files(const std::string &dir, bool omit_exts=false) const
string_vector find_matching_dirs(const std::string &dir) const
void set(const std::string &p, bool warn=false, bool is_init=false)
load_path(interpreter &interp)
bool contains_canonical(const std::string &dir_name) const
string_vector fcn_names() const
string_vector find_all_first_of(const string_vector &files) const
void prepend(const std::string &dir, bool warn=false)
void initialize(bool set_initial_path=false)
std::string find_file(const std::string &file) const
string_vector dirs() const
std::string system_path() const
void display(std::ostream &os) const
void read_dir_config(const std::string &dir) const
void execute_pkg_add(const std::string &dir)
bool remove(const std::string &dir)
std::string find_dir(const std::string &dir) const
std::list< std::string > overloads(const std::string &meth) const
bool contains_file_in_dir(const std::string &file_name, const std::string &dir_name)
void append(const std::string &dir, bool warn=false)
static const int OCT_FILE
void execute_pkg_del(const std::string &dir)
std::list< std::string > get_all_package_names(bool only_top_level=true) const
std::string get_command_line_path() const
std::list< std::string > dir_list() const
static const int MEX_FILE
std::string dir_name() const
octave_value_list & reverse()
octave_idx_type length() const
int strict_int_value(bool frc_str_conv=false) const
std::string string_value(bool force=false) const
octave_idx_type length() const
string_vector & sort(bool make_uniq=false)
void resize(octave_idx_type n, const std::string &rfv="")
std::ostream & list_in_columns(std::ostream &, int width=0, const std::string &prefix="") const
octave_idx_type numel() const
octave_user_code * user_code() const
bool is_built_in_function_name(const std::string &name)
OCTAVE_BEGIN_NAMESPACE(octave) static octave_value daspk_fcn
#define DEFMETHOD(name, interp_name, args_name, nargout_name, doc)
Macro to define a builtin method.
#define DEFUN(name, args_name, nargout_name, doc)
Macro to define a builtin function.
void warning(const char *fmt,...)
void warning_with_id(const char *id, const char *fmt,...)
void error(const char *fmt,...)
std::string dirname(const std::string &path)
symbol_table & __get_symbol_table__()
input_system & __get_input_system__()
interpreter & __get_interpreter__()
bool octave_interpreter_ready
F77_RET_T const F77_DBLE const F77_DBLE F77_DBLE * d
std::string fgets(FILE *f)
std::string genpath(const std::string &dirname, const string_vector &skip)
load_path::dir_info::fcn_file_map_type get_fcn_files(const std::string &d)
void source_file(const std::string &file_name, const std::string &context, bool verbose, bool require_file)
octave_value_list ovl(const OV_Args &... args)
Construct an octave_value_list with less typing.
fcn_file_map_type method_file_map
bool valid_identifier(const char *s)