X-Git-Url: https://git.hcoop.net/bpt/emacs.git/blobdiff_plain/51fb064bc72968e739e8dea580e58796c1a87f4c..114f9c96795aff3b51b9060d7c9c1b77debcc99a:/src/eval.c diff --git a/src/eval.c b/src/eval.c index 38cf87b509..6609d3b5c8 100644 --- a/src/eval.c +++ b/src/eval.c @@ -1,14 +1,14 @@ /* Evaluator for GNU Emacs Lisp interpreter. Copyright (C) 1985, 1986, 1987, 1993, 1994, 1995, 1999, 2000, 2001, - 2002, 2003, 2004, 2005, 2006, 2007, 2008 + 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. This file is part of GNU Emacs. -GNU Emacs is free software; you can redistribute it and/or modify +GNU Emacs is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3, or (at your option) -any later version. +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. GNU Emacs is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -16,18 +16,16 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License -along with GNU Emacs; see the file COPYING. If not, write to -the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -Boston, MA 02110-1301, USA. */ +along with GNU Emacs. If not, see . */ #include +#include #include "lisp.h" #include "blockinput.h" #include "commands.h" #include "keyboard.h" #include "dispextern.h" -#include #if HAVE_X_WINDOWS #include "xterm.h" @@ -51,41 +49,6 @@ struct backtrace struct backtrace *backtrace_list; -/* This structure helps implement the `catch' and `throw' control - structure. A struct catchtag contains all the information needed - to restore the state of the interpreter after a non-local jump. - - Handlers for error conditions (represented by `struct handler' - structures) just point to a catch tag to do the cleanup required - for their jumps. - - catchtag structures are chained together in the C calling stack; - the `next' member points to the next outer catchtag. - - A call like (throw TAG VAL) searches for a catchtag whose `tag' - member is TAG, and then unbinds to it. The `val' member is used to - hold VAL while the stack is unwound; `val' is returned as the value - of the catch form. - - All the other members are concerned with restoring the interpreter - state. */ - -struct catchtag -{ - Lisp_Object tag; - Lisp_Object val; - struct catchtag *next; - struct gcpro *gcpro; - jmp_buf jmp; - struct backtrace *backlist; - struct handler *handlerlist; - int lisp_eval_depth; - int pdlcount; - int poll_suppress_count; - int interrupt_input_blocked; - struct byte_stack *byte_stack; -}; - struct catchtag *catchlist; #ifdef DEBUG_GCPRO @@ -99,6 +62,7 @@ Lisp_Object Qand_rest, Qand_optional; Lisp_Object Qdebug_on_error; Lisp_Object Qdeclare; Lisp_Object Qdebug; +extern Lisp_Object Qinteractive_form; /* This holds either the symbol `run-hooks' or nil. It is nil at an early stage of startup, and when Emacs @@ -224,7 +188,7 @@ init_eval_once () specpdl_ptr = specpdl; /* Don't forget to update docs (lispref node "Local Variables"). */ max_specpdl_size = 1000; - max_lisp_eval_depth = 400; + max_lisp_eval_depth = 500; Vrun_hooks = Qnil; } @@ -283,7 +247,7 @@ call_debugger (arg) if (SPECPDL_INDEX () + 100 > max_specpdl_size) max_specpdl_size = SPECPDL_INDEX () + 100; -#ifdef HAVE_X_WINDOWS +#ifdef HAVE_WINDOW_SYSTEM if (display_hourglass_p) cancel_hourglass (); #endif @@ -457,7 +421,7 @@ usage: (progn BODY...) */) } DEFUN ("prog1", Fprog1, Sprog1, 1, UNEVALLED, 0, - doc: /* Eval FIRST and BODY sequentially; value from FIRST. + doc: /* Eval FIRST and BODY sequentially; return value from FIRST. The value of FIRST is saved during the evaluation of the remaining args, whose values are discarded. usage: (prog1 FIRST BODY...) */) @@ -491,7 +455,7 @@ usage: (prog1 FIRST BODY...) */) } DEFUN ("prog2", Fprog2, Sprog2, 2, UNEVALLED, 0, - doc: /* Eval FORM1, FORM2 and BODY sequentially; value from FORM2. + doc: /* Eval FORM1, FORM2 and BODY sequentially; return value from FORM2. The value of FORM2 is saved during the evaluation of the remaining args, whose values are discarded. usage: (prog2 FORM1 FORM2 BODY...) */) @@ -587,10 +551,10 @@ usage: (function ARG) */) DEFUN ("interactive-p", Finteractive_p, Sinteractive_p, 0, 0, 0, - doc: /* Return t if the function was run directly by user input. + doc: /* Return t if the containing function was run directly by user input. This means that the function was called with `call-interactively' \(which includes being called as the binding of a key) -and input is currently coming from the keyboard (not in keyboard macro), +and input is currently coming from the keyboard (not a keyboard macro), and Emacs is not running in batch mode (`noninteractive' is nil). The only known proper use of `interactive-p' is in deciding whether to @@ -599,28 +563,41 @@ of using it for any other purpose, it is quite likely that you're making a mistake. Think: what do you want to do when the command is called from a keyboard macro? -If you want to test whether your function was called with -`call-interactively', the way to do that is by adding an extra -optional argument, and making the `interactive' spec specify non-nil -unconditionally for that argument. (`p' is a good way to do this.) */) +To test whether your function was called with `call-interactively', +either (i) add an extra optional argument and give it an `interactive' +spec that specifies non-nil unconditionally (such as \"p\"); or (ii) +use `called-interactively-p'. */) () { return (INTERACTIVE && interactive_p (1)) ? Qt : Qnil; } -DEFUN ("called-interactively-p", Fcalled_interactively_p, Scalled_interactively_p, 0, 0, 0, - doc: /* Return t if the function using this was called with `call-interactively'. -This is used for implementing advice and other function-modifying -features of Emacs. +DEFUN ("called-interactively-p", Fcalled_interactively_p, Scalled_interactively_p, 0, 1, 0, + doc: /* Return t if the containing function was called by `call-interactively'. +If KIND is `interactive', then only return t if the call was made +interactively by the user, i.e. not in `noninteractive' mode nor +when `executing-kbd-macro'. +If KIND is `any', on the other hand, it will return t for any kind of +interactive call, including being called as the binding of a key, or +from a keyboard macro, or in `noninteractive' mode. -The cleanest way to test whether your function was called with -`call-interactively' is by adding an extra optional argument, -and making the `interactive' spec specify non-nil unconditionally -for that argument. (`p' is a good way to do this.) */) - () +The only known proper use of `interactive' for KIND is in deciding +whether to display a helpful message, or how to display it. If you're +thinking of using it for any other purpose, it is quite likely that +you're making a mistake. Think: what do you want to do when the +command is called from a keyboard macro? + +This function is meant for implementing advice and other +function-modifying features. Instead of using this, it is sometimes +cleaner to give your function an extra optional argument whose +`interactive' spec specifies non-nil unconditionally (\"p\" is a good +way to do this), or via (not (or executing-kbd-macro noninteractive)). */) + (kind) + Lisp_Object kind; { - return interactive_p (1) ? Qt : Qnil; + return ((INTERACTIVE || !EQ (kind, intern ("interactive"))) + && interactive_p (1)) ? Qt : Qnil; } @@ -708,7 +685,8 @@ the list ARGS... as it appears in the expression, and the result should be a form to be evaluated instead of the original. DECL is a declaration, optional, which can specify how to indent -calls to this macro and how Edebug should handle it. It looks like this: +calls to this macro, how Edebug should handle it, and which argument +should be treated as documentation. It looks like this: (declare SPECS...) The elements can look like this: (indent INDENT) @@ -717,6 +695,10 @@ The elements can look like this: (debug DEBUG) Set NAME's `edebug-form-spec' property to DEBUG. (This is equivalent to writing a `def-edebug-spec' for the macro.) + + (doc-string ELT) + Set NAME's `doc-string-elt' property to ELT. + usage: (defmacro NAME ARGLIST [DOCSTRING] [DECL] BODY...) */) (args) Lisp_Object args; @@ -772,9 +754,10 @@ DEFUN ("defvaralias", Fdefvaralias, Sdefvaralias, 2, 3, 0, doc: /* Make NEW-ALIAS a variable alias for symbol BASE-VARIABLE. Aliased variables always have the same value; setting one sets the other. Third arg DOCSTRING, if non-nil, is documentation for NEW-ALIAS. If it is - omitted or nil, NEW-ALIAS gets the documentation string of BASE-VARIABLE, - or of the variable at the end of the chain of aliases, if BASE-VARIABLE is - itself an alias. +omitted or nil, NEW-ALIAS gets the documentation string of BASE-VARIABLE, +or of the variable at the end of the chain of aliases, if BASE-VARIABLE is +itself an alias. If NEW-ALIAS is bound, and BASE-VARIABLE is not, +then the value of BASE-VARIABLE is set to that of NEW-ALIAS. The return value is BASE-VARIABLE. */) (new_alias, base_variable, docstring) Lisp_Object new_alias, base_variable, docstring; @@ -788,6 +771,12 @@ The return value is BASE-VARIABLE. */) error ("Cannot make a constant an alias"); sym = XSYMBOL (new_alias); + /* http://lists.gnu.org/archive/html/emacs-devel/2008-04/msg00834.html + If n_a is bound, but b_v is not, set the value of b_v to n_a. + This is for the sake of define-obsolete-variable-alias and user + customizations. */ + if (NILP (Fboundp (base_variable)) && !NILP (Fboundp (new_alias))) + XSYMBOL(base_variable)->value = sym->value; sym->indirect_variable = 1; sym->value = base_variable; sym->constant = SYMBOL_CONSTANT_P (base_variable); @@ -929,6 +918,13 @@ user_variable_p_eh (ignore) return Qnil; } +static Lisp_Object +lisp_indirect_variable (Lisp_Object sym) +{ + XSETSYMBOL (sym, indirect_variable (XSYMBOL (sym))); + return sym; +} + DEFUN ("user-variable-p", Fuser_variable_p, Suser_variable_p, 1, 1, 0, doc: /* Return t if VARIABLE is intended to be set and modified by users. \(The alternative is a variable used internally in a Lisp program.) @@ -949,7 +945,7 @@ chain of symbols. */) /* If indirect and there's an alias loop, don't check anything else. */ if (XSYMBOL (variable)->indirect_variable - && NILP (internal_condition_case_1 (indirect_variable, variable, + && NILP (internal_condition_case_1 (lisp_indirect_variable, variable, Qt, user_variable_p_eh))) return Qnil; @@ -1360,7 +1356,7 @@ instead of a single condition name. Then it handles all of them. When a handler handles an error, control returns to the `condition-case' and it executes the handler's BODY... -with VAR bound to (SIGNALED-CONDITIONS . SIGNAL-DATA) from the error. +with VAR bound to (ERROR-SYMBOL . SIGNAL-DATA) from the error. (If VAR is nil, the handler can't access that information.) Then the value of the last BODY form is returned from the `condition-case' expression. @@ -1640,7 +1636,7 @@ See also the function `condition-case'. */) #if 0 /* rms: I don't know why this was here, but it is surely wrong for an error that is handled. */ -#ifdef HAVE_X_WINDOWS +#ifdef HAVE_WINDOW_SYSTEM if (display_hourglass_p) cancel_hourglass (); #endif @@ -1858,6 +1854,36 @@ skip_debugger (conditions, data) return 0; } +/* Call the debugger if calling it is currently enabled for CONDITIONS. + SIG and DATA describe the signal, as in find_handler_clause. */ + +static int +maybe_call_debugger (conditions, sig, data) + Lisp_Object conditions, sig, data; +{ + Lisp_Object combined_data; + + combined_data = Fcons (sig, data); + + if ( + /* Don't try to run the debugger with interrupts blocked. + The editing loop would return anyway. */ + ! INPUT_BLOCKED_P + /* Does user want to enter debugger for this kind of error? */ + && (EQ (sig, Qquit) + ? debug_on_quit + : wants_debugger (Vdebug_on_error, conditions)) + && ! skip_debugger (conditions, combined_data) + /* rms: what's this for? */ + && when_entered_debugger < num_nonmacro_input_events) + { + call_debugger (Fcons (Qerror, Fcons (combined_data, Qnil))); + return 1; + } + + return 0; +} + /* Value of Qlambda means we have called debugger and user has continued. There are two ways to pass SIG and DATA: = SIG is the error symbol, and DATA is the rest of the data. @@ -1894,16 +1920,17 @@ find_handler_clause (handlers, conditions, sig, data) { if (!NILP (sig) && wants_debugger (Vstack_trace_on_error, conditions)) { + max_lisp_eval_depth += 15; max_specpdl_size++; - #ifdef PROTOTYPES - internal_with_output_to_temp_buffer ("*Backtrace*", - (Lisp_Object (*) (Lisp_Object)) Fbacktrace, - Qnil); - #else - internal_with_output_to_temp_buffer ("*Backtrace*", - Fbacktrace, Qnil); - #endif + if (noninteractive) + Fbacktrace (); + else + internal_with_output_to_temp_buffer + ("*Backtrace*", + (Lisp_Object (*) (Lisp_Object)) Fbacktrace, + Qnil); max_specpdl_size--; + max_lisp_eval_depth -= 15; } if (!debugger_considered) @@ -1958,36 +1985,6 @@ find_handler_clause (handlers, conditions, sig, data) return Qnil; } -/* Call the debugger if calling it is currently enabled for CONDITIONS. - SIG and DATA describe the signal, as in find_handler_clause. */ - -int -maybe_call_debugger (conditions, sig, data) - Lisp_Object conditions, sig, data; -{ - Lisp_Object combined_data; - - combined_data = Fcons (sig, data); - - if ( - /* Don't try to run the debugger with interrupts blocked. - The editing loop would return anyway. */ - ! INPUT_BLOCKED_P - /* Does user wants to enter debugger for this kind of error? */ - && (EQ (sig, Qquit) - ? debug_on_quit - : wants_debugger (Vdebug_on_error, conditions)) - && ! skip_debugger (conditions, combined_data) - /* rms: what's this for? */ - && when_entered_debugger < num_nonmacro_input_events) - { - call_debugger (Fcons (Qerror, Fcons (combined_data, Qnil))); - return 1; - } - - return 0; -} - /* dump an error message; called like printf */ /* VARARGS 1 */ @@ -2065,7 +2062,7 @@ then strings and vectors are not accepted. */) fun = function; while (SYMBOLP (fun)) { - Lisp_Object tmp = Fget (fun, intern ("interactive-form")); + Lisp_Object tmp = Fget (fun, Qinteractive_form); if (!NILP (tmp)) if_prop = Qt; fun = Fsymbol_function (fun); @@ -2099,7 +2096,6 @@ then strings and vectors are not accepted. */) return Qnil; } -/* ARGSUSED */ DEFUN ("autoload", Fautoload, Sautoload, 2, 5, 0, doc: /* Define FUNCTION to autoload from FILE. FUNCTION is a symbol; FILE is a file name string to pass to `load'. @@ -2116,9 +2112,7 @@ this does nothing and returns nil. */) (function, file, docstring, interactive, type) Lisp_Object function, file, docstring, interactive, type; { -#ifdef NO_ARG_ARRAY Lisp_Object args[4]; -#endif CHECK_SYMBOL (function); CHECK_STRING (file); @@ -2133,17 +2127,13 @@ this does nothing and returns nil. */) /* Only add entries after dumping, because the ones before are not useful and else we get loads of them from the loaddefs.el. */ LOADHIST_ATTACH (Fcons (Qautoload, function)); - -#ifdef NO_ARG_ARRAY - args[0] = file; - args[1] = docstring; - args[2] = interactive; - args[3] = type; - - return Ffset (function, Fcons (Qautoload, Flist (4, &args[0]))); -#else /* NO_ARG_ARRAY */ - return Ffset (function, Fcons (Qautoload, Flist (4, &file))); -#endif /* not NO_ARG_ARRAY */ + else + /* We don't want the docstring in purespace (instead, + Snarf-documentation should (hopefully) overwrite it). */ + docstring = make_number (0); + return Ffset (function, + Fpurecopy (list5 (Qautoload, file, docstring, + interactive, type))); } Lisp_Object @@ -2630,7 +2620,6 @@ run_hook_with_args (nargs, args, cond) enum run_hooks_condition cond; { Lisp_Object sym, val, ret; - Lisp_Object globals; struct gcpro gcpro1, gcpro2, gcpro3; /* If we are dying or still initializing, @@ -2651,7 +2640,7 @@ run_hook_with_args (nargs, args, cond) } else { - globals = Qnil; + Lisp_Object globals = Qnil; GCPRO3 (sym, val, globals); for (; @@ -2664,18 +2653,28 @@ run_hook_with_args (nargs, args, cond) { /* t indicates this hook has a local binding; it means to run the global binding too. */ + globals = Fdefault_value (sym); + if (NILP (globals)) continue; - for (globals = Fdefault_value (sym); - CONSP (globals) && ((cond == to_completion) - || (cond == until_success ? NILP (ret) - : !NILP (ret))); - globals = XCDR (globals)) + if (!CONSP (globals) || EQ (XCAR (globals), Qlambda)) + { + args[0] = globals; + ret = Ffuncall (nargs, args); + } + else { - args[0] = XCAR (globals); - /* In a global value, t should not occur. If it does, we - must ignore it to avoid an endless loop. */ - if (!EQ (args[0], Qt)) - ret = Ffuncall (nargs, args); + for (; + CONSP (globals) && ((cond == to_completion) + || (cond == until_success ? NILP (ret) + : !NILP (ret))); + globals = XCDR (globals)) + { + args[0] = XCAR (globals); + /* In a global value, t should not occur. If it does, we + must ignore it to avoid an endless loop. */ + if (!EQ (args[0], Qt)) + ret = Ffuncall (nargs, args); + } } } else @@ -3593,42 +3592,42 @@ To prevent this happening, set `quit-flag' to nil before making `inhibit-quit' nil. */); Vinhibit_quit = Qnil; - Qinhibit_quit = intern ("inhibit-quit"); + Qinhibit_quit = intern_c_string ("inhibit-quit"); staticpro (&Qinhibit_quit); - Qautoload = intern ("autoload"); + Qautoload = intern_c_string ("autoload"); staticpro (&Qautoload); - Qdebug_on_error = intern ("debug-on-error"); + Qdebug_on_error = intern_c_string ("debug-on-error"); staticpro (&Qdebug_on_error); - Qmacro = intern ("macro"); + Qmacro = intern_c_string ("macro"); staticpro (&Qmacro); - Qdeclare = intern ("declare"); + Qdeclare = intern_c_string ("declare"); staticpro (&Qdeclare); /* Note that the process handling also uses Qexit, but we don't want to staticpro it twice, so we just do it here. */ - Qexit = intern ("exit"); + Qexit = intern_c_string ("exit"); staticpro (&Qexit); - Qinteractive = intern ("interactive"); + Qinteractive = intern_c_string ("interactive"); staticpro (&Qinteractive); - Qcommandp = intern ("commandp"); + Qcommandp = intern_c_string ("commandp"); staticpro (&Qcommandp); - Qdefun = intern ("defun"); + Qdefun = intern_c_string ("defun"); staticpro (&Qdefun); - Qand_rest = intern ("&rest"); + Qand_rest = intern_c_string ("&rest"); staticpro (&Qand_rest); - Qand_optional = intern ("&optional"); + Qand_optional = intern_c_string ("&optional"); staticpro (&Qand_optional); - Qdebug = intern ("debug"); + Qdebug = intern_c_string ("debug"); staticpro (&Qdebug); DEFVAR_LISP ("stack-trace-on-error", &Vstack_trace_on_error, @@ -3647,7 +3646,8 @@ If the value is a list, an error only means to enter the debugger if one of its condition symbols appears in the list. When you evaluate an expression interactively, this variable is temporarily non-nil if `eval-expression-debug-on-error' is non-nil. -See also variable `debug-on-quit'. */); +The command `toggle-debug-on-error' toggles this. +See also the variable `debug-on-quit'. */); Vdebug_on_error = Qnil; DEFVAR_LISP ("debug-ignored-errors", &Vdebug_ignored_errors, @@ -3702,7 +3702,7 @@ DECL is a list `(declare ...)' containing the declarations. The value the function returns is not used. */); Vmacro_declaration_function = Qnil; - Vrun_hooks = intern ("run-hooks"); + Vrun_hooks = intern_c_string ("run-hooks"); staticpro (&Vrun_hooks); staticpro (&Vautoload_queue);