GNU Octave  6.2.0
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
ov-oncleanup.cc
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////
2 //
3 // Copyright (C) 2010-2021 The Octave Project Developers
4 //
5 // See the file COPYRIGHT.md in the top-level directory of this
6 // distribution or <https://octave.org/copyright/>.
7 //
8 // This file is part of Octave.
9 //
10 // Octave is free software: you can redistribute it and/or modify it
11 // under the terms of the GNU General Public License as published by
12 // the Free Software Foundation, either version 3 of the License, or
13 // (at your option) any later version.
14 //
15 // Octave is distributed in the hope that it will be useful, but
16 // WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 // GNU General Public License for more details.
19 //
20 // You should have received a copy of the GNU General Public License
21 // along with Octave; see the file COPYING. If not, see
22 // <https://www.gnu.org/licenses/>.
23 //
24 ////////////////////////////////////////////////////////////////////////
25 
26 #if defined (HAVE_CONFIG_H)
27 # include "config.h"
28 #endif
29 
30 #include "defun.h"
31 #include "interpreter.h"
32 #include "interpreter-private.h"
33 #include "ov-oncleanup.h"
34 #include "ov-fcn.h"
35 #include "ov-usr-fcn.h"
36 #include "parse.h"
37 #include "pt-misc.h"
38 
40  "onCleanup");
41 
43  : fcn (f)
44 {
45  if (f.is_function_handle ())
46  {
47  octave_function *fptr = f.function_value (true);
48  if (! fptr)
49  error ("onCleanup: no default dispatch for function handle");
50 
52  = dynamic_cast<octave_user_function *> (fptr);
53 
54  if (uptr != nullptr)
55  {
57 
58  if (pl != nullptr && pl->length () > 0)
59  warning ("onCleanup: cleanup action takes parameters");
60  }
61  }
62  else
63  {
64  fcn = octave_value ();
65  error ("onCleanup: argument must be a function handle");
66  }
67 }
68 
70 {
72 }
73 
76 {
78  retval.setfield ("task", fcn);
79  return retval;
80 }
81 
82 bool
83 octave_oncleanup::save_ascii (std::ostream& /* os */)
84 {
85  warning ("save: unable to save onCleanup variables, skipping");
86 
87  return true;
88 }
89 
90 bool
91 octave_oncleanup::load_ascii (std::istream& /* is */)
92 {
93  // Silently skip object that was not saved
94  return true;
95 }
96 
97 bool
98 octave_oncleanup::save_binary (std::ostream& /* os */,
99  bool /* save_as_floats */)
100 {
101  warning ("save: unable to save onCleanup variables, skipping");
102 
103  return true;
104 }
105 
106 bool
107 octave_oncleanup::load_binary (std::istream& /* is */, bool /* swap */,
109 {
110  // Silently skip object that was not saved
111  return true;
112 }
113 
114 bool
116  const char * /* name */,
117  bool /* save_as_floats */)
118 {
119  warning ("save: unable to save onCleanup variables, skipping");
120 
121  return true;
122 }
123 
124 bool
126  const char * /* name */)
127 {
128  // Silently skip object that was not saved
129  return true;
130 }
131 
132 void
133 octave_oncleanup::print (std::ostream& os, bool pr_as_read_syntax)
134 {
135  print_raw (os, pr_as_read_syntax);
136  newline (os);
137 }
138 
139 void
140 octave_oncleanup::print_raw (std::ostream& os, bool pr_as_read_syntax) const
141 {
142  os << "onCleanup (";
143  if (fcn.is_defined ())
144  fcn.print_raw (os, pr_as_read_syntax);
145  os << ')';
146 }
147 
148 void
150 {
151  if (fcn.is_undefined ())
152  return;
153 
154  octave_value the_fcn = fcn;
155  fcn = octave_value ();
156 
158 
159  // Clear interrupts.
162 
163  // Disallow quit().
164  frame.protect_var (quit_allowed);
165  quit_allowed = false;
166 
167  octave::interpreter& interp
168  = octave::__get_interpreter__ ("octave_oncleanup::call_object_destructor");
169 
170  interpreter_try (frame);
171 
172  try
173  {
174  // Run the actual code.
175  octave::feval (the_fcn);
176  }
177  catch (const octave::interrupt_exception&)
178  {
179  interp.recover_from_exception ();
180 
181  warning ("onCleanup: interrupt occurred in cleanup action");
182  }
183  catch (const octave::execution_exception& ee)
184  {
185  interp.recover_from_exception ();
186 
187  std::string msg = ee.message ();
188 
189  warning ("onCleanup: error caught while executing cleanup function:\n%s\n",
190  msg.c_str ());
191 
192  }
193  catch (const octave::exit_exception&)
194  {
195  // This shouldn't happen since we disabled quit above.
196  warning ("onCleanup: exit disabled while executing cleanup function");
197  }
198  catch (...) // Yes, the black hole. We're in a d-tor.
199  {
200  // This shouldn't happen, in theory.
201  warning ("onCleanup: internal error: unhandled exception in cleanup action");
202  }
203 }
204 
205 DEFUN (onCleanup, args, ,
206  doc: /* -*- texinfo -*-
207 @deftypefn {} {@var{obj} =} onCleanup (@var{function})
208 Create a special object that executes a given function upon destruction.
209 
210 If the object is copied to multiple variables (or cell or struct array
211 elements) or returned from a function, @var{function} will be executed after
212 clearing the last copy of the object. Note that if multiple local onCleanup
213 variables are created, the order in which they are called is unspecified.
214 For similar functionality @xref{The unwind_protect Statement}.
215 @end deftypefn */)
216 {
217  if (args.length () != 1)
218  print_usage ();
219 
220  return ovl (new octave_oncleanup (args(0)));
221 }
222 
223 /*
224 %!test
225 %! old_wstate = warning ("query");
226 %! unwind_protect
227 %! trigger = onCleanup (@() warning ("on", "__MY_WARNING__"));
228 %! warning ("off", "__MY_WARNING__");
229 %! assert ((warning ("query", "__MY_WARNING__")).state, "off");
230 %! clear trigger;
231 %! assert ((warning ("query", "__MY_WARNING__")).state, "on");
232 %! unwind_protect_cleanup
233 %! warning (old_wstate);
234 %! end_unwind_protect
235 */
size_t length(void) const
Definition: base-list.h:53
void recover_from_exception(void)
void newline(std::ostream &os) const
Definition: ov-base.cc:1321
friend class octave_value
Definition: ov-base.h:228
octave_scalar_map scalar_map_value(void) const
Definition: ov-oncleanup.cc:75
bool save_hdf5(octave_hdf5_id loc_id, const char *name, bool save_as_floats)
void call_object_destructor(void)
bool load_hdf5(octave_hdf5_id loc_id, const char *name)
octave_oncleanup(void)=default
void print_raw(std::ostream &os, bool pr_as_read_syntax=false) const
bool save_binary(std::ostream &os, bool save_as_floats)
Definition: ov-oncleanup.cc:98
bool load_ascii(std::istream &is)
Definition: ov-oncleanup.cc:91
bool load_binary(std::istream &is, bool swap, octave::mach_info::float_format fmt)
void print(std::ostream &os, bool pr_as_read_syntax=false)
octave_value fcn
Definition: ov-oncleanup.h:100
bool save_ascii(std::ostream &os)
Definition: ov-oncleanup.cc:83
octave::tree_parameter_list * parameter_list(void)
Definition: ov-usr-fcn.h:394
void print_raw(std::ostream &os, bool pr_as_read_syntax=false) const
Definition: ov.h:1233
bool is_defined(void) const
Definition: ov.h:551
bool is_undefined(void) const
Definition: ov.h:554
OCTINTERP_API void print_usage(void)
Definition: defun.cc:53
#define DEFUN(name, args_name, nargout_name, doc)
Macro to define a builtin function.
Definition: defun.h:56
void warning(const char *fmt,...)
Definition: error.cc:1050
void interpreter_try(octave::unwind_protect &frame)
Definition: error.cc:2182
void error(const char *fmt,...)
Definition: error.cc:968
bool quit_allowed
Definition: interpreter.cc:85
F77_RET_T const F77_DBLE const F77_DBLE * f
FloatComplex(* fptr)(const FloatComplex &, float, int, octave_idx_type &)
Definition: lo-specfun.cc:1128
interpreter & __get_interpreter__(const std::string &who)
octave_value_list feval(const char *name, const octave_value_list &args, int nargout)
Evaluate an Octave function (built-in or interpreted) and return the list of result values.
Definition: oct-parse.cc:9580
int64_t octave_hdf5_id
#define DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA(t, n, c)
Definition: ov-base.h:180
octave_value::octave_value(const Array< char > &chm, char type) return retval
Definition: ov.cc:811
octave_value_list ovl(const OV_Args &... args)
Construct an octave_value_list with less typing.
Definition: ovl.h:211
sig_atomic_t octave_interrupt_state
Definition: quit.cc:38