Mercurial > octave
annotate libcruft/misc/quit.h @ 7481:78f3811155f7
use exceptions in liboctave error handler
author | John W. Eaton <jwe@octave.org> |
---|---|
date | Thu, 14 Feb 2008 17:14:23 -0500 |
parents | a1dbe9d80eee |
children | c37081b9d5c9 |
rev | line source |
---|---|
4153 | 1 /* |
2 | |
7017 | 3 Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007 John W. Eaton |
4153 | 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 | |
7016 | 9 Free Software Foundation; either version 3 of the License, or (at your |
10 option) any later version. | |
4153 | 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 | |
7016 | 18 along with Octave; see the file COPYING. If not, see |
19 <http://www.gnu.org/licenses/>. | |
4153 | 20 |
21 */ | |
22 | |
23 #if !defined (octave_quit_h) | |
24 #define octave_quit_h 1 | |
25 | |
26 #ifdef __cplusplus | |
4268 | 27 #include <new> |
4153 | 28 extern "C" { |
29 #endif | |
30 | |
4180 | 31 #include <stdio.h> |
4153 | 32 |
4180 | 33 #include <signal.h> |
4153 | 34 #include <setjmp.h> |
35 | |
5451 | 36 #if defined (__WIN32__) && ! defined (_POSIX_VERSION) |
37 | |
38 #include <windows.h> | |
6123 | 39 #undef min |
40 #undef max | |
5451 | 41 |
6107 | 42 CRUFT_API extern void w32_sigint_init (void); /* setup */ |
43 CRUFT_API extern void w32_raise_final (void); /* tear down */ | |
44 CRUFT_API extern void w32_raise (int sig); /* raise signal in main thread */ | |
45 CRUFT_API extern int w32_in_main_thread (void); /* return true if in main thread */ | |
5451 | 46 |
47 #endif | |
48 | |
4180 | 49 #if defined (OCTAVE_HAVE_SIG_JUMP) |
50 | |
51 typedef sigjmp_buf octave_jmp_buf; | |
52 | |
53 #define octave_set_current_context sigsetjmp (current_context, 1) | |
54 | |
55 #else | |
56 | |
57 typedef jmp_buf octave_jmp_buf; | |
58 | |
59 #define octave_set_current_context setjmp (current_context) | |
60 | |
61 #endif | |
62 | |
6107 | 63 CRUFT_API extern octave_jmp_buf current_context; |
4153 | 64 |
6107 | 65 CRUFT_API extern void octave_save_current_context (void *); |
4153 | 66 |
6107 | 67 CRUFT_API extern void octave_restore_current_context (void *); |
4153 | 68 |
6107 | 69 CRUFT_API extern void octave_jump_to_enclosing_context (void) GCC_ATTR_NORETURN; |
4153 | 70 |
6107 | 71 CRUFT_API extern void octave_save_signal_mask (void); |
4153 | 72 |
6107 | 73 CRUFT_API extern void octave_restore_signal_mask (void); |
4153 | 74 |
75 #ifdef __cplusplus | |
76 class | |
7481
78f3811155f7
use exceptions in liboctave error handler
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
77 octave_execution_exception |
78f3811155f7
use exceptions in liboctave error handler
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
78 { |
78f3811155f7
use exceptions in liboctave error handler
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
79 }; |
78f3811155f7
use exceptions in liboctave error handler
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
80 |
78f3811155f7
use exceptions in liboctave error handler
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
81 class |
4153 | 82 octave_interrupt_exception |
83 { | |
84 }; | |
85 #endif | |
86 | |
7481
78f3811155f7
use exceptions in liboctave error handler
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
87 enum octave_exception |
78f3811155f7
use exceptions in liboctave error handler
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
88 { |
78f3811155f7
use exceptions in liboctave error handler
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
89 octave_no_exception = 0, |
78f3811155f7
use exceptions in liboctave error handler
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
90 octave_exec_exception = 1, |
78f3811155f7
use exceptions in liboctave error handler
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
91 octave_alloc_exception = 2 |
78f3811155f7
use exceptions in liboctave error handler
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
92 }; |
78f3811155f7
use exceptions in liboctave error handler
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
93 |
6107 | 94 CRUFT_API extern sig_atomic_t octave_interrupt_immediately; |
4153 | 95 |
5133 | 96 /* |
97 > 0: interrupt pending | |
98 0: no interrupt pending | |
99 < 0: handling interrupt | |
100 */ | |
6107 | 101 CRUFT_API extern sig_atomic_t octave_interrupt_state; |
4180 | 102 |
7481
78f3811155f7
use exceptions in liboctave error handler
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
103 CRUFT_API extern sig_atomic_t octave_exception_state; |
4153 | 104 |
6107 | 105 CRUFT_API extern sig_atomic_t octave_signal_caught; |
5142 | 106 |
6107 | 107 CRUFT_API extern void octave_handle_signal (void); |
5142 | 108 |
6107 | 109 CRUFT_API extern void octave_throw_interrupt_exception (void) GCC_ATTR_NORETURN; |
4153 | 110 |
7481
78f3811155f7
use exceptions in liboctave error handler
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
111 CRUFT_API extern void octave_throw_execution_exception (void) GCC_ATTR_NORETURN; |
78f3811155f7
use exceptions in liboctave error handler
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
112 |
6107 | 113 CRUFT_API extern void octave_throw_bad_alloc (void) GCC_ATTR_NORETURN; |
4180 | 114 |
7481
78f3811155f7
use exceptions in liboctave error handler
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
115 CRUFT_API extern void octave_rethrow_exception (void) GCC_ATTR_NORETURN; |
78f3811155f7
use exceptions in liboctave error handler
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
116 |
4153 | 117 #define OCTAVE_QUIT \ |
118 do \ | |
119 { \ | |
5142 | 120 if (octave_signal_caught) \ |
4153 | 121 { \ |
5142 | 122 octave_signal_caught = 0; \ |
123 octave_handle_signal (); \ | |
4153 | 124 } \ |
125 } \ | |
126 while (0) | |
127 | |
4302 | 128 /* Normally, you just want to use |
129 | |
130 BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; | |
131 ... some code that calls a "foreign" function ... | |
132 END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; | |
133 | |
134 but sometimes it is useful to do something like | |
135 | |
136 BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE_1; | |
137 ... custom code here, normally ending in a call to | |
7481
78f3811155f7
use exceptions in liboctave error handler
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
138 octave_rethrow_exception ... |
4302 | 139 BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE_2; |
140 | |
141 so that you can perform extra clean up operations before throwing | |
142 the interrupt exception. */ | |
143 | |
4153 | 144 #define BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE \ |
4302 | 145 BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE_1; \ |
7481
78f3811155f7
use exceptions in liboctave error handler
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
146 octave_rethrow_exception (); \ |
4302 | 147 BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE_2 |
148 | |
149 #define BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE_1 \ | |
4153 | 150 do \ |
151 { \ | |
4182 | 152 octave_jmp_buf saved_context; \ |
4153 | 153 \ |
5760 | 154 octave_save_current_context (saved_context); \ |
4153 | 155 \ |
156 if (octave_set_current_context) \ | |
157 { \ | |
5760 | 158 octave_restore_current_context (saved_context) |
4302 | 159 |
160 #define BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE_2 \ | |
4153 | 161 } \ |
162 else \ | |
163 { \ | |
4182 | 164 octave_interrupt_immediately++ |
4153 | 165 |
166 #define END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE \ | |
4182 | 167 octave_interrupt_immediately--; \ |
5760 | 168 octave_restore_current_context (saved_context); \ |
4153 | 169 } \ |
170 } \ | |
171 while (0) | |
172 | |
4196 | 173 #ifdef __cplusplus |
174 | |
4180 | 175 #define BEGIN_INTERRUPT_WITH_EXCEPTIONS \ |
4182 | 176 sig_atomic_t saved_octave_interrupt_immediately = octave_interrupt_immediately; \ |
4180 | 177 \ |
4182 | 178 try \ |
4180 | 179 { \ |
4182 | 180 octave_interrupt_immediately = 0; |
4180 | 181 |
182 #define END_INTERRUPT_WITH_EXCEPTIONS \ | |
183 } \ | |
4182 | 184 catch (octave_interrupt_exception) \ |
4180 | 185 { \ |
4182 | 186 octave_interrupt_immediately = saved_octave_interrupt_immediately; \ |
4180 | 187 octave_jump_to_enclosing_context (); \ |
188 } \ | |
7481
78f3811155f7
use exceptions in liboctave error handler
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
189 catch (octave_execution_exception) \ |
78f3811155f7
use exceptions in liboctave error handler
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
190 { \ |
78f3811155f7
use exceptions in liboctave error handler
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
191 octave_interrupt_immediately = saved_octave_interrupt_immediately; \ |
78f3811155f7
use exceptions in liboctave error handler
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
192 octave_exception_state = octave_exec_exception; \ |
78f3811155f7
use exceptions in liboctave error handler
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
193 octave_jump_to_enclosing_context (); \ |
78f3811155f7
use exceptions in liboctave error handler
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
194 } \ |
4181 | 195 catch (std::bad_alloc) \ |
4180 | 196 { \ |
4182 | 197 octave_interrupt_immediately = saved_octave_interrupt_immediately; \ |
7481
78f3811155f7
use exceptions in liboctave error handler
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
198 octave_exception_state = octave_alloc_exception; \ |
4180 | 199 octave_jump_to_enclosing_context (); \ |
200 } \ | |
201 \ | |
4182 | 202 octave_interrupt_immediately = saved_octave_interrupt_immediately |
4196 | 203 #endif |
4153 | 204 |
205 #ifdef __cplusplus | |
206 } | |
4560 | 207 |
4572 | 208 /* These should only be declared for C++ code, and should also be |
209 outside of any extern "C" block. */ | |
4560 | 210 |
6107 | 211 extern CRUFT_API void (*octave_signal_hook) (void); |
212 extern CRUFT_API void (*octave_interrupt_hook) (void); | |
213 extern CRUFT_API void (*octave_bad_alloc_hook) (void); | |
4560 | 214 |
4153 | 215 #endif |
216 | |
217 #endif | |
218 | |
219 /* | |
220 ;;; Local Variables: *** | |
221 ;;; mode: C++ *** | |
222 ;;; End: *** | |
223 */ |