changeset 14376:7dd6ac033e69

Warn when the default path is overwritten * load-path.h (dir_info): New member, is_init, true if this directory was set during init. (dir_info::dir_info): Initialise is_init param. (load_path::do_clear): Pass the new elements to add after clearing. (load_path::clear): Pass dummy empty elements. (load_path::do_set, load_path::do_append, load_path::do_add): Pass new bool if adding or setting an init directory. * load-path.cc (load_path::do_initalize, load_path::do_append, load_path::do_add): Pass around extra is_init argument. (do_set): Pass an std::set of new directories to do_append. (do_clear): Check if the init directories are getting removed and warn if so.
author Jordi Gutiérrez Hermoso <jordigh@octave.org>
date Thu, 16 Feb 2012 20:19:12 -0500
parents 4e4519a26e50
children c87f927d047d
files src/load-path.cc src/load-path.h
diffstat 2 files changed, 58 insertions(+), 21 deletions(-) [+]
line wrap: on
line diff
--- a/src/load-path.cc	Thu Feb 16 19:19:31 2012 -0500
+++ b/src/load-path.cc	Thu Feb 16 20:19:12 2012 -0500
@@ -519,13 +519,40 @@
   else
     xpath = sys_path;
 
-  do_set (xpath, false);
+  do_set (xpath, false, true);
 }
 
 void
-load_path::do_clear (void)
+load_path::do_clear (std::set<std::string>& new_elts)
 {
-  dir_info_list.clear ();
+  bool warn_default_path_clobbered = false;
+  for (dir_info_list_iterator i = dir_info_list.begin();
+       i != dir_info_list.end();
+       /* conditionally advance iterator in loop body */)
+    {
+      //Don't remove it if it's gonna be added again, but remove it from
+      //list of items to add, to avoid duplicates later on
+      std::set<std::string>::iterator j = new_elts.find(i->dir_name);
+      if (j != new_elts.end())
+        {
+          new_elts.erase(j);
+          i++;
+        }
+      else
+        {
+          //Warn if removing a default directory and not immediately adding
+          //it back again
+          if(i->is_init)
+            warn_default_path_clobbered = true;
+          i = dir_info_list.erase(i);
+        }
+    }
+
+  if (warn_default_path_clobbered)
+    warning_with_id ("Octave:remove-init-dir",
+                     "default load path altered.  Some built-in functions may "
+                     "not be found.  Try restoredefaultpath() to recover it.");
+
   fcn_map.clear ();
   private_fcn_map.clear ();
   method_map.clear ();
@@ -565,9 +592,10 @@
 }
 
 void
-load_path::do_set (const std::string& p, bool warn)
+load_path::do_set (const std::string& p, bool warn, bool is_init)
 {
-  std::list<std::string> elts = split_path (p);
+  std::list<std::string> elts_l = split_path (p);
+  std::set<std::string> elts(elts_l.begin(), elts_l.end());
 
   // Temporarily disable add hook.
 
@@ -576,12 +604,12 @@
 
   add_hook = 0;
 
-  do_clear ();
-
-  for (std::list<std::string>::const_iterator i = elts.begin ();
+  do_clear (elts);
+
+  for (std::set<std::string>::const_iterator i = elts.begin ();
        i != elts.end ();
        i++)
-    do_append (*i, warn);
+    do_append (*i, warn, is_init);
 
   // Restore add hook and execute for all newly added directories.
   frame.run_top ();
@@ -599,10 +627,10 @@
 }
 
 void
-load_path::do_append (const std::string& dir, bool warn)
+load_path::do_append (const std::string& dir, bool warn, bool is_init)
 {
   if (! dir.empty ())
-    do_add (dir, true, warn);
+    do_add (dir, true, warn, is_init);
 }
 
 void
@@ -631,7 +659,8 @@
 }
 
 void
-load_path::do_add (const std::string& dir_arg, bool at_end, bool warn)
+load_path::do_add (const std::string& dir_arg, bool at_end, bool warn,
+                   bool is_init)
 {
   size_t len = dir_arg.length ();
 
@@ -656,6 +685,7 @@
           if (fs.is_dir ())
             {
               dir_info di (dir);
+              di.is_init = is_init;
 
               if (! error_state)
                 {
--- a/src/load-path.h	Thu Feb 16 19:19:31 2012 -0500
+++ b/src/load-path.h	Thu Feb 16 20:19:12 2012 -0500
@@ -56,7 +56,10 @@
   static void clear (void)
   {
     if (instance_ok ())
-      instance->do_clear ();
+      {
+        std::set<std::string> no_new_elts;
+        instance->do_clear (no_new_elts);
+      }
   }
 
   static void set (const std::string& p, bool warn = false)
@@ -294,14 +297,14 @@
     // constructor for any other purpose.
     dir_info (void)
       : dir_name (), abs_dir_name (), is_relative (false),
-        dir_mtime (), dir_time_last_checked (), all_files (),
-        fcn_files (), private_file_map (), method_file_map ()
+        is_init(false), dir_mtime (), dir_time_last_checked (),
+        all_files (), fcn_files (), private_file_map (), method_file_map ()
       { }
 
     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 ()
+        is_init(false), dir_mtime (), dir_time_last_checked (),
+        all_files (), fcn_files (), private_file_map (), method_file_map ()
     {
       initialize ();
     }
@@ -309,6 +312,7 @@
     dir_info (const dir_info& di)
       : dir_name (di.dir_name), abs_dir_name (di.abs_dir_name),
         is_relative (di.is_relative),
+        is_init (di.is_init),
         dir_mtime (di.dir_mtime),
         dir_time_last_checked (di.dir_time_last_checked),
         all_files (di.all_files), fcn_files (di.fcn_files),
@@ -324,6 +328,7 @@
           dir_name = di.dir_name;
           abs_dir_name = di.abs_dir_name;
           is_relative = di.is_relative;
+          is_init = di.is_init;
           dir_mtime = di.dir_mtime;
           dir_time_last_checked = di.dir_time_last_checked;
           all_files = di.all_files;
@@ -340,6 +345,7 @@
     std::string dir_name;
     std::string abs_dir_name;
     bool is_relative;
+    bool is_init; //Was this directory set by init? Warn when clearing it.
     octave_time dir_mtime;
     octave_time dir_time_last_checked;
     string_vector all_files;
@@ -471,15 +477,16 @@
 
   void do_initialize (bool set_initial_path);
 
-  void do_clear (void);
+  void do_clear (std::set<std::string>& new_elts);
 
-  void do_set (const std::string& p, bool warn);
+  void do_set (const std::string& p, bool warn, bool is_init=false);
 
-  void do_append (const std::string& dir, bool warn);
+  void do_append (const std::string& dir, bool warn, bool is_init=false);
 
   void do_prepend (const std::string& dir, bool warn);
 
-  void do_add (const std::string& dir, bool at_end, bool warn);
+  void do_add (const std::string& dir, bool at_end, bool warn,
+               bool is_init=false);
 
   void remove_fcn_map (const std::string& dir, const string_vector& fcn_files);