changeset 4988:352d228d409b

[project @ 2004-09-11 13:05:38 by jwe]
author jwe
date Sat, 11 Sep 2004 13:05:39 +0000
parents bad4898b468e
children 19b73a80e1d9
files src/ChangeLog src/ls-oct-ascii.cc src/ov-fcn-handle.cc src/ov-fcn-handle.h src/ov-fcn-inline.cc src/variables.cc src/variables.h
diffstat 7 files changed, 447 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- a/src/ChangeLog	Fri Sep 10 20:24:06 2004 +0000
+++ b/src/ChangeLog	Sat Sep 11 13:05:39 2004 +0000
@@ -1,3 +1,22 @@
+2004-09-11  David Bateman  <dbateman@free.fr>
+
+	* ov-fcn-handle.cc (octave_fcn_handle::save_ascii,
+	octave_fcn_handle::load_ascii, octave_fcn_handle::save_binary,
+	octave_fcn_handle::load_binary, octave_fcn_handle::save_hdf5,
+	octave_fcn_handle::load_hdf5): New functions. 
+	* ov-fcn-handle.h: Provide decls.
+
+	* ov-fcn-inline.cc (octave_fcn_inline::load_ascii):
+	Allow spaces in saved function.
+ 	(octave_fcn_inline::save_hdf5): Properly close all HDF5 objects.
+
+	* ls-oct-ascii.cc (read_ascii_data): Check return type of 
+	<octave_value>.load_ascii for errors reading the variables
+
+	* variables.cc (lookup_function_handle, clear_variable,
+	clear_symbol): New functions.
+	* variables.h: Provide decls.
+
 2004-09-10  John W. Eaton  <jwe@octave.org>
 
 	* ov-builtin.cc (octave_builtin::do_multi_index_op): Use unwind
--- a/src/ls-oct-ascii.cc	Fri Sep 10 20:24:06 2004 +0000
+++ b/src/ls-oct-ascii.cc	Sat Sep 11 13:05:39 2004 +0000
@@ -377,7 +377,8 @@
       else
 	tc = octave_value_typeinfo::lookup_type (typ);
 
-      tc.load_ascii (is);
+      if (! tc.load_ascii (is))
+	error ("load: trouble reading ascii file `%s'", filename.c_str ());
     }
   else
     error ("load: failed to extract keyword specifying value type");
--- a/src/ov-fcn-handle.cc	Fri Sep 10 20:24:06 2004 +0000
+++ b/src/ov-fcn-handle.cc	Sat Sep 11 13:05:39 2004 +0000
@@ -45,6 +45,12 @@
 #include "pt-exp.h"
 #include "pt-assign.h"
 #include "variables.h"
+#include "parse.h"
+
+#include "byte-swap.h"
+#include "ls-oct-ascii.h"
+#include "ls-hdf5.h"
+#include "ls-utils.h"
 
 DEFINE_OCTAVE_ALLOCATOR (octave_fcn_handle);
 
@@ -91,6 +97,352 @@
   return retval;
 }
 
+bool
+octave_fcn_handle::save_ascii (std::ostream& os, bool&, bool)
+{
+  os << nm << "\n";
+  if (nm == "@<anonymous>")
+    {
+      OSSTREAM buf;
+      print_raw (buf, true);
+      os << OSSTREAM_STR (buf) << "\n" << OSSTREAM_ENDS;
+      OSSTREAM_FREEZE (buf);
+    }
+
+  return true;
+}
+
+bool
+octave_fcn_handle::load_ascii (std::istream& is)
+{
+  is >> nm;
+  if (nm == "@<anonymous>")
+    {
+      char c;
+      OSSTREAM buf;
+
+      // Skip preceeding newline(s)
+      while (is.get (c) && c == '\n');
+
+      if (is)
+	{
+	  buf << c;
+
+	  // Get a line of text whitespace characters included, leaving
+	  // newline in the stream
+	  while (is.peek () != '\n')
+	    {
+	      is.get (c);
+	      if (! is)
+		break;
+	      buf << c;
+	    }
+	}
+
+      buf << OSSTREAM_ENDS;
+
+      int parse_status;
+      octave_value anon_fcn_handle = eval_string (OSSTREAM_C_STR (buf), 
+						  true, parse_status);
+      OSSTREAM_FREEZE (buf);
+
+      fcn = anon_fcn_handle.fcn_handle_value () -> fcn;
+    }
+  else
+    {
+      fcn = lookup_function (nm);
+      if (! fcn.is_function ())
+	return false;
+    }
+
+  return true;
+}
+
+bool
+octave_fcn_handle::save_binary (std::ostream& os, bool&)
+{
+  FOUR_BYTE_INT tmp = nm.length ();
+  os.write (X_CAST (char *, &tmp), 4);
+  os.write (nm.c_str (), nm.length ());
+  if (nm == "@<anonymous>")
+    {
+      OSSTREAM buf;
+      print_raw (buf, true);
+      std::string stmp = OSSTREAM_STR (buf);
+      OSSTREAM_FREEZE (buf);
+      tmp = stmp.length ();
+      os.write (X_CAST (char *, &tmp), 4);
+      os.write (stmp.c_str (), stmp.length ());
+    }
+  return true;
+}
+
+bool
+octave_fcn_handle::load_binary (std::istream& is, bool swap,
+				oct_mach_info::float_format)
+{
+  FOUR_BYTE_INT tmp;
+  if (! is.read (X_CAST (char *, &tmp), 4))
+    return false;
+  if (swap)
+    swap_bytes<4> (&tmp);
+
+  OCTAVE_LOCAL_BUFFER (char, ctmp1, tmp+1);
+  is.read (ctmp1, tmp);
+  nm = std::string (ctmp1);
+
+  if (! is)
+    return false;
+
+  if (nm == "@<anonymous>")
+    {
+      if (! is.read (X_CAST (char *, &tmp), 4))
+	return false;
+      if (swap)
+	swap_bytes<4> (&tmp);
+
+      OCTAVE_LOCAL_BUFFER (char, ctmp2, tmp+1);
+      is.read (ctmp2, tmp);
+
+      int parse_status;
+      octave_value anon_fcn_handle = eval_string (ctmp2, true, parse_status);
+
+      fcn = anon_fcn_handle.fcn_handle_value () -> fcn;
+    }
+  else
+    {
+      fcn = lookup_function (nm);
+      if (! fcn.is_function ())
+	return false;
+    }
+  return true;
+}
+
+#if defined (HAVE_HDF5)
+bool
+octave_fcn_handle::save_hdf5 (hid_t loc_id, const char *name,
+			      bool /* save_as_floats */)
+{
+  hid_t group_hid = -1;
+  group_hid = H5Gcreate (loc_id, name, 0);
+  if (group_hid < 0 ) return false;
+
+  hid_t space_hid = -1, data_hid = -1, type_hid = -1;;
+  bool retval = true;
+
+  // attach the type of the variable
+  type_hid = H5Tcopy (H5T_C_S1);
+  H5Tset_size (type_hid, nm.length () + 1);
+  if (type_hid < 0)
+    {
+      H5Gclose (group_hid);
+      return false;
+    }
+
+  OCTAVE_LOCAL_BUFFER (hsize_t, hdims, 2);
+  hdims[0] = 0;
+  hdims[1] = 0;
+  space_hid = H5Screate_simple (0 , hdims, (hsize_t*) 0);
+  if (space_hid < 0)
+    {
+      H5Tclose (type_hid);
+      H5Gclose (group_hid);
+      return false;
+    }
+
+  data_hid = H5Dcreate (group_hid, "nm",  type_hid, space_hid, H5P_DEFAULT);
+  if (data_hid < 0 || H5Dwrite (data_hid, type_hid, H5S_ALL, H5S_ALL,
+				H5P_DEFAULT, (void*) nm.c_str ()) < 0)
+    {
+      H5Sclose (space_hid);
+      H5Tclose (type_hid);
+      H5Gclose (group_hid);
+      return false;
+    }
+  H5Dclose (data_hid);
+
+  if (nm == "@<anonymous>")
+    {
+      OSSTREAM buf;
+      print_raw (buf, true);
+      std::string stmp = OSSTREAM_STR (buf);
+      OSSTREAM_FREEZE (buf);
+
+      // attach the type of the variable
+      H5Tset_size (type_hid, stmp.length () + 1);
+      if (type_hid < 0)
+	{
+	  H5Gclose (group_hid);
+	  return false;
+	}
+
+      data_hid = H5Dcreate (group_hid, "fcn",  type_hid, space_hid,
+			    H5P_DEFAULT);
+      if (data_hid < 0 || H5Dwrite (data_hid, type_hid, H5S_ALL, H5S_ALL,
+				    H5P_DEFAULT, (void*) stmp.c_str ()) < 0)
+	{
+	  H5Sclose (space_hid);
+	  H5Tclose (type_hid);
+	  H5Gclose (group_hid);
+	  return false;
+	}
+
+      H5Dclose (data_hid);
+    }
+
+  H5Sclose (space_hid);
+  H5Tclose (type_hid);
+  H5Gclose (group_hid);
+
+  return retval;
+}
+
+bool
+octave_fcn_handle::load_hdf5 (hid_t loc_id, const char *name,
+			      bool /* have_h5giterate_bug */)
+{
+  hid_t group_hid, data_hid, space_hid, type_hid, type_class_hid, st_id;
+  hsize_t rank;
+  int slen;
+
+  group_hid = H5Gopen (loc_id, name);
+  if (group_hid < 0 ) return false;
+
+  data_hid = H5Dopen (group_hid, "nm");
+
+  if (data_hid < 0)
+    {
+      H5Gclose (group_hid);
+      return false;
+    }
+
+  type_hid = H5Dget_type (data_hid);
+  type_class_hid = H5Tget_class (type_hid);
+
+  if (type_class_hid != H5T_STRING)
+    {
+      H5Tclose (type_hid);
+      H5Dclose (data_hid);
+      H5Gclose (group_hid);
+      return false;
+    }
+
+  space_hid = H5Dget_space (data_hid);
+  rank = H5Sget_simple_extent_ndims (space_hid);
+
+  if (rank != 0)
+    {
+      H5Sclose (space_hid);
+      H5Tclose (type_hid);
+      H5Dclose (data_hid);
+      H5Gclose (group_hid);
+      return false;
+    }
+
+  slen = H5Tget_size (type_hid);
+  if (slen < 0)
+    {
+      H5Sclose (space_hid);
+      H5Tclose (type_hid);
+      H5Dclose (data_hid);
+      H5Gclose (group_hid);
+      return false;
+    }
+
+  OCTAVE_LOCAL_BUFFER (char, nm_tmp, slen);
+
+  // create datatype for (null-terminated) string to read into:
+  st_id = H5Tcopy (H5T_C_S1);
+  H5Tset_size (st_id, slen);
+
+  if (H5Dread (data_hid, st_id, H5S_ALL, H5S_ALL, H5P_DEFAULT,
+	       X_CAST (void *, nm_tmp)) < 0)
+    {
+      H5Sclose (space_hid);
+      H5Tclose (type_hid);
+      H5Gclose (group_hid);
+      return false;
+    }
+  H5Tclose (st_id);
+  H5Dclose (data_hid);
+  nm = nm_tmp;
+
+  if (nm == "@<anonymous>")
+    {
+      data_hid = H5Dopen (group_hid, "fcn");
+
+      if (data_hid < 0)
+	{
+	  H5Gclose (group_hid);
+	  return false;
+	}
+
+      type_hid = H5Dget_type (data_hid);
+      type_class_hid = H5Tget_class (type_hid);
+
+      if (type_class_hid != H5T_STRING)
+	{
+	  H5Tclose (type_hid);
+	  H5Dclose (data_hid);
+	  H5Gclose (group_hid);
+	  return false;
+	}
+
+      space_hid = H5Dget_space (data_hid);
+      rank = H5Sget_simple_extent_ndims (space_hid);
+
+      if (rank != 0)
+	{
+	  H5Sclose (space_hid);
+	  H5Tclose (type_hid);
+	  H5Dclose (data_hid);
+	  H5Gclose (group_hid);
+	  return false;
+	}
+
+      slen = H5Tget_size (type_hid);
+      if (slen < 0)
+	{
+	  H5Sclose (space_hid);
+	  H5Tclose (type_hid);
+	  H5Dclose (data_hid);
+	  H5Gclose (group_hid);
+	  return false;
+	}
+
+      OCTAVE_LOCAL_BUFFER (char, fcn_tmp, slen);
+
+      // create datatype for (null-terminated) string to read into:
+      st_id = H5Tcopy (H5T_C_S1);
+      H5Tset_size (st_id, slen);
+
+      if (H5Dread (data_hid, st_id, H5S_ALL, H5S_ALL, H5P_DEFAULT,
+		   X_CAST (void *, fcn_tmp)) < 0)
+	{
+	  H5Sclose (space_hid);
+	  H5Tclose (type_hid);
+	  H5Gclose (group_hid);
+	  return false;
+	}
+      H5Dclose (data_hid);
+      H5Tclose (st_id);
+
+      int parse_status;
+      octave_value anon_fcn_handle = eval_string (fcn_tmp, true, parse_status);
+
+      fcn = anon_fcn_handle.fcn_handle_value () -> fcn;
+    }
+  else
+    {
+      fcn = lookup_function (nm);
+      if (! fcn.is_function ())
+	return false;
+    }
+
+  return true;
+}
+#endif
+
 void
 octave_fcn_handle::print (std::ostream& os, bool pr_as_read_syntax) const
 {
--- a/src/ov-fcn-handle.h	Fri Sep 10 20:24:06 2004 +0000
+++ b/src/ov-fcn-handle.h	Sat Sep 11 13:05:39 2004 +0000
@@ -79,6 +79,22 @@
 
   std::string fcn_name (void) const { return nm; }
 
+  bool save_ascii (std::ostream& os, bool& infnan_warned,
+		 bool strip_nan_and_inf);
+
+  bool load_ascii (std::istream& is);
+
+  bool save_binary (std::ostream& os, bool& save_as_floats);
+
+  bool load_binary (std::istream& is, bool swap, 
+		    oct_mach_info::float_format fmt);
+
+#if defined (HAVE_HDF5)
+  bool save_hdf5 (hid_t loc_id, const char *name, bool save_as_floats);
+
+  bool load_hdf5 (hid_t loc_id, const char *name, bool have_h5giterate_bug);
+#endif
+
   void print (std::ostream& os, bool pr_as_read_syntax = false) const;
 
   void print_raw (std::ostream& os, bool pr_as_read_syntax = false) const;
--- a/src/ov-fcn-inline.cc	Fri Sep 10 20:24:06 2004 +0000
+++ b/src/ov-fcn-inline.cc	Sat Sep 11 13:05:39 2004 +0000
@@ -31,6 +31,7 @@
 #include <config.h>
 #endif
 
+#include <istream>
 #include <iostream>
 
 #include "defun.h"
@@ -125,7 +126,31 @@
       is >> nm;
       if (nm == "0")
 	nm = "";
-      is >> iftext;
+
+      char c;
+      OSSTREAM buf;
+
+      // Skip preceeding newline(s)
+      while (is.get (c) && c == '\n');
+
+      if (is)
+	{
+	  buf << c;
+
+	  // Get a line of text whitespace characters included, leaving
+	  // newline in the stream
+	  while (is.peek () != '\n')
+	    {
+	      is.get (c);
+	      if (! is)
+		break;
+	      buf << c;
+	    }
+	}
+
+      buf << OSSTREAM_ENDS;
+      iftext = OSSTREAM_STR (buf);
+      OSSTREAM_FREEZE (buf);
 
       octave_fcn_inline tmp (iftext, ifargs, nm);
       fcn = tmp.fcn;
@@ -331,6 +356,9 @@
     }
 
   H5Dclose (data_hid);
+  H5Sclose (space_hid);
+  H5Tclose (type_hid);
+  H5Gclose (group_hid);
 
   return retval;
 }
--- a/src/variables.cc	Fri Sep 10 20:24:06 2004 +0000
+++ b/src/variables.cc	Sat Sep 11 13:05:39 2004 +0000
@@ -897,6 +897,19 @@
 }
 
 octave_value
+lookup_function_handle (const std::string& nm)
+{
+  octave_value retval;
+
+  symbol_record *sr = curr_sym_tab->lookup (nm, true);
+
+  if (sr && sr->def ().is_function_handle ())
+    retval = sr->def ();
+
+  return retval;
+}
+
+octave_value
 get_global_value (const std::string& nm)
 {
   octave_value retval;
@@ -1921,13 +1934,24 @@
     } \
   while (0)
 
-
 bool
 clear_function (const std::string& nm)
 {
   return do_clear_function (nm);
 }
 
+bool
+clear_variable (const std::string& nm)
+{
+  return do_clear_variable (nm);
+}
+
+bool
+clear_symbol (const std::string& nm)
+{
+  return do_clear_symbol (nm);
+}
+
 DEFCMD (clear, args, ,
   "-*- texinfo -*-\n\
 @deffn {Command} clear [-x] pattern @dots{}\n\
--- a/src/variables.h	Fri Sep 10 20:24:06 2004 +0000
+++ b/src/variables.h	Sat Sep 11 13:05:39 2004 +0000
@@ -89,6 +89,8 @@
 
 extern octave_value lookup_user_function (const std::string& nm);
 
+extern octave_value lookup_function_handle (const std::string& nm);
+
 extern octave_value get_global_value (const std::string& nm);
 
 extern void set_global_value (const std::string& nm, const octave_value& val);
@@ -120,6 +122,8 @@
 extern bool mislocked (const std::string&);
 
 extern bool clear_function (const std::string& nm);
+extern bool clear_variable (const std::string& nm);
+extern bool clear_symbol (const std::string& nm);
 
 // Symbol table for symbols at the top level.
 extern symbol_table *top_level_sym_tab;