/* Evaluator for GNU Emacs Lisp interpreter.
Copyright (C) 1985, 1986, 1987, 1993, 1994, 1995, 1999, 2000, 2001,
- 2002, 2004, 2005 Free Software Foundation, Inc.
+ 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
This file is part of GNU Emacs.
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., 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
+the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+Boston, MA 02110-1301, USA. */
#include <config.h>
{
max_specpdl_size = XINT (XCAR (data));
max_lisp_eval_depth = XINT (XCDR (data));
+ return Qnil;
}
/* Call the Lisp debugger, giving it argument ARG. */
}
DEFUN ("prog2", Fprog2, Sprog2, 2, UNEVALLED, 0,
- doc: /* Eval X, Y and BODY sequentially; value from Y.
-The value of Y is saved during the evaluation of the remaining args,
-whose values are discarded.
-usage: (prog2 X Y BODY...) */)
+ doc: /* Eval FORM1, FORM2 and BODY sequentially; 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...) */)
(args)
Lisp_Object args;
{
DEFUN ("interactive-p", Finteractive_p, Sinteractive_p, 0, 0, 0,
doc: /* Return t if the 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)
+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 Emacs is not running in batch mode (`noninteractive' is nil).
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.
+ 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.
The cleanest way 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.) */)
+`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.) */)
()
{
return interactive_p (1) ? Qt : Qnil;
DEFUN ("defvar", Fdefvar, Sdefvar, 1, UNEVALLED, 0,
- doc: /* Define SYMBOL as a variable.
+ doc: /* Define SYMBOL as a variable, and return SYMBOL.
You are not required to define a variable in order to use it,
but the definition can supply documentation and an initial value
in a way that tags can recognize.
register Lisp_Object sym, tem, tail;
sym = Fcar (args);
- if (SYMBOL_CONSTANT_P (sym))
- error ("Constant symbol `%s' specified in defvar",
- SDATA (SYMBOL_NAME (sym)));
-
tail = Fcdr (args);
if (!NILP (Fcdr (Fcdr (tail))))
error ("Too many arguments");
tem = Fdefault_boundp (sym);
if (!NILP (tail))
{
+ if (SYMBOL_CONSTANT_P (sym))
+ {
+ /* For upward compatibility, allow (defvar :foo (quote :foo)). */
+ Lisp_Object tem = Fcar (tail);
+ if (! (CONSP (tem)
+ && EQ (XCAR (tem), Qquote)
+ && CONSP (XCDR (tem))
+ && EQ (XCAR (XCDR (tem)), sym)))
+ error ("Constant symbol `%s' specified in defvar",
+ SDATA (SYMBOL_NAME (sym)));
+ }
+
if (NILP (tem))
Fset_default (sym, Feval (Fcar (tail)));
else
return sym;
}
+/* Error handler used in Fuser_variable_p. */
+static Lisp_Object
+user_variable_p_eh (ignore)
+ Lisp_Object ignore;
+{
+ return Qnil;
+}
+
DEFUN ("user-variable-p", Fuser_variable_p, Suser_variable_p, 1, 1, 0,
- doc: /* Returns t if VARIABLE is intended to be set and modified by users.
+ 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.)
-Determined by whether the first character of the documentation
-for the variable is `*' or if the variable is customizable (has a non-nil
-value of `standard-value' or of `custom-autoload' on its property list). */)
+A variable is a user variable if
+\(1) the first character of its documentation is `*', or
+\(2) it is customizable (its property list contains a non-nil value
+ of `standard-value' or `custom-autoload'), or
+\(3) it is an alias for another user variable.
+Return nil if VARIABLE is an alias and there is a loop in the
+chain of symbols. */)
(variable)
Lisp_Object variable;
{
if (!SYMBOLP (variable))
return Qnil;
- documentation = Fget (variable, Qvariable_documentation);
- if (INTEGERP (documentation) && XINT (documentation) < 0)
- return Qt;
- if (STRINGP (documentation)
- && ((unsigned char) SREF (documentation, 0) == '*'))
- return Qt;
- /* If it is (STRING . INTEGER), a negative integer means a user variable. */
- if (CONSP (documentation)
- && STRINGP (XCAR (documentation))
- && INTEGERP (XCDR (documentation))
- && XINT (XCDR (documentation)) < 0)
- return Qt;
- /* Customizable? See `custom-variable-p'. */
- if ((!NILP (Fget (variable, intern ("standard-value"))))
- || (!NILP (Fget (variable, intern ("custom-autoload")))))
- return Qt;
- return Qnil;
+ /* 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,
+ Qt, user_variable_p_eh)))
+ return Qnil;
+
+ while (1)
+ {
+ documentation = Fget (variable, Qvariable_documentation);
+ if (INTEGERP (documentation) && XINT (documentation) < 0)
+ return Qt;
+ if (STRINGP (documentation)
+ && ((unsigned char) SREF (documentation, 0) == '*'))
+ return Qt;
+ /* If it is (STRING . INTEGER), a negative integer means a user variable. */
+ if (CONSP (documentation)
+ && STRINGP (XCAR (documentation))
+ && INTEGERP (XCDR (documentation))
+ && XINT (XCDR (documentation)) < 0)
+ return Qt;
+ /* Customizable? See `custom-variable-p'. */
+ if ((!NILP (Fget (variable, intern ("standard-value"))))
+ || (!NILP (Fget (variable, intern ("custom-autoload")))))
+ return Qt;
+
+ if (!XSYMBOL (variable)->indirect_variable)
+ return Qnil;
+
+ /* An indirect variable? Let's follow the chain. */
+ variable = XSYMBOL (variable)->value;
+ }
}
\f
DEFUN ("let*", FletX, SletX, 1, UNEVALLED, 0,
return form;
QUIT;
- if (consing_since_gc > gc_cons_threshold)
+ if (consing_since_gc > gc_cons_threshold
+ && consing_since_gc > gc_relative_threshold)
{
GCPRO1 (form);
Fgarbage_collect ();
register int i;
QUIT;
- if (consing_since_gc > gc_cons_threshold)
+ if (consing_since_gc > gc_cons_threshold
+ && consing_since_gc > gc_relative_threshold)
Fgarbage_collect ();
if (++lisp_eval_depth > max_lisp_eval_depth)
val = (*XSUBR (fun)->function) (internal_args[0]);
goto done;
case 2:
- val = (*XSUBR (fun)->function) (internal_args[0],
- internal_args[1]);
+ val = (*XSUBR (fun)->function) (internal_args[0], internal_args[1]);
goto done;
case 3:
val = (*XSUBR (fun)->function) (internal_args[0], internal_args[1],
goto done;
case 4:
val = (*XSUBR (fun)->function) (internal_args[0], internal_args[1],
- internal_args[2],
- internal_args[3]);
+ internal_args[2], internal_args[3]);
goto done;
case 5:
val = (*XSUBR (fun)->function) (internal_args[0], internal_args[1],
syms_of_eval ()
{
DEFVAR_INT ("max-specpdl-size", &max_specpdl_size,
- doc: /* *Limit on number of Lisp variable bindings & unwind-protects.
+ doc: /* *Limit on number of Lisp variable bindings and `unwind-protect's.
If Lisp code tries to increase the total number past this amount,
an error is signaled.
You can safely use a value considerably larger than the default value,
Vdebug_ignored_errors = Qnil;
DEFVAR_BOOL ("debug-on-quit", &debug_on_quit,
- doc: /* *Non-nil means enter debugger if quit is signaled (C-g, for example).
-Does not apply if quit is handled by a `condition-case'.
-When you evaluate an expression interactively, this variable
-is temporarily non-nil if `eval-expression-debug-on-quit' is non-nil. */);
+ doc: /* *Non-nil means enter debugger if quit is signaled (C-g, for example).
+Does not apply if quit is handled by a `condition-case'. */);
debug_on_quit = 0;
DEFVAR_BOOL ("debug-on-next-call", &debug_on_next_call,