Index: src/ls-oct-ascii.cc =================================================================== RCS file: /cvs/octave/src/ls-oct-ascii.cc,v retrieving revision 1.1 diff -c -r1.1 ls-oct-ascii.cc *** src/ls-oct-ascii.cc 2003/11/19 21:22:39 1.1 --- src/ls-oct-ascii.cc 2003/11/23 20:41:49 *************** *** 26,32 **** #include #endif - #include #include #include --- 26,31 ---- *************** *** 71,97 **** // 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) { --- 70,77 ---- *************** *** 123,191 **** 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 - skip_comments (std::istream& is) - { - char c = '\0'; - while (is.get (c)) - { - if (c == ' ' || c == '\t' || c == '\n') - ; // Skip whitespace on way to beginning of next line. - else - break; - } - - for (;;) - { - if (is && (c == '%' || c == '#')) - while (is.get (c) && c != '\n') - ; // Skip to beginning of next line, ignoring everything. - else - break; - } - } - // Extract a KEYWORD and its value from stream IS, returning the // associated value in a new string. // --- 103,108 ---- *************** *** 267,273 **** // // [%#][ \t]*keyword[ \t]*int-value.*\n ! static bool extract_keyword (std::istream& is, const char *keyword, int& value) { bool status = false; --- 184,190 ---- // // [%#][ \t]*keyword[ \t]*int-value.*\n ! bool extract_keyword (std::istream& is, const char *keyword, int& value) { bool status = false; *************** *** 441,637 **** } else typ = tag; - - if (SUBSTRING_COMPARE_EQ (typ, 0, 6, "scalar")) - { - double tmp = octave_read_double (is); - if (is) - tc = tmp; - else - error ("load: failed to load scalar constant"); - } - else if (SUBSTRING_COMPARE_EQ (typ, 0, 6, "matrix")) - { - int nr = 0; - int nc = 0; - - if (extract_keyword (is, "rows", nr) && nr >= 0 - && extract_keyword (is, "columns", nc) && nc >= 0) - { - if (nr > 0 && nc > 0) - { - Matrix tmp (nr, nc); - is >> tmp; - if (is) - tc = tmp; - else - error ("load: failed to load matrix constant"); - } - else if (nr == 0 || nc == 0) - tc = Matrix (nr, nc); - else - panic_impossible (); - } - else - error ("load: failed to extract number of rows and columns"); - } - else if (SUBSTRING_COMPARE_EQ (typ, 0, 4, "cell")) - { - int nr = 0; - int nc = 0; - - if (extract_keyword (is, "rows", nr) && nr >= 0 - && extract_keyword (is, "columns", nc) && nc >= 0) - { - if (nr > 0 && nc > 0) - { - Cell tmp (nr, nc); - - for (int j = 0; j < nc; j++) - { - for (int i = 0; i < nr; i++) - { - octave_value t2; - - // recurse to read cell elements - std::string nm - = read_ascii_data (is, filename, global, t2, count); - - if (nm == CELL_ELT_TAG) - { - if (is) - tmp.elem (i, j) = t2; - } - else - { - error ("load: cell array element had unexpected name"); - goto cell_read_error; - } - } - } - - cell_read_error: - - if (is) - tc = tmp; - else - error ("load: failed to load cell element"); - } - else if (nr == 0 || nc == 0) - tc = Cell (nr, nc); - else - panic_impossible (); - } - else - error ("load: failed to extract number of rows and columns for cell array"); - } - else if (SUBSTRING_COMPARE_EQ (typ, 0, 14, "complex scalar")) - { - Complex tmp = octave_read_complex (is); - if (is) - tc = tmp; - else - error ("load: failed to load complex scalar constant"); - } - else if (SUBSTRING_COMPARE_EQ (typ, 0, 14, "complex matrix")) - { - int nr = 0; - int nc = 0; - - if (extract_keyword (is, "rows", nr) && nr > 0 - && extract_keyword (is, "columns", nc) && nc > 0) - { - ComplexMatrix tmp (nr, nc); - is >> tmp; - if (is) - tc = tmp; - else - error ("load: failed to load complex matrix constant"); - } - else - error ("load: failed to extract number of rows and columns"); - } - else if (SUBSTRING_COMPARE_EQ (typ, 0, 12, "string array")) - { - int elements; - if (extract_keyword (is, "elements", elements) && elements >= 0) - { - // XXX FIXME XXX -- need to be able to get max length - // before doing anything. - - charMatrix chm (elements, 0); - int max_len = 0; - for (int i = 0; i < elements; i++) - { - int len; - if (extract_keyword (is, "length", len) && len >= 0) - { - OCTAVE_LOCAL_BUFFER (char, tmp, len+1); - - if (len > 0 && ! is.read (X_CAST (char *, tmp), len)) - { - error ("load: failed to load string constant"); - break; - } - else - { - tmp [len] = '\0'; - if (len > max_len) - { - max_len = len; - chm.resize (elements, max_len, 0); - } - chm.insert (tmp, i, 0); - } - } - else - error ("load: failed to extract string length for element %d", i+1); - } - - if (! error_state) - tc = octave_value (chm, true); - } - else - error ("load: failed to extract number of string elements"); - } - else if (SUBSTRING_COMPARE_EQ (typ, 0, 6, "string")) - { - int len; - if (extract_keyword (is, "length", len) && len >= 0) - { - OCTAVE_LOCAL_BUFFER (char, tmp, len+1); - - if (len > 0 && ! is.read (X_CAST (char *, tmp), len)) - { - error ("load: failed to load string constant"); - } - else - { - tmp [len] = '\0'; ! if (is) ! tc = tmp; ! else ! error ("load: failed to load string constant"); ! } ! } ! else ! error ("load: failed to extract string length"); ! } ! else if (SUBSTRING_COMPARE_EQ (typ, 0, 5, "range")) ! { ! // # base, limit, range comment added by save (). ! skip_comments (is); ! Range tmp; ! is >> tmp; ! if (is) ! tc = tmp; ! else ! error ("load: failed to load range constant"); ! } ! else ! error ("load: unknown constant type `%s'", tag.c_str ()); } else error ("load: failed to extract keyword specifying value type"); --- 358,367 ---- } else typ = tag; ! tc = octave_value_typeinfo::lookup_type (typ); ! tc.load_ascii (is); } else error ("load: failed to extract keyword specifying value type"); *************** *** 678,864 **** 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 (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 ! gripe_wrong_type_arg ("save", val, false); os.precision (old_precision); --- 408,420 ---- os.precision (precision); octave_value val = val_arg; ! if (mark_as_global) ! os << "# type: global " << val.type_name () << "\n"; else ! os << "# type: " << val.type_name() << "\n"; ! ! success = val . save_ascii(os, infnan_warned, strip_nan_and_inf); os.precision (old_precision); Index: src/ls-oct-ascii.h =================================================================== RCS file: /cvs/octave/src/ls-oct-ascii.h,v retrieving revision 1.1 diff -c -r1.1 ls-oct-ascii.h *** src/ls-oct-ascii.h 2003/11/19 21:22:39 1.1 --- src/ls-oct-ascii.h 2003/11/23 20:41:49 *************** *** 23,30 **** --- 23,44 ---- #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); + + extern bool + extract_keyword (std::istream& is, const char *keyword, int& value); extern std::string read_ascii_data (std::istream& is, const std::string& filename, bool& global, Index: src/ov-base.cc =================================================================== RCS file: /cvs/octave/src/ov-base.cc,v retrieving revision 1.54 diff -c -r1.54 ov-base.cc *** src/ov-base.cc 2003/11/23 08:07:53 1.54 --- src/ov-base.cc 2003/11/23 20:41:49 *************** *** 521,526 **** --- 521,541 ---- return retval; } + bool octave_base_value::save_ascii (std::ostream& os, bool& infnan_warned, + bool strip_nan_and_inf) + { + gripe_wrong_type_arg ("octave_base_value::save_ascii()", type_name()); + + return false; + } + + bool octave_base_value::load_ascii (std::istream& is) + { + gripe_wrong_type_arg ("octave_base_value::load_ascii()", type_name()); + + return false; + } + CONVDECLX (matrix_conv) { return new octave_matrix (); Index: src/ov-base.h =================================================================== RCS file: /cvs/octave/src/ov-base.h,v retrieving revision 1.62 diff -c -r1.62 ov-base.h *** src/ov-base.h 2003/11/23 08:07:53 1.62 --- src/ov-base.h 2003/11/23 20:41:49 *************** *** 250,255 **** --- 250,260 ---- void print_info (std::ostream& os, const std::string& prefix) const; + bool save_ascii (std::ostream& os, bool& infnan_warned, + bool strip_nan_and_inf); + + bool load_ascii (std::istream& is); + private: DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA; Index: src/ov-bool-mat.cc =================================================================== RCS file: /cvs/octave/src/ov-bool-mat.cc,v retrieving revision 1.20 diff -c -r1.20 ov-bool-mat.cc *** src/ov-bool-mat.cc 2003/11/22 12:25:44 1.20 --- src/ov-bool-mat.cc 2003/11/23 20:41:49 *************** *** 44,49 **** --- 44,51 ---- #include "ov-re-mat.h" #include "pr-output.h" + #include "ls-oct-ascii.h" + template class octave_base_matrix; DEFINE_OCTAVE_ALLOCATOR (octave_bool_matrix); *************** *** 146,151 **** --- 148,209 ---- { octave_print_internal (os, matrix, pr_as_read_syntax, current_print_indent_level ()); + } + + + bool + octave_bool_matrix::save_ascii (std::ostream& os, bool& infnan_warned, + bool strip_nan_and_inf) + { + os << "# rows: " << rows () << "\n" + << "# columns: " << columns () << "\n"; + + Matrix tmp = matrix_value (); + + os << tmp; + + return true; + } + + bool + octave_bool_matrix::load_ascii (std::istream& is) + { + int nr = 0; + int nc = 0; + bool success = true; + + if (extract_keyword (is, "rows", nr) && nr >= 0 + && extract_keyword (is, "columns", nc) && nc >= 0) + { + if (nr > 0 && nc > 0) + { + Matrix tmp (nr, nc); + is >> tmp; + if (!is) + { + error ("load: failed to load matrix constant"); + success = false; + } + + boolMatrix btmp (nr,nc); + for (int j = 0; j < nc; j++) + for (int i = 0; i < nr; i++) + btmp.elem (i,j) = (tmp.elem (i, j) != 0.); + + matrix = btmp; + } + else if (nr == 0 || nc == 0) + matrix = boolMatrix (nr, nc); + else + panic_impossible (); + } + else + { + error ("load: failed to extract number of rows and columns"); + success = false; + } + + return success; } /* Index: src/ov-bool-mat.h =================================================================== RCS file: /cvs/octave/src/ov-bool-mat.h,v retrieving revision 1.30 diff -c -r1.30 ov-bool-mat.h *** src/ov-bool-mat.h 2003/11/22 12:25:44 1.30 --- src/ov-bool-mat.h 2003/11/23 20:41:49 *************** *** 117,122 **** --- 117,127 ---- 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); + protected: DECLARE_OCTAVE_ALLOCATOR Index: src/ov-bool.cc =================================================================== RCS file: /cvs/octave/src/ov-bool.cc,v retrieving revision 1.16 diff -c -r1.16 ov-bool.cc *** src/ov-bool.cc 2003/11/14 19:49:56 1.16 --- src/ov-bool.cc 2003/11/23 20:41:49 *************** *** 43,48 **** --- 43,50 ---- #include "ov-scalar.h" #include "pr-output.h" + #include "ls-oct-ascii.h" + template class octave_base_scalar; DEFINE_OCTAVE_ALLOCATOR (octave_bool); *************** *** 110,115 **** --- 112,143 ---- s[1] = '\0'; return octave_value (s); + } + + bool + octave_bool::save_ascii (std::ostream& os, bool& infnan_warned, + bool strip_nan_and_inf) + { + double d = double_value (); + + octave_write_double (os, d); + os << "\n"; + + return true; + } + + bool + octave_bool::load_ascii (std::istream& is) + { + scalar = (octave_read_double (is) != 0.); + + if (!is) + { + error ("load: failed to load scalar constant"); + return false; + } + + return true; } /* Index: src/ov-bool.h =================================================================== RCS file: /cvs/octave/src/ov-bool.h,v retrieving revision 1.22 diff -c -r1.22 ov-bool.h *** src/ov-bool.h 2003/11/18 18:18:16 1.22 --- src/ov-bool.h 2003/11/23 20:41:50 *************** *** 110,115 **** --- 110,120 ---- 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); + private: DECLARE_OCTAVE_ALLOCATOR Index: src/ov-cell.cc =================================================================== RCS file: /cvs/octave/src/ov-cell.cc,v retrieving revision 1.30 diff -c -r1.30 ov-cell.cc *** src/ov-cell.cc 2003/11/14 19:49:56 1.30 --- src/ov-cell.cc 2003/11/23 20:41:50 *************** *** 45,50 **** --- 45,52 ---- #include "ov-re-mat.h" #include "ov-scalar.h" + #include "ls-oct-ascii.h" + template class octave_base_matrix; DEFINE_OCTAVE_ALLOCATOR (octave_cell); *************** *** 393,398 **** --- 395,491 ---- 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 << "# 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) + { + int nr = 0; + int nc = 0; + bool success = true; + + if (extract_keyword (is, "rows", nr) && nr >= 0 + && extract_keyword (is, "columns", nc) && nc >= 0) + { + if (nr > 0 && nc > 0) + { + Cell tmp (nr, nc); + + for (int j = 0; j < nc; j++) + { + for (int i = 0; i < nr; i++) + { + octave_value t2; + bool dummy; + + // recurse to read cell elements + std::string nm + = read_ascii_data (is, 0, dummy, t2, count); + + if (nm == CELL_ELT_TAG) + { + if (is) + tmp.elem (i, j) = t2; + } + else + { + error ("load: cell array element had unexpected name"); + success = false; + goto cell_read_error; + } + } + } + + cell_read_error: + + if (is) + matrix = tmp; + else + { + error ("load: failed to load cell element"); + success = false; + } + } + else if (nr == 0 || nc == 0) + matrix = Cell (nr, nc); + else + panic_impossible (); + } + else { + error ("load: failed to extract number of rows and columns for cell array"); + success = false; + } + return success; } DEFUN (iscell, args, , Index: src/ov-cell.h =================================================================== RCS file: /cvs/octave/src/ov-cell.h,v retrieving revision 1.21 diff -c -r1.21 ov-cell.h *** src/ov-cell.h 2003/11/23 08:07:53 1.21 --- src/ov-cell.h 2003/11/23 20:41:50 *************** *** 111,116 **** --- 111,122 ---- 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); + private: DECLARE_OCTAVE_ALLOCATOR Index: src/ov-complex.cc =================================================================== RCS file: /cvs/octave/src/ov-complex.cc,v retrieving revision 1.22 diff -c -r1.22 ov-complex.cc *** src/ov-complex.cc 2003/11/14 19:49:56 1.22 --- src/ov-complex.cc 2003/11/23 20:41:50 *************** *** 43,48 **** --- 43,50 ---- #include "gripes.h" #include "pr-output.h" + #include "ls-oct-ascii.h" + template class octave_base_scalar; DEFINE_OCTAVE_ALLOCATOR (octave_complex); *************** *** 144,149 **** --- 146,207 ---- 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) + { + 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) + { + scalar = octave_read_complex (is); + + if (!is) + { + error ("load: failed to load complex scalar constant"); + return false; + } + + return true; } /* Index: src/ov-complex.h =================================================================== RCS file: /cvs/octave/src/ov-complex.h,v retrieving revision 1.22 diff -c -r1.22 ov-complex.h *** src/ov-complex.h 2003/11/14 19:49:56 1.22 --- src/ov-complex.h 2003/11/23 20:41:50 *************** *** 98,103 **** --- 98,108 ---- 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); + private: DECLARE_OCTAVE_ALLOCATOR Index: src/ov-cx-mat.cc =================================================================== RCS file: /cvs/octave/src/ov-cx-mat.cc,v retrieving revision 1.31 diff -c -r1.31 ov-cx-mat.cc *** src/ov-cx-mat.cc 2003/11/22 12:25:44 1.31 --- src/ov-cx-mat.cc 2003/11/23 20:41:50 *************** *** 45,50 **** --- 45,52 ---- #include "ov-scalar.h" #include "pr-output.h" + #include "ls-oct-ascii.h" + template class octave_base_matrix; DEFINE_OCTAVE_ALLOCATOR (octave_complex_matrix); *************** *** 170,175 **** --- 172,266 ---- 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 << "# 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) + { + int nr = 0; + int nc = 0; + bool success = true; + + if (extract_keyword (is, "rows", nr) && nr > 0 + && extract_keyword (is, "columns", nc) && nc > 0) + { + ComplexMatrix tmp (nr, nc); + is >> tmp; + if (! is) + { + error ("load: failed to load complex matrix constant"); + success = false; + } + matrix = tmp; + } + else + { + error ("load: failed to extract number of rows and columns"); + success = false; + } + + return success; } void Index: src/ov-cx-mat.h =================================================================== RCS file: /cvs/octave/src/ov-cx-mat.h,v retrieving revision 1.29 diff -c -r1.29 ov-cx-mat.h *** src/ov-cx-mat.h 2003/11/22 12:25:44 1.29 --- src/ov-cx-mat.h 2003/11/23 20:41:50 *************** *** 108,113 **** --- 108,118 ---- 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); + void print_raw (std::ostream& os, bool pr_as_read_syntax = false) const; private: Index: src/ov-range.cc =================================================================== RCS file: /cvs/octave/src/ov-range.cc,v retrieving revision 1.34 diff -c -r1.34 ov-range.cc *** src/ov-range.cc 2003/11/14 19:49:56 1.34 --- src/ov-range.cc 2003/11/23 20:41:51 *************** *** 250,255 **** --- 250,316 ---- return retval; } + // Skip white space and comments on stream IS. + + static void + skip_comments (std::istream& is) + { + char c = '\0'; + while (is.get (c)) + { + if (c == ' ' || c == '\t' || c == '\n') + ; // Skip whitespace on way to beginning of next line. + else + break; + } + + for (;;) + { + if (is && (c == '%' || c == '#')) + while (is.get (c) && c != '\n') + ; // Skip to beginning of next line, ignoring everything. + else + break; + } + } + + 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 (); + + 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) + { + // # base, limit, range comment added by save (). + skip_comments (is); + + is >> range; + + if (!is) + { + error ("load: failed to load range constant"); + return false; + } + + return true; + } + /* ;;; Local Variables: *** ;;; mode: C++ *** Index: src/ov-range.h =================================================================== RCS file: /cvs/octave/src/ov-range.h,v retrieving revision 1.35 diff -c -r1.35 ov-range.h *** src/ov-range.h 2003/11/17 03:48:04 1.35 --- src/ov-range.h 2003/11/23 20:41:51 *************** *** 166,171 **** --- 166,176 ---- 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); + private: Range range; Index: src/ov-re-mat.cc =================================================================== RCS file: /cvs/octave/src/ov-re-mat.cc,v retrieving revision 1.38 diff -c -r1.38 ov-re-mat.cc *** src/ov-re-mat.cc 2003/11/23 08:07:53 1.38 --- src/ov-re-mat.cc 2003/11/23 20:41:51 *************** *** 49,54 **** --- 49,56 ---- #include "pr-output.h" #include "variables.h" + #include "ls-oct-ascii.h" + #if ! defined (UCHAR_MAX) #define UCHAR_MAX 255 #endif *************** *** 224,229 **** --- 226,319 ---- } 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 << "# 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) + { + int nr = 0; + int nc = 0; + bool success = true; + + if (extract_keyword (is, "rows", nr) && nr >= 0 + && extract_keyword (is, "columns", nc) && nc >= 0) + { + if (nr > 0 && nc > 0) + { + Matrix tmp (nr, nc); + is >> tmp; + if (!is) + { + error ("load: failed to load matrix constant"); + success = false; + } + matrix = tmp; + } + else if (nr == 0 || nc == 0) + matrix = Matrix (nr, nc); + else + panic_impossible (); + } + else + { + error ("load: failed to extract number of rows and columns"); + success = false; + } + + return success; } void Index: src/ov-re-mat.h =================================================================== RCS file: /cvs/octave/src/ov-re-mat.h,v retrieving revision 1.35 diff -c -r1.35 ov-re-mat.h *** src/ov-re-mat.h 2003/11/23 08:07:53 1.35 --- src/ov-re-mat.h 2003/11/23 20:41:51 *************** *** 114,119 **** --- 114,124 ---- 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); + private: DECLARE_OCTAVE_ALLOCATOR Index: src/ov-scalar.cc =================================================================== RCS file: /cvs/octave/src/ov-scalar.cc,v retrieving revision 1.23 diff -c -r1.23 ov-scalar.cc *** src/ov-scalar.cc 2003/11/23 08:07:53 1.23 --- src/ov-scalar.cc 2003/11/23 20:41:51 *************** *** 43,48 **** --- 43,50 ---- #include "xdiv.h" #include "xpow.h" + #include "ls-oct-ascii.h" + template class octave_base_scalar; DEFINE_OCTAVE_ALLOCATOR (octave_scalar); *************** *** 113,118 **** --- 115,168 ---- } return retval; + } + + bool + octave_scalar::save_ascii (std::ostream& os, bool& infnan_warned, + bool strip_nan_and_inf) + { + 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) + { + scalar = octave_read_double (is); + if (!is) + { + error ("load: failed to load scalar constant"); + return false; + } + + return true; } /* Index: src/ov-scalar.h =================================================================== RCS file: /cvs/octave/src/ov-scalar.h,v retrieving revision 1.29 diff -c -r1.29 ov-scalar.h *** src/ov-scalar.h 2003/11/23 08:07:53 1.29 --- src/ov-scalar.h 2003/11/23 20:41:51 *************** *** 108,113 **** --- 108,118 ---- void decrement (void) { --scalar; } + bool save_ascii (std::ostream& os, bool& infnan_warned, + bool strip_nan_and_inf); + + bool load_ascii (std::istream& is); + private: DECLARE_OCTAVE_ALLOCATOR Index: src/ov-str-mat.cc =================================================================== RCS file: /cvs/octave/src/ov-str-mat.cc,v retrieving revision 1.35 diff -c -r1.35 ov-str-mat.cc *** src/ov-str-mat.cc 2003/11/22 12:25:44 1.35 --- src/ov-str-mat.cc 2003/11/23 20:41:51 *************** *** 41,46 **** --- 41,48 ---- #include "pr-output.h" #include "pt-mat.h" + #include "ls-oct-ascii.h" + DEFINE_OCTAVE_ALLOCATOR (octave_char_matrix_str); DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_char_matrix_str, "string", "char"); *************** *** 211,216 **** --- 213,298 ---- { octave_print_internal (os, matrix, pr_as_read_syntax, current_print_indent_level (), true); + } + + bool + octave_char_matrix_str::save_ascii (std::ostream& os, bool& infnan_warned, + bool strip_nan_and_inf) + { + 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) + { + int elements; + bool success = true; + + if (extract_keyword (is, "elements", elements) && elements >= 0) + { + // XXX FIXME XXX -- need to be able to get max length + // before doing anything. + + charMatrix chm (elements, 0); + int max_len = 0; + for (int i = 0; i < elements; i++) + { + int len; + if (extract_keyword (is, "length", len) && len >= 0) + { + OCTAVE_LOCAL_BUFFER (char, tmp, len+1); + + if (len > 0 && ! is.read (X_CAST (char *, tmp), len)) + { + error ("load: failed to load string constant"); + success = false; + break; + } + else + { + tmp [len] = '\0'; + if (len > max_len) + { + max_len = len; + chm.resize (elements, max_len, 0); + } + chm.insert (tmp, i, 0); + } + } + else + { + error ("load: failed to extract string length for element %d", + i+1); + success = false; + } + } + + if (! error_state) + matrix = chm; + + } + else + { + error ("load: failed to extract number of string elements"); + success = false; + } + + return success; } /* Index: src/ov-str-mat.h =================================================================== RCS file: /cvs/octave/src/ov-str-mat.h,v retrieving revision 1.31 diff -c -r1.31 ov-str-mat.h *** src/ov-str-mat.h 2003/11/22 12:25:44 1.31 --- src/ov-str-mat.h 2003/11/23 20:41:51 *************** *** 116,121 **** --- 116,126 ---- 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); + private: DECLARE_OCTAVE_ALLOCATOR Index: src/ov.cc =================================================================== RCS file: /cvs/octave/src/ov.cc,v retrieving revision 1.99 diff -c -r1.99 ov.cc *** src/ov.cc 2003/11/23 08:07:53 1.99 --- src/ov.cc 2003/11/23 20:41:52 *************** *** 1521,1527 **** rep->print_info (os, prefix + " "); } - static void gripe_unary_op (const std::string& on, const std::string& tn) { --- 1521,1526 ---- Index: src/ov.h =================================================================== RCS file: /cvs/octave/src/ov.h,v retrieving revision 1.93 diff -c -r1.93 ov.h *** src/ov.h 2003/11/23 08:07:53 1.93 --- src/ov.h 2003/11/23 20:41:53 *************** *** 637,642 **** --- 637,650 ---- virtual void print_info (std::ostream& os, const std::string& prefix = std::string ()) const; + virtual bool save_ascii (std::ostream& os, bool& infnan_warned, + bool strip_nan_and_inf) + { return rep->save_ascii (os, infnan_warned, strip_nan_and_inf); } + + virtual bool load_ascii (std::istream& is) + { return rep->load_ascii (is); } + + protected: octave_value (const octave_xvalue&) : rep (0) { }