GNU Octave 10.1.0
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
 
Loading...
Searching...
No Matches
ov-oncleanup.cc
Go to the documentation of this file.
1////////////////////////////////////////////////////////////////////////
2//
3// Copyright (C) 2010-2025 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 "pt-misc.h"
37
39 "onCleanup");
40
42 : m_fcn (f)
43{
44 if (f.is_function_handle ())
45 {
47 if (! fptr)
48 error ("onCleanup: no default dispatch for function handle");
49
51 = dynamic_cast<octave_user_function *> (fptr);
52
53 if (uptr != nullptr)
54 {
55 octave::tree_parameter_list *pl = uptr->parameter_list ();
56
57 if (pl != nullptr && pl->size () > 0)
58 warning ("onCleanup: cleanup action takes parameters");
59 }
60 }
61 else
62 {
64 error ("onCleanup: argument must be a function handle");
65 }
66}
67
72
75{
76 octave_scalar_map retval;
77 retval.setfield ("task", m_fcn);
78 return retval;
79}
80
81bool
82octave_oncleanup::save_ascii (std::ostream& /* os */)
83{
84 warning ("save: unable to save onCleanup variables, skipping");
85
86 return true;
87}
88
89bool
90octave_oncleanup::load_ascii (std::istream& /* is */)
91{
92 // Silently skip object that was not saved
93 return true;
94}
95
96bool
97octave_oncleanup::save_binary (std::ostream& /* os */,
98 bool /* save_as_floats */)
99{
100 warning ("save: unable to save onCleanup variables, skipping");
101
102 return true;
103}
104
105bool
106octave_oncleanup::load_binary (std::istream& /* is */, bool /* swap */,
107 octave::mach_info::float_format /* fmt */)
108{
109 // Silently skip object that was not saved
110 return true;
111}
112
113bool
115 const char * /* name */,
116 bool /* save_as_floats */)
117{
118 warning ("save: unable to save onCleanup variables, skipping");
119
120 return true;
121}
122
123bool
125 const char * /* name */)
126{
127 // Silently skip object that was not saved
128 return true;
129}
130
131void
132octave_oncleanup::print (std::ostream& os, bool pr_as_read_syntax)
133{
134 print_raw (os, pr_as_read_syntax);
135 newline (os);
136}
137
138void
139octave_oncleanup::print_raw (std::ostream& os, bool pr_as_read_syntax) const
140{
141 os << "onCleanup (";
142 if (m_fcn.is_defined ())
143 m_fcn.print_raw (os, pr_as_read_syntax);
144 os << ')';
145}
146
147void
149{
150 if (m_fcn.is_undefined ())
151 return;
152
153 octave_value the_fcn = m_fcn;
154 m_fcn = octave_value ();
155
156 octave::unwind_protect frame;
157
158 // Clear interrupts.
159 frame.protect_var (octave_interrupt_state);
161
162 // Disallow quit().
163 frame.protect_var (quit_allowed);
164 quit_allowed = false;
165
166 octave::interpreter& interp = octave::__get_interpreter__ ();
167
168 octave::interpreter_try (frame);
169
170 try
171 {
172 // Run the actual code.
173 interp.feval (the_fcn);
174 }
175 catch (const octave::interrupt_exception&)
176 {
177 interp.recover_from_exception ();
178
179 warning ("onCleanup: interrupt occurred in cleanup action");
180 }
181 catch (const octave::execution_exception& ee)
182 {
183 interp.recover_from_exception ();
184
185 std::string msg = ee.message ();
186
187 warning ("onCleanup: error caught while executing cleanup function:\n%s\n",
188 msg.c_str ());
189
190 }
191 catch (const octave::exit_exception&)
192 {
193 // This shouldn't happen since we disabled quit above.
194 warning ("onCleanup: exit disabled while executing cleanup function");
195 }
196 catch (...) // Yes, the black hole. We're in a d-tor.
197 {
198 // This shouldn't happen, in theory.
199 warning ("onCleanup: internal error: unhandled exception in cleanup action");
200 }
201}
202
204
205DEFUN (onCleanup, args, ,
206 doc: /* -*- texinfo -*-
207@deftypefn {} {@var{obj} =} onCleanup (@var{function})
208Create a special object that executes a given @var{function} upon destruction.
209
210If the object is copied to multiple variables (or cell or struct array
211elements) or returned from a function, then @var{function} will be executed
212only after the last copy of the object is cleared.
213
214The input @var{function} is a handle to a function. The handle may point to an
215anonymous function in order to directly place commands in the @code{onCleanup}
216call.
217
218Programming Note: If multiple local @code{onCleanup} variables are created, the
219order in which they are called is unspecified. For similar functionality
220@xref{The unwind_protect Statement}.
221
222Example
223
224@example
225@group
226octave:1> trigger = onCleanup (@@() disp ('onCleanup was executed'));
227octave:2> clear trigger
228onCleanup was executed
229octave:3
230@end group
231@end example
232
233@end deftypefn */)
234{
235 if (args.length () != 1)
236 print_usage ();
237
238 return ovl (new octave_oncleanup (args(0)));
239}
240
241/*
242%!test
243%! old_wstate = warning ("query");
244%! unwind_protect
245%! trigger = onCleanup (@() warning ("on", "__MY_WARNING__"));
246%! warning ("off", "__MY_WARNING__");
247%! assert ((warning ("query", "__MY_WARNING__")).state, "off");
248%! clear trigger;
249%! assert ((warning ("query", "__MY_WARNING__")).state, "on");
250%! unwind_protect_cleanup
251%! warning (old_wstate);
252%! end_unwind_protect
253*/
254
255OCTAVE_END_NAMESPACE(octave)
void newline(std::ostream &os) const
Definition ov-base.cc:1377
virtual octave_function * function_value(bool silent=false)
Definition ov-base.cc:935
friend class octave_value
Definition ov-base.h:278
bool save_hdf5(octave_hdf5_id loc_id, const char *name, bool save_as_floats)
void call_object_destructor()
bool load_hdf5(octave_hdf5_id loc_id, const char *name)
void print_raw(std::ostream &os, bool pr_as_read_syntax=false) const
octave_scalar_map scalar_map_value() const
bool save_binary(std::ostream &os, bool save_as_floats)
bool load_ascii(std::istream &is)
octave_value m_fcn
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)
bool save_ascii(std::ostream &os)
octave_oncleanup()=default
void setfield(const std::string &key, const octave_value &val)
Definition oct-map.cc:190
octave::tree_parameter_list * parameter_list()
Definition ov-usr-fcn.h:387
bool is_undefined() const
Definition ov.h:595
void print_raw(std::ostream &os, bool pr_as_read_syntax=false) const
Definition ov.h:1339
bool is_defined() const
Definition ov.h:592
OCTAVE_BEGIN_NAMESPACE(octave) static octave_value daspk_fcn
void print_usage()
Definition defun-int.h:72
#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:1078
void error(const char *fmt,...)
Definition error.cc:1003
bool quit_allowed
F77_RET_T const F77_DBLE const F77_DBLE * f
FloatComplex(* fptr)(const FloatComplex &, float, int, octave_idx_type &)
int64_t octave_hdf5_id
#define DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA(t, n, c)
Definition ov-base.h:246
octave_value_list ovl(const OV_Args &... args)
Construct an octave_value_list with less typing.
Definition ovl.h:217
std::atomic< sig_atomic_t > octave_interrupt_state
Definition quit.cc:39