changeset 9182:23af5910e5f5

make load work for derived classses
author Robert T. Short <octave@phaselockedsystems.com>
date Tue, 05 May 2009 14:11:43 -0400
parents 86ae7e50dc5d
children 94ae487acd1b
files liboctave/ChangeLog liboctave/file-ops.h src/ChangeLog src/ov-base.h src/ov-class.cc src/ov-class.h
diffstat 6 files changed, 123 insertions(+), 29 deletions(-) [+]
line wrap: on
line diff
--- a/liboctave/ChangeLog	Tue May 05 13:32:15 2009 -0400
+++ b/liboctave/ChangeLog	Tue May 05 14:11:43 2009 -0400
@@ -1,3 +1,7 @@
+2009-05-05  Robert T. Short  <octave@phaselockedsystems.com>
+
+	* file-ops.h (file_ops::tail) New function.
+
 2009-05-05  Carsten Clark  <tantumquantum+gnuoctave@gmail.com>
 
 	* Quad.cc (user_function): Use access_double and assign_double on
--- a/liboctave/file-ops.h	Tue May 05 13:32:15 2009 -0400
+++ b/liboctave/file-ops.h	Tue May 05 14:11:43 2009 -0400
@@ -109,6 +109,19 @@
     return static_members::dir_sep_chars ();
   }
 
+  // Return the tail member of a path.
+  static std::string tail (std::string path)
+  {
+    size_t ipos = path.find_last_of (dir_sep_chars ());
+
+    if (ipos != std::string::npos)
+      ipos++;
+    else
+      ipos = 0;
+
+    return path.substr (ipos);
+  }
+
 private:
 
   // Use a singleton class for these data members instead of just
--- a/src/ChangeLog	Tue May 05 13:32:15 2009 -0400
+++ b/src/ChangeLog	Tue May 05 14:11:43 2009 -0400
@@ -1,3 +1,11 @@
+2009-05-05  Robert T. Short  <octave@phaselockedsystems.com>
+
+	* ov-class.h, ov-class.cc (octave_class::reconstruct_parents):
+	New function.
+	* ov-class.cc (octave_class::load_binary, octave_class::load_hdf5):
+	Contstruct parent list.
+	(get_current_method_class): Clean up method class extraction.
+
 2009-05-05  John W. Eaton  <jwe@octave.org>
 
 	* graphics.cc (array_property::validate): Require object to be any
--- a/src/ov-base.h	Tue May 05 13:32:15 2009 -0400
+++ b/src/ov-base.h	Tue May 05 14:11:43 2009 -0400
@@ -458,7 +458,6 @@
 
   virtual string_vector parent_class_names (void) const;
 
-  // FIXME -- should this warn if called for a non-class type?
   virtual octave_base_value *find_parent_class (const std::string&)
     { return 0; }
 
--- a/src/ov-class.cc	Tue May 05 13:32:15 2009 -0400
+++ b/src/ov-class.cc	Tue May 05 14:11:43 2009 -0400
@@ -33,6 +33,7 @@
 #include "Cell.h"
 #include "defun.h"
 #include "error.h"
+#include "file-ops.h"
 #include "gripes.h"
 #include "load-path.h"
 #include "ls-hdf5.h"
@@ -98,15 +99,13 @@
 {
   std::string retval;
 
-  // FIXME -- is there a better way to do this?
   octave_function *fcn = octave_call_stack::current ();
 
   std::string my_dir = fcn->dir_name ();
 
-  size_t ipos = my_dir.find_last_of ("@");
+  std::string method_class = file_ops::tail (my_dir);
 
-  if (ipos != std::string::npos)
-    retval = my_dir.substr (ipos+1);
+  retval = method_class.substr (1);
 
   return retval;
 }
@@ -814,12 +813,71 @@
     }
 }
 
+//  Load/save does not provide enough information to reconstruct the
+//  class inheritance structure.  reconstruct_parents () attempts to
+//  do so.  If successful, a "true" value is returned.
+//
+//  Note that we don't check the loaded object structure against the
+//  class structure here so the user's loadobj method has a chance
+//  to do its magic.
+bool
+octave_class::reconstruct_parents (void)
+{
+  bool retval = true, might_have_inheritance = false;
+  std::string dbgstr = "dork";
+
+  // First, check to see if there might be an issue with inheritance.
+  for (Octave_map::const_iterator p = map.begin (); p != map.end (); p++)
+    {
+      std::string  key = map.key (p);
+      Cell         val = map.contents (p);
+      if ( val(0).is_object() )
+	{
+	  dbgstr = "blork";
+	  if( key == val(0).class_name() )
+	    {
+	      might_have_inheritance = true;
+	      dbgstr = "cork";
+	      break;
+	    }
+	}
+    }
+  
+  if (might_have_inheritance)
+    {
+      octave_class::exemplar_const_iterator it
+	= octave_class::exemplar_map.find (c_name);
+
+      if (it == octave_class::exemplar_map.end ())
+	retval = false;
+      else
+	{
+	  octave_class::exemplar_info exmplr = it->second;
+	  parent_list = exmplr.parents ();
+	  for (std::list<std::string>::iterator pit = parent_list.begin ();
+	       pit != parent_list.end ();
+	       pit++)
+	    {
+	      dbgstr = *pit;
+	      bool dbgbool = map.contains (*pit);
+	      if (!dbgbool)
+		{
+		  retval = false;
+		  break;
+		}
+	    }
+	}
+    }
+
+  return retval;
+}
+
 bool
 octave_class::save_ascii (std::ostream& os)
 {
   os << "# classname: " << class_name () << "\n";
   Octave_map m;
-  if (load_path::find_method (class_name (), "saveobj") != std::string())
+  if (load_path::find_method (class_name (), "saveobj") != std::string ())
     {
       octave_value in = new octave_class (*this);
       octave_value_list tmp = feval ("saveobj", in, 1);
@@ -873,7 +931,7 @@
 		  std::string nm
 		    = read_ascii_data (is, std::string (), dummy, t2, j);
 
-		  if (!is)
+		  if (! is)
 		    break;
 
 		  Cell tcell = t2.is_cell () ? t2.cell_value () : Cell (t2);
@@ -892,8 +950,8 @@
 		  map = m;
 		  c_name = classname;
 
-		  if (load_path::find_method (classname, "loadobj") != 
-		      std::string())
+		  if (load_path::find_method (classname, "loadobj")
+		      != std::string ())
 		    {
 		      octave_value in = new octave_class (*this);
 		      octave_value_list tmp = feval ("loadobj", in, 1);
@@ -942,7 +1000,7 @@
   os << class_name ();
 
   Octave_map m;
-  if (load_path::find_method (class_name (), "saveobj") != std::string())
+  if (load_path::find_method (class_name (), "saveobj") != std::string ())
     {
       octave_value in = new octave_class (*this);
       octave_value_list tmp = feval ("saveobj", in, 1);
@@ -1015,7 +1073,7 @@
 	  std::string nm = read_binary_data (is, swap, fmt, std::string (), 
 					     dummy, t2, doc);
 
-	  if (!is)
+	  if (! is)
 	    break;
 
 	  Cell tcell = t2.is_cell () ? t2.cell_value () : Cell (t2);
@@ -1033,15 +1091,20 @@
 	{
 	  map = m;
 
-	  if (load_path::find_method (class_name(), "loadobj") != std::string())
+	  if (! reconstruct_parents ())
+	    error ("load: unable to reconstruct object inheritance");
+	  else
 	    {
-	      octave_value in = new octave_class (*this);
-	      octave_value_list tmp = feval ("loadobj", in, 1);
+	      if (load_path::find_method (c_name, "loadobj") != std::string ())
+		{
+		  octave_value in = new octave_class (*this);
+		  octave_value_list tmp = feval ("loadobj", in, 1);
 
-	      if (! error_state)
-		map = tmp(0).map_value ();
-	      else
-		success = false;
+		  if (! error_state)
+		    map = tmp(0).map_value ();
+		  else
+		    success = false;
+		}
 	    }
 	}
       else
@@ -1096,7 +1159,7 @@
   if (data_hid < 0)
     goto error_cleanup;
 
-  if (load_path::find_method (class_name (), "saveobj") != std::string())
+  if (load_path::find_method (class_name (), "saveobj") != std::string ())
     {
       octave_value in = new octave_class (*this);
       octave_value_list tmp = feval ("saveobj", in, 1);
@@ -1253,21 +1316,26 @@
     {
       map = m;
 
-      if (load_path::find_method (class_name(), "loadobj") != std::string())
+      if (!reconstruct_parents ())
+	error ("load: unable to reconstruct object inheritance");
+      else
 	{
-	  octave_value in = new octave_class (*this);
-	  octave_value_list tmp = feval ("loadobj", in, 1);
+	  if (load_path::find_method (c_name, "loadobj") != std::string ())
+	    {
+	      octave_value in = new octave_class (*this);
+	      octave_value_list tmp = feval ("loadobj", in, 1);
 
-	  if (! error_state)
-	    {
-	      map = tmp(0).map_value ();
-	      retval = true;
+	      if (! error_state)
+		{
+		  map = tmp(0).map_value ();
+		  retval = true;
+		}
+	      else
+		retval = false;
 	    }
 	  else
-	    retval = false;
+	    retval = true;
 	}
-      else
-	retval = true;
     }
   
  error_cleanup:
--- a/src/ov-class.h	Tue May 05 13:32:15 2009 -0400
+++ b/src/ov-class.h	Tue May 05 14:11:43 2009 -0400
@@ -144,6 +144,8 @@
   void print_with_name (std::ostream& os, const std::string& name, 
 			bool print_padding = true) const;
 
+  bool reconstruct_parents (void);
+
   bool save_ascii (std::ostream& os);
 
   bool load_ascii (std::istream& is);