# HG changeset patch # User Markus Mützel # Date 1732542157 -3600 # Mon Nov 25 14:42:37 2024 +0100 # Node ID aa2fcd4eb181d62a58645fea1781d8e7f436e369 # Parent 4d431739dbb033772cb6d9ca1832accea0c1a95a bug #66477 diff --git a/libinterp/corefcn/load-path.cc b/libinterp/corefcn/load-path.cc --- a/libinterp/corefcn/load-path.cc +++ b/libinterp/corefcn/load-path.cc @@ -351,7 +351,13 @@ load_path::set (const std::string& p, bo for (auto& di : m_dir_info_list) { if (m_add_hook) - m_add_hook (di.dir_name); + { + std::weak_ptr di_w = di; + m_add_hook (di->dir_name); + if (di_w.expired ()) + break; + } + } // Always prepend current directory. @@ -401,7 +407,7 @@ load_path::remove (const std::string& di if (m_remove_hook) m_remove_hook (dir); - dir_info& di = *i; + dir_info& di = **i; remove (di); @@ -427,25 +433,25 @@ load_path::update () for (dir_info_list_iterator di = m_dir_info_list.begin (); di != m_dir_info_list.end ();) { - bool ok = di->update (); + bool ok = (*di)->update (); if (! ok) { warning_with_id ("Octave:load-path:update-failed", "load-path: update failed for '%s', removing from path", - di->dir_name.c_str ()); + (*di)->dir_name.c_str ()); if (m_remove_hook) - m_remove_hook (di->dir_name.c_str ()); - - remove (*di); + m_remove_hook ((*di)->dir_name.c_str ()); + + remove (**di); di = m_dir_info_list.erase (di); } else { - add (*di, true, "", true); + add (**di, true, "", true); di++; } } @@ -458,7 +464,7 @@ load_path::contains_canonical (const std for (const auto& d : m_dir_info_list) { - if (sys::same_file (dir, d.dir_name)) + if (sys::same_file (dir, d->dir_name)) { retval = true; break; @@ -594,7 +600,7 @@ load_path::find_file (const std::string& // element of the load path in turn. for (const auto& di : m_dir_info_list) { - std::string tfile = sys::file_ops::concat (di.abs_dir_name, file); + std::string tfile = sys::file_ops::concat (di->abs_dir_name, file); if (sys::file_exists (tfile)) return tfile; @@ -605,14 +611,14 @@ load_path::find_file (const std::string& // Look in cache. for (const auto& di : m_dir_info_list) { - string_vector all_files = di.all_files; + 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 sys::file_ops::concat (di.abs_dir_name, file); + return sys::file_ops::concat (di->abs_dir_name, file); } } } @@ -637,7 +643,7 @@ load_path::find_dir (const std::string& std::string canon_dir = maybe_canonicalize (dir); for (const auto& di : m_dir_info_list) { - std::string dname = di.abs_dir_name; + std::string dname = di->abs_dir_name; std::size_t dname_len = dname.length (); @@ -653,8 +659,8 @@ load_path::find_dir (const std::string& if (dname_len > dir_len && sys::file_ops::is_dir_sep (dname[dname_len - dir_len - 1]) && canon_dir == dname.substr (dname_len - dir_len) - && sys::dir_exists (di.dir_name)) - return di.abs_dir_name; + && sys::dir_exists (di->dir_name)) + return di->abs_dir_name; } } @@ -678,7 +684,7 @@ load_path::find_matching_dirs (const std std::string canon_dir = maybe_canonicalize (dir); for (const auto& di : m_dir_info_list) { - std::string dname = di.abs_dir_name; + std::string dname = di->abs_dir_name; std::size_t dname_len = dname.length (); @@ -694,8 +700,8 @@ load_path::find_matching_dirs (const std if (dname_len > dir_len && sys::file_ops::is_dir_sep (dname[dname_len - dir_len - 1]) && canon_dir == dname.substr (dname_len - dir_len) - && sys::dir_exists (di.dir_name)) - retlist.push_back (di.abs_dir_name); + && sys::dir_exists (di->dir_name)) + retlist.push_back (di->abs_dir_name); } } @@ -733,7 +739,7 @@ load_path::find_first_of (const string_v for (const auto& di : m_dir_info_list) { std::string tfile; - tfile = sys::file_ops::concat (di.abs_dir_name, file); + tfile = sys::file_ops::concat (di->abs_dir_name, file); if (sys::file_exists (tfile)) return tfile; @@ -748,7 +754,7 @@ load_path::find_first_of (const string_v for (const auto& di : m_dir_info_list) { - string_vector all_files = di.all_files; + string_vector all_files = di->all_files; octave_idx_type len = all_files.numel (); @@ -758,7 +764,7 @@ load_path::find_first_of (const string_v { if (all_files[i] == rel_flist[j]) { - dir_name = di.abs_dir_name; + dir_name = di->abs_dir_name; file_name = rel_flist[j]; goto done; @@ -806,7 +812,7 @@ load_path::find_all_first_of (const stri for (const auto& di : m_dir_info_list) { std::string tfile; - tfile = sys::file_ops::concat (di.abs_dir_name, file); + tfile = sys::file_ops::concat (di->abs_dir_name, file); if (sys::file_exists (tfile)) retlist.push_back (tfile); @@ -821,7 +827,7 @@ load_path::find_all_first_of (const stri for (const auto& di : m_dir_info_list) { - string_vector all_files = di.all_files; + string_vector all_files = di->all_files; octave_idx_type len = all_files.numel (); @@ -830,7 +836,7 @@ load_path::find_all_first_of (const stri for (octave_idx_type j = 0; j < rel_flen; j++) { if (all_files[i] == rel_flist[j]) - retlist.push_back (sys::file_ops::concat (di.abs_dir_name, + retlist.push_back (sys::file_ops::concat (di->abs_dir_name, rel_flist[j])); } } @@ -849,7 +855,7 @@ load_path::dirs () const octave_idx_type k = 0; for (const auto& di : m_dir_info_list) - retval[k++] = di.dir_name; + retval[k++] = di->dir_name; return retval; } @@ -860,7 +866,7 @@ load_path::dir_list () const std::list retval; for (const auto& di : m_dir_info_list) - retval.push_back (di.dir_name); + retval.push_back (di->dir_name); return retval; } @@ -873,7 +879,7 @@ load_path::files (const std::string& dir const_dir_info_list_iterator p = find_dir_info (dir); if (p != m_dir_info_list.end ()) - retval = p->fcn_files; + retval = (*p)->fcn_files; if (omit_exts) { @@ -922,23 +928,23 @@ load_path::display (std::ostream& os) co { for (const auto& di : m_dir_info_list) { - string_vector fcn_files = di.fcn_files; + string_vector fcn_files = di->fcn_files; if (! fcn_files.empty ()) { - os << "\n*** function files in " << di.dir_name << ":\n\n"; + 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; + = di->method_file_map; if (! method_file_map.empty ()) { for (const auto& cls_ci : method_file_map) { - os << "\n*** methods in " << di.dir_name + os << "\n*** methods in " << di->dir_name << "/@" << cls_ci.first << ":\n\n"; const dir_info::class_info& ci = cls_ci.second; @@ -1013,7 +1019,7 @@ load_path::find_dir_info (const std::str while (retval != m_dir_info_list.cend ()) { - if (retval->dir_name == dir) + if ((*retval)->dir_name == dir) break; retval++; @@ -1033,7 +1039,7 @@ load_path::find_dir_info (const std::str while (retval != m_dir_info_list.end ()) { - if (retval->dir_name == dir) + if ((*retval)->dir_name == dir) break; retval++; @@ -1053,7 +1059,7 @@ load_path::move (dir_info_list_iterator { if (m_dir_info_list.size () > 1) { - dir_info di = *i; + std::shared_ptr di = *i; m_dir_info_list.erase (i); @@ -1062,7 +1068,7 @@ load_path::move (dir_info_list_iterator else m_dir_info_list.push_front (di); - move (di, at_end); + move (*di, at_end); } } @@ -1116,9 +1122,9 @@ load_path::add (const std::string& dir_a dir_info di (dir); if (at_end) - m_dir_info_list.push_back (di); + m_dir_info_list.push_back (std::make_shared (di)); else - m_dir_info_list.push_front (di); + m_dir_info_list.push_front (std::make_shared (di)); add (di, at_end); @@ -1235,7 +1241,7 @@ load_path::is_package (const std::string { for (const auto& di : m_dir_info_list) { - if (di.is_package (name)) + if (di->is_package (name)) return true; } diff --git a/libinterp/corefcn/load-path.h b/libinterp/corefcn/load-path.h --- a/libinterp/corefcn/load-path.h +++ b/libinterp/corefcn/load-path.h @@ -355,7 +355,7 @@ private: // overloaded functions (in the "@" directories used to implement // classes). - typedef std::list dir_info_list_type; + typedef std::list> 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;