changeset 9190:7a10410db2c6

[mq]: x
author Robert T. Short <rtshort@ieee.org>
date Fri, 08 May 2009 15:18:22 -0400
parents 8a348e4be8bb
children ad33527d2e51
files src/ChangeLog src/ov-class.cc src/ov-class.h src/ov-struct.cc
diffstat 4 files changed, 75 insertions(+), 12 deletions(-) [+]
line wrap: on
line diff
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,12 @@
+2009-05-07  Robert T. Short  <octave@phaselockedsystems.com>
+
+	* ov-class.h, ov-class.cc (octave_class::reconstruct_exemplar):
+	New function.
+	* ov-class.cc (octave_class::load_binary, octave_class::load_hdf5,
+	octave_class::load_ascii): Construct exemplar table and ensure
+	inheritance is correct.
+        * ov-struct.cc (struct): Return struct from object.
+
 2009-05-07  John W. Eaton  <jwe@octave.org>
 
 	* graphics.h.in (base_graphics_object::set): Undo previous change.
--- a/src/ov-class.cc
+++ b/src/ov-class.cc
@@ -813,6 +813,39 @@
     }
 }
 
+// Loading a class properly requires an exemplar map entry for success.
+// If we don't have one, we attempt to create one by calling the constructor 
+// with no arguments.
+bool
+octave_class::reconstruct_exemplar (void)
+{
+  bool retval = false;
+
+  octave_class::exemplar_const_iterator it
+    = octave_class::exemplar_map.find (c_name);
+
+  if (it != octave_class::exemplar_map.end ())
+    retval = true;
+  else
+    {
+      octave_value ctor = symbol_table::find_method (c_name, c_name);
+
+      if (ctor.is_defined ())
+	{
+	  octave_value_list result = feval (ctor, 1);
+
+	  if (result.length () == 1)
+	    retval = true;
+	  else
+	    warning ("call to constructor for class %s failed", c_name.c_str ());
+	}
+      else
+	warning ("no constructor for class %s", c_name.c_str ());
+    }
+
+  return retval;
+}
+
 //  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.
@@ -947,19 +980,26 @@
 
 	      if (is) 
 		{
-		  map = m;
 		  c_name = classname;
+		  reconstruct_exemplar ();
 
-		  if (load_path::find_method (classname, "loadobj")
-		      != std::string ())
+		  map = m;
+		  
+		  if (! reconstruct_parents ())
+		    warning ("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 (classname, "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
@@ -1052,6 +1092,7 @@
       return false;
     c_name = classname;
   }
+  reconstruct_exemplar ();
 
   int32_t len;
   if (! is.read (reinterpret_cast<char *> (&len), 4))
@@ -1092,7 +1133,7 @@
 	  map = m;
 
 	  if (! reconstruct_parents ())
-	    error ("load: unable to reconstruct object inheritance");
+	    warning ("load: unable to reconstruct object inheritance");
 	  else
 	    {
 	      if (load_path::find_method (c_name, "loadobj") != std::string ())
@@ -1109,7 +1150,7 @@
 	}
       else
 	{
-	  error ("load: failed to load class");
+	  warning ("load: failed to load class");
 	  success = false;
 	}
     }
@@ -1281,6 +1322,7 @@
       c_name = classname;
     }
   while (0);
+  reconstruct_exemplar ();
 
 
 #ifdef HAVE_H5GGET_NUM_OBJS
@@ -1317,7 +1359,7 @@
       map = m;
 
       if (!reconstruct_parents ())
-	error ("load: unable to reconstruct object inheritance");
+	warning ("load: unable to reconstruct object inheritance");
       else
 	{
 	  if (load_path::find_method (c_name, "loadobj") != std::string ())
--- a/src/ov-class.h
+++ b/src/ov-class.h
@@ -144,6 +144,8 @@
   void print_with_name (std::ostream& os, const std::string& name, 
 			bool print_padding = true) const;
 
+  bool reconstruct_exemplar (void);
+
   bool reconstruct_parents (void);
 
   bool save_ascii (std::ostream& os);
--- a/src/ov-struct.cc
+++ b/src/ov-struct.cc
@@ -701,6 +701,8 @@
 Singleton cells and non-cell values are repeated so that they fill\n\
 the entire array.  If the cells are empty, create an empty structure\n\
 array with the specified field names.\n\
+\n\
+If the argument is an object, return the underlying struct.\n\
 @end deftypefn")
 {
   octave_value retval;
@@ -715,6 +717,14 @@
   // Note that struct () creates a 1x1 struct with no fields for
   // compatibility with Matlab.
 
+  if (nargin == 1 && args(0).is_object ())
+    {
+      Octave_map m = args(0).map_value ();
+      retval = octave_value (new octave_struct (m));
+
+      return retval;
+    }
+
   if ((nargin == 1 || nargin == 2)
       && args(0).is_empty () && args(0).is_real_matrix ())
     {