changeset 14013:1734ebe27134

move onCleanup function and class to liboctinterp * ov-oncleanup.h, ov-oncleanup.cc: Move onCleanup class and function here. * onCleanup.cc: From here. * DLD-FUNCTIONS/module-list: Delete onCleanup.cc from the list. * src/Makefile.am (OV_INCLUDES): Add ov-oncleanup.h to the list. (OV_SRC): add ov-oncleanup.cc to the list. * ov.cc (register_types): Register octave_oncleanup here. * ov-typeinfo.cc (octave_value_typeinfo::instance_ok): Do register cleanup function.
author John W. Eaton <jwe@octave.org>
date Thu, 08 Dec 2011 00:52:39 -0500
parents 4faef552363d
children 907d03def9d5
files src/DLD-FUNCTIONS/module-files src/DLD-FUNCTIONS/onCleanup.cc src/Makefile.am src/ov-base.h src/ov-oncleanup.cc src/ov-oncleanup.h src/ov-typeinfo.cc src/ov.cc
diffstat 8 files changed, 335 insertions(+), 298 deletions(-) [+]
line wrap: on
line diff
--- a/src/DLD-FUNCTIONS/module-files	Thu Dec 08 00:49:51 2011 -0500
+++ b/src/DLD-FUNCTIONS/module-files	Thu Dec 08 00:52:39 2011 -0500
@@ -57,7 +57,6 @@
 md5sum.cc
 mgorth.cc
 nproc.cc
-onCleanup.cc
 pinv.cc
 qr.cc|$(QRUPDATE_CPPFLAGS) $(SPARSE_XCPPFLAGS)|$(QRUPDATE_LDFLAGS) $(SPARSE_XLDFLAGS)|$(QRUPDATE_LIBS) $(SPARSE_XLIBS)
 quad.cc
--- a/src/DLD-FUNCTIONS/onCleanup.cc	Thu Dec 08 00:49:51 2011 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,292 +0,0 @@
-/*
-
-Copyright (C) 2010-2011 VZLU Prague
-
-This file is part of Octave.
-
-Octave is free software; you can redistribute it and/or modify it
-under the terms of the GNU General Public License as published by the
-Free Software Foundation; either version 3 of the License, or (at your
-option) any later version.
-
-Octave is distributed in the hope that it will be useful, but WITHOUT
-ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-for more details.
-
-You should have received a copy of the GNU General Public License
-along with Octave; see the file COPYING.  If not, see
-<http://www.gnu.org/licenses/>.
-
-*/
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "defun-dld.h"
-#include "ov-base.h"
-#include "ov.h"
-#include "ov-fcn.h"
-#include "ov-usr-fcn.h"
-#include "pt-misc.h"
-#include "toplev.h"
-
-static void gripe_internal (void)
-{
-  error ("onCleanup: internal error: cloning nonempty object");
-}
-
-class octave_oncleanup : public octave_base_value, octave_auto_shlib
-{
-public:
-  octave_oncleanup (void) : fcn () { }
-  octave_oncleanup (const octave_value& fcn);
-
-  octave_base_value *clone (void) const
-    {
-      if (fcn.is_defined ())
-        gripe_internal ();
-      return empty_clone ();
-    }
-
-  octave_base_value *empty_clone (void) const { return new octave_oncleanup (); }
-
-  ~octave_oncleanup (void);
-
-  bool is_defined (void) const { return true; }
-
-  bool is_object (void) const { return true; } // do we want this?
-
-  octave_map map_value (void) const
-    { return scalar_map_value (); }
-
-  octave_scalar_map scalar_map_value (void) const;
-
-  dim_vector dims (void) const { static dim_vector dv (1, 1); return dv; }
-
-  bool save_ascii (std::ostream& os);
-
-  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);
-#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;
-
-private:
-
-  DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA
-
-protected:
-
-    octave_value fcn;
-
-};
-
-DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_oncleanup, "onCleanup", "onCleanup");
-
-octave_oncleanup::octave_oncleanup (const octave_value& f)
-  : fcn (f)
-{
-  if (f.is_function_handle ())
-    {
-      octave_function *fptr = f.function_value (true);
-      if (fptr)
-        {
-          octave_user_function *uptr = dynamic_cast<octave_user_function *> (fptr);
-          if (uptr != 0)
-            {
-              tree_parameter_list *pl = uptr->parameter_list ();
-              if (pl != 0 && pl->length () > 0)
-                warning ("onCleanup: cleanup action takes parameters");
-            }
-        }
-      else
-        error ("onCleanup: no default dispatch for function handle");
-    }
-  else
-    {
-      fcn = octave_value ();
-      error ("onCleanup: argument must be a function handle");
-    }
-}
-
-octave_oncleanup::~octave_oncleanup (void)
-{
-  if (fcn.is_undefined ())
-    return;
-
-  unwind_protect frame;
-
-  // Clear interrupts.
-  frame.protect_var (octave_interrupt_state);
-  octave_interrupt_state = 0;
-
-  // Disallow quit().
-  frame.protect_var (quit_allowed);
-  quit_allowed = false;
-
-  // Clear errors.
-  frame.protect_var (error_state);
-  error_state = 0;
-
-  try
-    {
-      // Run the actual code.
-      fcn.do_multi_index_op (0, octave_value_list ());
-    }
-  catch (octave_interrupt_exception)
-    {
-      // Swallow the interrupt.
-      warning ("onCleanup: interrupt occured in cleanup action");
-    }
-  catch (std::bad_alloc)
-    {
-      // Swallow the exception.
-      warning ("onCleanup: out of memory occured in cleanup action");
-    }
-  catch (...) // Yes, the black hole. We're in a d-tor.
-    {
-      // This shouldn't happen, in theory.
-      error ("onCleanup: internal error: unhandled exception in cleanup action");
-    }
-
-  // We don't want to ignore errors that occur in the cleanup code, so
-  // if an error is encountered there, leave error_state alone.
-  // Otherwise, set it back to what it was before.
-  if (error_state)
-    {
-      frame.discard_top ();
-      octave_call_stack::backtrace_error_message ();
-    }
-}
-
-octave_scalar_map
-octave_oncleanup::scalar_map_value (void) const
-{
-  octave_scalar_map retval;
-  retval.setfield ("task", fcn);
-  return retval;
-}
-
-static void
-warn_save_load (void)
-{
-  warning ("onCleanup: load and save not supported");
-}
-
-bool
-octave_oncleanup::save_ascii (std::ostream& /* os */)
-{
-  warn_save_load ();
-  return true;
-}
-
-bool
-octave_oncleanup::load_ascii (std::istream& /* is */)
-{
-  warn_save_load ();
-  return true;
-}
-
-bool
-octave_oncleanup::save_binary (std::ostream& /* os */, bool& /* save_as_floats */)
-{
-  warn_save_load ();
-  return true;
-}
-
-
-bool
-octave_oncleanup::load_binary (std::istream& /* is */, bool /* swap */,
-                               oct_mach_info::float_format /* fmt */)
-{
-  warn_save_load ();
-  return true;
-}
-
-#if defined (HAVE_HDF5)
-bool
-octave_oncleanup::save_hdf5 (hid_t /* loc_id */, const char * /* name */,
-                             bool /* save_as_floats */)
-{
-  warn_save_load ();
-  return true;
-}
-
-bool
-octave_oncleanup::load_hdf5 (hid_t /* loc_id */, const char * /* name */)
-{
-  warn_save_load ();
-  return true;
-}
-#endif
-
-void
-octave_oncleanup::print (std::ostream& os, bool pr_as_read_syntax) const
-{
-  print_raw (os, pr_as_read_syntax);
-  newline (os);
-}
-
-void
-octave_oncleanup::print_raw (std::ostream& os, bool pr_as_read_syntax) const
-{
-  os << "onCleanup (";
-  if (fcn.is_defined ())
-    fcn.print_raw (os, pr_as_read_syntax);
-  os << ")";
-}
-
-DEFUN_DLD (onCleanup, args, ,
-  "-*- texinfo -*-\n\
-@deftypefn {Loadable Function} {@var{c} =} onCleanup (@var{action})\n\
-Create a special object that executes a given function upon destruction.\n\
-If the object is copied to multiple variables (or cell or struct array\n\
-elements) or returned from a function, @var{action} will be executed after\n\
-clearing the last copy of the object.  Note that if multiple local onCleanup\n\
-variables are created, the order in which they are called is unspecified.\n\
-For similar functionality @xref{The @code{unwind_protect} Statement}.\n\
-@end deftypefn")
-{
-  octave_value retval;
-
-  if (args.length () == 1)
-    {
-      if (octave_oncleanup::static_type_id () < 0)
-        octave_oncleanup::register_type ();
-
-      retval = new octave_oncleanup (args(0));
-    }
-  else
-    print_usage ();
-
-  return retval;
-}
-
-/*
-
-%!test
-%! old_wstate = warning ("query");
-%! unwind_protect
-%!   trigger = onCleanup (@() warning ("on", "__MY_WARNING__"));
-%!   warning ("off", "__MY_WARNING__");
-%!   assert ((warning ("query", "__MY_WARNING__")).state, "off");
-%!   clear trigger
-%!   assert ((warning ("query", "__MY_WARNING__")).state, "on");
-%! unwind_protect_cleanup
-%!   warning (old_wstate);
-%! end_unwind_protect
-
-*/
--- a/src/Makefile.am	Thu Dec 08 00:49:51 2011 -0500
+++ b/src/Makefile.am	Thu Dec 08 00:52:39 2011 -0500
@@ -179,6 +179,7 @@
   ov-lazy-idx.h \
   ov-mex-fcn.h \
   ov-null-mat.h \
+  ov-oncleanup.h \
   ov-perm.h \
   ov-range.h \
   ov-re-diag.h \
@@ -357,6 +358,7 @@
   ov-lazy-idx.cc \
   ov-mex-fcn.cc \
   ov-null-mat.cc \
+  ov-oncleanup.cc \
   ov-perm.cc \
   ov-range.cc \
   ov-re-diag.cc \
--- a/src/ov-base.h	Thu Dec 08 00:49:51 2011 -0500
+++ b/src/ov-base.h	Thu Dec 08 00:52:39 2011 -0500
@@ -167,9 +167,9 @@
   const std::string t::c_name (c); \
   void t::register_type (void) \
     { \
-      t_id = octave_value_typeinfo::register_type (t::t_name, \
-                                                   t::c_name, \
-                                                   octave_value (new t ())); \
+      static t exemplar; \
+      octave_value v (&exemplar, true); \
+      t_id = octave_value_typeinfo::register_type (t::t_name, t::c_name, v); \
     }
 
 // A base value type, so that derived types only have to redefine what
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/ov-oncleanup.cc	Thu Dec 08 00:52:39 2011 -0500
@@ -0,0 +1,227 @@
+/*
+
+Copyright (C) 2010-2011 VZLU Prague
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "defun.h"
+#include "ov-cleanup.h"
+#include "ov-fcn.h"
+#include "ov-usr-fcn.h"
+#include "pt-misc.h"
+#include "toplev.h"
+
+DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_oncleanup, "onCleanup",
+                                     "onCleanup");
+
+octave_oncleanup::octave_oncleanup (const octave_value& f)
+  : fcn (f)
+{
+  if (f.is_function_handle ())
+    {
+      octave_function *fptr = f.function_value (true);
+      if (fptr)
+        {
+          octave_user_function *uptr
+            = dynamic_cast<octave_user_function *> (fptr);
+
+          if (uptr != 0)
+            {
+              tree_parameter_list *pl = uptr->parameter_list ();
+
+              if (pl != 0 && pl->length () > 0)
+                warning ("onCleanup: cleanup action takes parameters");
+            }
+        }
+      else
+        error ("onCleanup: no default dispatch for function handle");
+    }
+  else
+    {
+      fcn = octave_value ();
+      error ("onCleanup: argument must be a function handle");
+    }
+}
+
+octave_oncleanup::~octave_oncleanup (void)
+{
+  if (fcn.is_undefined ())
+    return;
+
+  unwind_protect frame;
+
+  // Clear interrupts.
+  frame.protect_var (octave_interrupt_state);
+  octave_interrupt_state = 0;
+
+  // Disallow quit().
+  frame.protect_var (quit_allowed);
+  quit_allowed = false;
+
+  // Clear errors.
+  frame.protect_var (error_state);
+  error_state = 0;
+
+  try
+    {
+      // Run the actual code.
+      fcn.do_multi_index_op (0, octave_value_list ());
+    }
+  catch (octave_interrupt_exception)
+    {
+      // Swallow the interrupt.
+      warning ("onCleanup: interrupt occured in cleanup action");
+    }
+  catch (std::bad_alloc)
+    {
+      // Swallow the exception.
+      warning ("onCleanup: out of memory occured in cleanup action");
+    }
+  catch (...) // Yes, the black hole. We're in a d-tor.
+    {
+      // This shouldn't happen, in theory.
+      error ("onCleanup: internal error: unhandled exception in cleanup action");
+    }
+
+  // We don't want to ignore errors that occur in the cleanup code, so
+  // if an error is encountered there, leave error_state alone.
+  // Otherwise, set it back to what it was before.
+  if (error_state)
+    {
+      frame.discard_top ();
+      octave_call_stack::backtrace_error_message ();
+    }
+}
+
+octave_scalar_map
+octave_oncleanup::scalar_map_value (void) const
+{
+  octave_scalar_map retval;
+  retval.setfield ("task", fcn);
+  return retval;
+}
+
+static void
+warn_save_load (void)
+{
+  warning ("onCleanup: load and save not supported");
+}
+
+bool
+octave_oncleanup::save_ascii (std::ostream& /* os */)
+{
+  warn_save_load ();
+  return true;
+}
+
+bool
+octave_oncleanup::load_ascii (std::istream& /* is */)
+{
+  warn_save_load ();
+  return true;
+}
+
+bool
+octave_oncleanup::save_binary (std::ostream& /* os */, bool& /* save_as_floats */)
+{
+  warn_save_load ();
+  return true;
+}
+
+bool
+octave_oncleanup::load_binary (std::istream& /* is */, bool /* swap */,
+                               oct_mach_info::float_format /* fmt */)
+{
+  warn_save_load ();
+  return true;
+}
+
+#if defined (HAVE_HDF5)
+bool
+octave_oncleanup::save_hdf5 (hid_t /* loc_id */, const char * /* name */,
+                             bool /* save_as_floats */)
+{
+  warn_save_load ();
+  return true;
+}
+
+bool
+octave_oncleanup::load_hdf5 (hid_t /* loc_id */, const char * /* name */)
+{
+  warn_save_load ();
+  return true;
+}
+#endif
+
+void
+octave_oncleanup::print (std::ostream& os, bool pr_as_read_syntax) const
+{
+  print_raw (os, pr_as_read_syntax);
+  newline (os);
+}
+
+void
+octave_oncleanup::print_raw (std::ostream& os, bool pr_as_read_syntax) const
+{
+  os << "onCleanup (";
+  if (fcn.is_defined ())
+    fcn.print_raw (os, pr_as_read_syntax);
+  os << ")";
+}
+
+DEFUN (onCleanup, args, ,
+  "-*- texinfo -*-\n\
+@deftypefn {Loadable Function} {@var{c} =} onCleanup (@var{action})\n\
+Create a special object that executes a given function upon destruction.\n\
+If the object is copied to multiple variables (or cell or struct array\n\
+elements) or returned from a function, @var{action} will be executed after\n\
+clearing the last copy of the object.  Note that if multiple local onCleanup\n\
+variables are created, the order in which they are called is unspecified.\n\
+For similar functionality @xref{The @code{unwind_protect} Statement}.\n\
+@end deftypefn")
+{
+  octave_value retval;
+
+  if (args.length () == 1)
+    retval = octave_value (new octave_oncleanup (args(0)));
+  else
+    print_usage ();
+
+  return retval;
+}
+
+/*
+
+%!test
+%! old_wstate = warning ("query");
+%! unwind_protect
+%!   trigger = onCleanup (@() warning ("on", "__MY_WARNING__"));
+%!   warning ("off", "__MY_WARNING__");
+%!   assert ((warning ("query", "__MY_WARNING__")).state, "off");
+%!   clear trigger
+%!   assert ((warning ("query", "__MY_WARNING__")).state, "on");
+%! unwind_protect_cleanup
+%!   warning (old_wstate);
+%! end_unwind_protect
+
+*/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/ov-oncleanup.h	Thu Dec 08 00:52:39 2011 -0500
@@ -0,0 +1,101 @@
+/*
+
+Copyright (C) 2010-2011 VZLU Prague
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <iosfwd>
+
+#include "ov-base.h"
+#include "ov-struct.h"
+#include "ov.h"
+
+static void
+gripe_internal (void)
+{
+  error ("onCleanup: internal error: cloning nonempty object");
+}
+
+class octave_oncleanup : public octave_base_value
+{
+public:
+  octave_oncleanup (void) : fcn () { }
+
+  octave_oncleanup (const octave_value& fcn);
+
+  octave_base_value *clone (void) const
+  {
+    if (fcn.is_defined ())
+      gripe_internal ();
+
+    return empty_clone ();
+  }
+
+  octave_base_value *empty_clone (void) const
+  {
+    return new octave_oncleanup ();
+  }
+
+  ~octave_oncleanup (void);
+
+  bool is_defined (void) const { return true; }
+
+  bool is_object (void) const { return true; } // do we want this?
+
+  octave_map map_value (void) const { return scalar_map_value (); }
+
+  octave_scalar_map scalar_map_value (void) const;
+
+  dim_vector dims (void) const
+  {
+    static dim_vector dv (1, 1);
+    return dv;
+  }
+
+  bool save_ascii (std::ostream& os);
+
+  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);
+#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;
+
+private:
+
+  DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA
+
+protected:
+
+  octave_value fcn;
+};
--- a/src/ov-typeinfo.cc	Thu Dec 08 00:49:51 2011 -0500
+++ b/src/ov-typeinfo.cc	Thu Dec 08 00:52:39 2011 -0500
@@ -46,10 +46,8 @@
     {
       instance = new octave_value_typeinfo ();
 
-#if 0
       if (instance)
         singleton_cleanup_list::add (cleanup_instance);
-#endif
     }
 
   if (! instance)
--- a/src/ov.cc	Thu Dec 08 00:49:51 2011 -0500
+++ b/src/ov.cc	Thu Dec 08 00:52:39 2011 -0500
@@ -65,6 +65,7 @@
 #include "ov-range.h"
 #include "ov-struct.h"
 #include "ov-class.h"
+#include "ov-cleanup.h"
 #include "ov-cs-list.h"
 #include "ov-colon.h"
 #include "ov-builtin.h"
@@ -2689,6 +2690,7 @@
   octave_null_str::register_type ();
   octave_null_sq_str::register_type ();
   octave_lazy_index::register_type ();
+  octave_oncleanup::register_type ();
 }
 
 DEFUN (sizeof, args, ,