Mercurial > hg > xemacs-beta
diff src/eval.c @ 771:943eaba38521
[xemacs-hg @ 2002-03-13 08:51:24 by ben]
The big ben-mule-21-5 check-in!
Various files were added and deleted. See CHANGES-ben-mule.
There are still some test suite failures. No crashes, though.
Many of the failures have to do with problems in the test suite itself
rather than in the actual code. I'll be addressing these in the next
day or so -- none of the test suite failures are at all critical.
Meanwhile I'll be trying to address the biggest issues -- i.e. build
or run failures, which will almost certainly happen on various platforms.
All comments should be sent to ben@xemacs.org -- use a Cc: if necessary
when sending to mailing lists. There will be pre- and post- tags,
something like
pre-ben-mule-21-5-merge-in, and
post-ben-mule-21-5-merge-in.
author | ben |
---|---|
date | Wed, 13 Mar 2002 08:54:06 +0000 |
parents | b1f74adcc1ff |
children | e38acbeb1cae |
line wrap: on
line diff
--- a/src/eval.c Fri Mar 08 13:33:14 2002 +0000 +++ b/src/eval.c Wed Mar 13 08:54:06 2002 +0000 @@ -392,7 +392,7 @@ entering_debugger = 1; val = internal_catch (Qdebugger, call_debugger_259, arg, &threw); - return unbind_to (speccount, ((threw) + return unbind_to_1 (speccount, ((threw) ? Qunbound /* Not returning a value */ : val)); } @@ -569,7 +569,7 @@ Qnil); else /* in batch mode, we want this going to stderr. */ backtrace_259 (Qnil); - unbind_to (speccount, Qnil); + unbind_to (speccount); *stack_trace_displayed = 1; } @@ -604,7 +604,7 @@ Qnil); else /* in batch mode, we want this going to stderr. */ backtrace_259 (Qnil); - unbind_to (speccount, Qnil); + unbind_to (speccount); *stack_trace_displayed = 1; } @@ -625,7 +625,7 @@ UNGCPRO; Vcondition_handlers = all_handlers; - return unbind_to (speccount, val); + return unbind_to_1 (speccount, val); } @@ -872,7 +872,7 @@ } specbind (symbol, value); } - return unbind_to (speccount, Fprogn (body)); + return unbind_to_1 (speccount, Fprogn (body)); } DEFUN ("let", Flet, 1, UNEVALLED, 0, /* @@ -941,7 +941,7 @@ UNGCPRO; - return unbind_to (speccount, Fprogn (body)); + return unbind_to_1 (speccount, Fprogn (body)); } DEFUN ("while", Fwhile, 1, UNEVALLED, 0, /* @@ -1369,7 +1369,7 @@ /* Unwind the specpdl stack, and then restore the proper set of handlers. */ - unbind_to (catchlist->pdlcount, Qnil); + unbind_to (catchlist->pdlcount); catchlist = catchlist->next; #ifdef ERROR_CHECK_TYPECHECK check_error_state_sanity (); @@ -1398,7 +1398,7 @@ --ben */ /* Unwind the specpdl stack */ - unbind_to (c->pdlcount, Qnil); + unbind_to (c->pdlcount); catchlist = c->next; #ifdef ERROR_CHECK_TYPECHECK check_error_state_sanity (); @@ -1508,7 +1508,7 @@ int speccount = specpdl_depth(); record_unwind_protect (Fprogn, XCDR (args)); - return unbind_to (speccount, Feval (XCAR (args))); + return unbind_to_1 (speccount, Feval (XCAR (args))); } @@ -1702,7 +1702,7 @@ /* Note: The unbind also resets Vcondition_handlers. Maybe we should delete this here. */ Vcondition_handlers = XCDR (c.tag); - unbind_to (speccount, Qnil); + unbind_to (speccount); UNGCPRO; /* free the conses *after* the unbind, because the unbind will run @@ -1724,7 +1724,7 @@ /* Note that this just undoes the binding of h.var; whoever longjmp()ed to us unwound the stack to c.pdlcount before throwing. */ - unbind_to (c.pdlcount, Qnil); + unbind_to (c.pdlcount); return val; #else int speccount; @@ -1736,7 +1736,7 @@ speccount = specpdl_depth(); specbind (var, Fcar (val)); val = Fprogn (Fcdr (val)); - return unbind_to (speccount, val); + return unbind_to_1 (speccount, val); #endif } @@ -1786,6 +1786,19 @@ Each element of HANDLERS looks like (CONDITION-NAME BODY...) where the BODY is made of Lisp expressions. +A typical usage of `condition-case' looks like this: + +(condition-case nil + ;; you need a progn here if you want more than one statement ... + (progn + (do-something) + (do-something-else)) + (error + (issue-warning-or) + ;; but strangely, you don't need one here. + (return-a-value-etc) + )) + A handler is applicable to an error if CONDITION-NAME is one of the error's condition names. If an error happens, the first applicable handler is run. As a special case, a CONDITION-NAME of t matches @@ -1853,7 +1866,7 @@ Vcondition_handlers = tem; /* Caller should have GC-protected args */ - return unbind_to (speccount, Ffuncall (nargs - 1, args + 1)); + return unbind_to_1 (speccount, Ffuncall (nargs - 1, args + 1)); } static int @@ -1922,9 +1935,7 @@ { /* who knows how much has been initialized? Safest bet is just to bomb out immediately. */ - /* let's not use stderr_out() here, because that does a bunch of - things that might not be safe yet. */ - fprintf (stderr, "Error before initialization is complete!\n"); + stderr_out ("Error before initialization is complete!\n"); abort (); } @@ -2159,7 +2170,7 @@ } PRIMITIVE_FUNCALL (val, get_opaque_ptr (kludgy_args[0]), kludgy_args + 3, XINT (kludgy_args[1])); - return unbind_to (speccount, val); + return unbind_to_1 (speccount, val); } /* Many functions would like to do one of three things if an error @@ -2259,7 +2270,7 @@ /* Use the returned value except in non-local exit, when RETVAL applies. */ /* Some perverse compilers require the perverse cast below. */ - return unbind_to (speccount, + return unbind_to_1 (speccount, threw ? *((Lisp_Object*) &(retval)) : the_retval); } } @@ -2328,7 +2339,7 @@ if (!reason) return frob; else - return Fcons (build_translated_string (reason), frob); + return Fcons (build_msg_string (reason), frob); } DOESNT_RETURN @@ -2381,7 +2392,7 @@ signal_error_2 (Lisp_Object type, const CIntbyte *reason, Lisp_Object frob0, Lisp_Object frob1) { - signal_error_1 (type, list3 (build_translated_string (reason), frob0, + signal_error_1 (type, list3 (build_msg_string (reason), frob0, frob1)); } @@ -2393,7 +2404,7 @@ /* Optimization: */ if (ERRB_EQ (errb, ERROR_ME_NOT)) return; - maybe_signal_error_1 (type, list3 (build_translated_string (reason), frob0, + maybe_signal_error_1 (type, list3 (build_msg_string (reason), frob0, frob1), class, errb); } @@ -2401,7 +2412,7 @@ signal_continuable_error_2 (Lisp_Object type, const CIntbyte *reason, Lisp_Object frob0, Lisp_Object frob1) { - return Fsignal (type, list3 (build_translated_string (reason), frob0, + return Fsignal (type, list3 (build_msg_string (reason), frob0, frob1)); } @@ -2414,7 +2425,7 @@ if (ERRB_EQ (errb, ERROR_ME_NOT)) return Qnil; return maybe_signal_continuable_error_1 - (type, list3 (build_translated_string (reason), frob0, frob1), + (type, list3 (build_msg_string (reason), frob0, frob1), class, errb); } @@ -2432,8 +2443,7 @@ va_list args; va_start (args, fmt); - obj = emacs_doprnt_string_va ((const Intbyte *) GETTEXT (fmt), Qnil, -1, - args); + obj = emacs_vsprintf_string (CGETTEXT (fmt), args); va_end (args); /* Fsignal GC-protects its args */ @@ -2452,8 +2462,7 @@ return; va_start (args, fmt); - obj = emacs_doprnt_string_va ((const Intbyte *) GETTEXT (fmt), Qnil, -1, - args); + obj = emacs_vsprintf_string (CGETTEXT (fmt), args); va_end (args); /* Fsignal GC-protects its args */ @@ -2467,8 +2476,7 @@ va_list args; va_start (args, fmt); - obj = emacs_doprnt_string_va ((const Intbyte *) GETTEXT (fmt), Qnil, -1, - args); + obj = emacs_vsprintf_string (CGETTEXT (fmt), args); va_end (args); /* Fsignal GC-protects its args */ @@ -2487,8 +2495,7 @@ return Qnil; va_start (args, fmt); - obj = emacs_doprnt_string_va ((const Intbyte *) GETTEXT (fmt), Qnil, -1, - args); + obj = emacs_vsprintf_string (CGETTEXT (fmt), args); va_end (args); /* Fsignal GC-protects its args */ @@ -2518,8 +2525,7 @@ va_list args; va_start (args, fmt); - obj = emacs_doprnt_string_va ((const Intbyte *) GETTEXT (fmt), Qnil, -1, - args); + obj = emacs_vsprintf_string (CGETTEXT (fmt), args); va_end (args); /* Fsignal GC-protects its args */ @@ -2539,8 +2545,7 @@ return; va_start (args, fmt); - obj = emacs_doprnt_string_va ((const Intbyte *) GETTEXT (fmt), Qnil, -1, - args); + obj = emacs_vsprintf_string (CGETTEXT (fmt), args); va_end (args); /* Fsignal GC-protects its args */ @@ -2556,8 +2561,7 @@ va_list args; va_start (args, fmt); - obj = emacs_doprnt_string_va ((const Intbyte *) GETTEXT (fmt), Qnil, -1, - args); + obj = emacs_vsprintf_string (CGETTEXT (fmt), args); va_end (args); /* Fsignal GC-protects its args */ @@ -2578,8 +2582,7 @@ return Qnil; va_start (args, fmt); - obj = emacs_doprnt_string_va ((const Intbyte *) GETTEXT (fmt), Qnil, -1, - args); + obj = emacs_vsprintf_string (CGETTEXT (fmt), args); va_end (args); /* Fsignal GC-protects its args */ @@ -2810,8 +2813,7 @@ va_list args; va_start (args, fmt); - obj = emacs_doprnt_string_va ((const Intbyte *) GETTEXT (fmt), Qnil, -1, - args); + obj = emacs_vsprintf_string (CGETTEXT (fmt), args); va_end (args); /* Fsignal GC-protects its args */ @@ -3114,7 +3116,7 @@ /* Once loading finishes, don't undo it. */ Vautoload_queue = Qt; - unbind_to (speccount, Qnil); + unbind_to (speccount); fun = indirect_function (fun, 0); @@ -3184,7 +3186,7 @@ messij = Fprin1_to_string (messij, Qnil); call3 (Qdisplay_warning, class, messij, level); UNGCPRO; - unbind_to (speccount, Qnil); + unbind_to (speccount); } if (!CONSP (form)) @@ -3802,7 +3804,7 @@ if (i < nargs) goto wrong_number_of_arguments; - return unbind_to (speccount, Fprogn (body)); + return unbind_to_1 (speccount, Fprogn (body)); wrong_number_of_arguments: return signal_wrong_number_of_arguments_error (fun, nargs); @@ -3912,7 +3914,7 @@ assert (!gc_in_progress); sym = args[0]; - val = symbol_value_in_buffer (sym, make_buffer (buf)); + val = symbol_value_in_buffer (sym, wrap_buffer (buf)); ret = (cond == RUN_HOOKS_UNTIL_FAILURE ? Qt : Qnil); if (UNBOUNDP (val) || NILP (val)) @@ -4281,7 +4283,7 @@ record_unwind_protect (Fset_buffer, Fcurrent_buffer ()); set_buffer_internal (buf); val = call0 (fn); - unbind_to (speccount, Qnil); + unbind_to (speccount); return val; } } @@ -4299,7 +4301,7 @@ record_unwind_protect (Fset_buffer, Fcurrent_buffer ()); set_buffer_internal (buf); val = call1 (fn, arg0); - unbind_to (speccount, Qnil); + unbind_to (speccount); return val; } } @@ -4317,7 +4319,7 @@ record_unwind_protect (Fset_buffer, Fcurrent_buffer ()); set_buffer_internal (buf); val = call2 (fn, arg0, arg1); - unbind_to (speccount, Qnil); + unbind_to (speccount); return val; } } @@ -4335,7 +4337,7 @@ record_unwind_protect (Fset_buffer, Fcurrent_buffer ()); set_buffer_internal (buf); val = call3 (fn, arg0, arg1, arg2); - unbind_to (speccount, Qnil); + unbind_to (speccount); return val; } } @@ -4354,7 +4356,7 @@ record_unwind_protect (Fset_buffer, Fcurrent_buffer ()); set_buffer_internal (buf); val = call4 (fn, arg0, arg1, arg2, arg3); - unbind_to (speccount, Qnil); + unbind_to (speccount); return val; } } @@ -4371,7 +4373,7 @@ record_unwind_protect (Fset_buffer, Fcurrent_buffer ()); set_buffer_internal (buf); val = Feval (form); - unbind_to (speccount, Qnil); + unbind_to (speccount); return val; } } @@ -4429,25 +4431,26 @@ static Lisp_Object caught_a_squirmer (Lisp_Object errordata, Lisp_Object arg) { + /* #### should be rewritten to work with emacs_sprintf_string_lisp(); but this + whole stuff is getting junked and replaced from my stderr-proc ws */ if (!NILP (errordata)) { Lisp_Object args[2]; if (!NILP (arg)) { - CIntbyte *str = (CIntbyte *) get_opaque_ptr (arg); - args[0] = build_string (str); + Intbyte *str = (Intbyte *) get_opaque_ptr (arg); + args[0] = build_intstring (str); } else - args[0] = build_string ("error"); + args[0] = build_msg_string ("error"); /* #### This should call (with-output-to-string (display-error errordata)) but that stuff is all in Lisp currently. */ args[1] = errordata; warn_when_safe_lispobj (Qerror, Qwarning, - emacs_doprnt_string_lisp ((const Intbyte *) "%s: %s", - Qnil, -1, 2, args)); + emacs_vsprintf_string_lisp ("%s: %s", Qnil, 2, args)); } return Qunbound; } @@ -4502,7 +4505,7 @@ XSETBUFFER (buffer, buf); specbind (Qinhibit_quit, Qt); - /* gc_currently_forbidden = 1; Currently no reason to do this; */ + /* begin_gc_forbidden(); Currently no reason to do this; */ cons = noseeum_cons (buffer, form); opaque = (warning_string ? make_opaque_ptr ((void *)warning_string) : Qnil); @@ -4516,8 +4519,7 @@ free_opaque_ptr (opaque); UNGCPRO; - /* gc_currently_forbidden = 0; */ - return unbind_to (speccount, tem); + return unbind_to_1 (speccount, tem); } static Lisp_Object @@ -4556,7 +4558,7 @@ free_opaque_ptr (opaque); UNGCPRO; - return unbind_to (speccount, tem); + return unbind_to_1 (speccount, tem); } /* Same as run_hook_trapping_errors() but also set the hook to nil @@ -4598,7 +4600,7 @@ free_cons (XCONS (cons)); UNGCPRO; - return unbind_to (speccount, tem); + return unbind_to_1 (speccount, tem); } static Lisp_Object @@ -4626,7 +4628,7 @@ GCPRO2 (opaque, function); speccount = specpdl_depth(); specbind (Qinhibit_quit, Qt); - /* gc_currently_forbidden = 1; Currently no reason to do this; */ + /* begin_gc_forbidden(); Currently no reason to do this; */ opaque = (warning_string ? make_opaque_ptr ((void *)warning_string) : Qnil); /* Qerror not Qt, so you can get a backtrace */ @@ -4637,8 +4639,7 @@ free_opaque_ptr (opaque); UNGCPRO; - /* gc_currently_forbidden = 0; */ - return unbind_to (speccount, tem); + return unbind_to_1 (speccount, tem); } static Lisp_Object @@ -4675,7 +4676,7 @@ GCPRO4 (cons, opaque, function, object); specbind (Qinhibit_quit, Qt); - /* gc_currently_forbidden = 1; Currently no reason to do this; */ + /* begin_gc_forbidden(); Currently no reason to do this; */ cons = noseeum_cons (function, object); opaque = (warning_string ? make_opaque_ptr ((void *)warning_string) : Qnil); @@ -4688,8 +4689,7 @@ free_cons (XCONS (cons)); UNGCPRO; - /* gc_currently_forbidden = 0; */ - return unbind_to (speccount, tem); + return unbind_to_1 (speccount, tem); } Lisp_Object @@ -4711,7 +4711,7 @@ GCPRO5 (cons, opaque, function, object1, object2); specbind (Qinhibit_quit, Qt); - /* gc_currently_forbidden = 1; Currently no reason to do this; */ + /* begin_gc_forbidden(); Currently no reason to do this; */ cons = list3 (function, object1, object2); opaque = (warning_string ? make_opaque_ptr ((void *)warning_string) : Qnil); @@ -4724,14 +4724,13 @@ free_list (cons); UNGCPRO; - /* gc_currently_forbidden = 0; */ - return unbind_to (speccount, tem); + return unbind_to_1 (speccount, tem); } /************************************************************************/ /* The special binding stack */ -/* Most C code should simply use specbind() and unbind_to(). */ +/* Most C code should simply use specbind() and unbind_to_1(). */ /* When performance is critical, use the macros in backtrace.h. */ /************************************************************************/ @@ -4854,7 +4853,7 @@ if (buffer_local == 0) { specpdl_ptr->old_value = find_symbol_value (symbol); - specpdl_ptr->func = 0; /* Handled specially by unbind_to */ + specpdl_ptr->func = 0; /* Handled specially by unbind_to_1 */ } else if (buffer_local > 0) { @@ -4877,10 +4876,14 @@ Fset (symbol, value); } -/* Note: As long as the unwind-protect exists, its arg is automatically - GCPRO'd. */ - -void +/* Record an unwind-protect -- FUNCTION will be called with ARG no matter + whether a normal or non-local exit occurs. (You need to call unbind_to_1() + before your function returns normally, passing in the integer returned + by this function.) Note: As long as the unwind-protect exists, ARG is + automatically GCPRO'd. The return value from FUNCTION is completely + ignored. #### We should eliminate it entirely. */ + +int record_unwind_protect (Lisp_Object (*function) (Lisp_Object arg), Lisp_Object arg) { @@ -4890,15 +4893,46 @@ specpdl_ptr->old_value = arg; specpdl_ptr++; specpdl_depth_counter++; -} - -extern int check_sigio (void); + return specpdl_depth_counter - 1; +} + +static Lisp_Object +free_pointer (Lisp_Object opaque) +{ + xfree (get_opaque_ptr (opaque)); + free_opaque_ptr (opaque); + return Qnil; +} + +/* Establish an unwind-protect which will free the specified block. + */ +int +record_unwind_protect_freeing (void *ptr) +{ + Lisp_Object opaque = make_opaque_ptr (ptr); + return record_unwind_protect (free_pointer, opaque); +} + +static Lisp_Object +free_dynarr (Lisp_Object opaque) +{ + Dynarr_free (get_opaque_ptr (opaque)); + free_opaque_ptr (opaque); + return Qnil; +} + +int +record_unwind_protect_freeing_dynarr (void *ptr) +{ + Lisp_Object opaque = make_opaque_ptr (ptr); + return record_unwind_protect (free_dynarr, opaque); +} /* Unwind the stack till specpdl_depth() == COUNT. VALUE is not used, except that, purely as a convenience to the - caller, it is protected from garbage-protection. */ + caller, it is protected from garbage-protection and returned. */ Lisp_Object -unbind_to (int count, Lisp_Object value) +unbind_to_1 (int count, Lisp_Object value) { UNBIND_TO_GCPRO (count, value); return value; @@ -4909,13 +4943,15 @@ void unbind_to_hairy (int count) { - int quitf; + Lisp_Object oquit; ++specpdl_ptr; ++specpdl_depth_counter; + /* Allow QUIT within unwind-protect routines, but defer any existing QUIT + until afterwards. */ check_quit (); /* make Vquit_flag accurate */ - quitf = !NILP (Vquit_flag); + oquit = Vquit_flag; Vquit_flag = Qnil; while (specpdl_depth_counter != count) @@ -4957,8 +4993,7 @@ #endif #endif } - if (quitf) - Vquit_flag = Qt; + Vquit_flag = oquit; } @@ -5256,8 +5291,7 @@ va_list args; va_start (args, fmt); - obj = emacs_doprnt_string_va ((const Intbyte *) GETTEXT (fmt), - Qnil, -1, args); + obj = emacs_vsprintf_string (CGETTEXT (fmt), args); va_end (args); warn_when_safe_lispobj (class, level, obj); @@ -5344,7 +5378,7 @@ } void -reinit_eval (void) +init_eval_early (void) { specpdl_ptr = specpdl; specpdl_depth_counter = 0; @@ -5446,6 +5480,15 @@ if one of its condition symbols appears in the list. This variable is overridden by `debug-ignored-errors'. See also variables `debug-on-quit' and `debug-on-signal'. +If this variable is set while XEmacs is running noninteractively, +an unhandled error will cause a backtrace to be output and the C +debugger entered using `force-debugging-signal'. This can be very +useful when debugging noninteractive errors in tricky situations, +e.g. makefiles, since you can set this variable using an environment +variable, like this: + +\(using csh) setenv XEMACSDEBUG '(setq debug-on-error t)' +\(using bash) export XEMACSDEBUG='(setq debug-on-error t)' */ ); Vdebug_on_error = Qnil; @@ -5496,6 +5539,4 @@ staticpro (&Vcurrent_error_state); Vcurrent_error_state = Qnil; /* errors as normal */ - - reinit_eval (); -} +}