Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #ifdef HAVE_CONFIG_H
00024 #include <config.h>
00025 #endif
00026
00027 #include "defun.h"
00028 #include "ov-oncleanup.h"
00029 #include "ov-fcn.h"
00030 #include "ov-usr-fcn.h"
00031 #include "pt-misc.h"
00032 #include "toplev.h"
00033
00034 DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_oncleanup, "onCleanup",
00035 "onCleanup");
00036
00037 octave_oncleanup::octave_oncleanup (const octave_value& f)
00038 : fcn (f)
00039 {
00040 if (f.is_function_handle ())
00041 {
00042 octave_function *fptr = f.function_value (true);
00043 if (fptr)
00044 {
00045 octave_user_function *uptr
00046 = dynamic_cast<octave_user_function *> (fptr);
00047
00048 if (uptr != 0)
00049 {
00050 tree_parameter_list *pl = uptr->parameter_list ();
00051
00052 if (pl != 0 && pl->length () > 0)
00053 warning ("onCleanup: cleanup action takes parameters");
00054 }
00055 }
00056 else
00057 error ("onCleanup: no default dispatch for function handle");
00058 }
00059 else
00060 {
00061 fcn = octave_value ();
00062 error ("onCleanup: argument must be a function handle");
00063 }
00064 }
00065
00066 octave_oncleanup::~octave_oncleanup (void)
00067 {
00068 if (fcn.is_undefined ())
00069 return;
00070
00071 unwind_protect frame;
00072
00073
00074 frame.protect_var (octave_interrupt_state);
00075 octave_interrupt_state = 0;
00076
00077
00078 frame.protect_var (quit_allowed);
00079 quit_allowed = false;
00080
00081
00082 frame.protect_var (error_state);
00083 error_state = 0;
00084
00085 try
00086 {
00087
00088 fcn.do_multi_index_op (0, octave_value_list ());
00089 }
00090 catch (octave_interrupt_exception)
00091 {
00092
00093 warning ("onCleanup: interrupt occured in cleanup action");
00094 }
00095 catch (std::bad_alloc)
00096 {
00097
00098 warning ("onCleanup: out of memory occured in cleanup action");
00099 }
00100 catch (...)
00101 {
00102
00103 error ("onCleanup: internal error: unhandled exception in cleanup action");
00104 }
00105
00106
00107
00108
00109 if (error_state)
00110 {
00111 frame.discard_top ();
00112 octave_call_stack::backtrace_error_message ();
00113 }
00114 }
00115
00116 octave_scalar_map
00117 octave_oncleanup::scalar_map_value (void) const
00118 {
00119 octave_scalar_map retval;
00120 retval.setfield ("task", fcn);
00121 return retval;
00122 }
00123
00124 static void
00125 warn_save_load (void)
00126 {
00127 warning ("onCleanup: load and save not supported");
00128 }
00129
00130 bool
00131 octave_oncleanup::save_ascii (std::ostream& )
00132 {
00133 warn_save_load ();
00134 return true;
00135 }
00136
00137 bool
00138 octave_oncleanup::load_ascii (std::istream& )
00139 {
00140 warn_save_load ();
00141 return true;
00142 }
00143
00144 bool
00145 octave_oncleanup::save_binary (std::ostream& , bool& )
00146 {
00147 warn_save_load ();
00148 return true;
00149 }
00150
00151 bool
00152 octave_oncleanup::load_binary (std::istream& , bool ,
00153 oct_mach_info::float_format )
00154 {
00155 warn_save_load ();
00156 return true;
00157 }
00158
00159 #if defined (HAVE_HDF5)
00160 bool
00161 octave_oncleanup::save_hdf5 (hid_t , const char * ,
00162 bool )
00163 {
00164 warn_save_load ();
00165 return true;
00166 }
00167
00168 bool
00169 octave_oncleanup::load_hdf5 (hid_t , const char * )
00170 {
00171 warn_save_load ();
00172 return true;
00173 }
00174 #endif
00175
00176 void
00177 octave_oncleanup::print (std::ostream& os, bool pr_as_read_syntax) const
00178 {
00179 print_raw (os, pr_as_read_syntax);
00180 newline (os);
00181 }
00182
00183 void
00184 octave_oncleanup::print_raw (std::ostream& os, bool pr_as_read_syntax) const
00185 {
00186 os << "onCleanup (";
00187 if (fcn.is_defined ())
00188 fcn.print_raw (os, pr_as_read_syntax);
00189 os << ")";
00190 }
00191
00192 DEFUN (onCleanup, args, ,
00193 "-*- texinfo -*-\n\
00194 @deftypefn {Loadable Function} {@var{c} =} onCleanup (@var{action})\n\
00195 Create a special object that executes a given function upon destruction.\n\
00196 If the object is copied to multiple variables (or cell or struct array\n\
00197 elements) or returned from a function, @var{action} will be executed after\n\
00198 clearing the last copy of the object. Note that if multiple local onCleanup\n\
00199 variables are created, the order in which they are called is unspecified.\n\
00200 For similar functionality @xref{The unwind_protect Statement}.\n\
00201 @end deftypefn")
00202 {
00203 octave_value retval;
00204
00205 if (args.length () == 1)
00206 retval = octave_value (new octave_oncleanup (args(0)));
00207 else
00208 print_usage ();
00209
00210 return retval;
00211 }
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227