Mercurial > hg > xemacs-beta
comparison src/eval.c @ 853:2b6fa2618f76
[xemacs-hg @ 2002-05-28 08:44:22 by ben]
merge my stderr-proc ws
make-docfile.c: Fix places where we forget to check for EOF.
code-init.el: Don't use CRLF conversion by default on process output. CMD.EXE and
friends work both ways but Cygwin programs don't like the CRs.
code-process.el, multicast.el, process.el: Removed.
Improvements to call-process-internal:
-- allows a buffer to be specified for input and stderr output
-- use it on all systems
-- implement C-g as documented
-- clean up and comment
call-process-region uses new call-process facilities; no temp file.
remove duplicate funs in process.el.
comment exactly how coding systems work and fix various problems.
open-multicast-group now does similar coding-system frobbing to
open-network-stream.
dumped-lisp.el, faces.el, msw-faces.el: Fix some hidden errors due to code not being defined at the right time.
xemacs.mak: Add -DSTRICT.
================================================================
ALLOW SEPARATION OF STDOUT AND STDERR IN PROCESSES
================================================================
Standard output and standard error can be processed separately in
a process. Each can have its own buffer, its own mark in that buffer,
and its filter function. You can specify a separate buffer for stderr
in `start-process' to get things started, or use the new primitives:
set-process-stderr-buffer
process-stderr-buffer
process-stderr-mark
set-process-stderr-filter
process-stderr-filter
Also, process-send-region takes a 4th optional arg, a buffer.
Currently always uses a pipe() under Unix to read the error output.
(#### Would a PTY be better?)
sysdep.h, sysproc.h, unexfreebsd.c, unexsunos4.c, nt.c, emacs.c, callproc.c, symsinit.h, sysdep.c, Makefile.in.in, process-unix.c: Delete callproc.c. Move child_setup() to process-unix.c.
wait_for_termination() now only needed on a few really old systems.
console-msw.h, event-Xt.c, event-msw.c, event-stream.c, event-tty.c, event-unixoid.c, events.h, process-nt.c, process-unix.c, process.c, process.h, procimpl.h: Rewrite the process methods to handle a separate channel for
error input. Create Lstreams for reading in the error channel.
Many process methods need change. In general the changes are
fairly clear as they involve duplicating what's used for reading
the normal stdout and changing for stderr -- although tedious,
as such changes are required throughout the entire process code.
Rewrote the code that reads process output to do two loops, one
for stdout and one for stderr.
gpmevent.c, tooltalk.c: set_process_filter takes an argument for stderr.
================================================================
NEW ERROR-TRAPPING MECHANISM
================================================================
Totally rewrite error trapping code to be unified and support more
features. Basic function is call_trapping_problems(), which lets
you specify, by means of flags, what sorts of problems you want
trapped. these can include
-- quit
-- errors
-- throws past the function
-- creation of "display objects" (e.g. buffers)
-- deletion of already-existing "display objects" (e.g. buffers)
-- modification of already-existing buffers
-- entering the debugger
-- gc
-- errors->warnings (ala suspended errors)
etc. All other error funs rewritten in terms of this one.
Various older mechanisms removed or rewritten.
window.c, insdel.c, console.c, buffer.c, device.c, frame.c: When creating a display object, added call to
note_object_created(), for use with trapping_problems mechanism.
When deleting, call check_allowed_operation() and note_object
deleted().
The trapping-problems code records the objects created since the
call-trapping-problems began. Those objects can be deleted, but
none others (i.e. previously existing ones).
bytecode.c, cmdloop.c: internal_catch takes another arg.
eval.c: Add long comments describing the "five lists" used to maintain
state (backtrace, gcpro, specbind, etc.) in the Lisp engine.
backtrace.h, eval.c: Implement trapping-problems mechanism, eliminate old mechanisms or
redo in terms of new one.
frame.c, gutter.c: Flush out the concept of "critical display section", defined by
the in_display() var. Use an internal_bind() to get it reset,
rather than just doing it at end, because there may be a non-local
exit.
event-msw.c, event-stream.c, console-msw.h, device.c, dialog-msw.c, frame.c, frame.h, intl.c, toolbar.c, menubar-msw.c, redisplay.c, alloc.c, menubar-x.c: Make use of new trapping-errors stuff and rewrite code based on
old mechanisms.
glyphs-widget.c, redisplay.h: Protect calling Lisp in redisplay.
insdel.c: Protect hooks against deleting existing buffers.
frame-msw.c: Use EQ, not EQUAL in hash tables whose keys are just numbers.
Otherwise we run into stickiness in redisplay because
internal_equal() can QUIT.
================================================================
SIGNAL, C-G CHANGES
================================================================
Here we change the way that C-g interacts with event reading. The
idea is that a C-g occurring while we're reading a user event
should be read as C-g, but elsewhere should be a QUIT. The former
code did all sorts of bizarreness -- requiring that no QUIT occurs
anywhere in event-reading code (impossible to enforce given the
stuff called or Lisp code invoked), and having some weird system
involving enqueue/dequeue of a C-g and interaction with Vquit_flag
-- and it didn't work.
Now, we simply enclose all code where we want C-g read as an event
with {begin/end}_dont_check_for_quit(). This completely turns off
the mechanism that checks (and may remove or alter) C-g in the
read-ahead queues, so we just get the C-g normal.
Signal.c documents this very carefully.
cmdloop.c: Correct use of dont_check_for_quit to new scheme, remove old
out-of-date comments.
event-stream.c: Fix C-g handling to actually work.
device-x.c: Disable quit checking when err out.
signal.c: Cleanup. Add large descriptive comment.
process-unix.c, process-nt.c, sysdep.c: Use QUIT instead of REALLY_QUIT.
It's not necessary to use REALLY_QUIT and just confuses the issue.
lisp.h: Comment quit handlers.
================================================================
CONS CHANGES
================================================================
free_cons() now takes a Lisp_Object not the result of XCONS().
car and cdr have been renamed so that they don't get used directly;
go through XCAR(), XCDR() instead.
alloc.c, dired.c, editfns.c, emodules.c, fns.c, glyphs-msw.c, glyphs-x.c, glyphs.c, keymap.c, minibuf.c, search.c, eval.c, lread.c, lisp.h: Correct free_cons calling convention: now takes Lisp_Object,
not Lisp_Cons
chartab.c: Eliminate direct use of ->car, ->cdr, should be black box.
callint.c: Rewrote using EXTERNAL_LIST_LOOP to avoid use of Lisp_Cons.
================================================================
USE INTERNAL-BIND-*
================================================================
eval.c: Cleanups of these funs.
alloc.c, fileio.c, undo.c, specifier.c, text.c, profile.c, lread.c, redisplay.c, menubar-x.c, macros.c: Rewrote to use internal_bind_int() and internal_bind_lisp_object()
in place of whatever varied and cumbersome mechanisms were
formerly there.
================================================================
SPECBIND SANITY
================================================================
backtrace.h: - Improved comments
backtrace.h, bytecode.c, eval.c: Add new mechanism check_specbind_stack_sanity() for sanity
checking code each time the catchlist or specbind stack change.
Removed older prototype of same mechanism.
================================================================
MISC
================================================================
lisp.h, insdel.c, window.c, device.c, console.c, buffer.c: Fleshed out authorship.
device-msw.c: Correct bad Unicode-ization.
print.c: Be more careful when not initialized or in fatal error handling.
search.c: Eliminate running_asynch_code, an FSF holdover.
alloc.c: Added comments about gc-cons-threshold.
dialog-x.c: Use begin_gc_forbidden() around code to build up a widget value
tree, like in menubar-x.c.
gui.c: Use Qunbound not Qnil as the default for
gethash.
lisp-disunion.h, lisp-union.h: Added warnings on use of VOID_TO_LISP().
lisp.h: Use ERROR_CHECK_STRUCTURES to turn on
ERROR_CHECK_TRAPPING_PROBLEMS and ERROR_CHECK_TYPECHECK
lisp.h: Add assert_with_message.
lisp.h: Add macros for gcproing entire arrays. (You could do this before
but it required manual twiddling the gcpro structure.)
lisp.h: Add prototypes for new functions defined elsewhere.
author | ben |
---|---|
date | Tue, 28 May 2002 08:45:36 +0000 |
parents | e7ee5f8bde58 |
children | 804517e16990 |
comparison
equal
deleted
inserted
replaced
852:d83885ef293b | 853:2b6fa2618f76 |
---|---|
19 along with XEmacs; see the file COPYING. If not, write to | 19 along with XEmacs; see the file COPYING. If not, write to |
20 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, | 20 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, |
21 Boston, MA 02111-1307, USA. */ | 21 Boston, MA 02111-1307, USA. */ |
22 | 22 |
23 /* Synched up with: FSF 19.30 (except for Fsignal), Mule 2.0. */ | 23 /* Synched up with: FSF 19.30 (except for Fsignal), Mule 2.0. */ |
24 | |
25 /* Authorship: | |
26 | |
27 Based on code from pre-release FSF 19, c. 1991. | |
28 Some work by Richard Mlynarik long ago (c. 1993?) -- | |
29 added call-with-condition-handler; synch. up to released FSF 19.7 | |
30 for lemacs 19.8. some signal changes. | |
31 Various work by Ben Wing, 1995-1996: | |
32 added all stuff dealing with trapping errors, suspended-errors, etc. | |
33 added most Fsignal front ends. | |
34 added warning code. | |
35 reworked the Fsignal code and synched the rest up to FSF 19.30. | |
36 Some changes by Martin Buchholz c. 1999? | |
37 e.g. PRIMITIVE_FUNCALL macros. | |
38 New call_trapping_problems code and large comments below | |
39 by Ben Wing, Mar-Apr 2000. | |
40 */ | |
41 | |
42 /* This file has been Mule-ized. */ | |
43 | |
44 /* What is in this file? | |
45 | |
46 This file contains the engine for the ELisp interpreter in XEmacs. | |
47 The engine does the actual work of implementing function calls, | |
48 form evaluation, non-local exits (catch, throw, signal, | |
49 condition-case, call-with-condition-handler), unwind-protects, | |
50 dynamic bindings, let constructs, backtraces, etc. You might say | |
51 that this module is the very heart of XEmacs, and everything else | |
52 in XEmacs is merely an auxiliary module implementing some specific | |
53 functionality that may be called from the heart at an appropriate | |
54 time. | |
55 | |
56 The only exception is the alloc.c module, which implements the | |
57 framework upon which this module (eval.c) works. alloc.c works | |
58 with creating the actual Lisp objects themselves and garbage | |
59 collecting them as necessary, preseting a nice, high-level | |
60 interface for object creation, deletion, access, and modification. | |
61 | |
62 The only other exception that could be cited is the event-handling | |
63 module in event-stream.c. From its perspective, it is also the | |
64 heart of XEmacs, and controls exactly what gets done at what time. | |
65 From its perspective, eval.c is merely one of the auxiliary modules | |
66 out there that can be invoked by event-stream.c. | |
67 | |
68 Although the event-stream-centric view is a convenient fiction that | |
69 makes sense particularly from the user's perspective and from the | |
70 perspective of time, the engine-centric view is actually closest to | |
71 the truth, because anywhere within the event-stream module, you are | |
72 still somewhere in a Lisp backtrace, and event-loops are begun by | |
73 functions such as `command-loop-1', a Lisp function. | |
74 | |
75 As the Lisp engine is doing its thing, it maintains the state of | |
76 the engine primarily in five list-like items, with are: | |
77 | |
78 -- the backtrace list | |
79 -- the catchtag list | |
80 -- the condition-handler list | |
81 -- the specbind list | |
82 -- the GCPRO list. | |
83 | |
84 These are described in detail in the next comment. | |
85 | |
86 --ben | |
87 */ | |
88 | |
89 /* Note that there are five separate lists used to maintain state in | |
90 the evaluator. All of them conceptually are stacks (last-in, | |
91 first-out). All non-local exits happen ultimately through the | |
92 catch/throw mechanism, which uses one of the five lists (the | |
93 catchtag list) and records the current state of the others in each | |
94 frame of the list (some other information is recorded and restored | |
95 as well, such as the current eval depth), so that all the state of | |
96 the evaluator is restored properly when a non-local exit occurs. | |
97 (Note that the current state of the condition-handler list is not | |
98 recorded in the catchtag list. Instead, when a condition-case or | |
99 call-with-condition-handler is set up, it installs an | |
100 unwind-protect on the specbind list to restore the appropriate | |
101 setting for the condition-handler list. During the course of | |
102 handling the non-local exit, all entries on the specbind list that | |
103 are past the location stored in the catch frame are "unwound" | |
104 (i.e. variable bindings are restored and unwind-protects are | |
105 executed), so the condition-handler list gets reset properly. | |
106 | |
107 The five lists are | |
108 | |
109 1. The backtrace list, which is chained through `struct backtrace's | |
110 declared in the stack frames of various primitives, and keeps | |
111 track of all Lisp function call entries and exits. | |
112 2. The catchtag list, which is chained through `struct catchtag's | |
113 declared in the stack frames of internal_catch and condition_case_1, | |
114 and keeps track of information needed to reset the internal state | |
115 of the evaluator to the state that was current when the catch or | |
116 condition-case were established, in the event of a non-local exit. | |
117 3. The condition-handler list, which is a simple Lisp list with new | |
118 entries consed onto the front of the list. It records condition-cases | |
119 and call-with-condition-handlers established either from C or from | |
120 Lisp. Unlike with the other lists (but similar to everything else | |
121 of a similar nature in the rest of the C and Lisp code), it takes care | |
122 of restoring itself appropriately in the event of a non-local exit | |
123 through the use of the unwind-protect mechanism. | |
124 4. The specbind list, which is a contiguous array of `struct specbinding's, | |
125 expanded as necessary using realloc(). It holds dynamic variable | |
126 bindings (the only kind we currently have in ELisp) and unwind-protects. | |
127 5. The GCPRO list, which is chained through `struct gcpro's declared in | |
128 the stack frames of any functions that need to GC-protect Lisp_Objects | |
129 declared on the stack. This is one of the most fragile areas of the | |
130 entire scheme -- you must not forget to UNGCPRO at the end of your | |
131 function, you must make sure you GCPRO in many circumstances you don't | |
132 think you have to, etc. See the internals manual for more information | |
133 about this. | |
134 | |
135 --ben | |
136 */ | |
24 | 137 |
25 #include <config.h> | 138 #include <config.h> |
26 #include "lisp.h" | 139 #include "lisp.h" |
27 | 140 |
28 #include "commands.h" | 141 #include "commands.h" |
29 #include "backtrace.h" | 142 #include "backtrace.h" |
30 #include "bytecode.h" | 143 #include "bytecode.h" |
31 #include "buffer.h" | 144 #include "buffer.h" |
32 #include "console.h" | 145 #include "console.h" |
146 #include "device.h" | |
147 #include "frame.h" | |
148 #include "lstream.h" | |
33 #include "opaque.h" | 149 #include "opaque.h" |
150 #include "window.h" | |
34 | 151 |
35 struct backtrace *backtrace_list; | 152 struct backtrace *backtrace_list; |
36 | 153 |
37 /* Note: you must always fill in all of the fields in a backtrace structure | 154 /* Note: you must always fill in all of the fields in a backtrace structure |
38 before pushing them on the backtrace_list. The profiling code depends | 155 before pushing them on the backtrace_list. The profiling code depends |
64 (((Lisp_Object (*)(EXFUN_##ac)) (fn)) (AV_##ac (av))) | 181 (((Lisp_Object (*)(EXFUN_##ac)) (fn)) (AV_##ac (av))) |
65 | 182 |
66 /* If subrs take more than 8 arguments, more cases need to be added | 183 /* If subrs take more than 8 arguments, more cases need to be added |
67 to this switch. (But wait - don't do it - if you really need | 184 to this switch. (But wait - don't do it - if you really need |
68 a SUBR with more than 8 arguments, use max_args == MANY. | 185 a SUBR with more than 8 arguments, use max_args == MANY. |
186 Or better, considering using a property list as one of your args. | |
69 See the DEFUN macro in lisp.h) */ | 187 See the DEFUN macro in lisp.h) */ |
70 #define PRIMITIVE_FUNCALL(rv, fn, av, ac) do { \ | 188 #define PRIMITIVE_FUNCALL(rv, fn, av, ac) do { \ |
71 void (*PF_fn)(void) = (void (*)(void)) fn; \ | 189 void (*PF_fn)(void) = (void (*)(void)) fn; \ |
72 Lisp_Object *PF_av = (av); \ | 190 Lisp_Object *PF_av = (av); \ |
73 switch (ac) \ | 191 switch (ac) \ |
87 #define FUNCALL_SUBR(rv, subr, av, ac) \ | 205 #define FUNCALL_SUBR(rv, subr, av, ac) \ |
88 PRIMITIVE_FUNCALL (rv, subr_function (subr), av, ac); | 206 PRIMITIVE_FUNCALL (rv, subr_function (subr), av, ac); |
89 | 207 |
90 | 208 |
91 /* This is the list of current catches (and also condition-cases). | 209 /* This is the list of current catches (and also condition-cases). |
92 This is a stack: the most recent catch is at the head of the | 210 This is a stack: the most recent catch is at the head of the list. |
93 list. Catches are created by declaring a 'struct catchtag' | 211 The list is threaded through the stack frames of the C functions |
94 locally, filling the .TAG field in with the tag, and doing | 212 that set up the catches; this is similar to the way the GCPRO list |
95 a setjmp() on .JMP. Fthrow() will store the value passed | 213 is handled, but different from the condition-handler list (which is |
96 to it in .VAL and longjmp() back to .JMP, back to the function | 214 a simple Lisp list) and the specbind stack, which is a contiguous |
97 that established the catch. This will always be either | 215 array of `struct specbinding's, grown (using realloc()) as |
98 internal_catch() (catches established internally or through | 216 necessary. (Note that all four of these lists behave as a stacks.) |
99 `catch') or condition_case_1 (condition-cases established | 217 |
100 internally or through `condition-case'). | 218 Catches are created by declaring a 'struct catchtag' locally, |
219 filling the .TAG field in with the tag, and doing a setjmp() on | |
220 .JMP. Fthrow() will store the value passed to it in .VAL and | |
221 longjmp() back to .JMP, back to the function that established the | |
222 catch. This will always be either internal_catch() (catches | |
223 established internally or through `catch') or condition_case_1 | |
224 (condition-cases established internally or through | |
225 `condition-case'). | |
101 | 226 |
102 The catchtag also records the current position in the | 227 The catchtag also records the current position in the |
103 call stack (stored in BACKTRACE_LIST), the current position | 228 call stack (stored in BACKTRACE_LIST), the current position |
104 in the specpdl stack (used for variable bindings and | 229 in the specpdl stack (used for variable bindings and |
105 unwind-protects), the value of LISP_EVAL_DEPTH, and the | 230 unwind-protects), the value of LISP_EVAL_DEPTH, and the |
106 current position in the GCPRO stack. All of these are | 231 current position in the GCPRO stack. All of these are |
107 restored by Fthrow(). | 232 restored by Fthrow(). |
108 */ | 233 */ |
109 | 234 |
110 struct catchtag *catchlist; | 235 struct catchtag *catchlist; |
236 | |
237 /* A special tag that can be used internally from C code to catch | |
238 every attempt to throw past this level. */ | |
239 Lisp_Object Vcatch_everything_tag; | |
111 | 240 |
112 Lisp_Object Qautoload, Qmacro, Qexit; | 241 Lisp_Object Qautoload, Qmacro, Qexit; |
113 Lisp_Object Qinteractive, Qcommandp, Qdefun, Qprogn, Qvalues; | 242 Lisp_Object Qinteractive, Qcommandp, Qdefun, Qprogn, Qvalues; |
114 Lisp_Object Vquit_flag, Vinhibit_quit; | 243 Lisp_Object Vquit_flag, Vinhibit_quit; |
115 Lisp_Object Qand_rest, Qand_optional; | 244 Lisp_Object Qand_rest, Qand_optional; |
121 Lisp_Object Qsetq; | 250 Lisp_Object Qsetq; |
122 Lisp_Object Qdisplay_warning; | 251 Lisp_Object Qdisplay_warning; |
123 Lisp_Object Vpending_warnings, Vpending_warnings_tail; | 252 Lisp_Object Vpending_warnings, Vpending_warnings_tail; |
124 Lisp_Object Qif; | 253 Lisp_Object Qif; |
125 | 254 |
126 /* Records whether we want errors to occur. This will be a boolean, | 255 /* Flags specifying which operations are currently inhibited. */ |
127 nil (errors OK) or t (no errors). If t, an error will cause a | 256 int inhibit_flags; |
128 throw to Qunbound_suspended_errors_tag. | 257 |
129 | 258 /* Buffers, frames, windows, devices, and consoles created since most |
130 See call_with_suspended_errors(). */ | 259 recent active |
131 Lisp_Object Vcurrent_error_state; | 260 call_trapping_problems (INHIBIT_EXISTING_PERMANENT_DISPLAY_OBJECT_DELETION). |
132 | 261 */ |
133 /* Current warning class when warnings occur, or nil for no warnings. | 262 Lisp_Object Vdeletable_permanent_display_objects; |
134 Only meaningful when Vcurrent_error_state is non-nil. | 263 |
135 See call_with_suspended_errors(). */ | 264 /* Buffers created since most recent active |
136 Lisp_Object Vcurrent_warning_class; | 265 call_trapping_problems (INHIBIT_EXISTING_BUFFER_TEXT_MODIFICATION). */ |
137 | 266 Lisp_Object Vmodifiable_buffers; |
138 /* Current warning level when warnings occur, or nil for no warnings. | |
139 Only meaningful when Vcurrent_error_state is non-nil. | |
140 See call_with_suspended_errors(). */ | |
141 Lisp_Object Vcurrent_warning_level; | |
142 | 267 |
143 /* Minimum level at which warnings are logged. Below this, they're ignored | 268 /* Minimum level at which warnings are logged. Below this, they're ignored |
144 entirely -- not even generated. */ | 269 entirely -- not even generated. */ |
145 Lisp_Object Vlog_warning_minimum_level; | 270 Lisp_Object Vlog_warning_minimum_level; |
146 | |
147 /* Special catch tag used in call_with_suspended_errors(). */ | |
148 Lisp_Object Qunbound_suspended_errors_tag; | |
149 | 271 |
150 /* Non-nil means record all fset's and provide's, to be undone | 272 /* Non-nil means record all fset's and provide's, to be undone |
151 if the file being autoloaded is not fully loaded. | 273 if the file being autoloaded is not fully loaded. |
152 They are recorded by being consed onto the front of Vautoload_queue: | 274 They are recorded by being consed onto the front of Vautoload_queue: |
153 (FUN . ODEF) for a defun, (OFEATURES . nil) for a provide. */ | 275 (FUN . ODEF) for a defun, (OFEATURES . nil) for a provide. */ |
223 static int entering_debugger; | 345 static int entering_debugger; |
224 | 346 |
225 /* Function to call to invoke the debugger */ | 347 /* Function to call to invoke the debugger */ |
226 Lisp_Object Vdebugger; | 348 Lisp_Object Vdebugger; |
227 | 349 |
228 /* Chain of condition handlers currently in effect. | 350 /* List of condition handlers currently in effect. |
229 The elements of this chain are contained in the stack frames | 351 The elements of this lists were at one point in the past |
230 of Fcondition_case and internal_condition_case. | 352 threaded through the stack frames of Fcondition_case and |
231 When an error is signaled (by calling Fsignal, below), | 353 related functions, but now are stored separately in a normal |
232 this chain is searched for an element that applies. | 354 stack. When an error is signaled (by calling Fsignal, below), |
355 this list is searched for an element that applies. | |
233 | 356 |
234 Each element of this list is one of the following: | 357 Each element of this list is one of the following: |
235 | 358 |
236 A list of a handler function and possibly args to pass to | 359 -- A list of a handler function and possibly args to pass to the |
237 the function. This is a handler established with | 360 function. This is a handler established with the Lisp primitive |
238 `call-with-condition-handler' (q.v.). | 361 `call-with-condition-handler' or related C function |
239 | 362 call_with_condition_handler(): |
240 A list whose car is Qunbound and whose cdr is Qt. | 363 |
241 This is a special condition-case handler established | 364 If the handler function is an opaque ptr object, it is a handler |
242 by C code with condition_case_1(). All errors are | 365 that was established in C using call_with_condition_handler(), |
243 trapped; the debugger is not invoked even if | 366 and the contents of the object are a function pointer which takes |
244 `debug-on-error' was set. | 367 three arguments, the signal name and signal data (same arguments |
245 | 368 passed to `signal') and a third Lisp_Object argument, specified |
246 A list whose car is Qunbound and whose cdr is Qerror. | 369 in the call to call_with_condition_handler() and stored as the |
247 This is a special condition-case handler established | 370 second element of the list containing the handler functionl. |
248 by C code with condition_case_1(). It is like Qt | 371 |
249 except that the debugger is invoked normally if it is | 372 If the handler function is a regular Lisp_Object, it is a handler |
250 called for. | 373 that was established using `call-with-condition-handler'. |
251 | 374 Currently there are no more arguments in the list containing the |
252 A list whose car is Qunbound and whose cdr is a list | 375 handler function, and only one argument is passed to the handler |
253 of lists (CONDITION-NAME BODY ...) exactly as in | 376 function: a cons of the signal name and signal data arguments |
254 `condition-case'. This is a normal `condition-case' | 377 passed to `signal'. |
255 handler. | 378 |
256 | 379 -- A list whose car is Qunbound and whose cdr is Qt. This is a |
257 Note that in all cases *except* the first, there is a | 380 special condition-case handler established by C code with |
258 corresponding catch, whose TAG is the value of | 381 condition_case_1(). All errors are trapped; the debugger is not |
259 Vcondition_handlers just after the handler data just | 382 invoked even if `debug-on-error' was set. |
260 described is pushed onto it. The reason is that | 383 |
261 `condition-case' handlers need to throw back to the | 384 -- A list whose car is Qunbound and whose cdr is Qerror. This is a |
262 place where the handler was installed before invoking | 385 special condition-case handler established by C code with |
263 it, while `call-with-condition-handler' handlers are | 386 condition_case_1(). It is like Qt except that the debugger is |
264 invoked in the environment that `signal' was invoked | 387 invoked normally if it is called for. |
265 in. | 388 |
266 */ | 389 -- A list whose car is Qunbound and whose cdr is a list of lists |
390 (CONDITION-NAME BODY ...) exactly as in `condition-case'. This is | |
391 a normal `condition-case' handler. | |
392 | |
393 Note that in all cases *except* the first, there is a corresponding | |
394 catch, whose TAG is the value of Vcondition_handlers just after the | |
395 handler data just described is pushed onto it. The reason is that | |
396 `condition-case' handlers need to throw back to the place where the | |
397 handler was installed before invoking it, while | |
398 `call-with-condition-handler' handlers are invoked in the | |
399 environment that `signal' was invoked in. */ | |
400 | |
401 | |
267 static Lisp_Object Vcondition_handlers; | 402 static Lisp_Object Vcondition_handlers; |
268 | 403 |
269 | 404 /* I think we should keep this enabled all the time, not just when |
405 error checking is enabled, because if one of these puppies pops up, | |
406 it will trash the stack if not caught, making it that much harder to | |
407 debug. It doesn't cause speed loss. */ | |
270 #define DEFEND_AGAINST_THROW_RECURSION | 408 #define DEFEND_AGAINST_THROW_RECURSION |
271 | 409 |
272 #ifdef DEFEND_AGAINST_THROW_RECURSION | 410 #ifdef DEFEND_AGAINST_THROW_RECURSION |
273 /* Used for error catching purposes by throw_or_bomb_out */ | 411 /* Used for error catching purposes by throw_or_bomb_out */ |
274 static int throw_level; | 412 static int throw_level; |
275 #endif | |
276 | |
277 #ifdef ERROR_CHECK_STRUCTURES | |
278 static void check_error_state_sanity (void); | |
279 #define CHECK_ERROR_STATE_SANITY() check_error_state_sanity () | |
280 #else | |
281 #define CHECK_ERROR_STATE_SANITY() | |
282 #endif | 413 #endif |
283 | 414 |
284 | 415 |
285 /************************************************************************/ | 416 /************************************************************************/ |
286 /* The subr object type */ | 417 /* The subr object type */ |
314 Lisp_Subr); | 445 Lisp_Subr); |
315 | 446 |
316 /************************************************************************/ | 447 /************************************************************************/ |
317 /* Entering the debugger */ | 448 /* Entering the debugger */ |
318 /************************************************************************/ | 449 /************************************************************************/ |
450 | |
451 static Lisp_Object | |
452 current_warning_level (void) | |
453 { | |
454 if (inhibit_flags & ISSUE_WARNINGS_AT_DEBUG_LEVEL) | |
455 return Qdebug; | |
456 else | |
457 return Qwarning; | |
458 } | |
319 | 459 |
320 /* unwind-protect used by call_debugger() to restore the value of | 460 /* unwind-protect used by call_debugger() to restore the value of |
321 entering_debugger. (We cannot use specbind() because the | 461 entering_debugger. (We cannot use specbind() because the |
322 variable is not Lisp-accessible.) */ | 462 variable is not Lisp-accessible.) */ |
323 | 463 |
384 { | 524 { |
385 int threw; | 525 int threw; |
386 Lisp_Object val; | 526 Lisp_Object val; |
387 int speccount; | 527 int speccount; |
388 | 528 |
529 debug_on_next_call = 0; | |
530 | |
531 if (inhibit_flags & INHIBIT_ENTERING_DEBUGGER) | |
532 { | |
533 if (!(inhibit_flags & INHIBIT_WARNING_ISSUE)) | |
534 warn_when_safe | |
535 (Qdebugger, current_warning_level (), | |
536 "Unable to enter debugger within critical section"); | |
537 return Qunbound; | |
538 } | |
539 | |
389 if (lisp_eval_depth + 20 > max_lisp_eval_depth) | 540 if (lisp_eval_depth + 20 > max_lisp_eval_depth) |
390 max_lisp_eval_depth = lisp_eval_depth + 20; | 541 max_lisp_eval_depth = lisp_eval_depth + 20; |
391 if (specpdl_size + 40 > max_specpdl_size) | 542 if (specpdl_size + 40 > max_specpdl_size) |
392 max_specpdl_size = specpdl_size + 40; | 543 max_specpdl_size = specpdl_size + 40; |
393 debug_on_next_call = 0; | 544 |
394 | 545 speccount = internal_bind_int (&entering_debugger, 1); |
395 speccount = specpdl_depth(); | 546 val = internal_catch (Qdebugger, call_debugger_259, arg, &threw, 0); |
396 record_unwind_protect (restore_entering_debugger, | |
397 (entering_debugger ? Qt : Qnil)); | |
398 entering_debugger = 1; | |
399 val = internal_catch (Qdebugger, call_debugger_259, arg, &threw); | |
400 | 547 |
401 return unbind_to_1 (speccount, ((threw) | 548 return unbind_to_1 (speccount, ((threw) |
402 ? Qunbound /* Not returning a value */ | 549 ? Qunbound /* Not returning a value */ |
403 : val)); | 550 : val)); |
404 } | 551 } |
545 Lisp_Object active_handlers, | 692 Lisp_Object active_handlers, |
546 int signal_vars_only, | 693 int signal_vars_only, |
547 int *stack_trace_displayed, | 694 int *stack_trace_displayed, |
548 int *debugger_entered) | 695 int *debugger_entered) |
549 { | 696 { |
697 #ifdef PIGS_FLY_AND_ALL_C_CODE_CAN_HANDLE_GC_OCCURRING_ALMOST_ANYWHERE | |
550 /* This function can GC */ | 698 /* This function can GC */ |
699 #else /* reality check */ | |
700 /* This function cannot GC because it inhibits GC during its operation */ | |
701 #endif | |
702 | |
551 Lisp_Object val = Qunbound; | 703 Lisp_Object val = Qunbound; |
552 Lisp_Object all_handlers = Vcondition_handlers; | 704 Lisp_Object all_handlers = Vcondition_handlers; |
553 Lisp_Object temp_data = Qnil; | 705 Lisp_Object temp_data = Qnil; |
554 int speccount = specpdl_depth(); | 706 int outer_speccount = specpdl_depth(); |
707 int speccount; | |
708 | |
709 #ifdef PIGS_FLY_AND_ALL_C_CODE_CAN_HANDLE_GC_OCCURRING_ALMOST_ANYWHERE | |
555 struct gcpro gcpro1, gcpro2; | 710 struct gcpro gcpro1, gcpro2; |
556 GCPRO2 (all_handlers, temp_data); | 711 GCPRO2 (all_handlers, temp_data); |
712 #else | |
713 begin_gc_forbidden (); | |
714 #endif | |
715 | |
716 speccount = specpdl_depth(); | |
557 | 717 |
558 Vcondition_handlers = active_handlers; | 718 Vcondition_handlers = active_handlers; |
559 | 719 |
560 temp_data = Fcons (sig, data); /* needed for skip_debugger */ | 720 temp_data = Fcons (sig, data); /* needed for skip_debugger */ |
561 | 721 |
590 specbind (Qstack_trace_on_error, Qnil); | 750 specbind (Qstack_trace_on_error, Qnil); |
591 specbind (Qdebug_on_signal, Qnil); | 751 specbind (Qdebug_on_signal, Qnil); |
592 specbind (Qstack_trace_on_signal, Qnil); | 752 specbind (Qstack_trace_on_signal, Qnil); |
593 | 753 |
594 val = call_debugger (list2 (Qerror, (Fcons (sig, data)))); | 754 val = call_debugger (list2 (Qerror, (Fcons (sig, data)))); |
755 unbind_to (speccount); | |
595 *debugger_entered = 1; | 756 *debugger_entered = 1; |
596 } | 757 } |
597 | 758 |
598 if (!entering_debugger && !*stack_trace_displayed | 759 if (!entering_debugger && !*stack_trace_displayed |
599 && wants_debugger (Vstack_trace_on_signal, conditions)) | 760 && wants_debugger (Vstack_trace_on_signal, conditions)) |
627 | 788 |
628 val = call_debugger (list2 (Qerror, (Fcons (sig, data)))); | 789 val = call_debugger (list2 (Qerror, (Fcons (sig, data)))); |
629 *debugger_entered = 1; | 790 *debugger_entered = 1; |
630 } | 791 } |
631 | 792 |
793 #ifdef PIGS_FLY_AND_ALL_C_CODE_CAN_HANDLE_GC_OCCURRING_ALMOST_ANYWHERE | |
632 UNGCPRO; | 794 UNGCPRO; |
795 #endif | |
633 Vcondition_handlers = all_handlers; | 796 Vcondition_handlers = all_handlers; |
634 return unbind_to_1 (speccount, val); | 797 return unbind_to_1 (outer_speccount, val); |
635 } | 798 } |
636 | 799 |
637 | 800 |
638 /************************************************************************/ | 801 /************************************************************************/ |
639 /* The basic special forms */ | 802 /* The basic special forms */ |
708 */ | 871 */ |
709 (int nargs, Lisp_Object *args)) | 872 (int nargs, Lisp_Object *args)) |
710 { | 873 { |
711 Lisp_Object cond = args[0]; | 874 Lisp_Object cond = args[0]; |
712 Lisp_Object body; | 875 Lisp_Object body; |
713 | 876 |
714 switch (nargs) | 877 switch (nargs) |
715 { | 878 { |
716 case 1: body = Qnil; break; | 879 case 1: body = Qnil; break; |
717 case 2: body = args[1]; break; | 880 case 2: body = args[1]; break; |
718 default: body = Fcons (Qprogn, Flist (nargs-1, args+1)); break; | 881 default: body = Fcons (Qprogn, Flist (nargs-1, args+1)); break; |
1278 (args)) | 1441 (args)) |
1279 { | 1442 { |
1280 /* This function can GC */ | 1443 /* This function can GC */ |
1281 Lisp_Object tag = Feval (XCAR (args)); | 1444 Lisp_Object tag = Feval (XCAR (args)); |
1282 Lisp_Object body = XCDR (args); | 1445 Lisp_Object body = XCDR (args); |
1283 return internal_catch (tag, Fprogn, body, 0); | 1446 return internal_catch (tag, Fprogn, body, 0, 0); |
1284 } | 1447 } |
1285 | 1448 |
1286 /* Set up a catch, then call C function FUNC on argument ARG. | 1449 /* Set up a catch, then call C function FUNC on argument ARG. |
1287 FUNC should return a Lisp_Object. | 1450 FUNC should return a Lisp_Object. |
1288 This is how catches are done from within C code. */ | 1451 This is how catches are done from within C code. */ |
1289 | 1452 |
1290 Lisp_Object | 1453 Lisp_Object |
1291 internal_catch (Lisp_Object tag, | 1454 internal_catch (Lisp_Object tag, |
1292 Lisp_Object (*func) (Lisp_Object arg), | 1455 Lisp_Object (*func) (Lisp_Object arg), |
1293 Lisp_Object arg, | 1456 Lisp_Object arg, |
1294 int * volatile threw) | 1457 int * volatile threw, |
1458 Lisp_Object * volatile thrown_tag) | |
1295 { | 1459 { |
1296 /* This structure is made part of the chain `catchlist'. */ | 1460 /* This structure is made part of the chain `catchlist'. */ |
1297 struct catchtag c; | 1461 struct catchtag c; |
1298 | 1462 |
1299 /* Fill in the components of c, and put it on the list. */ | 1463 /* Fill in the components of c, and put it on the list. */ |
1300 c.next = catchlist; | 1464 c.next = catchlist; |
1301 c.tag = tag; | 1465 c.tag = tag; |
1466 c.actual_tag = Qnil; | |
1302 c.val = Qnil; | 1467 c.val = Qnil; |
1303 c.backlist = backtrace_list; | 1468 c.backlist = backtrace_list; |
1304 #if 0 /* FSFmacs */ | 1469 #if 0 /* FSFmacs */ |
1305 /* #### */ | 1470 /* #### */ |
1306 c.handlerlist = handlerlist; | 1471 c.handlerlist = handlerlist; |
1316 /* Call FUNC. */ | 1481 /* Call FUNC. */ |
1317 if (SETJMP (c.jmp)) | 1482 if (SETJMP (c.jmp)) |
1318 { | 1483 { |
1319 /* Throw works by a longjmp that comes right here. */ | 1484 /* Throw works by a longjmp that comes right here. */ |
1320 if (threw) *threw = 1; | 1485 if (threw) *threw = 1; |
1486 if (thrown_tag) *thrown_tag = c.actual_tag; | |
1321 return c.val; | 1487 return c.val; |
1322 } | 1488 } |
1323 c.val = (*func) (arg); | 1489 c.val = (*func) (arg); |
1324 if (threw) *threw = 0; | 1490 if (threw) *threw = 0; |
1491 if (thrown_tag) *thrown_tag = Qnil; | |
1325 catchlist = c.next; | 1492 catchlist = c.next; |
1326 CHECK_ERROR_STATE_SANITY (); | 1493 check_catchlist_sanity (); |
1327 return c.val; | 1494 return c.val; |
1328 } | 1495 } |
1329 | 1496 |
1330 | 1497 |
1331 /* Unwind the specbind, catch, and handler stacks back to CATCH, and | 1498 /* Unwind the specbind, catch, and handler stacks back to CATCH, and |
1343 specified in the | 1510 specified in the |
1344 | 1511 |
1345 This is used for correct unwinding in Fthrow and Fsignal. */ | 1512 This is used for correct unwinding in Fthrow and Fsignal. */ |
1346 | 1513 |
1347 static void | 1514 static void |
1348 unwind_to_catch (struct catchtag *c, Lisp_Object val) | 1515 unwind_to_catch (struct catchtag *c, Lisp_Object val, Lisp_Object tag) |
1349 { | 1516 { |
1350 REGISTER int last_time; | 1517 REGISTER int last_time; |
1351 | 1518 |
1352 /* Unwind the specbind, catch, and handler stacks back to CATCH | 1519 /* Unwind the specbind, catch, and handler stacks back to CATCH |
1353 Before each catch is discarded, unbind all special bindings | 1520 Before each catch is discarded, unbind all special bindings |
1358 | 1525 |
1359 /* Save the value somewhere it will be GC'ed. | 1526 /* Save the value somewhere it will be GC'ed. |
1360 (Can't overwrite tag slot because an unwind-protect may | 1527 (Can't overwrite tag slot because an unwind-protect may |
1361 want to throw to this same tag, which isn't yet invalid.) */ | 1528 want to throw to this same tag, which isn't yet invalid.) */ |
1362 c->val = val; | 1529 c->val = val; |
1530 c->actual_tag = tag; | |
1363 | 1531 |
1364 #if 0 /* FSFmacs */ | 1532 #if 0 /* FSFmacs */ |
1365 /* Restore the polling-suppression count. */ | 1533 /* Restore the polling-suppression count. */ |
1366 set_poll_suppress_count (catch->poll_suppress_count); | 1534 set_poll_suppress_count (catch->poll_suppress_count); |
1367 #endif | 1535 #endif |
1373 | 1541 |
1374 /* Unwind the specpdl stack, and then restore the proper set of | 1542 /* Unwind the specpdl stack, and then restore the proper set of |
1375 handlers. */ | 1543 handlers. */ |
1376 unbind_to (catchlist->pdlcount); | 1544 unbind_to (catchlist->pdlcount); |
1377 catchlist = catchlist->next; | 1545 catchlist = catchlist->next; |
1378 CHECK_ERROR_STATE_SANITY (); | 1546 check_catchlist_sanity (); |
1379 } | 1547 } |
1380 while (! last_time); | 1548 while (! last_time); |
1381 #else | 1549 #else |
1382 /* Former XEmacs code. This is definitely not as correct because | 1550 /* Former XEmacs code. This is definitely not as correct because |
1383 there may be a number of catches we're unwinding, and a number | 1551 there may be a number of catches we're unwinding, and a number |
1400 --ben | 1568 --ben |
1401 */ | 1569 */ |
1402 /* Unwind the specpdl stack */ | 1570 /* Unwind the specpdl stack */ |
1403 unbind_to (c->pdlcount); | 1571 unbind_to (c->pdlcount); |
1404 catchlist = c->next; | 1572 catchlist = c->next; |
1405 CHECK_ERROR_STATE_SANITY (); | 1573 check_catchlist_sanity (); |
1406 #endif /* Former code */ | 1574 #endif /* Former code */ |
1407 | 1575 |
1408 gcprolist = c->gcpro; | 1576 gcprolist = c->gcpro; |
1409 backtrace_list = c->backlist; | 1577 backtrace_list = c->backlist; |
1410 lisp_eval_depth = c->lisp_eval_depth; | 1578 lisp_eval_depth = c->lisp_eval_depth; |
1437 occurs is when there's no catch for 'top-level -- the | 1605 occurs is when there's no catch for 'top-level -- the |
1438 'top-level catch and the catch-all error handler are | 1606 'top-level catch and the catch-all error handler are |
1439 established at the same time, in initial_command_loop/ | 1607 established at the same time, in initial_command_loop/ |
1440 top_level_1. | 1608 top_level_1. |
1441 | 1609 |
1442 #### Fix this horrifitude! | 1610 [[#### Fix this horrifitude!]] |
1611 | |
1612 I don't think this is horrifitude, just defensive programming. --ben | |
1443 */ | 1613 */ |
1444 | 1614 |
1445 while (1) | 1615 while (1) |
1446 { | 1616 { |
1447 REGISTER struct catchtag *c; | 1617 REGISTER struct catchtag *c; |
1449 #if 0 /* FSFmacs */ | 1619 #if 0 /* FSFmacs */ |
1450 if (!NILP (tag)) /* #### */ | 1620 if (!NILP (tag)) /* #### */ |
1451 #endif | 1621 #endif |
1452 for (c = catchlist; c; c = c->next) | 1622 for (c = catchlist; c; c = c->next) |
1453 { | 1623 { |
1454 if (EQ (c->tag, tag)) | 1624 if (EQ (c->tag, tag) || EQ (c->tag, Vcatch_everything_tag)) |
1455 unwind_to_catch (c, val); | 1625 unwind_to_catch (c, val, tag); |
1456 } | 1626 } |
1457 if (!bomb_out_p) | 1627 if (!bomb_out_p) |
1458 tag = Fsignal (Qno_catch, list2 (tag, val)); | 1628 tag = Fsignal (Qno_catch, list2 (tag, val)); |
1459 else | 1629 else |
1460 call1 (Qreally_early_error_handler, Fcons (sig, data)); | 1630 call1 (Qreally_early_error_handler, Fcons (sig, data)); |
1520 condition_bind_unwind (Lisp_Object loser) | 1690 condition_bind_unwind (Lisp_Object loser) |
1521 { | 1691 { |
1522 /* There is no problem freeing stuff here like there is in | 1692 /* There is no problem freeing stuff here like there is in |
1523 condition_case_unwind(), because there are no outside pointers | 1693 condition_case_unwind(), because there are no outside pointers |
1524 (like the tag below in the catchlist) pointing to the objects. */ | 1694 (like the tag below in the catchlist) pointing to the objects. */ |
1525 Lisp_Cons *victim; | 1695 |
1526 /* ((handler-fun . handler-args) ... other handlers) */ | 1696 /* ((handler-fun . handler-args) ... other handlers) */ |
1527 Lisp_Object tem = XCAR (loser); | 1697 Lisp_Object tem = XCAR (loser); |
1698 int first = 1; | |
1528 | 1699 |
1529 while (CONSP (tem)) | 1700 while (CONSP (tem)) |
1530 { | 1701 { |
1531 victim = XCONS (tem); | 1702 Lisp_Object victim = tem; |
1532 tem = victim->cdr; | 1703 if (first && OPAQUE_PTRP (XCAR (victim))) |
1704 free_opaque_ptr (XCAR (victim)); | |
1705 first = 0; | |
1706 tem = XCDR (victim); | |
1533 free_cons (victim); | 1707 free_cons (victim); |
1534 } | 1708 } |
1535 victim = XCONS (loser); | |
1536 | 1709 |
1537 if (EQ (loser, Vcondition_handlers)) /* may have been rebound to some tail */ | 1710 if (EQ (loser, Vcondition_handlers)) /* may have been rebound to some tail */ |
1538 Vcondition_handlers = victim->cdr; | 1711 Vcondition_handlers = XCDR (loser); |
1539 | 1712 |
1540 free_cons (victim); | 1713 free_cons (loser); |
1541 return Qnil; | 1714 return Qnil; |
1542 } | 1715 } |
1543 | 1716 |
1544 static Lisp_Object | 1717 static Lisp_Object |
1545 condition_case_unwind (Lisp_Object loser) | 1718 condition_case_unwind (Lisp_Object loser) |
1654 functions. --ben */ | 1827 functions. --ben */ |
1655 c.tag = noseeum_cons (noseeum_cons (Qunbound, handlers), | 1828 c.tag = noseeum_cons (noseeum_cons (Qunbound, handlers), |
1656 Vcondition_handlers); | 1829 Vcondition_handlers); |
1657 #endif | 1830 #endif |
1658 c.val = Qnil; | 1831 c.val = Qnil; |
1832 c.actual_tag = Qnil; | |
1659 c.backlist = backtrace_list; | 1833 c.backlist = backtrace_list; |
1660 #if 0 /* FSFmacs */ | 1834 #if 0 /* FSFmacs */ |
1661 /* #### */ | 1835 /* #### */ |
1662 c.handlerlist = handlerlist; | 1836 c.handlerlist = handlerlist; |
1663 #endif | 1837 #endif |
1694 | 1868 |
1695 /* Once we change `catchlist' below, the stuff in c will not be GCPRO'd. */ | 1869 /* Once we change `catchlist' below, the stuff in c will not be GCPRO'd. */ |
1696 GCPRO3 (harg, c.val, c.tag); | 1870 GCPRO3 (harg, c.val, c.tag); |
1697 | 1871 |
1698 catchlist = c.next; | 1872 catchlist = c.next; |
1699 CHECK_ERROR_STATE_SANITY (); | 1873 check_catchlist_sanity (); |
1700 /* Note: The unbind also resets Vcondition_handlers. Maybe we should | 1874 /* Note: The unbind also resets Vcondition_handlers. Maybe we should |
1701 delete this here. */ | 1875 delete this here. */ |
1702 Vcondition_handlers = XCDR (c.tag); | 1876 Vcondition_handlers = XCDR (c.tag); |
1703 unbind_to (speccount); | 1877 unbind_to (speccount); |
1704 | 1878 |
1705 UNGCPRO; | 1879 UNGCPRO; |
1706 /* free the conses *after* the unbind, because the unbind will run | 1880 /* free the conses *after* the unbind, because the unbind will run |
1707 condition_case_unwind above. */ | 1881 condition_case_unwind above. */ |
1708 free_cons (XCONS (XCAR (c.tag))); | 1882 free_cons (XCAR (c.tag)); |
1709 free_cons (XCONS (c.tag)); | 1883 free_cons (c.tag); |
1710 return c.val; | 1884 return c.val; |
1711 } | 1885 } |
1712 | 1886 |
1713 static Lisp_Object | 1887 static Lisp_Object |
1714 run_condition_case_handlers (Lisp_Object val, Lisp_Object var) | 1888 run_condition_case_handlers (Lisp_Object val, Lisp_Object var) |
1853 { | 2027 { |
1854 /* This function can GC */ | 2028 /* This function can GC */ |
1855 int speccount = specpdl_depth(); | 2029 int speccount = specpdl_depth(); |
1856 Lisp_Object tem; | 2030 Lisp_Object tem; |
1857 | 2031 |
1858 /* #### If there were a way to check that args[0] were a function | 2032 tem = Ffunction_max_args (args[0]); |
1859 which accepted one arg, that should be done here ... */ | 2033 if (! (XINT (Ffunction_min_args (args[0])) <= 1 |
1860 | 2034 && (NILP (tem) || 1 <= XINT (tem)))) |
1861 /* (handler-fun . handler-args) */ | 2035 invalid_argument ("Must be function of one argument", args[0]); |
2036 | |
2037 /* (handler-fun . handler-args) but currently there are no handler-args */ | |
1862 tem = noseeum_cons (list1 (args[0]), Vcondition_handlers); | 2038 tem = noseeum_cons (list1 (args[0]), Vcondition_handlers); |
1863 record_unwind_protect (condition_bind_unwind, tem); | 2039 record_unwind_protect (condition_bind_unwind, tem); |
1864 Vcondition_handlers = tem; | 2040 Vcondition_handlers = tem; |
1865 | 2041 |
1866 /* Caller should have GC-protected args */ | 2042 /* Caller should have GC-protected args */ |
1867 return unbind_to_1 (speccount, Ffuncall (nargs - 1, args + 1)); | 2043 return unbind_to_1 (speccount, Ffuncall (nargs - 1, args + 1)); |
2044 } | |
2045 | |
2046 /* This is the C version of the above function. It calls FUN, passing it | |
2047 ARG, first setting up HANDLER to catch signals in the environment in | |
2048 which they were signalled. (HANDLER is only invoked if there was no | |
2049 handler (either from condition-case or call-with-condition-handler) set | |
2050 later on that handled the signal; therefore, this is a real error. | |
2051 | |
2052 HANDLER is invoked with three arguments: the ERROR-SYMBOL and DATA as | |
2053 passed to `signal', and HANDLER_ARG. Originally I made HANDLER_ARG and | |
2054 ARG be void * to facilitate passing structures, but I changed to | |
2055 Lisp_Objects because all the other C interfaces to catch/condition-case/etc. | |
2056 take Lisp_Objects, and it is easy enough to use make_opaque_ptr() et al. | |
2057 to convert between Lisp_Objects and structure pointers. */ | |
2058 | |
2059 Lisp_Object | |
2060 call_with_condition_handler (Lisp_Object (*handler) (Lisp_Object, Lisp_Object, | |
2061 Lisp_Object), | |
2062 Lisp_Object handler_arg, | |
2063 Lisp_Object (*fun) (Lisp_Object), | |
2064 Lisp_Object arg) | |
2065 { | |
2066 /* This function can GC */ | |
2067 int speccount = specpdl_depth(); | |
2068 Lisp_Object tem; | |
2069 | |
2070 /* ((handler-fun . (handler-arg . nil)) ... ) */ | |
2071 tem = noseeum_cons (noseeum_cons (make_opaque_ptr (handler), | |
2072 noseeum_cons (handler_arg, Qnil)), | |
2073 Vcondition_handlers); | |
2074 record_unwind_protect (condition_bind_unwind, tem); | |
2075 Vcondition_handlers = tem; | |
2076 | |
2077 return unbind_to_1 (speccount, (*fun) (arg)); | |
1868 } | 2078 } |
1869 | 2079 |
1870 static int | 2080 static int |
1871 condition_type_p (Lisp_Object type, Lisp_Object conditions) | 2081 condition_type_p (Lisp_Object type, Lisp_Object conditions) |
1872 { | 2082 { |
1908 | 2118 |
1909 /************************************************************************/ | 2119 /************************************************************************/ |
1910 /* the workhorse error-signaling function */ | 2120 /* the workhorse error-signaling function */ |
1911 /************************************************************************/ | 2121 /************************************************************************/ |
1912 | 2122 |
2123 /* This exists only for debugging purposes, as a place to put a breakpoint | |
2124 that won't get signalled for errors occurring when | |
2125 call_with_suspended_errors() was invoked. */ | |
2126 | |
2127 static void | |
2128 signal_1 (void) | |
2129 { | |
2130 } | |
2131 | |
1913 /* #### This function has not been synched with FSF. It diverges | 2132 /* #### This function has not been synched with FSF. It diverges |
1914 significantly. */ | 2133 significantly. */ |
1915 | 2134 |
1916 static Lisp_Object | 2135 /* The simplest external error function: it would be called |
1917 signal_1 (Lisp_Object sig, Lisp_Object data) | 2136 signal_continuable_error() in the terminology below, but it's |
2137 Lisp-callable. */ | |
2138 | |
2139 DEFUN ("signal", Fsignal, 2, 2, 0, /* | |
2140 Signal a continuable error. Args are ERROR-SYMBOL, and associated DATA. | |
2141 An error symbol is a symbol defined using `define-error'. | |
2142 DATA should be a list. Its elements are printed as part of the error message. | |
2143 If the signal is handled, DATA is made available to the handler. | |
2144 See also the function `signal-error', and the functions to handle errors: | |
2145 `condition-case' and `call-with-condition-handler'. | |
2146 | |
2147 Note that this function can return, if the debugger is invoked and the | |
2148 user invokes the "return from signal" option. | |
2149 */ | |
2150 (error_symbol, data)) | |
1918 { | 2151 { |
1919 /* This function can GC */ | 2152 /* This function can GC */ |
1920 struct gcpro gcpro1, gcpro2; | 2153 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4; |
1921 Lisp_Object conditions; | 2154 Lisp_Object conditions = Qnil; |
1922 Lisp_Object handlers; | 2155 Lisp_Object handlers = Qnil; |
1923 /* signal_call_debugger() could get called more than once | 2156 /* signal_call_debugger() could get called more than once |
1924 (once when a call-with-condition-handler is about to | 2157 (once when a call-with-condition-handler is about to |
1925 be dealt with, and another when a condition-case handler | 2158 be dealt with, and another when a condition-case handler |
1926 is about to be invoked). So make sure the debugger and/or | 2159 is about to be invoked). So make sure the debugger and/or |
1927 stack trace aren't done more than once. */ | 2160 stack trace aren't done more than once. */ |
1928 int stack_trace_displayed = 0; | 2161 int stack_trace_displayed = 0; |
1929 int debugger_entered = 0; | 2162 int debugger_entered = 0; |
1930 GCPRO2 (conditions, handlers); | 2163 |
2164 /* Fsignal() is one of these functions that's called all the time | |
2165 with newly-created Lisp objects. We allow this; but we must GC- | |
2166 protect the objects because all sorts of weird stuff could | |
2167 happen. */ | |
2168 | |
2169 GCPRO4 (conditions, handlers, error_symbol, data); | |
2170 | |
2171 if (!(inhibit_flags & CALL_WITH_SUSPENDED_ERRORS)) | |
2172 signal_1 (); | |
1931 | 2173 |
1932 if (!initialized) | 2174 if (!initialized) |
1933 { | 2175 { |
1934 /* who knows how much has been initialized? Safest bet is | 2176 /* who knows how much has been initialized? Safest bet is |
1935 just to bomb out immediately. */ | 2177 just to bomb out immediately. */ |
1936 stderr_out ("Error before initialization is complete!\n"); | 2178 stderr_out ("Error before initialization is complete!\n"); |
1937 abort (); | 2179 abort (); |
1938 } | 2180 } |
1939 | 2181 |
1940 if (gc_in_progress || in_display) | 2182 if (gc_in_progress) |
1941 /* This is one of many reasons why you can't run lisp code from redisplay. | 2183 /* We used to abort if in_display: |
1942 There is no sensible way to handle errors there. */ | 2184 |
2185 [[This is one of many reasons why you can't run lisp code from | |
2186 redisplay. There is no sensible way to handle errors there.]] | |
2187 | |
2188 The above comment is not correct. | |
2189 | |
2190 Inhibit GC until the redisplay code is careful enough to properly | |
2191 GCPRO their structures; | |
2192 | |
2193 Surround all calls to Lisp code with error-trapping wrappers that | |
2194 catch all errors. --ben */ | |
1943 abort (); | 2195 abort (); |
1944 | 2196 |
1945 conditions = Fget (sig, Qerror_conditions, Qnil); | 2197 conditions = Fget (error_symbol, Qerror_conditions, Qnil); |
1946 | 2198 |
1947 for (handlers = Vcondition_handlers; | 2199 for (handlers = Vcondition_handlers; |
1948 CONSP (handlers); | 2200 CONSP (handlers); |
1949 handlers = XCDR (handlers)) | 2201 handlers = XCDR (handlers)) |
1950 { | 2202 { |
1959 Lisp_Object all_handlers = Vcondition_handlers; | 2211 Lisp_Object all_handlers = Vcondition_handlers; |
1960 struct gcpro ngcpro1; | 2212 struct gcpro ngcpro1; |
1961 NGCPRO1 (all_handlers); | 2213 NGCPRO1 (all_handlers); |
1962 Vcondition_handlers = outer_handlers; | 2214 Vcondition_handlers = outer_handlers; |
1963 | 2215 |
1964 tem = signal_call_debugger (conditions, sig, data, | 2216 tem = signal_call_debugger (conditions, error_symbol, data, |
1965 outer_handlers, 1, | 2217 outer_handlers, 1, |
1966 &stack_trace_displayed, | 2218 &stack_trace_displayed, |
1967 &debugger_entered); | 2219 &debugger_entered); |
1968 if (!UNBOUNDP (tem)) | 2220 if (!UNBOUNDP (tem)) |
1969 RETURN_NUNGCPRO (return_from_signal (tem)); | 2221 RETURN_NUNGCPRO (return_from_signal (tem)); |
1970 | 2222 |
1971 tem = Fcons (sig, data); | 2223 if (OPAQUE_PTRP (handler_fun)) |
1972 if (NILP (handler_data)) | 2224 { |
1973 tem = call1 (handler_fun, tem); | 2225 if (NILP (handler_data)) |
1974 else | 2226 { |
1975 { | 2227 Lisp_Object (*hfun) (Lisp_Object, Lisp_Object) = |
1976 /* (This code won't be used (for now?).) */ | 2228 (Lisp_Object (*) (Lisp_Object, Lisp_Object)) |
1977 struct gcpro nngcpro1; | 2229 (get_opaque_ptr (handler_fun)); |
1978 Lisp_Object args[3]; | 2230 |
1979 NNGCPRO1 (args[0]); | 2231 tem = (*hfun) (error_symbol, data); |
1980 nngcpro1.nvars = 3; | 2232 } |
1981 args[0] = handler_fun; | 2233 else |
1982 args[1] = tem; | 2234 { |
1983 args[2] = handler_data; | 2235 Lisp_Object (*hfun) (Lisp_Object, Lisp_Object, Lisp_Object) = |
1984 nngcpro1.var = args; | 2236 (Lisp_Object (*) (Lisp_Object, Lisp_Object, Lisp_Object)) |
1985 tem = Fapply (3, args); | 2237 (get_opaque_ptr (handler_fun)); |
1986 NNUNGCPRO; | 2238 |
1987 } | 2239 assert (NILP (XCDR (handler_data))); |
2240 tem = (*hfun) (error_symbol, data, XCAR (handler_data)); | |
2241 } | |
2242 } | |
2243 else | |
2244 { | |
2245 tem = Fcons (error_symbol, data); | |
2246 if (NILP (handler_data)) | |
2247 tem = call1 (handler_fun, tem); | |
2248 else | |
2249 { | |
2250 /* (This code won't be used (for now?).) */ | |
2251 struct gcpro nngcpro1; | |
2252 Lisp_Object args[3]; | |
2253 NNGCPRO1 (args[0]); | |
2254 nngcpro1.nvars = 3; | |
2255 args[0] = handler_fun; | |
2256 args[1] = tem; | |
2257 args[2] = handler_data; | |
2258 nngcpro1.var = args; | |
2259 tem = Fapply (3, args); | |
2260 NNUNGCPRO; | |
2261 } | |
2262 } | |
1988 NUNGCPRO; | 2263 NUNGCPRO; |
1989 #if 0 | 2264 #if 0 |
1990 if (!EQ (tem, Qsignal)) | 2265 if (!EQ (tem, Qsignal)) |
1991 return return_from_signal (tem); | 2266 return return_from_signal (tem); |
1992 #endif | 2267 #endif |
1999 /* t is used by handlers for all conditions, set up by C code. | 2274 /* t is used by handlers for all conditions, set up by C code. |
2000 * debugger is not called even if debug_on_error */ | 2275 * debugger is not called even if debug_on_error */ |
2001 else if (EQ (handler_data, Qt)) | 2276 else if (EQ (handler_data, Qt)) |
2002 { | 2277 { |
2003 UNGCPRO; | 2278 UNGCPRO; |
2004 return Fthrow (handlers, Fcons (sig, data)); | 2279 return Fthrow (handlers, Fcons (error_symbol, data)); |
2005 } | 2280 } |
2006 /* `error' is used similarly to the way `t' is used, but in | 2281 /* `error' is used similarly to the way `t' is used, but in |
2007 addition it invokes the debugger if debug_on_error. | 2282 addition it invokes the debugger if debug_on_error. |
2008 This is normally used for the outer command-loop error | 2283 This is normally used for the outer command-loop error |
2009 handler. */ | 2284 handler. */ |
2010 else if (EQ (handler_data, Qerror)) | 2285 else if (EQ (handler_data, Qerror)) |
2011 { | 2286 { |
2012 Lisp_Object tem = signal_call_debugger (conditions, sig, data, | 2287 Lisp_Object tem = signal_call_debugger (conditions, error_symbol, |
2288 data, | |
2013 outer_handlers, 0, | 2289 outer_handlers, 0, |
2014 &stack_trace_displayed, | 2290 &stack_trace_displayed, |
2015 &debugger_entered); | 2291 &debugger_entered); |
2016 | 2292 |
2017 UNGCPRO; | 2293 UNGCPRO; |
2018 if (!UNBOUNDP (tem)) | 2294 if (!UNBOUNDP (tem)) |
2019 return return_from_signal (tem); | 2295 return return_from_signal (tem); |
2020 | 2296 |
2021 tem = Fcons (sig, data); | 2297 tem = Fcons (error_symbol, data); |
2022 return Fthrow (handlers, tem); | 2298 return Fthrow (handlers, tem); |
2023 } | 2299 } |
2024 else | 2300 else |
2025 { | 2301 { |
2026 /* handler established by real (Lisp) condition-case */ | 2302 /* handler established by real (Lisp) condition-case */ |
2031 Lisp_Object clause = Fcar (h); | 2307 Lisp_Object clause = Fcar (h); |
2032 Lisp_Object tem = Fcar (clause); | 2308 Lisp_Object tem = Fcar (clause); |
2033 | 2309 |
2034 if (condition_type_p (tem, conditions)) | 2310 if (condition_type_p (tem, conditions)) |
2035 { | 2311 { |
2036 tem = signal_call_debugger (conditions, sig, data, | 2312 tem = signal_call_debugger (conditions, error_symbol, data, |
2037 outer_handlers, 1, | 2313 outer_handlers, 1, |
2038 &stack_trace_displayed, | 2314 &stack_trace_displayed, |
2039 &debugger_entered); | 2315 &debugger_entered); |
2040 UNGCPRO; | 2316 UNGCPRO; |
2041 if (!UNBOUNDP (tem)) | 2317 if (!UNBOUNDP (tem)) |
2042 return return_from_signal (tem); | 2318 return return_from_signal (tem); |
2043 | 2319 |
2044 /* Doesn't return */ | 2320 /* Doesn't return */ |
2045 tem = Fcons (Fcons (sig, data), Fcdr (clause)); | 2321 tem = Fcons (Fcons (error_symbol, data), Fcdr (clause)); |
2046 return Fthrow (handlers, tem); | 2322 return Fthrow (handlers, tem); |
2047 } | 2323 } |
2048 } | 2324 } |
2049 } | 2325 } |
2050 } | 2326 } |
2055 #### The only time that no handler is present is during | 2331 #### The only time that no handler is present is during |
2056 temacs or perhaps very early in XEmacs. In both cases, | 2332 temacs or perhaps very early in XEmacs. In both cases, |
2057 there is no 'top-level catch. (That's why the | 2333 there is no 'top-level catch. (That's why the |
2058 "bomb-out" hack was added.) | 2334 "bomb-out" hack was added.) |
2059 | 2335 |
2060 #### Fix this horrifitude! | 2336 [[#### Fix this horrifitude!]] |
2061 */ | 2337 |
2062 signal_call_debugger (conditions, sig, data, Qnil, 0, | 2338 I don't think this is horrifitude, but just defensive coding. --ben */ |
2339 | |
2340 signal_call_debugger (conditions, error_symbol, data, Qnil, 0, | |
2063 &stack_trace_displayed, | 2341 &stack_trace_displayed, |
2064 &debugger_entered); | 2342 &debugger_entered); |
2065 UNGCPRO; | 2343 UNGCPRO; |
2066 throw_or_bomb_out (Qtop_level, Qt, 1, sig, data); /* Doesn't return */ | 2344 throw_or_bomb_out (Qtop_level, Qt, 1, error_symbol, |
2345 data); /* Doesn't return */ | |
2067 return Qnil; | 2346 return Qnil; |
2068 } | 2347 } |
2069 | 2348 |
2070 | |
2071 /****************** Error functions class 1 ******************/ | 2349 /****************** Error functions class 1 ******************/ |
2072 | 2350 |
2073 /* Class 1: General functions that signal an error. | 2351 /* Class 1: General functions that signal an error. |
2074 These functions take an error type and a list of associated error | 2352 These functions take an error type and a list of associated error |
2075 data. */ | 2353 data. */ |
2076 | 2354 |
2077 /* The simplest external error function: it would be called | 2355 /* No signal_continuable_error_1(); it's called Fsignal(). */ |
2078 signal_continuable_error_1() in the terminology below, but it's | |
2079 Lisp-callable. */ | |
2080 | |
2081 DEFUN ("signal", Fsignal, 2, 2, 0, /* | |
2082 Signal a continuable error. Args are ERROR-SYMBOL, and associated DATA. | |
2083 An error symbol is a symbol defined using `define-error'. | |
2084 DATA should be a list. Its elements are printed as part of the error message. | |
2085 If the signal is handled, DATA is made available to the handler. | |
2086 See also the function `signal-error', and the functions to handle errors: | |
2087 `condition-case' and `call-with-condition-handler'. | |
2088 | |
2089 Note that this function can return, if the debugger is invoked and the | |
2090 user invokes the "return from signal" option. | |
2091 */ | |
2092 (error_symbol, data)) | |
2093 { | |
2094 /* Fsignal() is one of these functions that's called all the time | |
2095 with newly-created Lisp objects. We allow this; but we must GC- | |
2096 protect the objects because all sorts of weird stuff could | |
2097 happen. */ | |
2098 | |
2099 struct gcpro gcpro1; | |
2100 | |
2101 GCPRO1 (data); | |
2102 if (!NILP (Vcurrent_error_state)) | |
2103 { | |
2104 if (!NILP (Vcurrent_warning_class) && !NILP (Vcurrent_warning_level)) | |
2105 warn_when_safe_lispobj (Vcurrent_warning_class, Vcurrent_warning_level, | |
2106 Fcons (error_symbol, data)); | |
2107 Fthrow (Qunbound_suspended_errors_tag, Qnil); | |
2108 abort (); /* Better not get here! */ | |
2109 } | |
2110 RETURN_UNGCPRO (signal_1 (error_symbol, data)); | |
2111 } | |
2112 | 2356 |
2113 /* Signal a non-continuable error. */ | 2357 /* Signal a non-continuable error. */ |
2114 | 2358 |
2115 DOESNT_RETURN | 2359 DOESNT_RETURN |
2116 signal_error_1 (Lisp_Object sig, Lisp_Object data) | 2360 signal_error_1 (Lisp_Object sig, Lisp_Object data) |
2117 { | 2361 { |
2118 for (;;) | 2362 for (;;) |
2119 Fsignal (sig, data); | 2363 Fsignal (sig, data); |
2120 } | 2364 } |
2121 #ifdef ERROR_CHECK_STRUCTURES | 2365 |
2122 static void | 2366 #ifdef ERROR_CHECK_CATCH |
2123 check_error_state_sanity (void) | 2367 |
2124 { | 2368 void |
2369 check_catchlist_sanity (void) | |
2370 { | |
2371 #if 0 | |
2372 /* vou me tomar no cu! i just masked andy's missing-unbind | |
2373 bug! */ | |
2125 struct catchtag *c; | 2374 struct catchtag *c; |
2126 int found_error_tag = 0; | 2375 int found_error_tag = 0; |
2127 | 2376 |
2128 for (c = catchlist; c; c = c->next) | 2377 for (c = catchlist; c; c = c->next) |
2129 { | 2378 { |
2133 break; | 2382 break; |
2134 } | 2383 } |
2135 } | 2384 } |
2136 | 2385 |
2137 assert (found_error_tag || NILP (Vcurrent_error_state)); | 2386 assert (found_error_tag || NILP (Vcurrent_error_state)); |
2138 } | 2387 #endif /* vou me tomar no cul */ |
2139 #endif | 2388 } |
2140 | 2389 |
2141 static Lisp_Object | 2390 void |
2142 restore_current_warning_class (Lisp_Object warning_class) | 2391 check_specbind_stack_sanity (void) |
2143 { | 2392 { |
2144 Vcurrent_warning_class = warning_class; | 2393 } |
2145 return Qnil; | 2394 |
2146 } | 2395 #endif /* ERROR_CHECK_CATCH */ |
2147 | |
2148 static Lisp_Object | |
2149 restore_current_warning_level (Lisp_Object warning_level) | |
2150 { | |
2151 Vcurrent_warning_level = warning_level; | |
2152 return Qnil; | |
2153 } | |
2154 | |
2155 static Lisp_Object | |
2156 restore_current_error_state (Lisp_Object error_state) | |
2157 { | |
2158 Vcurrent_error_state = error_state; | |
2159 return Qnil; | |
2160 } | |
2161 | |
2162 static Lisp_Object | |
2163 call_with_suspended_errors_1 (Lisp_Object opaque_arg) | |
2164 { | |
2165 Lisp_Object val; | |
2166 Lisp_Object *kludgy_args = (Lisp_Object *) get_opaque_ptr (opaque_arg); | |
2167 int speccount = specpdl_depth (); | |
2168 | |
2169 if (NILP (Vcurrent_error_state)) | |
2170 { | |
2171 record_unwind_protect (restore_current_error_state, | |
2172 Vcurrent_error_state); | |
2173 Vcurrent_error_state = Qt; | |
2174 } | |
2175 PRIMITIVE_FUNCALL (val, get_opaque_ptr (kludgy_args[0]), | |
2176 kludgy_args + 2, XINT (kludgy_args[1])); | |
2177 return unbind_to_1 (speccount, val); | |
2178 } | |
2179 | |
2180 /* Many functions would like to do one of three things if an error | |
2181 occurs: | |
2182 | |
2183 (1) signal the error, as usual. | |
2184 (2) silently fail and return some error value. | |
2185 (3) do as (2) but issue a warning in the process. | |
2186 | |
2187 Currently there's lots of stuff that passes an Error_Behavior | |
2188 value and calls maybe_signal_error() and other such functions. | |
2189 This approach is inherently error-prone and broken. A much | |
2190 more robust and easier approach is to use call_with_suspended_errors(). | |
2191 Wrap this around any function in which you might want errors | |
2192 to not be errors. | |
2193 */ | |
2194 | |
2195 Lisp_Object | |
2196 call_with_suspended_errors (lisp_fn_t fun, volatile Lisp_Object retval, | |
2197 Lisp_Object class, Error_Behavior errb, | |
2198 int nargs, ...) | |
2199 { | |
2200 va_list vargs; | |
2201 int speccount; | |
2202 Lisp_Object kludgy_args[22]; | |
2203 Lisp_Object *args = kludgy_args + 2; | |
2204 int i; | |
2205 | |
2206 assert (SYMBOLP (class)); /* sanity-check */ | |
2207 assert (!NILP (class)); | |
2208 assert (nargs >= 0 && nargs < 20); | |
2209 | |
2210 va_start (vargs, nargs); | |
2211 for (i = 0; i < nargs; i++) | |
2212 args[i] = va_arg (vargs, Lisp_Object); | |
2213 va_end (vargs); | |
2214 | |
2215 /* ERROR_ME means don't trap errors. (However, if errors are | |
2216 already trapped, we leave them trapped.) | |
2217 | |
2218 Otherwise, we trap errors, and display as warnings if ERROR_ME_WARN. | |
2219 | |
2220 If ERROR_ME_NOT, we silently fail. | |
2221 | |
2222 If ERROR_ME_DEBUG_WARN, we display a warning, but at warning level to | |
2223 `debug'. Normally these disappear, but can be seen if we changed | |
2224 log-warning-minimum-level. | |
2225 */ | |
2226 | |
2227 /* If error-checking is not disabled, just call the function. | |
2228 It's important not to override disabled error-checking with | |
2229 enabled error-checking. */ | |
2230 | |
2231 if (ERRB_EQ (errb, ERROR_ME)) | |
2232 { | |
2233 Lisp_Object val; | |
2234 PRIMITIVE_FUNCALL (val, fun, args, nargs); | |
2235 return val; | |
2236 } | |
2237 | |
2238 speccount = specpdl_depth (); | |
2239 if (NILP (Vcurrent_warning_class)) | |
2240 { | |
2241 /* Don't change the existing class. | |
2242 #### Should we be consing the two together? */ | |
2243 record_unwind_protect (restore_current_warning_class, | |
2244 Vcurrent_warning_class); | |
2245 Vcurrent_warning_class = class; | |
2246 } | |
2247 | |
2248 record_unwind_protect (restore_current_warning_level, | |
2249 Vcurrent_warning_level); | |
2250 Vcurrent_warning_level = | |
2251 (ERRB_EQ (errb, ERROR_ME_NOT) ? Qnil : | |
2252 ERRB_EQ (errb, ERROR_ME_DEBUG_WARN) ? Qdebug : | |
2253 Qwarning); | |
2254 | |
2255 | |
2256 { | |
2257 int threw; | |
2258 Lisp_Object the_retval; | |
2259 Lisp_Object opaque1 = make_opaque_ptr (kludgy_args); | |
2260 Lisp_Object opaque2 = make_opaque_ptr ((void *) fun); | |
2261 struct gcpro gcpro1, gcpro2; | |
2262 | |
2263 GCPRO2 (opaque1, opaque2); | |
2264 kludgy_args[0] = opaque2; | |
2265 kludgy_args[1] = make_int (nargs); | |
2266 the_retval = internal_catch (Qunbound_suspended_errors_tag, | |
2267 call_with_suspended_errors_1, | |
2268 opaque1, &threw); | |
2269 free_opaque_ptr (opaque1); | |
2270 free_opaque_ptr (opaque2); | |
2271 UNGCPRO; | |
2272 /* Use the returned value except in non-local exit, when | |
2273 RETVAL applies. */ | |
2274 /* Some perverse compilers require the perverse cast below. */ | |
2275 return unbind_to_1 (speccount, | |
2276 threw ? *((Lisp_Object*) &(retval)) : the_retval); | |
2277 } | |
2278 } | |
2279 | 2396 |
2280 /* Signal a non-continuable error or display a warning or do nothing, | 2397 /* Signal a non-continuable error or display a warning or do nothing, |
2281 according to ERRB. CLASS is the class of warning and should | 2398 according to ERRB. CLASS is the class of warning and should |
2282 refer to what sort of operation is being done (e.g. Qtoolbar, | 2399 refer to what sort of operation is being done (e.g. Qtoolbar, |
2283 Qresource, etc.). */ | 2400 Qresource, etc.). */ |
2604 | 2721 |
2605 /* This is what the QUIT macro calls to signal a quit */ | 2722 /* This is what the QUIT macro calls to signal a quit */ |
2606 void | 2723 void |
2607 signal_quit (void) | 2724 signal_quit (void) |
2608 { | 2725 { |
2609 /* This function can GC */ | 2726 /* This function cannot GC. GC is prohibited because most callers do |
2727 not expect GC occurring in QUIT. Remove this if/when that gets fixed. | |
2728 --ben */ | |
2729 | |
2730 int count; | |
2731 | |
2610 if (EQ (Vquit_flag, Qcritical)) | 2732 if (EQ (Vquit_flag, Qcritical)) |
2611 debug_on_quit |= 2; /* set critical bit. */ | 2733 debug_on_quit |= 2; /* set critical bit. */ |
2612 Vquit_flag = Qnil; | 2734 Vquit_flag = Qnil; |
2735 count = begin_gc_forbidden (); | |
2613 /* note that this is continuable. */ | 2736 /* note that this is continuable. */ |
2614 Fsignal (Qquit, Qnil); | 2737 Fsignal (Qquit, Qnil); |
2738 unbind_to (count); | |
2615 } | 2739 } |
2616 | 2740 |
2617 | 2741 |
2618 /************************ convenience error functions ***********************/ | 2742 /************************ convenience error functions ***********************/ |
2619 | 2743 |
3162 | 3286 |
3163 static Lisp_Object funcall_lambda (Lisp_Object fun, | 3287 static Lisp_Object funcall_lambda (Lisp_Object fun, |
3164 int nargs, Lisp_Object args[]); | 3288 int nargs, Lisp_Object args[]); |
3165 static int in_warnings; | 3289 static int in_warnings; |
3166 | 3290 |
3167 static Lisp_Object | |
3168 in_warnings_restore (Lisp_Object minimus) | |
3169 { | |
3170 in_warnings = 0; | |
3171 return Qnil; | |
3172 } | |
3173 | 3291 |
3174 void handle_compiled_function_with_and_rest (Lisp_Compiled_Function *f, | 3292 void handle_compiled_function_with_and_rest (Lisp_Compiled_Function *f, |
3175 int nargs, | 3293 int nargs, |
3176 Lisp_Object args[]); | 3294 Lisp_Object args[]); |
3177 | 3295 |
3296 Lisp_Object fun, val, original_fun, original_args; | 3414 Lisp_Object fun, val, original_fun, original_args; |
3297 int nargs; | 3415 int nargs; |
3298 struct backtrace backtrace; | 3416 struct backtrace backtrace; |
3299 | 3417 |
3300 /* I think this is a pretty safe place to call Lisp code, don't you? */ | 3418 /* I think this is a pretty safe place to call Lisp code, don't you? */ |
3301 while (!in_warnings && !NILP (Vpending_warnings)) | 3419 while (!in_warnings && !NILP (Vpending_warnings) |
3420 /* well, perhaps not so safe after all! */ | |
3421 && !(inhibit_flags & INHIBIT_ANY_CHANGE_AFFECTING_REDISPLAY)) | |
3302 { | 3422 { |
3303 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4; | 3423 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4; |
3304 int speccount = specpdl_depth(); | |
3305 Lisp_Object this_warning_cons, this_warning, class, level, messij; | 3424 Lisp_Object this_warning_cons, this_warning, class, level, messij; |
3306 | 3425 int speccount = internal_bind_int (&in_warnings, 1); |
3307 record_unwind_protect (in_warnings_restore, Qnil); | 3426 |
3308 in_warnings = 1; | |
3309 this_warning_cons = Vpending_warnings; | 3427 this_warning_cons = Vpending_warnings; |
3310 this_warning = XCAR (this_warning_cons); | 3428 this_warning = XCAR (this_warning_cons); |
3311 /* in case an error occurs in the warn function, at least | 3429 /* in case an error occurs in the warn function, at least |
3312 it won't happen infinitely */ | 3430 it won't happen infinitely */ |
3313 Vpending_warnings = XCDR (Vpending_warnings); | 3431 Vpending_warnings = XCDR (Vpending_warnings); |
3314 free_cons (XCONS (this_warning_cons)); | 3432 free_cons (this_warning_cons); |
3315 class = XCAR (this_warning); | 3433 class = XCAR (this_warning); |
3316 level = XCAR (XCDR (this_warning)); | 3434 level = XCAR (XCDR (this_warning)); |
3317 messij = XCAR (XCDR (XCDR (this_warning))); | 3435 messij = XCAR (XCDR (XCDR (this_warning))); |
3318 free_list (this_warning); | 3436 free_list (this_warning); |
3319 | 3437 |
3812 | 3930 |
3813 DEFUN ("function-min-args", Ffunction_min_args, 1, 1, 0, /* | 3931 DEFUN ("function-min-args", Ffunction_min_args, 1, 1, 0, /* |
3814 Return the minimum number of arguments a function may be called with. | 3932 Return the minimum number of arguments a function may be called with. |
3815 The function may be any form that can be passed to `funcall', | 3933 The function may be any form that can be passed to `funcall', |
3816 any special form, or any macro. | 3934 any special form, or any macro. |
3935 | |
3936 To check if a function can be called with a specified number of | |
3937 arguments, use `function-allows-args'. | |
3817 */ | 3938 */ |
3818 (function)) | 3939 (function)) |
3819 { | 3940 { |
3820 return function_argcount (function, 1); | 3941 return function_argcount (function, 1); |
3821 } | 3942 } |
3824 Return the maximum number of arguments a function may be called with. | 3945 Return the maximum number of arguments a function may be called with. |
3825 The function may be any form that can be passed to `funcall', | 3946 The function may be any form that can be passed to `funcall', |
3826 any special form, or any macro. | 3947 any special form, or any macro. |
3827 If the function takes an arbitrary number of arguments or is | 3948 If the function takes an arbitrary number of arguments or is |
3828 a built-in special form, nil is returned. | 3949 a built-in special form, nil is returned. |
3950 | |
3951 To check if a function can be called with a specified number of | |
3952 arguments, use `function-allows-args'. | |
3829 */ | 3953 */ |
3830 (function)) | 3954 (function)) |
3831 { | 3955 { |
3832 return function_argcount (function, 0); | 3956 return function_argcount (function, 0); |
3833 } | 3957 } |
4143 return run_hook_with_args_in_buffer (current_buffer, nargs, args, cond); | 4267 return run_hook_with_args_in_buffer (current_buffer, nargs, args, cond); |
4144 } | 4268 } |
4145 | 4269 |
4146 #if 0 | 4270 #if 0 |
4147 | 4271 |
4148 /* From FSF 19.30, not currently used */ | 4272 /* From FSF 19.30, not currently used; seems like a big kludge. */ |
4149 | 4273 |
4150 /* Run a hook symbol ARGS[0], but use FUNLIST instead of the actual | 4274 /* Run a hook symbol ARGS[0], but use FUNLIST instead of the actual |
4151 present value of that symbol. | 4275 present value of that symbol. |
4152 Call each element of FUNLIST, | 4276 Call each element of FUNLIST, |
4153 passing each of them the rest of ARGS. | 4277 passing each of them the rest of ARGS. |
4155 except that it isn't necessary to gcpro ARGS[0]. */ | 4279 except that it isn't necessary to gcpro ARGS[0]. */ |
4156 | 4280 |
4157 Lisp_Object | 4281 Lisp_Object |
4158 run_hook_list_with_args (Lisp_Object funlist, int nargs, Lisp_Object *args) | 4282 run_hook_list_with_args (Lisp_Object funlist, int nargs, Lisp_Object *args) |
4159 { | 4283 { |
4160 Lisp_Object sym = args[0]; | 4284 omitted; |
4161 Lisp_Object val; | |
4162 struct gcpro gcpro1, gcpro2; | |
4163 | |
4164 GCPRO2 (sym, val); | |
4165 | |
4166 for (val = funlist; CONSP (val); val = XCDR (val)) | |
4167 { | |
4168 if (EQ (XCAR (val), Qt)) | |
4169 { | |
4170 /* t indicates this hook has a local binding; | |
4171 it means to run the global binding too. */ | |
4172 Lisp_Object globals; | |
4173 | |
4174 for (globals = Fdefault_value (sym); | |
4175 CONSP (globals); | |
4176 globals = XCDR (globals)) | |
4177 { | |
4178 args[0] = XCAR (globals); | |
4179 /* In a global value, t should not occur. If it does, we | |
4180 must ignore it to avoid an endless loop. */ | |
4181 if (!EQ (args[0], Qt)) | |
4182 Ffuncall (nargs, args); | |
4183 } | |
4184 } | |
4185 else | |
4186 { | |
4187 args[0] = XCAR (val); | |
4188 Ffuncall (nargs, args); | |
4189 } | |
4190 } | |
4191 UNGCPRO; | |
4192 return Qnil; | |
4193 } | 4285 } |
4194 | 4286 |
4195 #endif /* 0 */ | 4287 #endif /* 0 */ |
4196 | 4288 |
4197 void | 4289 void |
4239 } | 4331 } |
4240 | 4332 |
4241 Lisp_Object | 4333 Lisp_Object |
4242 run_hook (Lisp_Object hook) | 4334 run_hook (Lisp_Object hook) |
4243 { | 4335 { |
4244 Frun_hooks (1, &hook); | 4336 return run_hook_with_args (1, &hook, RUN_HOOKS_TO_COMPLETION); |
4245 return Qnil; | |
4246 } | 4337 } |
4247 | 4338 |
4248 | 4339 |
4249 /************************************************************************/ | 4340 /************************************************************************/ |
4250 /* Front-ends to eval, funcall, apply */ | 4341 /* Front-ends to eval, funcall, apply */ |
4540 | 4631 |
4541 /************************************************************************/ | 4632 /************************************************************************/ |
4542 /* Error-catching front-ends to eval, funcall, apply */ | 4633 /* Error-catching front-ends to eval, funcall, apply */ |
4543 /************************************************************************/ | 4634 /************************************************************************/ |
4544 | 4635 |
4545 /* Call function fn on no arguments, with condition handler */ | 4636 int |
4637 get_inhibit_flags (void) | |
4638 { | |
4639 return inhibit_flags; | |
4640 } | |
4641 | |
4642 void | |
4643 check_allowed_operation (int what, Lisp_Object obj, Lisp_Object prop) | |
4644 { | |
4645 if (inhibit_flags & INHIBIT_EXISTING_BUFFER_TEXT_MODIFICATION) | |
4646 { | |
4647 if (what == OPERATION_MODIFY_BUFFER_TEXT && BUFFERP (obj) | |
4648 && NILP (memq_no_quit (obj, Vmodifiable_buffers))) | |
4649 invalid_change | |
4650 ("Modification of this buffer not currently permitted", obj); | |
4651 } | |
4652 if (inhibit_flags & INHIBIT_EXISTING_PERMANENT_DISPLAY_OBJECT_DELETION) | |
4653 { | |
4654 if (what == OPERATION_DELETE_OBJECT | |
4655 && (BUFFERP (obj) || WINDOWP (obj) || FRAMEP (obj) || DEVICEP (obj) | |
4656 || CONSOLEP (obj)) | |
4657 && NILP (memq_no_quit (obj, Vdeletable_permanent_display_objects))) | |
4658 invalid_change | |
4659 ("Deletion of this object not currently permitted", obj); | |
4660 } | |
4661 } | |
4662 | |
4663 void | |
4664 note_object_created (Lisp_Object obj) | |
4665 { | |
4666 if (inhibit_flags & INHIBIT_EXISTING_BUFFER_TEXT_MODIFICATION) | |
4667 { | |
4668 if (BUFFERP (obj)) | |
4669 Vmodifiable_buffers = Fcons (obj, Vmodifiable_buffers); | |
4670 } | |
4671 if (inhibit_flags & INHIBIT_EXISTING_PERMANENT_DISPLAY_OBJECT_DELETION) | |
4672 { | |
4673 if (BUFFERP (obj) || WINDOWP (obj) || FRAMEP (obj) || DEVICEP (obj) | |
4674 || CONSOLEP (obj)) | |
4675 Vdeletable_permanent_display_objects = | |
4676 Fcons (obj, Vdeletable_permanent_display_objects); | |
4677 } | |
4678 } | |
4679 | |
4680 void | |
4681 note_object_deleted (Lisp_Object obj) | |
4682 { | |
4683 if (inhibit_flags & INHIBIT_EXISTING_BUFFER_TEXT_MODIFICATION) | |
4684 { | |
4685 if (BUFFERP (obj)) | |
4686 Vmodifiable_buffers = delq_no_quit (obj, Vmodifiable_buffers); | |
4687 } | |
4688 if (inhibit_flags & INHIBIT_EXISTING_PERMANENT_DISPLAY_OBJECT_DELETION) | |
4689 { | |
4690 if (BUFFERP (obj) || WINDOWP (obj) || FRAMEP (obj) || DEVICEP (obj) | |
4691 || CONSOLEP (obj)) | |
4692 Vdeletable_permanent_display_objects = | |
4693 delq_no_quit (obj, Vdeletable_permanent_display_objects); | |
4694 } | |
4695 } | |
4696 | |
4697 struct call_trapping_problems | |
4698 { | |
4699 Lisp_Object catchtag; | |
4700 Lisp_Object error_conditions; | |
4701 Lisp_Object data; | |
4702 Lisp_Object backtrace; | |
4703 Lisp_Object warning_class; | |
4704 | |
4705 const CIntbyte *warning_string; | |
4706 Lisp_Object (*fun) (void *); | |
4707 void *arg; | |
4708 }; | |
4709 | |
4710 static Lisp_Object | |
4711 flagged_a_squirmer (Lisp_Object error_conditions, Lisp_Object data, | |
4712 Lisp_Object opaque) | |
4713 { | |
4714 struct call_trapping_problems *p = | |
4715 (struct call_trapping_problems *) get_opaque_ptr (opaque); | |
4716 struct gcpro gcpro1; | |
4717 Lisp_Object lstream = Qnil; | |
4718 Lisp_Object errstr; | |
4719 int speccount = specpdl_depth (); | |
4720 | |
4721 if (! (inhibit_flags & INHIBIT_WARNING_ISSUE)) | |
4722 { | |
4723 /* We're no longer protected against errors or quit here, so at | |
4724 least let's temporarily inhibit quit. We definitely do not | |
4725 want to inhibit quit during the calling of the function | |
4726 itself!!!!!!!!!!! */ | |
4727 | |
4728 specbind (Qinhibit_quit, Qt); | |
4729 | |
4730 GCPRO1 (lstream); | |
4731 lstream = make_resizing_buffer_output_stream (); | |
4732 Fbacktrace (lstream, Qt); | |
4733 Lstream_flush (XLSTREAM (lstream)); | |
4734 p->backtrace = resizing_buffer_to_lisp_string (XLSTREAM (lstream)); | |
4735 Lstream_delete (XLSTREAM (lstream)); | |
4736 UNGCPRO; | |
4737 | |
4738 /* #### This should call | |
4739 (with-output-to-string (display-error (cons error_conditions data)) | |
4740 but that stuff is all in Lisp currently. */ | |
4741 errstr = | |
4742 emacs_sprintf_string_lisp | |
4743 ("%s: (%s %s)\n\nBacktrace follows:\n\n%s", | |
4744 Qnil, 4, | |
4745 build_msg_string (p->warning_string ? p->warning_string : "error"), | |
4746 error_conditions, data, p->backtrace); | |
4747 | |
4748 warn_when_safe_lispobj (p->warning_class, current_warning_level (), | |
4749 errstr); | |
4750 | |
4751 unbind_to (speccount); | |
4752 | |
4753 } | |
4754 else | |
4755 p->backtrace = Qnil; | |
4756 | |
4757 p->error_conditions = error_conditions; | |
4758 p->data = data; | |
4759 | |
4760 Fthrow (p->catchtag, Qnil); | |
4761 return Qnil; /* not reached */ | |
4762 } | |
4763 | |
4764 static Lisp_Object | |
4765 call_trapping_problems_2 (Lisp_Object opaque) | |
4766 { | |
4767 struct call_trapping_problems *p = | |
4768 (struct call_trapping_problems *) get_opaque_ptr (opaque); | |
4769 | |
4770 return (p->fun) (p->arg); | |
4771 } | |
4772 | |
4773 static Lisp_Object | |
4774 call_trapping_problems_1 (Lisp_Object opaque) | |
4775 { | |
4776 return call_with_condition_handler (flagged_a_squirmer, opaque, | |
4777 call_trapping_problems_2, opaque); | |
4778 } | |
4779 | |
4780 /* This is equivalent to (*fun) (arg), except that various conditions | |
4781 can be trapped or inhibited, according to FLAGS. | |
4782 | |
4783 If FLAGS does not contain NO_INHIBIT_ERRORS, when an error occurs, | |
4784 the error is caught and a warning is issued, specifying the | |
4785 specific error that occurred and a backtrace. In that case, | |
4786 WARNING_STRING should be given, and will be printed at the | |
4787 beginning of the error to indicate where the error occurred. | |
4788 | |
4789 If FLAGS does not contain NO_INHIBIT_THROWS, all attempts to | |
4790 `throw' out of the function being called are trapped, and a warning | |
4791 issued. (Again, WARNING_STRING should be given.) | |
4792 | |
4793 (If FLAGS contains INHIBIT_WARNING_ISSUE, no warnings are issued; | |
4794 this applies to recursive invocations of call_trapping_problems, too. | |
4795 | |
4796 If FLAGS contains ISSUE_WARNINGS_AT_DEBUG_LEVEL, warnings will be | |
4797 issued, but at level `debug', which normally is below the minimum | |
4798 specified by `log-warning-minimum-level', meaning such warnings will | |
4799 be ignored entirely. The user can change this variable, however, | |
4800 to see the warnings.) | |
4801 | |
4802 Note: If neither of NO_INHIBIT_THROWS or NO_INHIBIT_ERRORS is | |
4803 given, you are *guaranteed* that there will be no non-local exits | |
4804 out of this function. | |
4805 | |
4806 If FLAGS contains INHIBIT_QUIT, QUIT using C-g is inhibited. (This | |
4807 is *rarely* a good idea. Unless you use NO_INHIBIT_ERRORS, QUIT is | |
4808 automatically caught as well, and treated as an error; you can | |
4809 check for this using EQ (problems->error_conditions, Qquit). | |
4810 | |
4811 If FLAGS contains UNINHIBIT_QUIT, QUIT checking will be explicitly | |
4812 turned on. (It will abort the code being called, but will still be | |
4813 trapped and reported as an error, unless NO_INHIBIT_ERRORS is | |
4814 given.) This is useful when QUIT checking has been turned off by a | |
4815 higher-level caller. | |
4816 | |
4817 If FLAGS contains INHIBIT_GC, garbage collection is inhibited. | |
4818 This is useful for Lisp called within redisplay or inside of the | |
4819 QUIT macro (where GC is generally not expected), for example. | |
4820 | |
4821 If FLAGS contains INHIBIT_EXISTING_PERMANENT_DISPLAY_OBJECT_DELETION, | |
4822 Lisp code is not allowed to delete any window, buffers, frames, devices, | |
4823 or consoles that were already in existence at the time this function | |
4824 was called. (However, it's perfectly legal for code to create a new | |
4825 buffer and then delete it.) | |
4826 | |
4827 #### It might be useful to have a flag that inhibits deletion of a | |
4828 specific permanent display object and everything it's attached to | |
4829 (e.g. a window, and the buffer, frame, device, and console it's | |
4830 attached to. | |
4831 | |
4832 If FLAGS contains INHIBIT_EXISTING_BUFFER_TEXT_MODIFICATION, Lisp | |
4833 code is not allowed to modify the text of any buffers that were | |
4834 already in existence at the time this function was called. | |
4835 (However, it's perfectly legal for code to create a new buffer and | |
4836 then modify its text.) | |
4837 | |
4838 [These last two flags are implemented using global variables | |
4839 Vdeletable_permanent_display_objects and Vmodifiable_buffers, | |
4840 which keep track of a list of all buffers or permanent display | |
4841 objects created since the last time one of these flags was set. | |
4842 The code that deletes buffers, etc. and modifies buffers checks | |
4843 | |
4844 (1) if the corresponding flag is set (through the global variable | |
4845 inhibit_flags or its accessor function get_inhibit_flags()), and | |
4846 | |
4847 (2) if the object to be modified or deleted is not in the | |
4848 appropriate list. | |
4849 | |
4850 If so, it signals an error. | |
4851 | |
4852 Recursive calls to call_trapping_problems() are allowed. In | |
4853 the case of the two flags mentioned above, the current values | |
4854 of the global variables are stored in an unwind-protect, and | |
4855 they're reset to nil.] | |
4856 | |
4857 If FLAGS contains INHIBIT_ENTERING_DEBUGGER, the debugger will not | |
4858 be entered if an error occurs inside the Lisp code being called, | |
4859 even when the user has requested an error. In such case, a warning | |
4860 is issued stating that access to the debugger is denied, unless | |
4861 INHIBIT_WARNING_ISSUE has also been supplied. This is useful when | |
4862 calling Lisp code inside redisplay, in menu callbacks, etc. because | |
4863 in such cases either the display is in an inconsistent state or | |
4864 doing window operations is explicitly forbidden by the OS, and the | |
4865 debugger would causes visual changes on the screen and might create | |
4866 another frame. | |
4867 | |
4868 If FLAGS contains INHIBIT_ANY_CHANGE_AFFECTING_REDISPLAY, no | |
4869 changes of any sort to extents, faces, glyphs, buffer text, | |
4870 specifiers relating to display, other variables relating to | |
4871 display, splitting, deleting, or resizing windows or frames, | |
4872 deleting buffers, windows, frames, devices, or consoles, etc. is | |
4873 allowed. This is for things called absolutely in the middle of | |
4874 redisplay, which expects things to be *exactly* the same after the | |
4875 call as before. This isn't completely implemented and needs to be | |
4876 thought out some more to determine exactly what its semantics are. | |
4877 For the moment, turning on this flag also turns on | |
4878 | |
4879 INHIBIT_EXISTING_PERMANENT_DISPLAY_OBJECT_DELETION | |
4880 INHIBIT_EXISTING_BUFFER_TEXT_MODIFICATION | |
4881 INHIBIT_ENTERING_DEBUGGER | |
4882 INHIBIT_WARNING_ISSUE | |
4883 INHIBIT_GC | |
4884 | |
4885 #### The following five flags are defined, but unimplemented: | |
4886 | |
4887 #define INHIBIT_EXISTING_CODING_SYSTEM_DELETION (1<<6) | |
4888 #define INHIBIT_EXISTING_CHARSET_DELETION (1<<7) | |
4889 #define INHIBIT_PERMANENT_DISPLAY_OBJECT_CREATION (1<<8) | |
4890 #define INHIBIT_CODING_SYSTEM_CREATION (1<<9) | |
4891 #define INHIBIT_CHARSET_CREATION (1<<10) | |
4892 | |
4893 FLAGS containing CALL_WITH_SUSPENDED_ERRORS is a sign that | |
4894 call_with_suspended_errors() was invoked. This exists only for | |
4895 debugging purposes -- often we want to break when a signal happens, | |
4896 but ignore signals from call_with_suspended_errors(), because they | |
4897 occur often and for legitimate reasons. | |
4898 | |
4899 If PROBLEM is non-zero, it should be a pointer to a structure into | |
4900 which exact information about any occurring problems (either an | |
4901 error or an attempted throw past this boundary). | |
4902 | |
4903 If a problem occurred and aborted operation (error, quit, or | |
4904 invalid throw), Qunbound is returned. Otherwise the return value | |
4905 from the call to (*fun) (arg) is returned. */ | |
4906 | |
4546 Lisp_Object | 4907 Lisp_Object |
4547 call0_with_handler (Lisp_Object handler, Lisp_Object fn) | 4908 call_trapping_problems (Lisp_Object warning_class, |
4548 { | 4909 const CIntbyte *warning_string, |
4549 /* This function can GC */ | 4910 int flags, |
4911 struct call_trapping_problems_result *problem, | |
4912 Lisp_Object (*fun) (void *), | |
4913 void *arg) | |
4914 { | |
4915 int speccount = specpdl_depth(); | |
4916 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5; | |
4917 struct call_trapping_problems package; | |
4918 Lisp_Object opaque, thrown_tag, tem; | |
4919 int thrown = 0; | |
4920 | |
4921 assert (SYMBOLP (warning_class)); /* sanity-check */ | |
4922 assert (!NILP (warning_class)); | |
4923 | |
4924 flags ^= INTERNAL_INHIBIT_ERRORS | INTERNAL_INHIBIT_THROWS; | |
4925 | |
4926 package.warning_class = warning_class; | |
4927 package.warning_string = warning_string; | |
4928 package.fun = fun; | |
4929 package.arg = arg; | |
4930 package.catchtag = | |
4931 flags & INTERNAL_INHIBIT_THROWS ? Vcatch_everything_tag : | |
4932 flags & INTERNAL_INHIBIT_ERRORS ? make_opaque_ptr (0) : | |
4933 Qnil; | |
4934 package.error_conditions = Qnil; | |
4935 package.data = Qnil; | |
4936 package.backtrace = Qnil; | |
4937 | |
4938 if (flags & INHIBIT_ANY_CHANGE_AFFECTING_REDISPLAY) | |
4939 flags |= INHIBIT_EXISTING_PERMANENT_DISPLAY_OBJECT_DELETION | |
4940 | INHIBIT_EXISTING_BUFFER_TEXT_MODIFICATION | |
4941 | INHIBIT_ENTERING_DEBUGGER | |
4942 | INHIBIT_WARNING_ISSUE | |
4943 | INHIBIT_GC; | |
4944 | |
4945 { | |
4946 int new_inhibit_flags = inhibit_flags | flags; | |
4947 if (new_inhibit_flags != inhibit_flags) | |
4948 internal_bind_int (&inhibit_flags, new_inhibit_flags); | |
4949 } | |
4950 | |
4951 if (flags & INHIBIT_QUIT) | |
4952 specbind (Qinhibit_quit, Qt); | |
4953 | |
4954 if (flags & UNINHIBIT_QUIT) | |
4955 begin_do_check_for_quit (); | |
4956 | |
4957 if (flags & INHIBIT_GC) | |
4958 begin_gc_forbidden (); | |
4959 | |
4960 /* #### If we have nested calls to call_trapping_problems(), and the | |
4961 inner one creates some buffers/etc., should the outer one be able | |
4962 to delete them? I think so, but it means we need to combine rather | |
4963 than just reset the value. */ | |
4964 if (flags & INHIBIT_EXISTING_PERMANENT_DISPLAY_OBJECT_DELETION) | |
4965 internal_bind_lisp_object (&Vdeletable_permanent_display_objects, Qnil); | |
4966 | |
4967 if (flags & INHIBIT_EXISTING_BUFFER_TEXT_MODIFICATION) | |
4968 internal_bind_lisp_object (&Vmodifiable_buffers, Qnil); | |
4969 | |
4970 if (flags & (INTERNAL_INHIBIT_THROWS | INTERNAL_INHIBIT_ERRORS)) | |
4971 opaque = make_opaque_ptr (&package); | |
4972 else | |
4973 opaque = Qnil; | |
4974 | |
4975 GCPRO5 (package.catchtag, package.error_conditions, package.data, | |
4976 package.backtrace, opaque); | |
4977 | |
4978 if (flags & INTERNAL_INHIBIT_ERRORS) | |
4979 /* We need a catch so that our condition-handler can throw back here | |
4980 after printing the warning. (We print the warning in the stack | |
4981 context of the error, so we can get a backtrace.) */ | |
4982 tem = internal_catch (package.catchtag, call_trapping_problems_1, opaque, | |
4983 &thrown, &thrown_tag); | |
4984 else if (flags & INTERNAL_INHIBIT_THROWS) | |
4985 /* We skip over the first wrapper, which traps errors. */ | |
4986 tem = internal_catch (package.catchtag, call_trapping_problems_2, opaque, | |
4987 &thrown, &thrown_tag); | |
4988 else | |
4989 /* Nothing special. */ | |
4990 tem = (fun) (arg); | |
4991 | |
4992 if (thrown && !EQ (thrown_tag, package.catchtag) | |
4993 && (!flags & INHIBIT_WARNING_ISSUE)) | |
4994 { | |
4995 Lisp_Object errstr; | |
4996 | |
4997 if (!(flags & INHIBIT_QUIT)) | |
4998 /* We're no longer protected against errors or quit here, so at | |
4999 least let's temporarily inhibit quit. */ | |
5000 specbind (Qinhibit_quit, Qt); | |
5001 errstr = | |
5002 emacs_sprintf_string_lisp | |
5003 ("%s: Attempt to throw outside of function " | |
5004 "to catch `%s' with value `%s'", | |
5005 Qnil, 3, build_msg_string (warning_string ? warning_string : "error"), | |
5006 thrown_tag, tem); | |
5007 | |
5008 warn_when_safe_lispobj (Qerror, current_warning_level (), errstr); | |
5009 } | |
5010 | |
5011 if (problem) | |
5012 { | |
5013 if (!thrown) | |
5014 { | |
5015 problem->caught_error = 0; | |
5016 problem->caught_throw = 0; | |
5017 problem->error_conditions = Qnil; | |
5018 problem->data = Qnil; | |
5019 problem->backtrace = Qnil; | |
5020 problem->thrown_tag = Qnil; | |
5021 problem->thrown_value = Qnil; | |
5022 } | |
5023 else if (EQ (thrown_tag, package.catchtag)) | |
5024 { | |
5025 problem->caught_error = 1; | |
5026 problem->caught_throw = 0; | |
5027 problem->error_conditions = package.error_conditions; | |
5028 problem->data = package.data; | |
5029 problem->backtrace = package.backtrace; | |
5030 problem->thrown_tag = Qnil; | |
5031 problem->thrown_value = Qnil; | |
5032 } | |
5033 else | |
5034 { | |
5035 problem->caught_error = 0; | |
5036 problem->caught_throw = 1; | |
5037 problem->error_conditions = Qnil; | |
5038 problem->data = Qnil; | |
5039 problem->backtrace = Qnil; | |
5040 problem->thrown_tag = thrown_tag; | |
5041 problem->thrown_value = tem; | |
5042 } | |
5043 } | |
5044 | |
5045 if (!NILP (package.catchtag) && | |
5046 !EQ (package.catchtag, Vcatch_everything_tag)) | |
5047 free_opaque_ptr (package.catchtag); | |
5048 | |
5049 if (!NILP (opaque)) | |
5050 free_opaque_ptr (opaque); | |
5051 | |
5052 unbind_to (speccount); | |
5053 RETURN_UNGCPRO (thrown ? Qunbound : tem); | |
5054 } | |
5055 | |
5056 struct va_call_trapping_problems | |
5057 { | |
5058 lisp_fn_t fun; | |
5059 int nargs; | |
5060 Lisp_Object *args; | |
5061 }; | |
5062 | |
5063 static Lisp_Object | |
5064 va_call_trapping_problems_1 (void *ai_mi_madre) | |
5065 { | |
5066 struct va_call_trapping_problems *ai_no_corrida = | |
5067 (struct va_call_trapping_problems *) ai_mi_madre; | |
5068 Lisp_Object pegar_no_bumbum; | |
5069 | |
5070 PRIMITIVE_FUNCALL (pegar_no_bumbum, ai_no_corrida->fun, | |
5071 ai_no_corrida->args, ai_no_corrida->nargs); | |
5072 return pegar_no_bumbum; | |
5073 } | |
5074 | |
5075 /* #### document me. */ | |
5076 | |
5077 Lisp_Object | |
5078 va_call_trapping_problems (Lisp_Object warning_class, | |
5079 const CIntbyte *warning_string, | |
5080 int flags, | |
5081 struct call_trapping_problems_result *problem, | |
5082 lisp_fn_t fun, int nargs, ...) | |
5083 { | |
5084 va_list vargs; | |
5085 Lisp_Object args[20]; | |
5086 int i; | |
5087 struct va_call_trapping_problems fazer_invocacao_atrapalhando_problemas; | |
4550 struct gcpro gcpro1; | 5088 struct gcpro gcpro1; |
5089 | |
5090 assert (nargs >= 0 && nargs < 20); | |
5091 | |
5092 va_start (vargs, nargs); | |
5093 for (i = 0; i < nargs; i++) | |
5094 args[i] = va_arg (vargs, Lisp_Object); | |
5095 va_end (vargs); | |
5096 | |
5097 fazer_invocacao_atrapalhando_problemas.fun = fun; | |
5098 fazer_invocacao_atrapalhando_problemas.nargs = nargs; | |
5099 fazer_invocacao_atrapalhando_problemas.args = args; | |
5100 | |
5101 GCPRO1_ARRAY (args, nargs); | |
5102 RETURN_UNGCPRO | |
5103 (call_trapping_problems | |
5104 (warning_class, warning_string, flags, problem, | |
5105 va_call_trapping_problems_1, &fazer_invocacao_atrapalhando_problemas)); | |
5106 } | |
5107 | |
5108 /* this is an older interface, barely different from | |
5109 va_call_trapping_problems. | |
5110 | |
5111 #### eliminate this or at least merge the ERROR_BEHAVIOR stuff into | |
5112 va_call_trapping_problems(). */ | |
5113 | |
5114 Lisp_Object | |
5115 call_with_suspended_errors (lisp_fn_t fun, Lisp_Object retval, | |
5116 Lisp_Object class, Error_Behavior errb, | |
5117 int nargs, ...) | |
5118 { | |
5119 va_list vargs; | |
5120 Lisp_Object args[20]; | |
5121 int i; | |
5122 struct va_call_trapping_problems fazer_invocacao_atrapalhando_problemas; | |
5123 int flags; | |
5124 struct gcpro gcpro1; | |
5125 | |
5126 assert (SYMBOLP (class)); /* sanity-check */ | |
5127 assert (!NILP (class)); | |
5128 assert (nargs >= 0 && nargs < 20); | |
5129 | |
5130 va_start (vargs, nargs); | |
5131 for (i = 0; i < nargs; i++) | |
5132 args[i] = va_arg (vargs, Lisp_Object); | |
5133 va_end (vargs); | |
5134 | |
5135 /* If error-checking is not disabled, just call the function. */ | |
5136 | |
5137 if (ERRB_EQ (errb, ERROR_ME)) | |
5138 { | |
5139 Lisp_Object val; | |
5140 PRIMITIVE_FUNCALL (val, fun, args, nargs); | |
5141 return val; | |
5142 } | |
5143 | |
5144 if (ERRB_EQ (errb, ERROR_ME_NOT)) /* person wants no warnings */ | |
5145 flags = INHIBIT_WARNING_ISSUE | INHIBIT_ENTERING_DEBUGGER; | |
5146 else if (ERRB_EQ (errb, ERROR_ME_DEBUG_WARN)) | |
5147 flags = ISSUE_WARNINGS_AT_DEBUG_LEVEL | INHIBIT_ENTERING_DEBUGGER; | |
5148 else | |
5149 { | |
5150 assert (ERRB_EQ (errb, ERROR_ME_WARN)); | |
5151 flags = INHIBIT_ENTERING_DEBUGGER; | |
5152 } | |
5153 | |
5154 flags |= CALL_WITH_SUSPENDED_ERRORS; | |
5155 | |
5156 fazer_invocacao_atrapalhando_problemas.fun = fun; | |
5157 fazer_invocacao_atrapalhando_problemas.nargs = nargs; | |
5158 fazer_invocacao_atrapalhando_problemas.args = args; | |
5159 | |
5160 GCPRO1_ARRAY (args, nargs); | |
5161 { | |
5162 Lisp_Object its_way_too_goddamn_late = | |
5163 call_trapping_problems | |
5164 (class, 0, flags, 0, va_call_trapping_problems_1, | |
5165 &fazer_invocacao_atrapalhando_problemas); | |
5166 UNGCPRO; | |
5167 if (UNBOUNDP (its_way_too_goddamn_late)) | |
5168 return retval; | |
5169 else | |
5170 return its_way_too_goddamn_late; | |
5171 } | |
5172 } | |
5173 | |
5174 struct calln_trapping_problems | |
5175 { | |
5176 int nargs; | |
5177 Lisp_Object *args; | |
5178 }; | |
5179 | |
5180 static Lisp_Object | |
5181 calln_trapping_problems_1 (void *puta) | |
5182 { | |
5183 struct calln_trapping_problems *p = (struct calln_trapping_problems *) puta; | |
5184 | |
5185 return Ffuncall (p->nargs, p->args); | |
5186 } | |
5187 | |
5188 static Lisp_Object | |
5189 calln_trapping_problems (Lisp_Object warning_class, | |
5190 const CIntbyte *warning_string, int flags, | |
5191 struct call_trapping_problems_result *problem, | |
5192 int nargs, Lisp_Object *args) | |
5193 { | |
5194 struct calln_trapping_problems foo; | |
5195 struct gcpro gcpro1; | |
5196 | |
5197 if (SYMBOLP (args[0])) | |
5198 { | |
5199 Lisp_Object tem = XSYMBOL (args[0])->function; | |
5200 if (NILP (tem) || UNBOUNDP (tem)) | |
5201 { | |
5202 if (problem) | |
5203 { | |
5204 problem->caught_error = 0; | |
5205 problem->caught_throw = 0; | |
5206 problem->error_conditions = Qnil; | |
5207 problem->data = Qnil; | |
5208 problem->backtrace = Qnil; | |
5209 problem->thrown_tag = Qnil; | |
5210 problem->thrown_value = Qnil; | |
5211 } | |
5212 return Qnil; | |
5213 } | |
5214 } | |
5215 | |
5216 foo.nargs = nargs; | |
5217 foo.args = args; | |
5218 | |
5219 GCPRO1_ARRAY (args, nargs); | |
5220 RETURN_UNGCPRO (call_trapping_problems (warning_class, warning_string, | |
5221 flags, problem, | |
5222 calln_trapping_problems_1, | |
5223 &foo)); | |
5224 } | |
5225 | |
5226 /* #### fix these functions to follow the calling convention of | |
5227 call_trapping_problems! */ | |
5228 | |
5229 Lisp_Object | |
5230 call0_trapping_problems (const CIntbyte *warning_string, Lisp_Object function, | |
5231 int flags) | |
5232 { | |
5233 return calln_trapping_problems (Qerror, warning_string, flags, 0, 1, | |
5234 &function); | |
5235 } | |
5236 | |
5237 Lisp_Object | |
5238 call1_trapping_problems (const CIntbyte *warning_string, Lisp_Object function, | |
5239 Lisp_Object object, int flags) | |
5240 { | |
4551 Lisp_Object args[2]; | 5241 Lisp_Object args[2]; |
4552 args[0] = handler; | 5242 |
4553 args[1] = fn; | 5243 args[0] = function; |
4554 GCPRO1 (args[0]); | 5244 args[1] = object; |
4555 gcpro1.nvars = 2; | 5245 |
4556 RETURN_UNGCPRO (Fcall_with_condition_handler (2, args)); | 5246 return calln_trapping_problems (Qerror, warning_string, flags, 0, 2, |
4557 } | 5247 args); |
4558 | 5248 } |
4559 /* Call function fn with argument arg0, with condition handler */ | 5249 |
4560 Lisp_Object | 5250 Lisp_Object |
4561 call1_with_handler (Lisp_Object handler, Lisp_Object fn, | 5251 call2_trapping_problems (const CIntbyte *warning_string, Lisp_Object function, |
4562 Lisp_Object arg0) | 5252 Lisp_Object object1, Lisp_Object object2, |
4563 { | 5253 int flags) |
4564 /* This function can GC */ | 5254 { |
4565 struct gcpro gcpro1; | |
4566 Lisp_Object args[3]; | 5255 Lisp_Object args[3]; |
4567 args[0] = handler; | 5256 |
4568 args[1] = fn; | 5257 args[0] = function; |
4569 args[2] = arg0; | 5258 args[1] = object1; |
4570 GCPRO1 (args[0]); | 5259 args[2] = object2; |
4571 gcpro1.nvars = 3; | 5260 |
4572 RETURN_UNGCPRO (Fcall_with_condition_handler (3, args)); | 5261 return calln_trapping_problems (Qerror, warning_string, flags, 0, 3, |
4573 } | 5262 args); |
4574 | 5263 } |
4575 | 5264 |
4576 /* The following functions provide you with error-trapping versions | 5265 Lisp_Object |
4577 of the various front-ends above. They take an additional | 5266 call3_trapping_problems (const CIntbyte *warning_string, Lisp_Object function, |
4578 "warning_string" argument; if non-zero, a warning with this | 5267 Lisp_Object object1, Lisp_Object object2, |
4579 string and the actual error that occurred will be displayed | 5268 Lisp_Object object3, int flags) |
4580 in the *Warnings* buffer if an error occurs. In all cases, | 5269 { |
4581 QUIT is inhibited while these functions are running, and if | 5270 Lisp_Object args[4]; |
4582 an error occurs, Qunbound is returned instead of the normal | 5271 |
4583 return value. | 5272 args[0] = function; |
4584 */ | 5273 args[1] = object1; |
4585 | 5274 args[2] = object2; |
4586 /* #### This stuff needs to catch throws as well. We need to | 5275 args[3] = object3; |
4587 improve internal_catch() so it can take a "catch anything" | 5276 |
4588 argument similar to Qt or Qerror for condition_case_1(). */ | 5277 return calln_trapping_problems (Qerror, warning_string, flags, 0, 4, |
5278 args); | |
5279 } | |
5280 | |
5281 Lisp_Object | |
5282 call4_trapping_problems (const CIntbyte *warning_string, Lisp_Object function, | |
5283 Lisp_Object object1, Lisp_Object object2, | |
5284 Lisp_Object object3, Lisp_Object object4, | |
5285 int flags) | |
5286 { | |
5287 Lisp_Object args[5]; | |
5288 | |
5289 args[0] = function; | |
5290 args[1] = object1; | |
5291 args[2] = object2; | |
5292 args[3] = object3; | |
5293 args[4] = object4; | |
5294 | |
5295 return calln_trapping_problems (Qerror, warning_string, flags, 0, 5, | |
5296 args); | |
5297 } | |
5298 | |
5299 Lisp_Object | |
5300 call5_trapping_problems (const CIntbyte *warning_string, Lisp_Object function, | |
5301 Lisp_Object object1, Lisp_Object object2, | |
5302 Lisp_Object object3, Lisp_Object object4, | |
5303 Lisp_Object object5, int flags) | |
5304 { | |
5305 Lisp_Object args[6]; | |
5306 | |
5307 args[0] = function; | |
5308 args[1] = object1; | |
5309 args[2] = object2; | |
5310 args[3] = object3; | |
5311 args[4] = object4; | |
5312 args[5] = object5; | |
5313 | |
5314 return calln_trapping_problems (Qerror, warning_string, flags, 0, 6, | |
5315 args); | |
5316 } | |
5317 | |
5318 struct eval_in_buffer_trapping_problems | |
5319 { | |
5320 struct buffer *buf; | |
5321 Lisp_Object form; | |
5322 }; | |
4589 | 5323 |
4590 static Lisp_Object | 5324 static Lisp_Object |
4591 caught_a_squirmer (Lisp_Object errordata, Lisp_Object arg) | 5325 eval_in_buffer_trapping_problems_1 (void *arg) |
4592 { | 5326 { |
4593 /* #### should be rewritten to work with emacs_sprintf_string_lisp(); but this | 5327 struct eval_in_buffer_trapping_problems *p = |
4594 whole stuff is getting junked and replaced from my stderr-proc ws */ | 5328 (struct eval_in_buffer_trapping_problems *) arg; |
4595 if (!NILP (errordata)) | 5329 |
4596 { | 5330 return eval_in_buffer (p->buf, p->form); |
4597 Lisp_Object args[2]; | 5331 } |
4598 | 5332 |
4599 if (!NILP (arg)) | 5333 /* #### fix these functions to follow the calling convention of |
4600 { | 5334 call_trapping_problems! */ |
4601 Intbyte *str = (Intbyte *) get_opaque_ptr (arg); | 5335 |
4602 args[0] = build_intstring (str); | 5336 Lisp_Object |
4603 } | 5337 eval_in_buffer_trapping_problems (const CIntbyte *warning_string, |
4604 else | 5338 struct buffer *buf, Lisp_Object form, |
4605 args[0] = build_msg_string ("error"); | 5339 int flags) |
4606 /* #### This should call | 5340 { |
4607 (with-output-to-string (display-error errordata)) | 5341 struct eval_in_buffer_trapping_problems p; |
4608 but that stuff is all in Lisp currently. */ | 5342 Lisp_Object buffer = wrap_buffer (buf); |
4609 args[1] = errordata; | 5343 struct gcpro gcpro1, gcpro2; |
4610 warn_when_safe_lispobj | 5344 |
4611 (Qerror, Qwarning, | 5345 GCPRO2 (buffer, form); |
4612 emacs_vsprintf_string_lisp ("%s: %s", Qnil, 2, args)); | 5346 p.buf = buf; |
4613 } | 5347 p.form = form; |
4614 return Qunbound; | 5348 RETURN_UNGCPRO (call_trapping_problems (Qerror, warning_string, flags, 0, |
5349 eval_in_buffer_trapping_problems_1, | |
5350 &p)); | |
5351 } | |
5352 | |
5353 Lisp_Object | |
5354 run_hook_trapping_problems (const CIntbyte *warning_string, | |
5355 Lisp_Object hook_symbol, | |
5356 int flags) | |
5357 { | |
5358 return run_hook_with_args_trapping_problems (warning_string, 1, &hook_symbol, | |
5359 RUN_HOOKS_TO_COMPLETION, | |
5360 flags); | |
4615 } | 5361 } |
4616 | 5362 |
4617 static Lisp_Object | 5363 static Lisp_Object |
4618 allow_quit_caught_a_squirmer (Lisp_Object errordata, Lisp_Object arg) | 5364 safe_run_hook_trapping_problems_1 (void *puta) |
4619 { | 5365 { |
4620 if (CONSP (errordata) && EQ (XCAR (errordata), Qquit)) | 5366 Lisp_Object hook = VOID_TO_LISP (puta); |
4621 return Fsignal (Qquit, XCDR (errordata)); | 5367 |
4622 return caught_a_squirmer (errordata, arg); | 5368 run_hook (hook); |
4623 } | 5369 return Qnil; |
4624 | 5370 } |
4625 static Lisp_Object | 5371 |
4626 safe_run_hook_caught_a_squirmer (Lisp_Object errordata, Lisp_Object arg) | 5372 /* Same as run_hook_trapping_problems() but also set the hook to nil |
4627 { | 5373 if an error occurs (but not a quit). */ |
4628 Lisp_Object hook = Fcar (arg); | |
4629 arg = Fcdr (arg); | |
4630 /* Clear out the hook. */ | |
4631 Fset (hook, Qnil); | |
4632 return caught_a_squirmer (errordata, arg); | |
4633 } | |
4634 | |
4635 static Lisp_Object | |
4636 allow_quit_safe_run_hook_caught_a_squirmer (Lisp_Object errordata, | |
4637 Lisp_Object arg) | |
4638 { | |
4639 Lisp_Object hook = Fcar (arg); | |
4640 arg = Fcdr (arg); | |
4641 if (!CONSP (errordata) || !EQ (XCAR (errordata), Qquit)) | |
4642 /* Clear out the hook. */ | |
4643 Fset (hook, Qnil); | |
4644 return allow_quit_caught_a_squirmer (errordata, arg); | |
4645 } | |
4646 | |
4647 static Lisp_Object | |
4648 catch_them_squirmers_eval_in_buffer (Lisp_Object cons) | |
4649 { | |
4650 return eval_in_buffer (XBUFFER (XCAR (cons)), XCDR (cons)); | |
4651 } | |
4652 | 5374 |
4653 Lisp_Object | 5375 Lisp_Object |
4654 eval_in_buffer_trapping_errors (const CIntbyte *warning_string, | 5376 safe_run_hook_trapping_problems (const CIntbyte *warning_string, |
4655 struct buffer *buf, Lisp_Object form) | 5377 Lisp_Object hook_symbol, |
4656 { | 5378 int flags) |
4657 int speccount = specpdl_depth(); | 5379 { |
4658 Lisp_Object tem; | 5380 Lisp_Object tem; |
4659 Lisp_Object buffer; | |
4660 Lisp_Object cons; | |
4661 Lisp_Object opaque; | |
4662 struct gcpro gcpro1, gcpro2; | 5381 struct gcpro gcpro1, gcpro2; |
4663 | 5382 struct call_trapping_problems_result prob; |
4664 buffer = wrap_buffer (buf); | |
4665 | |
4666 specbind (Qinhibit_quit, Qt); | |
4667 /* begin_gc_forbidden(); Currently no reason to do this; */ | |
4668 | |
4669 cons = noseeum_cons (buffer, form); | |
4670 opaque = (warning_string ? make_opaque_ptr ((void *)warning_string) : Qnil); | |
4671 GCPRO2 (cons, opaque); | |
4672 /* Qerror not Qt, so you can get a backtrace */ | |
4673 tem = condition_case_1 (Qerror, | |
4674 catch_them_squirmers_eval_in_buffer, cons, | |
4675 caught_a_squirmer, opaque); | |
4676 free_cons (XCONS (cons)); | |
4677 if (OPAQUE_PTRP (opaque)) | |
4678 free_opaque_ptr (opaque); | |
4679 UNGCPRO; | |
4680 | |
4681 return unbind_to_1 (speccount, tem); | |
4682 } | |
4683 | |
4684 static Lisp_Object | |
4685 catch_them_squirmers_run_hook (Lisp_Object hook_symbol) | |
4686 { | |
4687 /* This function can GC */ | |
4688 run_hook (hook_symbol); | |
4689 return Qnil; | |
4690 } | |
4691 | |
4692 Lisp_Object | |
4693 run_hook_trapping_errors (const CIntbyte *warning_string, | |
4694 Lisp_Object hook_symbol) | |
4695 { | |
4696 int speccount; | |
4697 Lisp_Object tem; | |
4698 Lisp_Object opaque; | |
4699 struct gcpro gcpro1; | |
4700 | 5383 |
4701 if (!initialized || preparing_for_armageddon) | 5384 if (!initialized || preparing_for_armageddon) |
4702 return Qnil; | 5385 return Qnil; |
4703 tem = find_symbol_value (hook_symbol); | 5386 tem = find_symbol_value (hook_symbol); |
4704 if (NILP (tem) || UNBOUNDP (tem)) | 5387 if (NILP (tem) || UNBOUNDP (tem)) |
4705 return Qnil; | 5388 return Qnil; |
4706 | 5389 |
4707 speccount = specpdl_depth(); | 5390 GCPRO2 (hook_symbol, tem); |
4708 specbind (Qinhibit_quit, Qt); | 5391 tem = call_trapping_problems (Qerror, warning_string, flags, |
4709 | 5392 &prob, |
4710 opaque = (warning_string ? make_opaque_ptr ((void *)warning_string) : Qnil); | 5393 safe_run_hook_trapping_problems_1, |
4711 GCPRO1 (opaque); | 5394 LISP_TO_VOID (hook_symbol)); |
4712 /* Qerror not Qt, so you can get a backtrace */ | 5395 if (prob.caught_throw || (prob.caught_error && !EQ (prob.error_conditions, |
4713 tem = condition_case_1 (Qerror, | 5396 Qquit))) |
4714 catch_them_squirmers_run_hook, hook_symbol, | 5397 Fset (hook_symbol, Qnil); |
4715 caught_a_squirmer, opaque); | 5398 RETURN_UNGCPRO (tem); |
4716 if (OPAQUE_PTRP (opaque)) | 5399 } |
4717 free_opaque_ptr (opaque); | 5400 |
4718 UNGCPRO; | 5401 struct run_hook_with_args_in_buffer_trapping_problems |
4719 | 5402 { |
4720 return unbind_to_1 (speccount, tem); | 5403 struct buffer *buf; |
4721 } | 5404 int nargs; |
4722 | 5405 Lisp_Object *args; |
4723 /* Same as run_hook_trapping_errors() but also set the hook to nil | 5406 enum run_hooks_condition cond; |
4724 if an error occurs. */ | 5407 }; |
5408 | |
5409 static Lisp_Object | |
5410 run_hook_with_args_in_buffer_trapping_problems_1 (void *puta) | |
5411 { | |
5412 struct run_hook_with_args_in_buffer_trapping_problems *porra = | |
5413 (struct run_hook_with_args_in_buffer_trapping_problems *) puta; | |
5414 | |
5415 return run_hook_with_args_in_buffer (porra->buf, porra->nargs, porra->args, | |
5416 porra->cond); | |
5417 } | |
5418 | |
5419 /* #### fix these functions to follow the calling convention of | |
5420 call_trapping_problems! */ | |
4725 | 5421 |
4726 Lisp_Object | 5422 Lisp_Object |
4727 safe_run_hook_trapping_errors (const CIntbyte *warning_string, | 5423 run_hook_with_args_in_buffer_trapping_problems (const CIntbyte *warning_string, |
4728 Lisp_Object hook_symbol, | 5424 struct buffer *buf, int nargs, |
4729 int allow_quit) | 5425 Lisp_Object *args, |
4730 { | 5426 enum run_hooks_condition cond, |
4731 int speccount = specpdl_depth(); | 5427 int flags) |
4732 Lisp_Object tem; | 5428 { |
4733 Lisp_Object cons = Qnil; | 5429 Lisp_Object sym, val, ret; |
5430 struct run_hook_with_args_in_buffer_trapping_problems diversity_and_distrust; | |
4734 struct gcpro gcpro1; | 5431 struct gcpro gcpro1; |
4735 | 5432 |
4736 if (!initialized || preparing_for_armageddon) | 5433 if (!initialized || preparing_for_armageddon) |
5434 /* We need to bail out of here pronto. */ | |
4737 return Qnil; | 5435 return Qnil; |
4738 tem = find_symbol_value (hook_symbol); | 5436 |
4739 if (NILP (tem) || UNBOUNDP (tem)) | 5437 GCPRO1_ARRAY (args, nargs); |
4740 return Qnil; | 5438 |
4741 | 5439 sym = args[0]; |
4742 if (!allow_quit) | 5440 val = symbol_value_in_buffer (sym, wrap_buffer (buf)); |
4743 specbind (Qinhibit_quit, Qt); | 5441 ret = (cond == RUN_HOOKS_UNTIL_FAILURE ? Qt : Qnil); |
4744 | 5442 |
4745 cons = noseeum_cons (hook_symbol, | 5443 if (UNBOUNDP (val) || NILP (val)) |
4746 warning_string ? make_opaque_ptr ((void *)warning_string) | 5444 RETURN_UNGCPRO (ret); |
4747 : Qnil); | 5445 |
4748 GCPRO1 (cons); | 5446 diversity_and_distrust.buf = buf; |
4749 /* Qerror not Qt, so you can get a backtrace */ | 5447 diversity_and_distrust.nargs = nargs; |
4750 tem = condition_case_1 (Qerror, | 5448 diversity_and_distrust.args = args; |
4751 catch_them_squirmers_run_hook, | 5449 diversity_and_distrust.cond = cond; |
4752 hook_symbol, | 5450 |
4753 allow_quit ? | 5451 RETURN_UNGCPRO |
4754 allow_quit_safe_run_hook_caught_a_squirmer : | 5452 (call_trapping_problems |
4755 safe_run_hook_caught_a_squirmer, | 5453 (Qerror, warning_string, |
4756 cons); | 5454 flags, 0, |
4757 if (OPAQUE_PTRP (XCDR (cons))) | 5455 run_hook_with_args_in_buffer_trapping_problems_1, |
4758 free_opaque_ptr (XCDR (cons)); | 5456 &diversity_and_distrust)); |
4759 free_cons (XCONS (cons)); | 5457 } |
4760 UNGCPRO; | 5458 |
4761 | 5459 Lisp_Object |
4762 return unbind_to_1 (speccount, tem); | 5460 run_hook_with_args_trapping_problems (const CIntbyte *warning_string, |
4763 } | 5461 int nargs, |
4764 | 5462 Lisp_Object *args, |
4765 static Lisp_Object | 5463 enum run_hooks_condition cond, |
4766 catch_them_squirmers_call0 (Lisp_Object function) | 5464 int flags) |
5465 { | |
5466 return run_hook_with_args_in_buffer_trapping_problems | |
5467 (warning_string, current_buffer, nargs, args, cond, flags); | |
5468 } | |
5469 | |
5470 Lisp_Object | |
5471 va_run_hook_with_args_trapping_problems (const CIntbyte *warning_string, | |
5472 Lisp_Object hook_var, | |
5473 int nargs, ...) | |
4767 { | 5474 { |
4768 /* This function can GC */ | 5475 /* This function can GC */ |
4769 return call0 (function); | 5476 struct gcpro gcpro1; |
5477 int i; | |
5478 va_list vargs; | |
5479 Lisp_Object *funcall_args = alloca_array (Lisp_Object, 1 + nargs); | |
5480 int flags; | |
5481 | |
5482 va_start (vargs, nargs); | |
5483 funcall_args[0] = hook_var; | |
5484 for (i = 0; i < nargs; i++) | |
5485 funcall_args[i + 1] = va_arg (vargs, Lisp_Object); | |
5486 flags = va_arg (vargs, int); | |
5487 va_end (vargs); | |
5488 | |
5489 GCPRO1_ARRAY (funcall_args, nargs + 1); | |
5490 RETURN_UNGCPRO (run_hook_with_args_in_buffer_trapping_problems | |
5491 (warning_string, current_buffer, nargs + 1, funcall_args, | |
5492 RUN_HOOKS_TO_COMPLETION, flags)); | |
4770 } | 5493 } |
4771 | 5494 |
4772 Lisp_Object | 5495 Lisp_Object |
4773 call0_trapping_errors (const CIntbyte *warning_string, Lisp_Object function) | 5496 va_run_hook_with_args_in_buffer_trapping_problems (const CIntbyte * |
4774 { | 5497 warning_string, |
4775 int speccount; | 5498 struct buffer *buf, |
4776 Lisp_Object tem; | 5499 Lisp_Object hook_var, |
4777 Lisp_Object opaque = Qnil; | 5500 int nargs, ...) |
4778 struct gcpro gcpro1, gcpro2; | |
4779 | |
4780 if (SYMBOLP (function)) | |
4781 { | |
4782 tem = XSYMBOL (function)->function; | |
4783 if (NILP (tem) || UNBOUNDP (tem)) | |
4784 return Qnil; | |
4785 } | |
4786 | |
4787 GCPRO2 (opaque, function); | |
4788 speccount = specpdl_depth(); | |
4789 specbind (Qinhibit_quit, Qt); | |
4790 /* begin_gc_forbidden(); Currently no reason to do this; */ | |
4791 | |
4792 opaque = (warning_string ? make_opaque_ptr ((void *)warning_string) : Qnil); | |
4793 /* Qerror not Qt, so you can get a backtrace */ | |
4794 tem = condition_case_1 (Qerror, | |
4795 catch_them_squirmers_call0, function, | |
4796 caught_a_squirmer, opaque); | |
4797 if (OPAQUE_PTRP (opaque)) | |
4798 free_opaque_ptr (opaque); | |
4799 UNGCPRO; | |
4800 | |
4801 return unbind_to_1 (speccount, tem); | |
4802 } | |
4803 | |
4804 static Lisp_Object | |
4805 catch_them_squirmers_call1 (Lisp_Object cons) | |
4806 { | 5501 { |
4807 /* This function can GC */ | 5502 /* This function can GC */ |
4808 return call1 (XCAR (cons), XCDR (cons)); | 5503 struct gcpro gcpro1; |
4809 } | 5504 int i; |
4810 | 5505 va_list vargs; |
4811 static Lisp_Object | 5506 Lisp_Object *funcall_args = alloca_array (Lisp_Object, 1 + nargs); |
4812 catch_them_squirmers_call2 (Lisp_Object cons) | 5507 int flags; |
4813 { | 5508 |
4814 /* This function can GC */ | 5509 va_start (vargs, nargs); |
4815 return call2 (XCAR (cons), XCAR (XCDR (cons)), XCAR (XCDR (XCDR (cons)))); | 5510 funcall_args[0] = hook_var; |
4816 } | 5511 for (i = 0; i < nargs; i++) |
4817 | 5512 funcall_args[i + 1] = va_arg (vargs, Lisp_Object); |
4818 Lisp_Object | 5513 flags = va_arg (vargs, int); |
4819 call1_trapping_errors (const CIntbyte *warning_string, Lisp_Object function, | 5514 va_end (vargs); |
4820 Lisp_Object object) | 5515 |
4821 { | 5516 GCPRO1_ARRAY (funcall_args, nargs + 1); |
4822 int speccount = specpdl_depth(); | 5517 RETURN_UNGCPRO (run_hook_with_args_in_buffer_trapping_problems |
4823 Lisp_Object tem; | 5518 (warning_string, buf, nargs + 1, funcall_args, |
4824 Lisp_Object cons = Qnil; | 5519 RUN_HOOKS_TO_COMPLETION, flags)); |
4825 Lisp_Object opaque = Qnil; | |
4826 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4; | |
4827 | |
4828 if (SYMBOLP (function)) | |
4829 { | |
4830 tem = XSYMBOL (function)->function; | |
4831 if (NILP (tem) || UNBOUNDP (tem)) | |
4832 return Qnil; | |
4833 } | |
4834 | |
4835 GCPRO4 (cons, opaque, function, object); | |
4836 | |
4837 specbind (Qinhibit_quit, Qt); | |
4838 /* begin_gc_forbidden(); Currently no reason to do this; */ | |
4839 | |
4840 cons = noseeum_cons (function, object); | |
4841 opaque = (warning_string ? make_opaque_ptr ((void *)warning_string) : Qnil); | |
4842 /* Qerror not Qt, so you can get a backtrace */ | |
4843 tem = condition_case_1 (Qerror, | |
4844 catch_them_squirmers_call1, cons, | |
4845 caught_a_squirmer, opaque); | |
4846 if (OPAQUE_PTRP (opaque)) | |
4847 free_opaque_ptr (opaque); | |
4848 free_cons (XCONS (cons)); | |
4849 UNGCPRO; | |
4850 | |
4851 return unbind_to_1 (speccount, tem); | |
4852 } | |
4853 | |
4854 Lisp_Object | |
4855 call2_trapping_errors (const CIntbyte *warning_string, Lisp_Object function, | |
4856 Lisp_Object object1, Lisp_Object object2) | |
4857 { | |
4858 int speccount = specpdl_depth(); | |
4859 Lisp_Object tem; | |
4860 Lisp_Object cons = Qnil; | |
4861 Lisp_Object opaque = Qnil; | |
4862 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5; | |
4863 | |
4864 if (SYMBOLP (function)) | |
4865 { | |
4866 tem = XSYMBOL (function)->function; | |
4867 if (NILP (tem) || UNBOUNDP (tem)) | |
4868 return Qnil; | |
4869 } | |
4870 | |
4871 GCPRO5 (cons, opaque, function, object1, object2); | |
4872 specbind (Qinhibit_quit, Qt); | |
4873 /* begin_gc_forbidden(); Currently no reason to do this; */ | |
4874 | |
4875 cons = list3 (function, object1, object2); | |
4876 opaque = (warning_string ? make_opaque_ptr ((void *)warning_string) : Qnil); | |
4877 /* Qerror not Qt, so you can get a backtrace */ | |
4878 tem = condition_case_1 (Qerror, | |
4879 catch_them_squirmers_call2, cons, | |
4880 caught_a_squirmer, opaque); | |
4881 if (OPAQUE_PTRP (opaque)) | |
4882 free_opaque_ptr (opaque); | |
4883 free_list (cons); | |
4884 UNGCPRO; | |
4885 | |
4886 return unbind_to_1 (speccount, tem); | |
4887 } | 5520 } |
4888 | 5521 |
4889 | 5522 |
4890 /************************************************************************/ | 5523 /************************************************************************/ |
4891 /* The special binding stack */ | 5524 /* The special binding stack */ |
4920 if (specpdl_size > max_specpdl_size) | 5553 if (specpdl_size > max_specpdl_size) |
4921 specpdl_size = max_specpdl_size; | 5554 specpdl_size = max_specpdl_size; |
4922 } | 5555 } |
4923 XREALLOC_ARRAY (specpdl, struct specbinding, specpdl_size); | 5556 XREALLOC_ARRAY (specpdl, struct specbinding, specpdl_size); |
4924 specpdl_ptr = specpdl + specpdl_depth(); | 5557 specpdl_ptr = specpdl + specpdl_depth(); |
5558 check_specbind_stack_sanity (); | |
4925 } | 5559 } |
4926 | 5560 |
4927 | 5561 |
4928 /* Handle unbinding buffer-local variables */ | 5562 /* Handle unbinding buffer-local variables */ |
4929 static Lisp_Object | 5563 static Lisp_Object |
4930 specbind_unwind_local (Lisp_Object ovalue) | 5564 specbind_unwind_local (Lisp_Object ovalue) |
4931 { | 5565 { |
4932 Lisp_Object current = Fcurrent_buffer (); | 5566 Lisp_Object current = Fcurrent_buffer (); |
4933 Lisp_Object symbol = specpdl_ptr->symbol; | 5567 Lisp_Object symbol = specpdl_ptr->symbol; |
4934 Lisp_Cons *victim = XCONS (ovalue); | 5568 Lisp_Object victim = ovalue; |
4935 Lisp_Object buf = get_buffer (victim->car, 0); | 5569 Lisp_Object buf = get_buffer (XCAR (victim), 0); |
4936 ovalue = victim->cdr; | 5570 ovalue = XCDR (victim); |
4937 | 5571 |
4938 free_cons (victim); | 5572 free_cons (victim); |
4939 | 5573 |
4940 if (NILP (buf)) | 5574 if (NILP (buf)) |
4941 { | 5575 { |
4999 | 5633 |
5000 void | 5634 void |
5001 specbind (Lisp_Object symbol, Lisp_Object value) | 5635 specbind (Lisp_Object symbol, Lisp_Object value) |
5002 { | 5636 { |
5003 SPECBIND (symbol, value); | 5637 SPECBIND (symbol, value); |
5638 | |
5639 check_specbind_stack_sanity (); | |
5004 } | 5640 } |
5005 | 5641 |
5006 void | 5642 void |
5007 specbind_magic (Lisp_Object symbol, Lisp_Object value) | 5643 specbind_magic (Lisp_Object symbol, Lisp_Object value) |
5008 { | 5644 { |
5031 specpdl_ptr->symbol = symbol; | 5667 specpdl_ptr->symbol = symbol; |
5032 specpdl_ptr++; | 5668 specpdl_ptr++; |
5033 specpdl_depth_counter++; | 5669 specpdl_depth_counter++; |
5034 | 5670 |
5035 Fset (symbol, value); | 5671 Fset (symbol, value); |
5672 | |
5673 check_specbind_stack_sanity (); | |
5036 } | 5674 } |
5037 | 5675 |
5038 /* Record an unwind-protect -- FUNCTION will be called with ARG no matter | 5676 /* Record an unwind-protect -- FUNCTION will be called with ARG no matter |
5039 whether a normal or non-local exit occurs. (You need to call unbind_to_1() | 5677 whether a normal or non-local exit occurs. (You need to call unbind_to_1() |
5040 before your function returns normally, passing in the integer returned | 5678 before your function returns normally, passing in the integer returned |
5050 specpdl_ptr->func = function; | 5688 specpdl_ptr->func = function; |
5051 specpdl_ptr->symbol = Qnil; | 5689 specpdl_ptr->symbol = Qnil; |
5052 specpdl_ptr->old_value = arg; | 5690 specpdl_ptr->old_value = arg; |
5053 specpdl_ptr++; | 5691 specpdl_ptr++; |
5054 specpdl_depth_counter++; | 5692 specpdl_depth_counter++; |
5693 check_specbind_stack_sanity (); | |
5055 return specpdl_depth_counter - 1; | 5694 return specpdl_depth_counter - 1; |
5056 } | 5695 } |
5057 | 5696 |
5058 static Lisp_Object | 5697 static Lisp_Object |
5059 restore_lisp_object (Lisp_Object cons) | 5698 restore_lisp_object (Lisp_Object cons) |
5060 { | 5699 { |
5061 Lisp_Object opaque = XCAR (cons); | 5700 Lisp_Object opaque = XCAR (cons); |
5062 Lisp_Object *addr = (Lisp_Object *) get_opaque_ptr (opaque); | 5701 Lisp_Object *addr = (Lisp_Object *) get_opaque_ptr (opaque); |
5063 *addr = XCDR (cons); | 5702 *addr = XCDR (cons); |
5064 free_opaque_ptr (opaque); | 5703 free_opaque_ptr (opaque); |
5065 free_cons (XCONS (cons)); | 5704 free_cons (cons); |
5066 return Qnil; | 5705 return Qnil; |
5067 } | 5706 } |
5068 | 5707 |
5069 /* Establish an unwind-protect which will restore the Lisp_Object pointed to | 5708 /* Establish an unwind-protect which will restore the Lisp_Object pointed to |
5070 by ADDR with the value VAL. */ | 5709 by ADDR with the value VAL. */ |
5107 free_opaque_ptr (lval); | 5746 free_opaque_ptr (lval); |
5108 } | 5747 } |
5109 | 5748 |
5110 *addr = val; | 5749 *addr = val; |
5111 free_opaque_ptr (opaque); | 5750 free_opaque_ptr (opaque); |
5112 free_cons (XCONS (cons)); | 5751 free_cons (cons); |
5113 return Qnil; | 5752 return Qnil; |
5114 } | 5753 } |
5115 | 5754 |
5116 /* Establish an unwind-protect which will restore the int pointed to | 5755 /* Establish an unwind-protect which will restore the int pointed to |
5117 by ADDR with the value VAL. This function works correctly with | 5756 by ADDR with the value VAL. This function works correctly with |
5181 caller, it is protected from garbage-protection and returned. */ | 5820 caller, it is protected from garbage-protection and returned. */ |
5182 Lisp_Object | 5821 Lisp_Object |
5183 unbind_to_1 (int count, Lisp_Object value) | 5822 unbind_to_1 (int count, Lisp_Object value) |
5184 { | 5823 { |
5185 UNBIND_TO_GCPRO (count, value); | 5824 UNBIND_TO_GCPRO (count, value); |
5825 check_specbind_stack_sanity (); | |
5186 return value; | 5826 return value; |
5187 } | 5827 } |
5188 | 5828 |
5189 /* Don't call this directly. | 5829 /* Don't call this directly. |
5190 Only for use by UNBIND_TO* macros in backtrace.h */ | 5830 Only for use by UNBIND_TO* macros in backtrace.h */ |
5240 } | 5880 } |
5241 #endif | 5881 #endif |
5242 #endif | 5882 #endif |
5243 } | 5883 } |
5244 Vquit_flag = oquit; | 5884 Vquit_flag = oquit; |
5885 check_specbind_stack_sanity (); | |
5245 } | 5886 } |
5246 | 5887 |
5247 | 5888 |
5248 | 5889 |
5249 /* Get the value of symbol's global binding, even if that binding is | 5890 /* Get the value of symbol's global binding, even if that binding is |
5653 void | 6294 void |
5654 reinit_vars_of_eval (void) | 6295 reinit_vars_of_eval (void) |
5655 { | 6296 { |
5656 preparing_for_armageddon = 0; | 6297 preparing_for_armageddon = 0; |
5657 in_warnings = 0; | 6298 in_warnings = 0; |
5658 Qunbound_suspended_errors_tag = make_opaque_ptr (&Qunbound_suspended_errors_tag); | |
5659 staticpro_nodump (&Qunbound_suspended_errors_tag); | |
5660 | |
5661 specpdl_size = 50; | 6299 specpdl_size = 50; |
5662 specpdl = xnew_array (struct specbinding, specpdl_size); | 6300 specpdl = xnew_array (struct specbinding, specpdl_size); |
5663 /* XEmacs change: increase these values. */ | 6301 /* XEmacs change: increase these values. */ |
5664 max_specpdl_size = 3000; | 6302 max_specpdl_size = 3000; |
5665 max_lisp_eval_depth = 1000; | 6303 max_lisp_eval_depth = 1000; |
5684 You can safely make it considerably larger than its default value, | 6322 You can safely make it considerably larger than its default value, |
5685 if that proves inconveniently small. | 6323 if that proves inconveniently small. |
5686 */ ); | 6324 */ ); |
5687 | 6325 |
5688 DEFVAR_LISP ("quit-flag", &Vquit_flag /* | 6326 DEFVAR_LISP ("quit-flag", &Vquit_flag /* |
5689 Non-nil causes `eval' to abort, unless `inhibit-quit' is non-nil. | 6327 t causes running Lisp code to abort, unless `inhibit-quit' is non-nil. |
5690 Typing C-G sets `quit-flag' non-nil, regardless of `inhibit-quit'. | 6328 `critical' causes running Lisp code to abort regardless of `inhibit-quit'. |
6329 Normally, you do not need to set this value yourself. It is set to | |
6330 t each time a Control-G is detected, and to `critical' each time a | |
6331 Shift-Control-G is detected. The XEmacs core C code is littered with | |
6332 calls to the QUIT; macro, which check the values of `quit-flag' and | |
6333 `inhibit-quit' and abort (or more accurately, call (signal 'quit)) if | |
6334 it's correct to do so. | |
5691 */ ); | 6335 */ ); |
5692 Vquit_flag = Qnil; | 6336 Vquit_flag = Qnil; |
5693 | 6337 |
5694 DEFVAR_LISP ("inhibit-quit", &Vinhibit_quit /* | 6338 DEFVAR_LISP ("inhibit-quit", &Vinhibit_quit /* |
5695 Non-nil inhibits C-g quitting from happening immediately. | 6339 Non-nil inhibits C-g quitting from happening immediately. |
5696 Note that `quit-flag' will still be set by typing C-g, | 6340 Note that `quit-flag' will still be set by typing C-g, |
5697 so a quit will be signalled as soon as `inhibit-quit' is nil. | 6341 so a quit will be signalled as soon as `inhibit-quit' is nil. |
5698 To prevent this happening, set `quit-flag' to nil | 6342 To prevent this happening, set `quit-flag' to nil |
5699 before making `inhibit-quit' nil. The value of `inhibit-quit' is | 6343 before making `inhibit-quit' nil. |
5700 ignored if a critical quit is requested by typing control-shift-G in | 6344 |
5701 an X frame. | 6345 The value of `inhibit-quit' is ignored if a critical quit is |
6346 requested by typing control-shift-G in a window-system frame; | |
6347 this is explained in more detail in `quit-flag'. | |
5702 */ ); | 6348 */ ); |
5703 Vinhibit_quit = Qnil; | 6349 Vinhibit_quit = Qnil; |
5704 | 6350 |
5705 DEFVAR_LISP ("stack-trace-on-error", &Vstack_trace_on_error /* | 6351 DEFVAR_LISP ("stack-trace-on-error", &Vstack_trace_on_error /* |
5706 *Non-nil means automatically display a backtrace buffer | 6352 *Non-nil means automatically display a backtrace buffer |
5781 If due to `apply' or `funcall' entry, one arg, `lambda'. | 6427 If due to `apply' or `funcall' entry, one arg, `lambda'. |
5782 If due to `eval' entry, one arg, t. | 6428 If due to `eval' entry, one arg, t. |
5783 */ ); | 6429 */ ); |
5784 Vdebugger = Qnil; | 6430 Vdebugger = Qnil; |
5785 | 6431 |
6432 staticpro (&Vcatch_everything_tag); | |
6433 Vcatch_everything_tag = make_opaque (OPAQUE_CLEAR, 0); | |
6434 | |
5786 staticpro (&Vpending_warnings); | 6435 staticpro (&Vpending_warnings); |
5787 Vpending_warnings = Qnil; | 6436 Vpending_warnings = Qnil; |
5788 dump_add_root_object (&Vpending_warnings_tail); | 6437 dump_add_root_object (&Vpending_warnings_tail); |
5789 Vpending_warnings_tail = Qnil; | 6438 Vpending_warnings_tail = Qnil; |
5790 | 6439 |
5794 staticpro (&Vautoload_queue); | 6443 staticpro (&Vautoload_queue); |
5795 Vautoload_queue = Qnil; | 6444 Vautoload_queue = Qnil; |
5796 | 6445 |
5797 staticpro (&Vcondition_handlers); | 6446 staticpro (&Vcondition_handlers); |
5798 | 6447 |
5799 staticpro (&Vcurrent_warning_class); | 6448 staticpro (&Vdeletable_permanent_display_objects); |
5800 Vcurrent_warning_class = Qnil; | 6449 Vdeletable_permanent_display_objects = Qnil; |
5801 | 6450 |
5802 staticpro (&Vcurrent_warning_level); | 6451 staticpro (&Vmodifiable_buffers); |
5803 Vcurrent_warning_level = Qnil; | 6452 Vmodifiable_buffers = Qnil; |
5804 | 6453 |
5805 staticpro (&Vcurrent_error_state); | 6454 inhibit_flags = 0; |
5806 Vcurrent_error_state = Qnil; /* errors as normal */ | 6455 } |
5807 } |