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 }