# HG changeset patch # User Robert T. Short # Date 1241547103 14400 # Node ID 23af5910e5f52174a69f2b95a427ff5fe33305f9 # Parent 86ae7e50dc5dea037d4121988f04b42b1c54990e make load work for derived classses diff --git a/liboctave/ChangeLog b/liboctave/ChangeLog --- a/liboctave/ChangeLog +++ b/liboctave/ChangeLog @@ -1,3 +1,7 @@ +2009-05-05 Robert T. Short + + * file-ops.h (file_ops::tail) New function. + 2009-05-05 Carsten Clark * Quad.cc (user_function): Use access_double and assign_double on diff --git a/liboctave/file-ops.h b/liboctave/file-ops.h --- a/liboctave/file-ops.h +++ b/liboctave/file-ops.h @@ -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 diff --git a/src/ChangeLog b/src/ChangeLog --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,11 @@ +2009-05-05 Robert T. Short + + * 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 * graphics.cc (array_property::validate): Require object to be any diff --git a/src/ov-base.h b/src/ov-base.h --- a/src/ov-base.h +++ b/src/ov-base.h @@ -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; } diff --git a/src/ov-class.cc b/src/ov-class.cc --- a/src/ov-class.cc +++ b/src/ov-class.cc @@ -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::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: diff --git a/src/ov-class.h b/src/ov-class.h --- 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_parents (void); + bool save_ascii (std::ostream& os); bool load_ascii (std::istream& is);