GNU Octave  3.8.0
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
ov-oncleanup.cc
Go to the documentation of this file.
1 /*
2 
3 Copyright (C) 2010-2013 VZLU Prague
4 
5 This file is part of Octave.
6 
7 Octave is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published by the
9 Free Software Foundation; either version 3 of the License, or (at your
10 option) any later version.
11 
12 Octave is distributed in the hope that it will be useful, but WITHOUT
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 for more details.
16 
17 You should have received a copy of the GNU General Public License
18 along with Octave; see the file COPYING. If not, see
19 <http://www.gnu.org/licenses/>.
20 
21 */
22 
23 #ifdef HAVE_CONFIG_H
24 #include <config.h>
25 #endif
26 
27 #include "defun.h"
28 #include "ov-oncleanup.h"
29 #include "ov-fcn.h"
30 #include "ov-usr-fcn.h"
31 #include "pt-misc.h"
32 #include "toplev.h"
33 
35  "onCleanup");
36 
38  : fcn (f)
39 {
40  if (f.is_function_handle ())
41  {
43  if (fptr)
44  {
46  = dynamic_cast<octave_user_function *> (fptr);
47 
48  if (uptr != 0)
49  {
50  tree_parameter_list *pl = uptr->parameter_list ();
51 
52  if (pl != 0 && pl->length () > 0)
53  warning ("onCleanup: cleanup action takes parameters");
54  }
55  }
56  else
57  error ("onCleanup: no default dispatch for function handle");
58  }
59  else
60  {
61  fcn = octave_value ();
62  error ("onCleanup: argument must be a function handle");
63  }
64 }
65 
67 {
68  if (fcn.is_undefined ())
69  return;
70 
71  unwind_protect frame;
72 
73  // Clear interrupts.
76 
77  // Disallow quit().
78  frame.protect_var (quit_allowed);
79  quit_allowed = false;
80 
81  // Clear errors.
82  frame.protect_var (error_state);
83  error_state = 0;
84 
85  try
86  {
87  // Run the actual code.
89  }
90  catch (octave_interrupt_exception)
91  {
92  // Swallow the interrupt.
93  warning ("onCleanup: interrupt occured in cleanup action");
94  }
95  catch (...) // Yes, the black hole. We're in a d-tor.
96  {
97  // This shouldn't happen, in theory.
98  error ("onCleanup: internal error: unhandled exception in cleanup action");
99  }
100 
101  // We don't want to ignore errors that occur in the cleanup code, so
102  // if an error is encountered there, leave error_state alone.
103  // Otherwise, set it back to what it was before.
104  if (error_state)
105  {
106  frame.discard_first ();
108  }
109 }
110 
113 {
114  octave_scalar_map retval;
115  retval.setfield ("task", fcn);
116  return retval;
117 }
118 
119 static void
121 {
122  warning ("onCleanup: load and save not supported");
123 }
124 
125 bool
126 octave_oncleanup::save_ascii (std::ostream& /* os */)
127 {
128  warn_save_load ();
129  return true;
130 }
131 
132 bool
133 octave_oncleanup::load_ascii (std::istream& /* is */)
134 {
135  warn_save_load ();
136  return true;
137 }
138 
139 bool
140 octave_oncleanup::save_binary (std::ostream& /* os */,
141  bool& /* save_as_floats */)
142 {
143  warn_save_load ();
144  return true;
145 }
146 
147 bool
148 octave_oncleanup::load_binary (std::istream& /* is */, bool /* swap */,
149  oct_mach_info::float_format /* fmt */)
150 {
151  warn_save_load ();
152  return true;
153 }
154 
155 #if defined (HAVE_HDF5)
156 bool
157 octave_oncleanup::save_hdf5 (hid_t /* loc_id */, const char * /* name */,
158  bool /* save_as_floats */)
159 {
160  warn_save_load ();
161  return true;
162 }
163 
164 bool
165 octave_oncleanup::load_hdf5 (hid_t /* loc_id */, const char * /* name */)
166 {
167  warn_save_load ();
168  return true;
169 }
170 #endif
171 
172 void
173 octave_oncleanup::print (std::ostream& os, bool pr_as_read_syntax) const
174 {
175  print_raw (os, pr_as_read_syntax);
176  newline (os);
177 }
178 
179 void
180 octave_oncleanup::print_raw (std::ostream& os, bool pr_as_read_syntax) const
181 {
182  os << "onCleanup (";
183  if (fcn.is_defined ())
184  fcn.print_raw (os, pr_as_read_syntax);
185  os << ")";
186 }
187 
188 DEFUN (onCleanup, args, ,
189  "-*- texinfo -*-\n\
190 @deftypefn {Built-in Function} {@var{c} =} onCleanup (@var{action})\n\
191 Create a special object that executes a given function upon destruction.\n\
192 If the object is copied to multiple variables (or cell or struct array\n\
193 elements) or returned from a function, @var{action} will be executed after\n\
194 clearing the last copy of the object. Note that if multiple local onCleanup\n\
195 variables are created, the order in which they are called is unspecified.\n\
196 For similar functionality @xref{The unwind_protect Statement}.\n\
197 @end deftypefn")
198 {
199  octave_value retval;
200 
201  if (args.length () == 1)
202  retval = octave_value (new octave_oncleanup (args(0)));
203  else
204  print_usage ();
205 
206  return retval;
207 }
208 
209 /*
210 %!test
211 %! old_wstate = warning ("query");
212 %! unwind_protect
213 %! trigger = onCleanup (@() warning ("on", "__MY_WARNING__"));
214 %! warning ("off", "__MY_WARNING__");
215 %! assert ((warning ("query", "__MY_WARNING__")).state, "off");
216 %! clear trigger;
217 %! assert ((warning ("query", "__MY_WARNING__")).state, "on");
218 %! unwind_protect_cleanup
219 %! warning (old_wstate);
220 %! end_unwind_protect
221 */