26 #if defined (HAVE_CONFIG_H)
38 #if ! defined (OCTAVE_USE_WINDOWS_API)
61 maybe_canonicalize (
const std::string& dir_arg)
63 bool is_absolute_path = sys::env::absolute_pathname (dir_arg);
67 if (canonical_dir.empty ())
73 if (! is_absolute_path)
78 if (dir.compare (0, cwd.length (), cwd) == 0)
79 dir.erase (0, cwd.length ()+1);
89 maybe_add_path_elts (std::string& path,
const std::string& dir)
91 std::string tpath =
genpath (maybe_canonicalize (dir));
102 static std::list<std::string>
103 split_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);
138 strip_trailing_separators (
const std::string& dir_arg)
140 std::string dir = dir_arg;
142 std::size_t k = dir.length ();
147 if (k < dir.length ())
156 in_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);
203 subdirs_modified (
const std::string&
d,
const sys::file_time& last_checked)
205 sys::dir_entry dir (
d);
215 std::string fname = flist[i];
221 #if defined (OCTAVE_USE_WINDOWS_API)
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 ());
249 std::string load_path::s_sys_path;
250 load_path::abs_dir_cache_type load_path::s_abs_dir_cache;
253 : m_add_hook ([=] (const std::string& dir) { this->
execute_pkg_add (dir); }),
254 m_remove_hook ([=] (
const std::string& dir) { this->
execute_pkg_del (dir); }),
255 m_interpreter (interp), m_package_map (), m_top_level_package (),
256 m_dir_info_list (), m_init_dirs (), m_command_line_path ()
264 if (set_initial_path)
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)
351 for (
auto& di : m_dir_info_list)
354 m_add_hook (di.dir_name);
365 add (dir,
true, warn);
372 add (dir,
false, warn);
380 if (! dir_arg.empty ())
384 warning (R
"(rmpath: can't remove "." from path)");
393 dir = strip_trailing_separators (dir);
395 auto i = find_dir_info (dir);
397 if (i != m_dir_info_list.end ())
408 m_dir_info_list.erase (i);
423 m_top_level_package.clear ();
425 m_package_map.clear ();
427 for (dir_info_list_iterator di = m_dir_info_list.begin ();
428 di != m_dir_info_list.end ();)
430 bool ok = di->update ();
435 (
"Octave:load-path:update-failed",
436 "load-path: update failed for '%s', removing from path",
437 di->dir_name.c_str ());
440 m_remove_hook (di->dir_name.c_str ());
444 di = m_dir_info_list.erase (di);
448 add (*di,
true,
"",
true);
459 for (
const auto&
d : m_dir_info_list)
473 const std::string& dir)
476 bool addpath_option =
true;
478 std::string curr_dir = sys::env::get_current_directory ();
487 std::string base_file = (file.length () > dir.length ())
488 ? file.substr (dir.length () + 1)
489 : sys::env::base_pathname (file);
491 std::string lp_file =
find_file (base_file);
493 if (dir_in_load_path)
511 addpath_option =
false;
526 m_interpreter.
chdir (dir);
545 std::list<std::string>
548 std::list<std::string> retval;
552 m_top_level_package.overloads (meth, retval);
554 for (
const auto& nm_ldr : m_package_map)
555 nm_ldr.second.overloads (meth, retval);
560 std::list<std::string>
563 std::list<std::string> retval;
565 for (
const auto& dir_ldr : m_package_map)
567 if (! only_top_level || dir_ldr.first.find (
'.') == std::string::npos)
568 retval.push_back (dir_ldr.first);
579 if (sys::env::absolute_pathname (file)
580 || sys::env::rooted_relative_pathname (file))
584 std::string tfile = find_private_file (file);
586 if (! tfile.empty ())
591 != std::string::npos)
595 for (
const auto& di : m_dir_info_list)
606 for (
const auto& di : m_dir_info_list)
614 if (all_files[i] == file)
629 && (sys::env::absolute_pathname (dir)
630 || sys::env::rooted_relative_pathname (dir)))
637 std::string canon_dir = maybe_canonicalize (dir);
638 for (
const auto& di : m_dir_info_list)
640 std::string dname = di.abs_dir_name;
642 std::size_t dname_len = dname.length ();
644 if (dname.substr (dname_len - 1)
647 dname = dname.substr (0, dname_len - 1);
651 std::size_t dir_len = canon_dir.length ();
653 if (dname_len > dir_len
655 && canon_dir == dname.substr (dname_len - dir_len)
657 return di.abs_dir_name;
667 std::list<std::string> retlist;
670 && (sys::env::absolute_pathname (dir)
671 || sys::env::rooted_relative_pathname (dir)))
674 retlist.push_back (dir);
678 std::string canon_dir = maybe_canonicalize (dir);
679 for (
const auto& di : m_dir_info_list)
681 std::string dname = di.abs_dir_name;
683 std::size_t dname_len = dname.length ();
685 if (dname.substr (dname_len - 1)
688 dname = dname.substr (0, dname_len - 1);
692 std::size_t dir_len = canon_dir.length ();
694 if (dname_len > dir_len
696 && canon_dir == dname.substr (dname_len - dir_len)
698 retlist.push_back (di.abs_dir_name);
710 std::string dir_name;
711 std::string file_name;
720 std::string file = flist[i];
723 != std::string::npos)
725 if (sys::env::absolute_pathname (file)
726 || sys::env::rooted_relative_pathname (file))
733 for (
const auto& di : m_dir_info_list)
744 rel_flist[rel_flen++] = file;
747 rel_flist.
resize (rel_flen);
749 for (
const auto& di : m_dir_info_list)
759 if (all_files[i] == rel_flist[j])
761 dir_name = di.abs_dir_name;
762 file_name = rel_flist[j];
772 if (! dir_name.empty ())
781 std::list<std::string> retlist;
783 std::string dir_name;
784 std::string file_name;
793 std::string file = flist[i];
796 != std::string::npos)
798 if (sys::env::absolute_pathname (file)
799 || sys::env::rooted_relative_pathname (file))
802 retlist.push_back (file);
806 for (
const auto& di : m_dir_info_list)
812 retlist.push_back (tfile);
817 rel_flist[rel_flen++] = file;
820 rel_flist.
resize (rel_flen);
822 for (
const auto& di : m_dir_info_list)
832 if (all_files[i] == rel_flist[j])
845 std::size_t
len = m_dir_info_list.size ();
851 for (
const auto& di : m_dir_info_list)
852 retval[k++] = di.dir_name;
857 std::list<std::string>
860 std::list<std::string> retval;
862 for (
const auto& di : m_dir_info_list)
863 retval.push_back (di.dir_name);
873 const_dir_info_list_iterator p = find_dir_info (dir);
875 if (p != m_dir_info_list.end ())
876 retval = p->fcn_files;
884 std::string fname = retval[i];
886 std::size_t pos = fname.rfind (
'.');
888 if (pos != std::string::npos)
889 retval[i] = fname.substr (0, pos);
899 return m_top_level_package.fcn_names ();
923 for (
const auto& di : m_dir_info_list)
927 if (! fcn_files.
empty ())
929 os <<
"\n*** function files in " << di.dir_name <<
":\n\n";
934 const dir_info::method_file_map_type& method_file_map
935 = di.method_file_map;
937 if (! method_file_map.empty ())
939 for (
const auto& cls_ci : method_file_map)
941 os <<
"\n*** methods in " << di.dir_name
942 <<
"/@" << cls_ci.first <<
":\n\n";
953 m_top_level_package.display (os);
955 for (
const auto& nm_ldr : m_package_map)
956 nm_ldr.second.display (os);
962 execute_pkg_add_or_del (dir,
"PKG_ADD");
968 execute_pkg_add_or_del (dir,
"PKG_DEL");
990 load_path::execute_pkg_add_or_del (
const std::string& dir,
991 const std::string& script_file)
1005 load_path::const_dir_info_list_iterator
1006 load_path::find_dir_info (
const std::string& dir_arg)
const
1010 dir = maybe_canonicalize (dir);
1012 auto retval = m_dir_info_list.cbegin ();
1014 while (retval != m_dir_info_list.cend ())
1016 if (retval->dir_name == dir)
1025 load_path::dir_info_list_iterator
1026 load_path::find_dir_info (
const std::string& dir_arg)
1030 dir = maybe_canonicalize (dir);
1032 auto retval = m_dir_info_list.begin ();
1034 while (retval != m_dir_info_list.end ())
1036 if (retval->dir_name == dir)
1046 load_path::contains (
const std::string& dir)
const
1048 return find_dir_info (dir) != m_dir_info_list.end ();
1052 load_path::move (dir_info_list_iterator i,
bool at_end)
1054 if (m_dir_info_list.size () > 1)
1058 m_dir_info_list.erase (i);
1061 m_dir_info_list.push_back (di);
1063 m_dir_info_list.push_front (di);
1070 load_path::move (
const dir_info& di,
bool at_end,
const std::string& pname)
1072 package_info& l = get_package (pname);
1074 l.move (di, at_end);
1076 dir_info::package_dir_map_type package_dir_map = di.package_dir_map;
1078 for (
const auto& pkg_di : package_dir_map)
1080 std::string full_name = pkg_di.first;
1082 if (! pname.empty ())
1083 full_name = pname +
'.' + full_name;
1085 move (pkg_di.second, at_end, full_name);
1090 load_path::add (
const std::string& dir_arg,
bool at_end,
bool warn)
1092 std::size_t
len = dir_arg.length ();
1094 if (
len > 1 && dir_arg.substr (
len-2) ==
"//")
1096 "trailing '//' is no longer special in search path elements");
1100 dir = strip_trailing_separators (dir);
1102 dir = maybe_canonicalize (dir);
1104 auto i = find_dir_info (dir);
1106 if (i != m_dir_info_list.end ())
1119 m_dir_info_list.push_back (di);
1121 m_dir_info_list.push_front (di);
1129 if (warn && ! msg.empty ())
1130 warning (
"addpath: %s: %s", dir_arg.c_str (), msg.c_str ());
1135 i = find_dir_info (
".");
1137 if (i != m_dir_info_list.end ())
1144 package_info& l = get_package (pname);
1148 dir_info::package_dir_map_type package_dir_map = di.package_dir_map;
1150 for (
const auto& pkg_di : package_dir_map)
1152 std::string full_name = pkg_di.first;
1154 if (! pname.empty ())
1155 full_name = pname +
'.' + full_name;
1157 remove (pkg_di.second, full_name);
1178 std::string enc_val =
"delete";
1187 const std::string enc_prop =
"encoding";
1190 std::string conf_str =
fgets (cfile, eof);
1193 auto it = std::find_if_not (conf_str.begin (), conf_str.end (),
1194 [] (
unsigned char c)
1195 { return std::isblank (c); });
1196 conf_str.erase (conf_str.begin (), it);
1199 if (conf_str.compare (0, enc_prop.size (), enc_prop) == 0)
1202 std::size_t pos = conf_str.find_first_not_of (
" \t=:",
1204 if (pos == std::string::npos)
1207 std::string enc_val = conf_str.substr (pos);
1210 it = std::find_if_not (enc_val.begin (), enc_val.end (),
1211 [] (
unsigned char c)
1212 { return std::isalnum (c) || c ==
'-'; });
1213 enc_val.erase(it, enc_val.end ());
1215 if (enc_val.empty ())
1228 std::string enc_val =
"delete";
1234 load_path::is_package (
const std::string& name)
const
1236 for (
const auto& di : m_dir_info_list)
1238 if (di.is_package (name))
1246 load_path::add (
const dir_info& di,
bool at_end,
1247 const std::string& pname,
bool updating)
1249 package_info& l = get_package (pname);
1251 l.add (di, at_end, updating);
1253 dir_info::package_dir_map_type package_dir_map = di.package_dir_map;
1255 for (
const auto& pkg_di : package_dir_map)
1257 std::string full_name = pkg_di.first;
1259 if (! pname.empty ())
1260 full_name = pname +
'.' + full_name;
1262 add (pkg_di.second, at_end, full_name);
1267 load_path::get_file_list (
const load_path::dir_info::fcn_file_map_type& lst)
const
1275 for (
const auto& nm_typ : lst)
1277 std::string nm = nm_typ.first;
1279 int types = nm_typ.second;
1288 retval[count++] = nm;
1298 load_path::find_private_file (
const std::string& fname)
const
1315 std::string dir_name = curr_code->
dir_name ();
1317 if (! dir_name.empty ())
1331 load_path::dir_info::fcn_file_map_type
1334 load_path::dir_info::fcn_file_map_type retval;
1340 warning (
"load_path: %s: %s",
d.c_str (), msg.c_str ());
1347 std::string fname = flist[i];
1349 std::size_t pos = fname.rfind (
'.');
1351 if (pos != std::string::npos)
1353 std::string base = fname.substr (0, pos);
1354 std::string ext = fname.substr (pos);
1362 else if (ext ==
".oct")
1364 else if (ext ==
".mex")
1369 load_path::dir_info::fcn_file_map_iterator p
1370 = retval.find (base);
1372 if (p == retval.end ())
1386 load_path::dir_info::update ()
1388 #if defined (OCTAVE_USE_WINDOWS_API)
1394 sys::file_stat fs (dir_name);
1398 std::string msg = fs.error ();
1401 "load_path: %s: %s", dir_name.c_str (), msg.c_str ());
1412 const_abs_dir_cache_iterator p = s_abs_dir_cache.find (abs_name);
1414 if (p != s_abs_dir_cache.end ())
1421 const dir_info& di = p->second;
1423 #if defined (OCTAVE_USE_WINDOWS_API)
1424 if ((sys::file_time (dir_name)
1426 if ((sys::file_time (fs.mtime ().unix_time ())
1428 + sys::file_time::time_resolution ()
1429 > di.dir_time_last_checked)
1430 || subdirs_modified (dir_name, dir_time_last_checked))
1436 abs_dir_name = di.abs_dir_name;
1437 dir_mtime = di.dir_mtime;
1438 dir_time_last_checked = di.dir_time_last_checked;
1439 all_files = di.all_files;
1440 fcn_files = di.fcn_files;
1441 private_file_map = di.private_file_map;
1442 method_file_map = di.method_file_map;
1443 package_dir_map = di.package_dir_map;
1463 #if defined (OCTAVE_USE_WINDOWS_API)
1464 else if (sys::file_time (dir_name)
1466 else if (sys::file_time (fs.mtime ().unix_time ())
1468 + sys::file_time::time_resolution () > dir_time_last_checked
1469 || subdirs_modified (dir_name, dir_time_last_checked))
1476 load_path::dir_info::is_package (
const std::string& name)
const
1478 std::size_t pos = name.find (
'.');
1480 if (pos == std::string::npos)
1481 return package_dir_map.find (name) != package_dir_map.end ();
1484 std::string name_head = name.substr (0, pos);
1485 std::string name_tail = name.substr (pos + 1);
1487 const_package_dir_map_iterator it = package_dir_map.find (name_head);
1489 if (it != package_dir_map.end ())
1490 return it->second.is_package (name_tail);
1497 load_path::dir_info::initialize ()
1499 is_relative = ! sys::env::absolute_pathname (dir_name);
1501 dir_time_last_checked = sys::file_time (
static_cast<OCTAVE_TIME_T
> (0));
1503 #if defined (OCTAVE_USE_WINDOWS_API)
1508 sys::file_stat fs (dir_name);
1513 method_file_map.clear ();
1514 package_dir_map.clear ();
1516 #if defined (OCTAVE_USE_WINDOWS_API)
1517 dir_mtime = sys::file_time (dir_name);
1519 dir_mtime = fs.mtime ().unix_time ();
1522 dir_time_last_checked = sys::file_time ();
1524 get_file_list (dir_name);
1534 s_abs_dir_cache[abs_dir_name] = *
this;
1548 #if ! defined (OCTAVE_USE_WINDOWS_API)
1549 std::string msg = fs.error ();
1551 warning (
"load_path: %s: %s", dir_name.c_str (), msg.c_str ());
1556 load_path::dir_info::get_file_list (
const std::string&
d)
1563 warning (
"load_path: %s: %s",
d.c_str (), msg.c_str ());
1569 all_files.resize (
len);
1570 fcn_files.resize (
len);
1577 std::string fname = flist[i];
1583 if (fname ==
"private")
1584 get_private_file_map (full_name);
1585 else if (fname[0] ==
'@')
1586 get_method_file_map (full_name, fname.substr (1));
1587 else if (fname[0] ==
'+')
1588 get_package_dir (full_name, fname.substr (1));
1592 all_files[all_files_count++] = fname;
1594 std::size_t pos = fname.rfind (
'.');
1596 if (pos != std::string::npos)
1598 std::string ext = fname.substr (pos);
1600 if (ext ==
".m" || ext ==
".oct" || ext ==
".mex")
1602 std::string base = fname.substr (0, pos);
1605 fcn_files[fcn_files_count++] = fname;
1611 all_files.resize (all_files_count);
1612 fcn_files.resize (fcn_files_count);
1616 load_path::dir_info::get_private_file_map (
const std::string&
d)
1622 load_path::dir_info::get_method_file_map (
const std::string&
d,
1623 const std::string& class_name)
1630 method_file_map[class_name].private_file_map =
get_fcn_files (pd);
1634 load_path::dir_info::get_package_dir (
const std::string&
d,
1635 const std::string& package_name)
1637 package_dir_map[package_name] = dir_info (
d);
1641 load_path::package_info::move (
const dir_info& di,
bool at_end)
1643 std::string dir_name = di.abs_dir_name;
1645 auto s = std::find (m_dir_list.begin (), m_dir_list.end (), dir_name);
1647 if (s != m_dir_list.end ())
1649 m_dir_list.erase (s);
1652 m_dir_list.push_back (dir_name);
1654 m_dir_list.push_front (dir_name);
1657 move_fcn_map (dir_name, di.fcn_files, at_end);
1661 move_method_map (dir_name, at_end);
1665 load_path::package_info::remove (
const dir_info& di)
1667 std::string dir = di.abs_dir_name;
1671 m_dir_list.remove (dir);
1673 remove_fcn_map (dir, fcn_files);
1675 remove_private_fcn_map (dir);
1677 remove_method_map (dir);
1681 load_path::package_info::display (std::ostream& os)
const
1683 os <<
"*** package_info: "
1684 << (m_package_name.empty () ?
"<top-level>" : m_package_name)
1687 for (
const auto& dir : m_dir_list)
1691 for (
const auto& dir_fnlst : m_private_fcn_map)
1693 os <<
"\n*** private functions in "
1697 print_fcn_list (os, dir_fnlst.second);
1700 #if defined (DEBUG_LOAD_PATH)
1702 for (
const auto& nm_filst : m_fcn_map)
1704 os << nm_filst.first <<
":\n";
1706 const file_info_list_type& file_info_list = nm_filst.second;
1708 for (
const auto& finfo : file_info_list)
1710 os <<
" " << finfo.dir_name <<
" (";
1712 print_types (os, finfo.types);
1718 for (
const auto& cls_fnmap : m_method_map)
1720 os <<
"CLASS " << cls_fnmap.first <<
":\n";
1722 const fcn_map_type& fm = cls_fnmap.second;
1724 for (
const auto& nm_fnlst : m_fcn_map)
1726 os <<
" " << nm_fnlst.first <<
":\n";
1728 const file_info_list_type& file_info_list = nm_fnlst.second;
1730 for (
const auto& finfo : file_info_list)
1732 os <<
" " << finfo.dir_name <<
" (";
1734 print_types (os, finfo.types);
1747 load_path::package_info::find_fcn (
const std::string& fcn,
1748 std::string& dir_name,
1755 if (fcn.length () > 0 && fcn[0] ==
'@')
1757 std::size_t pos = fcn.find (
'/');
1759 if (pos != std::string::npos)
1761 std::string class_name = fcn.substr (1, pos-1);
1762 std::string meth = fcn.substr (pos+1);
1764 retval = find_method (class_name, meth, dir_name);
1772 const_fcn_map_iterator p = m_fcn_map.find (fcn);
1774 if (p != m_fcn_map.end ())
1776 const file_info_list_type& file_info_list = p->second;
1778 for (
const auto& fi : file_info_list)
1782 if (check_file_type (retval, type, fi.types,
1783 fcn,
"load_path::find_fcn"))
1785 dir_name = fi.dir_name;
1798 load_path::package_info::find_private_fcn (
const std::string& dir,
1799 const std::string& fcn,
1806 const_private_fcn_map_iterator q = m_private_fcn_map.find (dir);
1808 if (q != m_private_fcn_map.end ())
1810 const dir_info::fcn_file_map_type& fcn_file_map = q->second;
1812 dir_info::const_fcn_file_map_iterator p = fcn_file_map.find (fcn);
1814 if (p != fcn_file_map.end ())
1820 if (check_file_type (fname, type, p->second, fcn,
1821 "load_path::find_private_fcn"))
1830 load_path::package_info::find_method (
const std::string& class_name,
1831 const std::string& meth,
1832 std::string& dir_name,
1842 const_method_map_iterator q = m_method_map.find (class_name);
1844 if (q != m_method_map.end ())
1846 const fcn_map_type&
m = q->second;
1848 const_fcn_map_iterator p =
m.find (meth);
1852 const file_info_list_type& file_info_list = p->second;
1854 for (
const auto& fi : file_info_list)
1858 bool found = check_file_type (retval, type, fi.types,
1859 meth,
"load_path::find_method");
1863 dir_name = fi.dir_name;
1875 std::list<std::string>
1876 load_path::package_info::methods (
const std::string& class_name)
const
1878 std::list<std::string> retval;
1882 const_method_map_iterator mtd_map_it = m_method_map.find (class_name);
1884 if (mtd_map_it != m_method_map.end ())
1886 for (
const auto& nm_filst : mtd_map_it->second)
1887 retval.push_back (nm_filst.first);
1890 if (! retval.empty ())
1897 load_path::package_info::overloads (
const std::string& meth,
1898 std::list<std::string>& l)
const
1900 for (
const auto& cls_fnmap : m_method_map)
1902 const fcn_map_type&
m = cls_fnmap.second;
1904 if (
m.find (meth) !=
m.end ())
1906 std::string class_name = cls_fnmap.first;
1908 if (! m_package_name.empty ())
1909 class_name = m_package_name +
'.' + class_name;
1911 l.push_back (class_name);
1917 load_path::package_info::fcn_names ()
const
1919 std::size_t
len = m_fcn_map.size ();
1925 for (
const auto& nm_filst : m_fcn_map)
1926 retval[count++] = nm_filst.first;
1932 load_path::package_info::add_to_fcn_map (
const dir_info& di,
1933 bool at_end,
bool updating)
1935 std::string dir_name = di.abs_dir_name;
1943 std::string fname = fcn_files[i];
1946 std::string base = fname;
1948 std::size_t pos = fname.rfind (
'.');
1950 if (pos != std::string::npos)
1952 base = fname.substr (0, pos);
1953 ext = fname.substr (pos);
1956 file_info_list_type& file_info_list = m_fcn_map[base];
1958 auto p = file_info_list.begin ();
1960 while (p != file_info_list.end ())
1962 if (p->dir_name == dir_name)
1971 else if (ext ==
".oct")
1973 else if (ext ==
".mex")
1976 if (p == file_info_list.end ())
1983 if (file_info_list.empty ())
1993 "function %s shadows a built-in function",
1999 file_info& old = file_info_list.front ();
2008 if (fname !=
"Contents.m"
2009 && s_sys_path.find (old.dir_name) != std::string::npos
2010 && in_path_list (s_sys_path, old.dir_name))
2016 "function %s shadows a core library function",
2025 file_info_list.push_back (fi);
2027 file_info_list.push_front (fi);
2039 load_path::package_info::add_to_private_fcn_map (
const dir_info& di)
2041 dir_info::fcn_file_map_type private_file_map = di.private_file_map;
2043 if (! private_file_map.empty ())
2044 m_private_fcn_map[di.abs_dir_name] = private_file_map;
2048 load_path::package_info::add_to_method_map (
const dir_info& di,
bool at_end)
2050 std::string dir_name = di.abs_dir_name;
2053 dir_info::method_file_map_type method_file_map = di.method_file_map;
2055 for (
const auto& cls_ci : method_file_map)
2057 std::string class_name = cls_ci.first;
2059 fcn_map_type& fm = m_method_map[class_name];
2061 std::string full_dir_name
2064 const dir_info::class_info& ci = cls_ci.second;
2067 const dir_info::fcn_file_map_type&
m = ci.method_file_map;
2069 for (
const auto& nm_typ :
m)
2071 std::string base = nm_typ.first;
2072 int types = nm_typ.second;
2074 file_info_list_type& file_info_list = fm[base];
2076 auto p2 = file_info_list.begin ();
2077 while (p2 != file_info_list.end ())
2079 if (p2->dir_name == full_dir_name)
2085 if (p2 == file_info_list.end ())
2090 file_info_list.push_back (fi);
2092 file_info_list.push_front (fi);
2104 dir_info::fcn_file_map_type private_file_map = ci.private_file_map;
2106 if (! private_file_map.empty ())
2107 m_private_fcn_map[full_dir_name] = private_file_map;
2112 load_path::package_info::move_fcn_map (
const std::string& dir_name,
2120 std::string fname = fcn_files[k];
2123 std::string base = fname;
2125 std::size_t pos = fname.rfind (
'.');
2127 if (pos != std::string::npos)
2129 base = fname.substr (0, pos);
2130 ext = fname.substr (pos);
2133 file_info_list_type& file_info_list = m_fcn_map[base];
2135 if (file_info_list.size () == 1)
2139 for (
auto fi_it = file_info_list.begin ();
2140 fi_it != file_info_list.end ();
2143 if (fi_it->dir_name == dir_name)
2147 file_info_list.erase (fi_it);
2150 file_info_list.push_back (fi_tmp);
2152 file_info_list.push_front (fi_tmp);
2162 load_path::package_info::move_method_map (
const std::string& dir_name,
2165 for (
auto& cls_fnmap : m_method_map)
2167 std::string class_name = cls_fnmap.first;
2169 fcn_map_type& fn_map = cls_fnmap.second;
2171 std::string full_dir_name
2174 for (
auto& nm_filst : fn_map)
2176 file_info_list_type& file_info_list = nm_filst.second;
2178 if (file_info_list.size () == 1)
2182 for (
auto fi_it = file_info_list.begin ();
2183 fi_it != file_info_list.end (); fi_it++)
2185 if (fi_it->dir_name == full_dir_name)
2189 file_info_list.erase (fi_it);
2192 file_info_list.push_back (fi_tmp);
2194 file_info_list.push_front (fi_tmp);
2205 load_path::package_info::remove_fcn_map (
const std::string& dir,
2212 std::string fname = fcn_files[k];
2215 std::string base = fname;
2217 std::size_t pos = fname.rfind (
'.');
2219 if (pos != std::string::npos)
2221 base = fname.substr (0, pos);
2222 ext = fname.substr (pos);
2225 file_info_list_type& file_info_list = m_fcn_map[base];
2227 for (
auto fi_it = file_info_list.begin ();
2228 fi_it != file_info_list.end ();
2231 if (fi_it->dir_name == dir)
2233 file_info_list.erase (fi_it);
2235 if (file_info_list.empty ())
2236 m_fcn_map.erase (fname);
2245 load_path::package_info::remove_private_fcn_map (
const std::string& dir)
2247 auto p = m_private_fcn_map.find (dir);
2249 if (p != m_private_fcn_map.end ())
2250 m_private_fcn_map.erase (p);
2254 load_path::package_info::remove_method_map (
const std::string& dir)
2256 for (
auto& cls_fnmap : m_method_map)
2258 std::string class_name = cls_fnmap.first;
2260 fcn_map_type& fn_map = cls_fnmap.second;
2262 std::string full_dir_name
2265 for (
auto& nm_filst : fn_map)
2267 file_info_list_type& file_info_list = nm_filst.second;
2269 if (file_info_list.size () == 1)
2273 for (
auto fi_it = file_info_list.begin ();
2274 fi_it != file_info_list.end (); fi_it++)
2276 if (fi_it->dir_name == full_dir_name)
2278 file_info_list.erase (fi_it);
2292 load_path::package_info::check_file_type (std::string& fname,
int type,
2294 const std::string& fcn,
2295 const char *who)
const
2297 bool retval =
false;
2382 error (
"%s: %s: invalid type code = %d", who, fcn.c_str (), type);
2388 load_path::package_info::print_types (std::ostream& os,
int types)
const
2390 bool printed_type =
false;
2395 printed_type =
true;
2403 printed_type =
true;
2411 printed_type =
true;
2416 load_path::package_info::print_fcn_list (std::ostream& os,
2417 const load_path::dir_info::fcn_file_map_type& lst)
const
2419 for (
const auto& nm_typ : lst)
2421 os <<
" " << nm_typ.first <<
" (";
2423 print_types (os, nm_typ.second);
2441 dirlist = dirlist.
sort (
false);
2447 std::string elt = dirlist[i];
2449 bool skip_p = (elt ==
"." || elt ==
".." || elt[0] ==
'@'
2456 skip_p = (elt == skip[j]);
2490 int nargin = args.length ();
2499 std::string
dirname = args(0).xstring_value (
"genpath: DIR must be a string");
2505 std::string
dirname = args(0).xstring_value (
"genpath: all arguments must be strings");
2510 skip[i-1] = args(i).xstring_value (
"genpath: all arguments must be strings");
2524 load_path& lp = interp.get_load_path ();
2531 DEFMETHOD (command_line_path, interp, args, ,
2540 if (! args.empty ())
2543 load_path& lp = interp.get_load_path ();
2548 DEFMETHOD (restoredefaultpath, interp, args, ,
2557 if (! args.empty ())
2560 load_path& lp = interp.get_load_path ();
2578 load_path& lp = interp.get_load_path ();
2604 int nargin = args.length ();
2608 load_path& lp = interp.get_load_path ();
2612 std::string path = argv[1];
2614 for (
int i = 2; i <= nargin; i++)
2617 lp.
set (path,
true);
2624 else if (nargin == 0 && nargout == 0)
2627 "\nOctave's search path contains the following directories:\n\n";
2639 DEFMETHOD (addpath, interp, args, nargout,
2674 int nargin = args.length ();
2679 load_path& lp = interp.get_load_path ();
2684 retval = lp.
path ();
2686 bool append =
false;
2694 if (option ==
"-end")
2699 else if (option ==
"-begin")
2704 int val = option_arg.
xint_value (
"addpath: OPTION must be '-begin'/0 or '-end'/1");
2714 error (
"addpath: OPTION must be '-begin'/0 or '-end'/1");
2717 bool need_to_update =
false;
2723 for (
int i = 0; i < arglist.
length (); i++)
2725 std::string arg = arglist(i).xstring_value (
"addpath: all arguments must be strings");
2727 std::list<std::string> dir_elts = split_path (arg);
2730 std::reverse (dir_elts.begin (), dir_elts.end ());
2732 for (
auto dir : dir_elts)
2735 auto it_start = dir.begin ();
2736 #if defined (OCTAVE_HAVE_WINDOWS_FILESYSTEM)
2740 dir.erase (std::unique
2741 (it_start, dir.end (),
2744 return l == r && sys::file_ops::is_dir_sep (l);
2749 if (pos == std::string::npos)
2751 if (! dir.empty () && dir[0] ==
'+')
2753 "addpath: package directories should not be "
2754 "added to path: %s\n", dir.c_str ());
2758 if (pos + 1 < dir.length () && dir[pos+1] ==
'+')
2760 "addpath: package directories should not be "
2761 "added to path: %s\n", dir.c_str ());
2769 need_to_update =
true;
2779 DEFMETHOD (rmpath, interp, args, nargout,
2802 int nargin = args.length ();
2809 load_path& lp = interp.get_load_path ();
2812 retval = lp.
path ();
2814 bool need_to_update =
false;
2816 for (
int i = 0; i < nargin; i++)
2818 std::string arg = args(i).xstring_value (
"rmpath: all arguments must be strings");
2819 std::list<std::string> dir_elts = split_path (arg);
2821 for (
const auto& dir : dir_elts)
2827 warning (
"rmpath: %s: not found", dir.c_str ());
2829 need_to_update =
true;
2839 DEFMETHOD (__dump_load_path__, interp, , ,
2845 load_path& lp = interp.get_load_path ();
2852 OCTAVE_END_NAMESPACE(
octave)
ComplexNDArray concat(NDArray &ra, ComplexNDArray &rb, const Array< octave_idx_type > &ra_idx)
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)
event_manager & get_event_manager()
symbol_scope get_current_scope() const
int chdir(const std::string &dir)
void recover_from_exception()
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
std::string string_value(bool force=false) const
int xint_value(const char *fmt,...) 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
std::string local_oct_file_dir()
std::string local_fcn_file_dir()
std::string local_api_oct_file_dir()
std::string fcn_file_dir()
std::string local_api_fcn_file_dir()
std::string local_ver_fcn_file_dir()
std::string local_ver_oct_file_dir()
std::string oct_file_dir()
std::string oct_data_dir()
#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 dir_sep_str()
std::string dir_sep_chars()
std::string dirname(const std::string &path)
interpreter & __get_interpreter__()
input_system & __get_input_system__()
symbol_table & __get_symbol_table__()
bool octave_interpreter_ready
F77_RET_T const F77_DBLE const F77_DBLE F77_DBLE * d
bool dir_exists(const std::string &dirname)
std::FILE * fopen(const std::string &filename, const std::string &mode)
bool file_exists(const std::string &filename, bool is_dir)
bool get_dirlist(const std::string &dirname, string_vector &dirlist, std::string &msg)
bool same_file(const std::string &file1, const std::string &file2)
std::string fgets(FILE *f)
std::string genpath(const std::string &dir, const string_vector &skip="private")
std::string tilde_expand(const std::string &name)
std::string canonicalize_file_name(const std::string &name)
load_path::dir_info::fcn_file_map_type get_fcn_files(const std::string &d)
bool valid_identifier(const char *s)
octave_value_list ovl(const OV_Args &... args)
Construct an octave_value_list with less typing.
void source_file(const std::string &file_name, const std::string &context="", bool verbose=false, bool require_file=true)
fcn_file_map_type method_file_map