diff options
Diffstat (limited to 'src/eval.c')
-rw-r--r-- | src/eval.c | 51 |
1 files changed, 34 insertions, 17 deletions
diff --git a/src/eval.c b/src/eval.c index c05c8d8f8de..22b02b49521 100644 --- a/src/eval.c +++ b/src/eval.c @@ -856,11 +856,9 @@ usage: (let* VARLIST BODY...) */) lexenv = Vinternal_interpreter_environment; - varlist = XCAR (args); - CHECK_LIST (varlist); - while (CONSP (varlist)) + for (varlist = XCAR (args); CONSP (varlist); varlist = XCDR (varlist)) { - QUIT; + maybe_quit (); elt = XCAR (varlist); if (SYMBOLP (elt)) @@ -894,9 +892,8 @@ usage: (let* VARLIST BODY...) */) } else specbind (var, val); - - varlist = XCDR (varlist); } + CHECK_LIST_END (varlist, XCAR (args)); val = Fprogn (XCDR (args)); return unbind_to (count, val); @@ -928,7 +925,7 @@ usage: (let VARLIST BODY...) */) for (argnum = 0; CONSP (varlist); varlist = XCDR (varlist)) { - QUIT; + maybe_quit (); elt = XCAR (varlist); if (SYMBOLP (elt)) temps [argnum++] = Qnil; @@ -981,7 +978,7 @@ usage: (while TEST BODY...) */) body = XCDR (args); while (!NILP (eval_sub (test))) { - QUIT; + maybe_quit (); prog_ignore (body); } @@ -1014,7 +1011,7 @@ definitions to shadow the loaded ones for use in file byte-compilation. */) until we get a symbol that is not an alias. */ while (SYMBOLP (def)) { - QUIT; + maybe_quit (); sym = def; tem = Fassq (sym, environment); if (NILP (tem)) @@ -1134,7 +1131,6 @@ unwind_to_catch (struct handler *catch, Lisp_Object value) /* Restore certain special C variables. */ set_poll_suppress_count (catch->poll_suppress_count); unblock_input_to (catch->interrupt_input_blocked); - immediate_quit = 0; do { @@ -1453,7 +1449,7 @@ static Lisp_Object find_handler_clause (Lisp_Object, Lisp_Object); static bool maybe_call_debugger (Lisp_Object conditions, Lisp_Object sig, Lisp_Object data); -void +static void process_quit_flag (void) { Lisp_Object flag = Vquit_flag; @@ -1465,6 +1461,28 @@ process_quit_flag (void) quit (); } +/* Check quit-flag and quit if it is non-nil. Typing C-g does not + directly cause a quit; it only sets Vquit_flag. So the program + needs to call maybe_quit at times when it is safe to quit. Every + loop that might run for a long time or might not exit ought to call + maybe_quit at least once, at a safe place. Unless that is + impossible, of course. But it is very desirable to avoid creating + loops where maybe_quit is impossible. + + If quit-flag is set to `kill-emacs' the SIGINT handler has received + a request to exit Emacs when it is safe to do. + + When not quitting, process any pending signals. */ + +void +maybe_quit (void) +{ + if (!NILP (Vquit_flag) && NILP (Vinhibit_quit)) + process_quit_flag (); + else if (pending_signals) + process_pending_signals (); +} + DEFUN ("signal", Fsignal, Ssignal, 2, 2, 0, doc: /* Signal an error. Args are ERROR-SYMBOL and associated DATA. This function does not return. @@ -1508,10 +1526,9 @@ signal_or_quit (Lisp_Object error_symbol, Lisp_Object data, bool keyboard_quit) Lisp_Object string; Lisp_Object real_error_symbol = (NILP (error_symbol) ? Fcar (data) : error_symbol); - register Lisp_Object clause = Qnil; + Lisp_Object clause = Qnil; struct handler *h; - immediate_quit = 0; if (gc_in_progress || waiting_for_input) emacs_abort (); @@ -2129,7 +2146,7 @@ eval_sub (Lisp_Object form) if (!CONSP (form)) return form; - QUIT; + maybe_quit (); maybe_gc (); @@ -2715,7 +2732,7 @@ usage: (funcall FUNCTION &rest ARGUMENTS) */) Lisp_Object val; ptrdiff_t count; - QUIT; + maybe_quit (); if (++lisp_eval_depth > max_lisp_eval_depth) { @@ -2960,7 +2977,7 @@ funcall_lambda (Lisp_Object fun, ptrdiff_t nargs, bool previous_optional_or_rest = false; for (; CONSP (syms_left); syms_left = XCDR (syms_left)) { - QUIT; + maybe_quit (); next = XCAR (syms_left); if (!SYMBOLP (next)) @@ -3098,7 +3115,7 @@ lambda_arity (Lisp_Object fun) if (EQ (XCAR (fun), Qclosure)) { fun = XCDR (fun); /* Drop `closure'. */ - CHECK_LIST_CONS (fun, fun); + CHECK_CONS (fun); } syms_left = XCDR (fun); if (CONSP (syms_left)) |