From octave-maintainers-request at bevo dot che dot wisc dot edu Fri Nov 21 20:19:27 2003 Subject: Re: restructuring load-save From: David Bateman To: "John W. Eaton" Date: Sat, 22 Nov 2003 04:11:24 +0100 --zjcmjzIkjQU2rmur Content-Type: text/plain; charset=iso-8859-1 Content-Disposition: inline Content-Transfer-Encoding: 8bit Ok, I've started coding for the ascii file type, since code talks. I've done the save functions, and am starting on the load functions. Checked that it compiles but its late here and so haven't had the time to also check that it works. However, for the load functions I've run into a problem of what is the best way to convert from a string of the type name to an octave_value. I thought I could use octave_value_typeinfo class, something like octave_value octave_value_typeinfo::lookup_type (const std::string &nm) { for (int i = 0;i < num_types; i++) if (nm == types(i)) { // FIXME: How do I initialize an octave_value of the right type? return octave_value(); } return octave_value(); } I can use this to get the static_type_id of the type, but don't see an obvious way of converting that to an octave_value. Does anyone have a clue? In any case I attach the patch of my work in progress for discussion... D. Daprès John W. Eaton (le 20/11/2003): > On 20-Nov-2003, David Bateman wrote: > > | I've been thinking on how to fix up the load/save issue as well, and I > | think this could also be fixed fairly easily by introducing into ov-base.h > | > | void * oct_ascii_load (void); > | void * oct_ascii_save (void); > | void * oct_binary_load (void); > | void * oct_binary_save (void); > | > | bool have_oct_ascii_load { return false; } > | bool have_oct_ascii_save { return false; } > | bool have_oct_binary_load { return false; } > | bool have_oct_binary_save { return false; } > | > | and appropriate virtual functions in ov.h. Then modify ov-oct-{ascii,binary}.cc > | to do something like > | > | bool > | save_ascii_data ...... > | > | { > | if (val_arg->have_oct_ascii_save()) { > | val_arg->oct_ascii_save(); > | } else > | // The old version of the code > | } > | } > | > | bool > | load_ascii_data ...... > | > | { > | if (val_arg->have_oct_ascii_load()) { > | val_arg->oct_ascii_load(); > | } else > | // The old version of the code > | } > | } > > What is the void* return type for the save/load functions for? You > don't seem to be using it here. > > | The the user type can overload the oct_* methods and setup the > | have_oct_* functions appropriately. Similar things could also be done > | for the Matlab and HDF file formats. > > Yes, this is a start, but let's examine it a bit more. First, let's > look at the save functions, because they are probably easier (we > already have an object, so we know its type and can call a method for > it). > > If you are going to use virtual functions, then I think the default > save functionality should be in the octave_base_value class in > ov-base.{h,cc}. Then you wouldn't need the have_*_save functions, > because if a derived class did not provide it's own save or load > function, you would get the default version in the octave_base_value > class. Since we would be splitting all the code in the current > load-save functions up, I don't think there would be any old version > of the code left, so we would probably just be left with a "unable to > save objects of type XXX" error in the base code. This is essentially > trading a switch statement in the current code for virtual function > dispatch, which is generally good, because extending it for new > objects is potentially cleaner. > > For the load functions, things are more difficult, because you don't > know the type of the object until you read something from the file. > But perhaps this is not too much of a problem because I think each > file format includes some header information for each object that > tells us what the type is, so we could do something like > > octave_name_and_value_struct > load_oct_binary_object (ostream& os, ...) > { > // get the name from the file along with a dummy object of the > // appropriate type (used for dispatching). > octave_name_and_value_struct tmp = read_object_info (os); > tmp.val.oct_load (os); > return tmp; > } > > This function would be called repeatedly until an error occurs or we > are out of values (signaled by returning an empty name and value > struct?). The information returned could be added to an octave_value > struct array or inserted in the symbol table as needed. > > Now, the only remaining problem is how to make load work for new > types? Obviously, the read_object_info function can't know everything > about every type that might be added to Octave later, so it needs to > get some information from the file and pass it to each of the possible > octave_value subtypes in some reasonable order and allow them to > decide whether they are the appropriate object type to handle the > request. Or, I suppose this could also be done with a lookup table > that is filled in when the various types are installed in the > interpreter. We would also need some way of mapping MAT file type > information to specific octave_value types. > > | Would such a change be acceptable? If so I wouldn't might coding it up... > > Maybe. > > It happens that I am currently in the process of splitting up the > load-save code into separate files based on file type, and trying to > make sure that we support all (or most) data types for each file > type. Splitting it up further would also be OK, but I'd like to agree > that we have a good plan first. > > jwe -- David Bateman David dot Bateman at motorola dot com Motorola CRM +33 1 69 35 48 04 (Ph) Parc Les Algorithmes, Commune de St Aubin +33 1 69 35 77 01 (Fax) 91193 Gif-Sur-Yvette FRANCE The information contained in this communication has been classified as: [x] General Business Information [ ] Motorola Internal Use Only [ ] Motorola Confidential Proprietary --zjcmjzIkjQU2rmur Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=patch Index: ls-oct-ascii.cc =================================================================== RCS file: /cvs/octave/src/ls-oct-ascii.cc,v retrieving revision 1.1 diff -u -r1.1 ls-oct-ascii.cc --- ls-oct-ascii.cc 2003/11/19 21:22:39 1.1 +++ ls-oct-ascii.cc 2003/11/22 02:00:24 at @ -26,7 +26,6 @@ #include #endif -#include #include #include at @ -71,27 +70,8 @@ // The number of decimal digits to use when writing ascii data. static int Vsave_precision; -#define CELL_ELT_TAG "" - -// Used when converting Inf to something that gnuplot can read. - -#ifndef OCT_RBV -#define OCT_RBV DBL_MAX / 100.0 -#endif - // Functions for reading ascii data. -static void -ascii_save_type (std::ostream& os, const char *type, bool mark_as_global) -{ - if (mark_as_global) - os << "# type: global "; - else - os << "# type: "; - - os << type << "\n"; -} - static Matrix strip_infnan (const Matrix& m) { at @ -123,45 +103,6 @@ return retval; } -static ComplexMatrix -strip_infnan (const ComplexMatrix& m) -{ - int nr = m.rows (); - int nc = m.columns (); - - ComplexMatrix retval (nr, nc); - - int k = 0; - for (int i = 0; i < nr; i++) - { - for (int j = 0; j < nc; j++) - { - Complex c = m (i, j); - if (xisnan (c)) - goto next_row; - else - { - double re = real (c); - double im = imag (c); - - re = xisinf (re) ? (re > 0 ? OCT_RBV : -OCT_RBV) : re; - im = xisinf (im) ? (im > 0 ? OCT_RBV : -OCT_RBV) : im; - - retval (k, j) = Complex (re, im); - } - } - k++; - - next_row: - continue; - } - - if (k > 0) - retval.resize (k, nc); - - return retval; -} - // Skip white space and comments on stream IS. static void at @ -442,6 +383,9 @@ else typ = tag; +#if 0 + +#else if (SUBSTRING_COMPARE_EQ (typ, 0, 6, "scalar")) { double tmp = octave_read_double (is); at @ -632,6 +576,8 @@ } else error ("load: unknown constant type `%s'", tag.c_str ()); + +#endif } else error ("load: failed to extract keyword specifying value type"); at @ -676,189 +622,15 @@ long old_precision = os.precision (); os.precision (precision); - - octave_value val = val_arg; - - if (val.is_range ()) - { - Range r = val.range_value (); - double base = r.base (); - double limit = r.limit (); - double inc = r.inc (); - if (! (NINT (base) == base - && NINT (limit) == limit - && NINT (inc) == inc)) - val = val.matrix_value (); - } - - if (val.is_string ()) - { - ascii_save_type (os, "string array", mark_as_global); - charMatrix chm = val.char_matrix_value (); - int elements = chm.rows (); - os << "# elements: " << elements << "\n"; - for (int i = 0; i < elements; i++) - { - unsigned len = chm.cols (); - os << "# length: " << len << "\n"; - std::string tstr = chm.row_as_string (i, false, true); - const char *tmp = tstr.data (); - if (tstr.length () > len) - panic_impossible (); - os.write (X_CAST (char *, tmp), len); - os << "\n"; - } - } - else if (val.is_range ()) - { - ascii_save_type (os, "range", mark_as_global); - Range tmp = val.range_value (); - os << "# base, limit, increment\n"; - octave_write_double (os, tmp.base ()); - os << " "; - octave_write_double (os, tmp.limit ()); - os << " "; - octave_write_double (os, tmp.inc ()); - os << "\n"; - } - else if (val.is_real_scalar ()) - { - ascii_save_type (os, "scalar", mark_as_global); - - double d = val.double_value (); - - if (strip_nan_and_inf) - { - if (xisnan (d)) - { - error ("only value to plot is NaN"); - success = false; - } - else - { - d = xisinf (d) ? (d > 0 ? OCT_RBV : -OCT_RBV) : d; - octave_write_double (os, d); - os << "\n"; - } - } - else - { - if (! infnan_warned && (xisnan (d) || xisinf (d))) - { - warning ("save: Inf or NaN values may not be reloadable"); - infnan_warned = true; - } - - octave_write_double (os, d); - os << "\n"; - } - } - else if (val.is_real_matrix ()) - { - ascii_save_type (os, "matrix", mark_as_global); - - os << "# rows: " << val.rows () << "\n" - << "# columns: " << val.columns () << "\n"; - - Matrix tmp = val.matrix_value (); - - if (strip_nan_and_inf) - tmp = strip_infnan (tmp); - else if (! infnan_warned && tmp.any_element_is_inf_or_nan ()) - { - warning ("save: Inf or NaN values may not be reloadable"); - infnan_warned = true; - } - - os << tmp; - } - else if (val.is_cell ()) - { - ascii_save_type (os, "cell", mark_as_global); - - os << "# rows: " << val.rows () << "\n" - << "# columns: " << val.columns () << "\n"; - - Cell tmp = val.cell_value (); - - for (int j = 0; j < tmp.cols (); j++) - { - for (int i = 0; i < tmp.rows (); i++) - { - octave_value o_val = tmp.elem (i, j); - - // Recurse to print sub-value. - bool b = save_ascii_data (os, o_val, CELL_ELT_TAG, - infnan_warned, strip_nan_and_inf, - mark_as_global, 0); - - if (! b) - return os; - } - - os << "\n"; - } - } - else if (val.is_complex_scalar ()) - { - ascii_save_type (os, "complex scalar", mark_as_global); - - Complex c = val.complex_value (); - if (strip_nan_and_inf) - { - if (xisnan (c)) - { - error ("only value to plot is NaN"); - success = false; - } - else - { - double re = real (c); - double im = imag (c); - - re = xisinf (re) ? (re > 0 ? OCT_RBV : -OCT_RBV) : re; - im = xisinf (im) ? (im > 0 ? OCT_RBV : -OCT_RBV) : im; - - c = Complex (re, im); - - octave_write_complex (os, c); - os << "\n"; - } - } - else - { - if (! infnan_warned && (xisnan (c) || xisinf (c))) - { - warning ("save: Inf or NaN values may not be reloadable"); - infnan_warned = true; - } - - octave_write_complex (os, c); - os << "\n"; - } - } - else if (val.is_complex_matrix ()) - { - ascii_save_type (os, "complex matrix", mark_as_global); - - os << "# rows: " << val.rows () << "\n" - << "# columns: " << val.columns () << "\n"; - - ComplexMatrix tmp = val.complex_matrix_value (); + if (mark_as_global) + os << "# type: global "; + else + os << "# type: "; - if (strip_nan_and_inf) - tmp = strip_infnan (tmp); - else if (! infnan_warned && tmp.any_element_is_inf_or_nan ()) - { - warning ("save: Inf or NaN values may not be reloadable"); - infnan_warned = true; - } + octave_value val = val_arg; - os << tmp; - } - else - gripe_wrong_type_arg ("save", val, false); + success = val . save_ascii(os, infnan_warned, strip_nan_and_inf); os.precision (old_precision); Index: ls-oct-ascii.h =================================================================== RCS file: /cvs/octave/src/ls-oct-ascii.h,v retrieving revision 1.1 diff -u -r1.1 ls-oct-ascii.h --- ls-oct-ascii.h 2003/11/19 21:22:39 1.1 +++ ls-oct-ascii.h 2003/11/22 02:00:24 at @ -23,6 +23,17 @@ #if !defined (octave_ls_oct_ascii_h) #define octave_ls_oct_ascii_h 1 +#include + +// Flag for cell elements +#define CELL_ELT_TAG "" + +// Used when converting Inf to something that gnuplot can read. + +#ifndef OCT_RBV +#define OCT_RBV DBL_MAX / 100.0 +#endif + extern std::string extract_keyword (std::istream& is, const char *keyword); Index: ov-cell.cc =================================================================== RCS file: /cvs/octave/src/ov-cell.cc,v retrieving revision 1.30 diff -u -r1.30 ov-cell.cc --- ov-cell.cc 2003/11/14 19:49:56 1.30 +++ ov-cell.cc 2003/11/22 02:00:24 at @ -45,6 +45,8 @@ #include "ov-re-mat.h" #include "ov-scalar.h" +#include "ls-oct-ascii.h" + template class octave_base_matrix; DEFINE_OCTAVE_ALLOCATOR (octave_cell); at @ -393,6 +395,42 @@ os << "{" << dv.str () << " Cell Array}"; newline (os); } +} + +#define CELL_ELT_TAG "" + +bool octave_cell::save_ascii (std::ostream& os, bool& infnan_warned, + bool strip_nan_and_inf) +{ + os << "cell\n"; + + os << "# rows: " << rows () << "\n" + << "# columns: " << columns () << "\n"; + + Cell tmp = cell_value (); + + for (int j = 0; j < tmp.cols (); j++) + { + for (int i = 0; i < tmp.rows (); i++) + { + octave_value o_val = tmp.elem (i, j); + + // Recurse to print sub-value. + bool b = save_ascii_data (os, o_val, CELL_ELT_TAG, + infnan_warned, strip_nan_and_inf, 0, 0); + + if (! b) + return os; + } + + os << "\n"; + } + return true; +} + +bool octave_cell::load_ascii (std::istream& is, bool& global) +{ + return false; } DEFUN (iscell, args, , Index: ov-cell.h =================================================================== RCS file: /cvs/octave/src/ov-cell.h,v retrieving revision 1.20 diff -u -r1.20 ov-cell.h --- ov-cell.h 2003/11/14 19:49:56 1.20 +++ ov-cell.h 2003/11/22 02:00:24 at @ -109,6 +109,12 @@ void print_raw (std::ostream& os, bool pr_as_read_syntax = false) const; + + bool save_ascii (std::ostream& os, bool& infnan_warned, + bool strip_nan_and_inf); + + bool load_ascii (std::istream& is, bool& global); + private: DECLARE_OCTAVE_ALLOCATOR Index: ov-complex.cc =================================================================== RCS file: /cvs/octave/src/ov-complex.cc,v retrieving revision 1.22 diff -u -r1.22 ov-complex.cc --- ov-complex.cc 2003/11/14 19:49:56 1.22 +++ ov-complex.cc 2003/11/22 02:00:25 at @ -43,6 +43,8 @@ #include "gripes.h" #include "pr-output.h" +#include "ls-oct-ascii.h" + template class octave_base_scalar; DEFINE_OCTAVE_ALLOCATOR (octave_complex); at @ -144,6 +146,54 @@ octave_complex::complex_array_value (bool force_conversion) const { return ComplexNDArray (dim_vector (1, 1), scalar); +} + +bool octave_complex::save_ascii (std::ostream& os, bool& infnan_warned, + bool strip_nan_and_inf) +{ + os << "complex scalar\n"; + + Complex c = complex_value (); + + if (strip_nan_and_inf) + { + if (xisnan (c)) + { + error ("only value to plot is NaN"); + return false; + } + else + { + double re = real (c); + double im = imag (c); + + re = xisinf (re) ? (re > 0 ? OCT_RBV : -OCT_RBV) : re; + im = xisinf (im) ? (im > 0 ? OCT_RBV : -OCT_RBV) : im; + + c = Complex (re, im); + + octave_write_complex (os, c); + os << "\n"; + } + } + else + { + if (! infnan_warned && (xisnan (c) || xisinf (c))) + { + warning ("save: Inf or NaN values may not be reloadable"); + infnan_warned = true; + } + + octave_write_complex (os, c); + os << "\n"; + } + + return true; +} + +bool octave_complex::load_ascii (std::istream& is, bool& global) +{ + return false; } /* Index: ov-complex.h =================================================================== RCS file: /cvs/octave/src/ov-complex.h,v retrieving revision 1.22 diff -u -r1.22 ov-complex.h --- ov-complex.h 2003/11/14 19:49:56 1.22 +++ ov-complex.h 2003/11/22 02:00:25 at @ -98,6 +98,11 @@ void decrement (void) { scalar -= 1.0; } + bool save_ascii (std::ostream& os, bool& infnan_warned, + bool strip_nan_and_inf); + + bool load_ascii (std::istream& is, bool& global); + private: DECLARE_OCTAVE_ALLOCATOR Index: ov-cx-mat.cc =================================================================== RCS file: /cvs/octave/src/ov-cx-mat.cc,v retrieving revision 1.30 diff -u -r1.30 ov-cx-mat.cc --- ov-cx-mat.cc 2003/11/14 19:49:56 1.30 +++ ov-cx-mat.cc 2003/11/22 02:00:25 at @ -45,6 +45,8 @@ #include "ov-scalar.h" #include "pr-output.h" +#include "ls-oct-ascii.h" + template class octave_base_matrix; DEFINE_OCTAVE_ALLOCATOR (octave_complex_matrix); at @ -170,6 +172,73 @@ octave_complex_matrix::complex_matrix_value (bool) const { return matrix.matrix_value (); +} + +static ComplexMatrix +strip_infnan (const ComplexMatrix& m) +{ + int nr = m.rows (); + int nc = m.columns (); + + ComplexMatrix retval (nr, nc); + + int k = 0; + for (int i = 0; i < nr; i++) + { + for (int j = 0; j < nc; j++) + { + Complex c = m (i, j); + if (xisnan (c)) + goto next_row; + else + { + double re = real (c); + double im = imag (c); + + re = xisinf (re) ? (re > 0 ? OCT_RBV : -OCT_RBV) : re; + im = xisinf (im) ? (im > 0 ? OCT_RBV : -OCT_RBV) : im; + + retval (k, j) = Complex (re, im); + } + } + k++; + + next_row: + continue; + } + + if (k > 0) + retval.resize (k, nc); + + return retval; +} + +bool octave_complex_matrix::save_ascii (std::ostream& os, bool& infnan_warned, + bool strip_nan_and_inf) +{ + os << "complex matrix\n"; + + os << "# rows: " << rows () << "\n" + << "# columns: " << columns () << "\n"; + + ComplexMatrix tmp = complex_matrix_value (); + + if (strip_nan_and_inf) + tmp = strip_infnan (tmp); + else if (! infnan_warned && tmp.any_element_is_inf_or_nan ()) + { + warning ("save: Inf or NaN values may not be reloadable"); + infnan_warned = true; + } + + os << tmp; + + return true; +} + +bool octave_complex_matrix::load_ascii (std::istream& is, bool& global) +{ + return false; } /* Index: ov-cx-mat.h =================================================================== RCS file: /cvs/octave/src/ov-cx-mat.h,v retrieving revision 1.28 diff -u -r1.28 ov-cx-mat.h --- ov-cx-mat.h 2003/10/27 15:41:55 1.28 +++ ov-cx-mat.h 2003/11/22 02:00:25 at @ -108,6 +108,11 @@ void decrement (void) { matrix -= Complex (1.0); } + bool save_ascii (std::ostream& os, bool& infnan_warned, + bool strip_nan_and_inf); + + bool load_ascii (std::istream& is, bool& global); + private: DECLARE_OCTAVE_ALLOCATOR Index: ov-range.cc =================================================================== RCS file: /cvs/octave/src/ov-range.cc,v retrieving revision 1.34 diff -u -r1.34 ov-range.cc --- ov-range.cc 2003/11/14 19:49:56 1.34 +++ ov-range.cc 2003/11/22 02:00:25 at @ -250,6 +250,39 @@ return retval; } +bool octave_range::save_ascii (std::ostream& os, bool& infnan_warned, + bool strip_nan_and_inf) +{ + Range r = range_value (); + double base = r.base (); + double limit = r.limit (); + double inc = r.inc (); + + if (! (NINT (base) == base + && NINT (limit) == limit + && NINT (inc) == inc)) + { + octave_matrix val (matrix_value()); + + return val . save_ascii(os, infnan_warned, strip_nan_and_inf); + } + os << "range\n"; + os << "# base, limit, increment\n"; + octave_write_double (os, base); + os << " "; + octave_write_double (os, limit); + os << " "; + octave_write_double (os, inc); + os << "\n"; + + return true; +} + +bool octave_range::load_ascii (std::istream& is, bool& global) +{ + return false; +} + /* ;;; Local Variables: *** ;;; mode: C++ *** Index: ov-range.h =================================================================== RCS file: /cvs/octave/src/ov-range.h,v retrieving revision 1.35 diff -u -r1.35 ov-range.h --- ov-range.h 2003/11/17 03:48:04 1.35 +++ ov-range.h 2003/11/22 02:00:25 at @ -166,6 +166,11 @@ bool print_name_tag (std::ostream& os, const std::string& name) const; + bool save_ascii (std::ostream& os, bool& infnan_warned, + bool strip_nan_and_inf); + + bool load_ascii (std::istream& is, bool& global); + private: Range range; Index: ov-re-mat.cc =================================================================== RCS file: /cvs/octave/src/ov-re-mat.cc,v retrieving revision 1.36 diff -u -r1.36 ov-re-mat.cc --- ov-re-mat.cc 2003/11/14 19:49:56 1.36 +++ ov-re-mat.cc 2003/11/22 02:00:25 at @ -49,6 +49,8 @@ #include "pr-output.h" #include "variables.h" +#include "ls-oct-ascii.h" + #if ! defined (UCHAR_MAX) #define UCHAR_MAX 255 #endif at @ -202,6 +204,65 @@ } return retval; +} + +static Matrix +strip_infnan (const Matrix& m) +{ + int nr = m.rows (); + int nc = m.columns (); + + Matrix retval (nr, nc); + + int k = 0; + for (int i = 0; i < nr; i++) + { + for (int j = 0; j < nc; j++) + { + double d = m (i, j); + if (xisnan (d)) + goto next_row; + else + retval (k, j) = xisinf (d) ? (d > 0 ? OCT_RBV : -OCT_RBV) : d; + } + k++; + + next_row: + continue; + } + + if (k > 0) + retval.resize (k, nc); + + return retval; +} + +bool octave_matrix::save_ascii (std::ostream& os, bool& infnan_warned, + bool strip_nan_and_inf) +{ + os << "matrix\n"; + + os << "# rows: " << rows () << "\n" + << "# columns: " << columns () << "\n"; + + Matrix tmp = matrix_value (); + + if (strip_nan_and_inf) + tmp = strip_infnan (tmp); + else if (! infnan_warned && tmp.any_element_is_inf_or_nan ()) + { + warning ("save: Inf or NaN values may not be reloadable"); + infnan_warned = true; + } + + os << tmp; + + return true; +} + +bool octave_matrix::load_ascii (std::istream& is, bool& global) +{ + return false; } /* Index: ov-re-mat.h =================================================================== RCS file: /cvs/octave/src/ov-re-mat.h,v retrieving revision 1.33 diff -u -r1.33 ov-re-mat.h --- ov-re-mat.h 2003/10/27 15:41:55 1.33 +++ ov-re-mat.h 2003/11/22 02:00:25 at @ -109,6 +109,11 @@ octave_value convert_to_str_internal (bool pad, bool force) const; + bool save_ascii (std::ostream& os, bool& infnan_warned, + bool strip_nan_and_inf); + + bool load_ascii (std::istream& is, bool& global); + private: DECLARE_OCTAVE_ALLOCATOR Index: ov-scalar.cc =================================================================== RCS file: /cvs/octave/src/ov-scalar.cc,v retrieving revision 1.22 diff -u -r1.22 ov-scalar.cc --- ov-scalar.cc 2003/11/14 19:49:56 1.22 +++ ov-scalar.cc 2003/11/22 02:00:25 at @ -43,6 +43,8 @@ #include "xdiv.h" #include "xpow.h" +#include "ls-oct-ascii.h" + template class octave_base_scalar; DEFINE_OCTAVE_ALLOCATOR (octave_scalar); at @ -100,6 +102,47 @@ } return retval; +} + +bool octave_scalar::save_ascii (std::ostream& os, bool& infnan_warned, + bool strip_nan_and_inf) +{ + os << "scalar\n"; + + double d = double_value (); + + if (strip_nan_and_inf) + { + if (xisnan (d)) + { + error ("only value to plot is NaN"); + return false; + } + else + { + d = xisinf (d) ? (d > 0 ? OCT_RBV : -OCT_RBV) : d; + octave_write_double (os, d); + os << "\n"; + } + } + else + { + if (! infnan_warned && (xisnan (d) || xisinf (d))) + { + warning ("save: Inf or NaN values may not be reloadable"); + infnan_warned = true; + } + + octave_write_double (os, d); + os << "\n"; + } + + return true; +} + +bool octave_scalar::load_ascii (std::istream& is, bool& global) +{ + return false; } /* Index: ov-scalar.h =================================================================== RCS file: /cvs/octave/src/ov-scalar.h,v retrieving revision 1.28 diff -u -r1.28 ov-scalar.h --- ov-scalar.h 2003/11/18 18:18:16 1.28 +++ ov-scalar.h 2003/11/22 02:00:26 at @ -106,6 +106,11 @@ void decrement (void) { --scalar; } + bool save_ascii (std::ostream& os, bool& infnan_warned, + bool strip_nan_and_inf); + + bool load_ascii (std::istream& is, bool& global); + private: DECLARE_OCTAVE_ALLOCATOR Index: ov-str-mat.cc =================================================================== RCS file: /cvs/octave/src/ov-str-mat.cc,v retrieving revision 1.34 diff -u -r1.34 ov-str-mat.cc --- ov-str-mat.cc 2003/11/14 19:49:56 1.34 +++ ov-str-mat.cc 2003/11/22 02:00:26 at @ -190,6 +190,34 @@ current_print_indent_level (), true); } +bool octave_char_matrix_str::save_ascii (std::ostream& os, + bool& infnan_warned, + bool strip_nan_and_inf) +{ + os << "string array\n"; + charMatrix chm = char_matrix_value (); + int elements = chm.rows (); + os << "# elements: " << elements << "\n"; + for (int i = 0; i < elements; i++) + { + unsigned len = chm.cols (); + os << "# length: " << len << "\n"; + std::string tstr = chm.row_as_string (i, false, true); + const char *tmp = tstr.data (); + if (tstr.length () > len) + panic_impossible (); + os.write (X_CAST (char *, tmp), len); + os << "\n"; + } + + return true; +} + +bool octave_char_matrix_str::load_ascii (std::istream& is, bool& global) +{ + return false; +} + /* ;;; Local Variables: *** ;;; mode: C++ *** Index: ov-str-mat.h =================================================================== RCS file: /cvs/octave/src/ov-str-mat.h,v retrieving revision 1.30 diff -u -r1.30 ov-str-mat.h --- ov-str-mat.h 2003/10/30 05:48:17 1.30 +++ ov-str-mat.h 2003/11/22 02:00:26 at @ -114,6 +114,11 @@ void print_raw (std::ostream& os, bool pr_as_read_syntax = false) const; + bool save_ascii (std::ostream& os, bool& infnan_warned, + bool strip_nan_and_inf); + + bool load_ascii (std::istream& is, bool& global); + private: DECLARE_OCTAVE_ALLOCATOR Index: ov-typeinfo.cc =================================================================== RCS file: /cvs/octave/src/ov-typeinfo.cc,v retrieving revision 1.26 diff -u -r1.26 ov-typeinfo.cc --- ov-typeinfo.cc 2003/11/15 12:51:20 1.26 +++ ov-typeinfo.cc 2003/11/22 02:00:26 at @ -380,6 +380,19 @@ return retval; } +octave_value +octave_value_typeinfo::lookup_type (const std::string &nm) +{ + for (int i = 0;i < num_types; i++) + if (nm == types(i)) + { + // FIXME: How do I initialize an octave_value of the right type? + return octave_value(); + } + + return octave_value(); +} + DEFUN (typeinfo, args, , "-*- texinfo -*-\n\ at deftypefn {Built-in Function} {} typeinfo (@var{expr})\n\ Index: ov-typeinfo.h =================================================================== RCS file: /cvs/octave/src/ov-typeinfo.h,v retrieving revision 1.14 diff -u -r1.14 ov-typeinfo.h --- ov-typeinfo.h 2003/11/14 19:49:56 1.14 +++ ov-typeinfo.h 2003/11/22 02:00:26 at @ -111,6 +111,8 @@ return instance->do_installed_type_names (); } + octave_value lookup_type (const std::string nm); + protected: octave_value_typeinfo (void) Index: ov.cc =================================================================== RCS file: /cvs/octave/src/ov.cc,v retrieving revision 1.97 diff -u -r1.97 ov.cc --- ov.cc 2003/11/11 00:23:35 1.97 +++ ov.cc 2003/11/22 02:00:27 at @ -1503,6 +1503,23 @@ rep->print_info (os, prefix + " "); } +bool octave_value::save_ascii (std::ostream& os, bool& infnan_warned, + bool strip_nan_and_inf) +{ + gripe_wrong_type_arg ("octave_value::save_ascii()", type_name()); + + os << "\n"; + + return false; +} + +bool octave_value::load_ascii (std::istream& is, bool& global) +{ + gripe_wrong_type_arg ("octave_value::load_ascii()", type_name()); + + return false; +} + static void gripe_unary_op (const std::string& on, const std::string& tn) { Index: ov.h =================================================================== RCS file: /cvs/octave/src/ov.h,v retrieving revision 1.90 diff -u -r1.90 ov.h --- ov.h 2003/11/14 19:49:56 1.90 +++ ov.h 2003/11/22 02:00:28 at @ -627,6 +627,12 @@ virtual void print_info (std::ostream& os, const std::string& prefix = std::string ()) const; + bool save_ascii (std::ostream& os, bool& infnan_warned, + bool strip_nan_and_inf); + + bool load_ascii (std::istream& is, bool& global); + + protected: octave_value (const octave_xvalue&) : rep (0) { } --zjcmjzIkjQU2rmur--