Mercurial > hg > octave-terminal
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 +++ b/src/DLD-FUNCTIONS/module-files @@ -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
deleted file mode 100644 --- a/src/DLD-FUNCTIONS/onCleanup.cc +++ /dev/null @@ -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 +++ b/src/Makefile.am @@ -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 +++ b/src/ov-base.h @@ -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
new file mode 100644 --- /dev/null +++ b/src/ov-oncleanup.cc @@ -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 + +*/
new file mode 100644 --- /dev/null +++ b/src/ov-oncleanup.h @@ -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 +++ b/src/ov-typeinfo.cc @@ -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 +++ b/src/ov.cc @@ -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, ,