changeset 18304:b0e8cc676396

Fix out-of-date status check for package functions. * ov-fcn.h (octave_function::xpackage_name): New member to keep track of the package to which a function belongs. (octave_function::octave_function): Initialize it; (octave_function::stash_package_name, octave_function::package_name): New accessor methods. (octave_function::canonical_name): New method to return to fully-qualified name of a function. * oct-parse.in.yy (load_fcn_from_file): Store package name in loaded function. * symtab.cc (split_name_with_package): New utility function. (out_of_date_check): Use the package owning the function when searching for newer versions in load_path. (load_out_of_date_fcn): New argument to pass the package name to load_fcn_from_file.
author Michael Goffioul <michael.goffioul@gmail.com>
date Sat, 18 Jan 2014 15:31:21 -0500
parents 57d5bd8700df
children 81c1edd70bfd
files libinterp/corefcn/symtab.cc libinterp/octave-value/ov-fcn.h libinterp/parse-tree/oct-parse.in.yy
diffstat 3 files changed, 62 insertions(+), 10 deletions(-) [+]
line wrap: on
line diff
--- a/libinterp/corefcn/symtab.cc	Fri Jan 17 21:42:18 2014 -0800
+++ b/libinterp/corefcn/symtab.cc	Sat Jan 18 15:31:21 2014 -0500
@@ -150,6 +150,24 @@
   return retval;
 }
 
+static void
+split_name_with_package (const std::string& name, std::string& fname,
+                         std::string& pname)
+{
+  size_t pos = name.rfind ('.');
+
+  fname.clear ();
+  pname.clear ();
+
+  if (pos != std::string::npos)
+    {
+      fname = name.substr (pos + 1);
+      pname = name.substr (0, pos);
+    }
+  else
+    fname = name;
+}
+
 // Check the load path to see if file that defined this is still
 // visible.  If the file is no longer visible, then erase the
 // definition and move on.  If the file is visible, then we also
@@ -166,11 +184,13 @@
 static inline bool
 load_out_of_date_fcn (const std::string& ff, const std::string& dir_name,
                       octave_value& function,
-                      const std::string& dispatch_type = std::string ())
+                      const std::string& dispatch_type = std::string (),
+                      const std::string& package_name = std::string ())
 {
   bool retval = false;
 
-  octave_function *fcn = load_fcn_from_file (ff, dir_name, dispatch_type);
+  octave_function *fcn = load_fcn_from_file (ff, dir_name, dispatch_type,
+                                             package_name);
 
   if (fcn)
     {
@@ -212,6 +232,8 @@
                 {
                   bool clear_breakpoints = false;
                   std::string nm = fcn->name ();
+                  std::string pack = fcn->package_name ();
+                  std::string canonical_nm = fcn->canonical_name ();
 
                   bool is_same_file = false;
 
@@ -236,10 +258,13 @@
                           if (! dispatch_type.empty ())
                             {
                               file = load_path::find_method (dispatch_type, nm,
-                                                             dir_name);
+                                                             dir_name, pack);
 
                               if (file.empty ())
                                 {
+                                  std::string s_name;
+                                  std::string s_pack;
+
                                   const std::list<std::string>& plist
                                     = symbol_table::parent_classes (dispatch_type);
                                   std::list<std::string>::const_iterator it
@@ -247,10 +272,17 @@
 
                                   while (it != plist.end ())
                                     {
+                                      split_name_with_package (*it, s_name,
+                                                               s_pack);
+
                                       file = load_path::find_method (*it, nm,
-                                                                     dir_name);
+                                                                     dir_name,
+                                                                     s_pack);
                                       if (! file.empty ())
-                                        break;
+                                        {
+                                          pack = s_pack;
+                                          break;
+                                        }
 
                                       it++;
                                     }
@@ -262,7 +294,7 @@
                             file = lookup_autoload (nm);
 
                           if (file.empty ())
-                            file = load_path::find_fcn (nm, dir_name);
+                            file = load_path::find_fcn (nm, dir_name, pack);
                         }
 
                       if (! file.empty ())
@@ -304,7 +336,8 @@
                                 {
                                   retval = load_out_of_date_fcn (ff, dir_name,
                                                                  function,
-                                                                 dispatch_type);
+                                                                 dispatch_type,
+                                                                 pack);
 
                                   clear_breakpoints = true;
                                 }
@@ -323,7 +356,7 @@
                       // place of the old.
 
                       retval = load_out_of_date_fcn (file, dir_name, function,
-                                                     dispatch_type);
+                                                     dispatch_type, pack);
 
                       clear_breakpoints = true;
                     }
@@ -331,7 +364,8 @@
                   // If the function has been replaced then clear any
                   // breakpoints associated with it
                   if (clear_breakpoints)
-                    bp_table::remove_all_breakpoints_in_file (nm, true);
+                    bp_table::remove_all_breakpoints_in_file (canonical_nm,
+                                                              true);
                 }
             }
         }
--- a/libinterp/octave-value/ov-fcn.h	Fri Jan 17 21:42:18 2014 -0800
+++ b/libinterp/octave-value/ov-fcn.h	Sat Jan 18 15:31:21 2014 -0500
@@ -46,7 +46,8 @@
 
   octave_function (void)
     : relative (false), locked (false), private_function (false),
-      xdispatch_class (), my_name (), my_dir_name (), doc () { }
+      xdispatch_class (), xpackage_name (), my_name (), my_dir_name (),
+      doc () { }
 
   ~octave_function (void) { }
 
@@ -100,6 +101,10 @@
 
   std::string dispatch_class (void) const { return xdispatch_class; }
 
+  void stash_package_name (const std::string& pack) { xpackage_name = pack; }
+
+  std::string package_name (void) const { return xpackage_name; }
+
   virtual void
   mark_as_private_function (const std::string& cname = std::string ())
   {
@@ -156,6 +161,14 @@
 
   std::string name (void) const { return my_name; }
 
+  std::string canonical_name (void) const
+    {
+      if (xpackage_name.empty ())
+        return my_name;
+      else
+        return xpackage_name + "." + my_name;
+    }
+
   void document (const std::string& ds) { doc = ds; }
 
   std::string doc_string (void) const { return doc; }
@@ -188,6 +201,10 @@
   // to which the method belongs.
   std::string xdispatch_class;
 
+  // If this function is part of a package, this is the full name
+  // of the package to which the function belongs.
+  std::string xpackage_name;
+
   // The name of this function.
   std::string my_name;
 
--- a/libinterp/parse-tree/oct-parse.in.yy	Fri Jan 17 21:42:18 2014 -0800
+++ b/libinterp/parse-tree/oct-parse.in.yy	Sat Jan 18 15:31:21 2014 -0500
@@ -4033,6 +4033,7 @@
   if (retval)
     {
       retval->stash_dir_name (dir_name);
+      retval->stash_package_name (package_name);
 
       if (retval->is_user_function ())
         {