X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/8515044c3212ba5dd943b76cb457b1a8214f0d88..75728599a0bc6903eaa538c049d96a178ba85150:/src/eval.c diff --git a/src/eval.c b/src/eval.c index d616addde4..147e8bef2d 100644 --- a/src/eval.c +++ b/src/eval.c @@ -1,5 +1,5 @@ /* Evaluator for GNU Emacs Lisp interpreter. - Copyright (C) 1985, 86, 87, 93, 94, 95, 99, 2000 + Copyright (C) 1985, 86, 87, 93, 94, 95, 99, 2000, 2001 Free Software Foundation, Inc. This file is part of GNU Emacs. @@ -32,17 +32,17 @@ Boston, MA 02111-1307, USA. */ /* Putting it in lisp.h makes cc bomb out! */ struct backtrace - { - struct backtrace *next; - Lisp_Object *function; - Lisp_Object *args; /* Points to vector of args. */ - int nargs; /* Length of vector. +{ + struct backtrace *next; + Lisp_Object *function; + Lisp_Object *args; /* Points to vector of args. */ + int nargs; /* Length of vector. If nargs is UNEVALLED, args points to slot holding list of unevalled args */ - char evalargs; - /* Nonzero means call value of debugger when done with this operation. */ - char debug_on_exit; - }; + char evalargs; + /* Nonzero means call value of debugger when done with this operation. */ + char debug_on_exit; +}; struct backtrace *backtrace_list; @@ -64,20 +64,21 @@ struct backtrace *backtrace_list; 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; - struct byte_stack *byte_stack; - }; +{ + 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; + struct byte_stack *byte_stack; +}; struct catchtag *catchlist; @@ -88,13 +89,14 @@ int gcpro_level; Lisp_Object Qautoload, Qmacro, Qexit, Qinteractive, Qcommandp, Qdefun; Lisp_Object Qinhibit_quit, Vinhibit_quit, Vquit_flag; -Lisp_Object Qmocklisp_arguments, Vmocklisp_arguments, Qmocklisp; Lisp_Object Qand_rest, Qand_optional; Lisp_Object Qdebug_on_error; +Lisp_Object Qdeclare; /* This holds either the symbol `run-hooks' or nil. It is nil at an early stage of startup, and when Emacs is shutting down. */ + Lisp_Object Vrun_hooks; /* Non-nil means record all fset's and provide's, to be undone @@ -105,27 +107,34 @@ Lisp_Object Vrun_hooks; Lisp_Object Vautoload_queue; /* Current number of specbindings allocated in specpdl. */ + int specpdl_size; /* Pointer to beginning of specpdl. */ + struct specbinding *specpdl; /* Pointer to first unused element in specpdl. */ + struct specbinding *specpdl_ptr; /* Maximum size allowed for specpdl allocation */ -int max_specpdl_size; + +EMACS_INT max_specpdl_size; /* Depth in Lisp evaluations and function calls. */ + int lisp_eval_depth; /* Maximum allowed depth in Lisp evaluations and function calls. */ -int max_lisp_eval_depth; + +EMACS_INT max_lisp_eval_depth; /* Nonzero means enter debugger before next function call */ + int debug_on_next_call; -/* Non-zero means debuffer may continue. This is zero when the +/* Non-zero means debugger may continue. This is zero when the debugger is called during redisplay, where it might not be safe to continue the interrupted redisplay. */ @@ -133,24 +142,30 @@ int debugger_may_continue; /* List of conditions (non-nil atom means all) which cause a backtrace if an error is handled by the command loop's error handler. */ + Lisp_Object Vstack_trace_on_error; /* List of conditions (non-nil atom means all) which enter the debugger if an error is handled by the command loop's error handler. */ + Lisp_Object Vdebug_on_error; /* List of conditions and regexps specifying error messages which - do not enter the debugger even if Vdebug_on_errors says they should. */ + do not enter the debugger even if Vdebug_on_error says they should. */ + Lisp_Object Vdebug_ignored_errors; /* Non-nil means call the debugger even if the error will be handled. */ + Lisp_Object Vdebug_on_signal; /* Hook for edebug to use. */ + Lisp_Object Vsignal_hook_function; /* Nonzero means enter debugger if a quit signal is handled by the command loop's error handler. */ + int debug_on_quit; /* The value of num_nonmacro_input_events as of the last time we @@ -159,16 +174,28 @@ int debug_on_quit; know that the debugger itself has an error, and we should just signal the error instead of entering an infinite loop of debugger invocations. */ + int when_entered_debugger; Lisp_Object Vdebugger; -void specbind (), record_unwind_protect (); +/* The function from which the last `signal' was called. Set in + Fsignal. */ + +Lisp_Object Vsignaling_function; + +/* Set to non-zero while processing X events. Checked in Feval to + make sure the Lisp interpreter isn't called from a signal handler, + which is unsafe because the interpreter isn't reentrant. */ + +int handling_signal; -Lisp_Object run_hook_with_args (); +/* Function to process declarations in defmacro forms. */ -Lisp_Object funcall_lambda (); -extern Lisp_Object ml_apply (); /* Apply a mocklisp function to unevaluated argument list */ +Lisp_Object Vmacro_declaration_function; + + +static Lisp_Object funcall_lambda P_ ((Lisp_Object, int, Lisp_Object*)); void init_eval_once () @@ -214,8 +241,8 @@ call_debugger (arg) max_specpdl_size = specpdl_size + 40; #ifdef HAVE_X_WINDOWS - if (display_busy_cursor_p) - cancel_busy_cursor (); + if (display_hourglass_p) + cancel_hourglass (); #endif debug_on_next_call = 0; @@ -227,12 +254,18 @@ call_debugger (arg) redisplaying_p = 0; specbind (intern ("debugger-may-continue"), debug_while_redisplaying ? Qnil : Qt); + specbind (Qinhibit_redisplay, Qnil); + +#if 0 /* Binding this prevents execution of Lisp code during + redisplay, which necessarily leads to display problems. */ + specbind (Qinhibit_eval_during_redisplay, Qt); +#endif val = apply1 (Vdebugger, arg); /* Interrupting redisplay and resuming it later is not safe under all circumstances. So, when the debugger returns, abort the - interupted redisplay by going back to the top-level. */ + interrupted redisplay by going back to the top-level. */ if (debug_while_redisplaying) Ftop_level (); @@ -253,10 +286,11 @@ do_debug_on_call (code) The definition of `For' shows what you have to do. */ DEFUN ("or", For, Sor, 0, UNEVALLED, 0, - "Eval args until one of them yields non-nil, then return that value.\n\ -The remaining args are not evalled at all.\n\ -If all args return nil, return nil.") - (args) + doc: /* Eval args until one of them yields non-nil, then return that value. +The remaining args are not evalled at all. +If all args return nil, return nil. +usage: (or CONDITIONS ...) */) + (args) Lisp_Object args; { register Lisp_Object val; @@ -283,10 +317,11 @@ If all args return nil, return nil.") } DEFUN ("and", Fand, Sand, 0, UNEVALLED, 0, - "Eval args until one of them yields nil, then return nil.\n\ -The remaining args are not evalled at all.\n\ -If no arg yields nil, return the last arg's value.") - (args) + doc: /* Eval args until one of them yields nil, then return nil. +The remaining args are not evalled at all. +If no arg yields nil, return the last arg's value. +usage: (and CONDITIONS ...) */) + (args) Lisp_Object args; { register Lisp_Object val; @@ -313,11 +348,12 @@ If no arg yields nil, return the last arg's value.") } DEFUN ("if", Fif, Sif, 2, UNEVALLED, 0, - "If COND yields non-nil, do THEN, else do ELSE...\n\ -Returns the value of THEN or the value of the last of the ELSE's.\n\ -THEN must be one expression, but ELSE... can be zero or more expressions.\n\ -If COND yields nil, and there are no ELSE's, the value is nil.") - (args) + doc: /* If COND yields non-nil, do THEN, else do ELSE... +Returns the value of THEN or the value of the last of the ELSE's. +THEN must be one expression, but ELSE... can be zero or more expressions. +If COND yields nil, and there are no ELSE's, the value is nil. +usage: (if COND THEN ELSE...) */) + (args) Lisp_Object args; { register Lisp_Object cond; @@ -333,15 +369,16 @@ If COND yields nil, and there are no ELSE's, the value is nil.") } DEFUN ("cond", Fcond, Scond, 0, UNEVALLED, 0, - "Try each clause until one succeeds.\n\ -Each clause looks like (CONDITION BODY...). CONDITION is evaluated\n\ -and, if the value is non-nil, this clause succeeds:\n\ -then the expressions in BODY are evaluated and the last one's\n\ -value is the value of the cond-form.\n\ -If no clause succeeds, cond returns nil.\n\ -If a clause has one element, as in (CONDITION),\n\ -CONDITION's value if non-nil is returned from the cond-form.") - (args) + doc: /* Try each clause until one succeeds. +Each clause looks like (CONDITION BODY...). CONDITION is evaluated +and, if the value is non-nil, this clause succeeds: +then the expressions in BODY are evaluated and the last one's +value is the value of the cond-form. +If no clause succeeds, cond returns nil. +If a clause has one element, as in (CONDITION), +CONDITION's value if non-nil is returned from the cond-form. +usage: (cond CLAUSES...) */) + (args) Lisp_Object args; { register Lisp_Object clause, val; @@ -367,26 +404,15 @@ CONDITION's value if non-nil is returned from the cond-form.") } DEFUN ("progn", Fprogn, Sprogn, 0, UNEVALLED, 0, - "Eval BODY forms sequentially and return value of last one.") - (args) + doc: /* Eval BODY forms sequentially and return value of last one. +usage: (progn BODY ...) */) + (args) Lisp_Object args; { - register Lisp_Object val, tem; + register Lisp_Object val; Lisp_Object args_left; struct gcpro gcpro1; - /* In Mocklisp code, symbols at the front of the progn arglist - are to be bound to zero. */ - if (!EQ (Vmocklisp_arguments, Qt)) - { - val = make_number (0); - while (!NILP (args) && (tem = Fcar (args), SYMBOLP (tem))) - { - QUIT; - specbind (tem, val), args = Fcdr (args); - } - } - if (NILP(args)) return Qnil; @@ -405,10 +431,11 @@ DEFUN ("progn", Fprogn, Sprogn, 0, UNEVALLED, 0, } DEFUN ("prog1", Fprog1, Sprog1, 1, UNEVALLED, 0, - "Eval FIRST and BODY sequentially; value from FIRST.\n\ -The value of FIRST is saved during the evaluation of the remaining args,\n\ -whose values are discarded.") - (args) + doc: /* Eval FIRST and BODY sequentially; value from FIRST. +The value of FIRST is saved during the evaluation of the remaining args, +whose values are discarded. +usage: (prog1 FIRST BODY...) */) + (args) Lisp_Object args; { Lisp_Object val; @@ -438,10 +465,11 @@ whose values are discarded.") } DEFUN ("prog2", Fprog2, Sprog2, 2, UNEVALLED, 0, - "Eval X, Y and BODY sequentially; value from Y.\n\ -The value of Y is saved during the evaluation of the remaining args,\n\ -whose values are discarded.") - (args) + 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...) */) + (args) Lisp_Object args; { Lisp_Object val; @@ -473,14 +501,15 @@ whose values are discarded.") } DEFUN ("setq", Fsetq, Ssetq, 0, UNEVALLED, 0, - "Set each SYM to the value of its VAL.\n\ -The symbols SYM are variables; they are literal (not evaluated).\n\ -The values VAL are expressions; they are evaluated.\n\ -Thus, (setq x (1+ y)) sets `x' to the value of `(1+ y)'.\n\ -The second VAL is not computed until after the first SYM is set, and so on;\n\ -each VAL can use the new value of variables set earlier in the `setq'.\n\ -The return value of the `setq' form is the value of the last VAL.") - (args) + doc: /* Set each SYM to the value of its VAL. +The symbols SYM are variables; they are literal (not evaluated). +The values VAL are expressions; they are evaluated. +Thus, (setq x (1+ y)) sets `x' to the value of `(1+ y)'. +The second VAL is not computed until after the first SYM is set, and so on; +each VAL can use the new value of variables set earlier in the `setq'. +The return value of the `setq' form is the value of the last VAL. +usage: (setq SYM VAL SYM VAL ...) */) + (args) Lisp_Object args; { register Lisp_Object args_left; @@ -507,40 +536,60 @@ The return value of the `setq' form is the value of the last VAL.") } DEFUN ("quote", Fquote, Squote, 1, UNEVALLED, 0, - "Return the argument, without evaluating it. `(quote x)' yields `x'.") - (args) + doc: /* Return the argument, without evaluating it. `(quote x)' yields `x'. +usage: (quote ARG) */) + (args) Lisp_Object args; { return Fcar (args); } DEFUN ("function", Ffunction, Sfunction, 1, UNEVALLED, 0, - "Like `quote', but preferred for objects which are functions.\n\ -In byte compilation, `function' causes its argument to be compiled.\n\ -`quote' cannot do that.") - (args) + doc: /* Like `quote', but preferred for objects which are functions. +In byte compilation, `function' causes its argument to be compiled. +`quote' cannot do that. +usage: (function ARG) */) + (args) Lisp_Object args; { return Fcar (args); } + DEFUN ("interactive-p", Finteractive_p, Sinteractive_p, 0, 0, 0, - "Return t if function in which this appears was called interactively.\n\ -This means that the function was called with call-interactively (which\n\ -includes being called as the binding of a key)\n\ -and input is currently coming from the keyboard (not in keyboard macro).") - () + doc: /* Return t if function in which this appears was called interactively. +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). */) + () { - register struct backtrace *btp; - register Lisp_Object fun; + return interactive_p (1) ? Qt : Qnil; +} + + +/* Return 1 if function in which this appears was called + interactively. 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). + + EXCLUDE_SUBRS_P non-zero means always return 0 if the function + called is a built-in. */ + +int +interactive_p (exclude_subrs_p) + int exclude_subrs_p; +{ + struct backtrace *btp; + Lisp_Object fun; if (!INTERACTIVE) - return Qnil; + return 0; btp = backtrace_list; /* If this isn't a byte-compiled function, there may be a frame at - the top for Finteractive_p itself. If so, skip it. */ + the top for Finteractive_p. If so, skip it. */ fun = Findirect_function (*btp->function); if (SUBRP (fun) && XSUBR (fun) == &Sinteractive_p) btp = btp->next; @@ -564,20 +613,23 @@ and input is currently coming from the keyboard (not in keyboard macro).") Fbytecode at the top. If this frame is for a built-in function (such as load or eval-region) return nil. */ fun = Findirect_function (*btp->function); - if (SUBRP (fun)) - return Qnil; + if (exclude_subrs_p && SUBRP (fun)) + return 0; + /* btp points to the frame of a Lisp function that called interactive-p. Return t if that function was called interactively. */ if (btp && btp->next && EQ (*btp->next->function, Qcall_interactively)) - return Qt; - return Qnil; + return 1; + return 0; } + DEFUN ("defun", Fdefun, Sdefun, 2, UNEVALLED, 0, - "Define NAME as a function.\n\ -The definition is (lambda ARGLIST [DOCSTRING] BODY...).\n\ -See also the function `interactive'.") - (args) + doc: /* Define NAME as a function. +The definition is (lambda ARGLIST [DOCSTRING] BODY...). +See also the function `interactive'. +usage: (defun NAME ARGLIST [DOCSTRING] BODY...) */) + (args) Lisp_Object args; { register Lisp_Object fn_name; @@ -593,20 +645,51 @@ See also the function `interactive'.") } DEFUN ("defmacro", Fdefmacro, Sdefmacro, 2, UNEVALLED, 0, - "Define NAME as a macro.\n\ -The definition is (macro lambda ARGLIST [DOCSTRING] BODY...).\n\ -When the macro is called, as in (NAME ARGS...),\n\ -the function (lambda ARGLIST BODY...) is applied to\n\ -the list ARGS... as it appears in the expression,\n\ -and the result should be a form to be evaluated instead of the original.") - (args) + doc: /* Define NAME as a macro. +The definition is (macro lambda ARGLIST [DOCSTRING] BODY...). +When the macro is called, as in (NAME ARGS...), +the function (lambda ARGLIST BODY...) is applied to +the list ARGS... as it appears in the expression, +and the result should be a form to be evaluated instead of the original. +usage: (defmacro NAME ARGLIST [DOCSTRING] BODY...) */) + (args) Lisp_Object args; { register Lisp_Object fn_name; register Lisp_Object defn; + Lisp_Object lambda_list, doc, tail; fn_name = Fcar (args); - defn = Fcons (Qmacro, Fcons (Qlambda, Fcdr (args))); + lambda_list = Fcar (Fcdr (args)); + tail = Fcdr (Fcdr (args)); + + doc = Qnil; + if (STRINGP (Fcar (tail))) + { + doc = Fcar (tail); + tail = Fcdr (tail); + } + + while (CONSP (Fcar (tail)) + && EQ (Fcar (Fcar (tail)), Qdeclare)) + { + if (!NILP (Vmacro_declaration_function)) + { + struct gcpro gcpro1; + GCPRO1 (args); + call2 (Vmacro_declaration_function, fn_name, Fcar (tail)); + UNGCPRO; + } + + tail = Fcdr (tail); + } + + if (NILP (doc)) + tail = Fcons (lambda_list, tail); + else + tail = Fcons (lambda_list, Fcons (doc, tail)); + defn = Fcons (Qmacro, Fcons (Qlambda, tail)); + if (!NILP (Vpurify_flag)) defn = Fpurecopy (defn); Ffset (fn_name, defn); @@ -614,19 +697,49 @@ and the result should be a form to be evaluated instead of the original.") return fn_name; } + +DEFUN ("defvaralias", Fdefvaralias, Sdefvaralias, 2, 2, 0, + doc: /* Make SYMBOL a variable alias for symbol ALIASED. +Setting the value of SYMBOL will subsequently set the value of ALIASED, +and getting the value of SYMBOL will return the value ALIASED has. +ALIASED nil means remove the alias; SYMBOL is unbound after that. */) + (symbol, aliased) + Lisp_Object symbol, aliased; +{ + struct Lisp_Symbol *sym; + + CHECK_SYMBOL (symbol); + CHECK_SYMBOL (aliased); + + if (SYMBOL_CONSTANT_P (symbol)) + error ("Cannot make a constant an alias"); + + sym = XSYMBOL (symbol); + sym->indirect_variable = 1; + sym->value = aliased; + sym->constant = SYMBOL_CONSTANT_P (aliased); + LOADHIST_ATTACH (symbol); + + return aliased; +} + + DEFUN ("defvar", Fdefvar, Sdefvar, 1, UNEVALLED, 0, - "Define SYMBOL as a variable.\n\ -You are not required to define a variable in order to use it,\n\ -but the definition can supply documentation and an initial value\n\ -in a way that tags can recognize.\n\n\ -INITVALUE is evaluated, and used to set SYMBOL, only if SYMBOL's value is void.\n\ -If SYMBOL is buffer-local, its default value is what is set;\n\ - buffer-local values are not affected.\n\ -INITVALUE and DOCSTRING are optional.\n\ -If DOCSTRING starts with *, this variable is identified as a user option.\n\ - This means that M-x set-variable and M-x edit-options recognize it.\n\ -If INITVALUE is missing, SYMBOL's value is not set.") - (args) + doc: /* Define SYMBOL as a variable. +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. + +INITVALUE is evaluated, and used to set SYMBOL, only if SYMBOL's value is void. +If SYMBOL is buffer-local, its default value is what is set; + buffer-local values are not affected. +INITVALUE and DOCSTRING are optional. +If DOCSTRING starts with *, this variable is identified as a user option. + This means that M-x set-variable recognizes it. + See also `user-variable-p'. +If INITVALUE is missing, SYMBOL's value is not set. +usage: (defvar SYMBOL &optional INITVALUE DOCSTRING) */) + (args) Lisp_Object args; { register Lisp_Object sym, tem, tail; @@ -636,32 +749,40 @@ If INITVALUE is missing, SYMBOL's value is not set.") if (!NILP (Fcdr (Fcdr (tail)))) error ("too many arguments"); + tem = Fdefault_boundp (sym); if (!NILP (tail)) { - tem = Fdefault_boundp (sym); if (NILP (tem)) - Fset_default (sym, Feval (Fcar (Fcdr (args)))); - } - tail = Fcdr (Fcdr (args)); - if (!NILP (Fcar (tail))) - { - tem = Fcar (tail); - if (!NILP (Vpurify_flag)) - tem = Fpurecopy (tem); - Fput (sym, Qvariable_documentation, tem); + Fset_default (sym, Feval (Fcar (tail))); + tail = Fcdr (tail); + if (!NILP (Fcar (tail))) + { + tem = Fcar (tail); + if (!NILP (Vpurify_flag)) + tem = Fpurecopy (tem); + Fput (sym, Qvariable_documentation, tem); + } + LOADHIST_ATTACH (sym); } - LOADHIST_ATTACH (sym); + else + /* A (defvar ) should not take precedence in the load-history over + an earlier (defvar ), so only add to history if the default + value is still unbound. */ + if (NILP (tem)) + LOADHIST_ATTACH (sym); + return sym; } DEFUN ("defconst", Fdefconst, Sdefconst, 2, UNEVALLED, 0, - "Define SYMBOL as a constant variable.\n\ -The intent is that neither programs nor users should ever change this value.\n\ -Always sets the value of SYMBOL to the result of evalling INITVALUE.\n\ -If SYMBOL is buffer-local, its default value is what is set;\n\ - buffer-local values are not affected.\n\ -DOCSTRING is optional.") - (args) + doc: /* Define SYMBOL as a constant variable. +The intent is that neither programs nor users should ever change this value. +Always sets the value of SYMBOL to the result of evalling INITVALUE. +If SYMBOL is buffer-local, its default value is what is set; + buffer-local values are not affected. +DOCSTRING is optional. +usage: (defconst SYMBOL INITVALUE [DOCSTRING]) */) + (args) Lisp_Object args; { register Lisp_Object sym, tem; @@ -686,13 +807,13 @@ DOCSTRING is optional.") } DEFUN ("user-variable-p", Fuser_variable_p, Suser_variable_p, 1, 1, 0, - "Returns t if VARIABLE is intended to be set and modified by users.\n\ -\(The alternative is a variable used internally in a Lisp program.)\n\ -Determined by whether the first character of the documentation\n\ -for the variable is `*' or if the variable is customizable (has a non-nil\n\ -value of any of `custom-type', `custom-loads' or `standard-value'\n\ -on its property list).") - (variable) + doc: /* Returns 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 any of `custom-type', `custom-loads' or `standard-value' +on its property list). */) + (variable) Lisp_Object variable; { Lisp_Object documentation; @@ -721,12 +842,13 @@ on its property list).") } DEFUN ("let*", FletX, SletX, 1, UNEVALLED, 0, - "Bind variables according to VARLIST then eval BODY.\n\ -The value of the last form in BODY is returned.\n\ -Each element of VARLIST is a symbol (which is bound to nil)\n\ -or a list (SYMBOL VALUEFORM) (which binds SYMBOL to the value of VALUEFORM).\n\ -Each VALUEFORM can refer to the symbols already bound by this VARLIST.") - (args) + doc: /* Bind variables according to VARLIST then eval BODY. +The value of the last form in BODY is returned. +Each element of VARLIST is a symbol (which is bound to nil) +or a list (SYMBOL VALUEFORM) (which binds SYMBOL to the value of VALUEFORM). +Each VALUEFORM can refer to the symbols already bound by this VARLIST. +usage: (let* VARLIST BODY...) */) + (args) Lisp_Object args; { Lisp_Object varlist, val, elt; @@ -759,12 +881,13 @@ Each VALUEFORM can refer to the symbols already bound by this VARLIST.") } DEFUN ("let", Flet, Slet, 1, UNEVALLED, 0, - "Bind variables according to VARLIST then eval BODY.\n\ -The value of the last form in BODY is returned.\n\ -Each element of VARLIST is a symbol (which is bound to nil)\n\ -or a list (SYMBOL VALUEFORM) (which binds SYMBOL to the value of VALUEFORM).\n\ -All the VALUEFORMs are evalled before any symbols are bound.") - (args) + doc: /* Bind variables according to VARLIST then eval BODY. +The value of the last form in BODY is returned. +Each element of VARLIST is a symbol (which is bound to nil) +or a list (SYMBOL VALUEFORM) (which binds SYMBOL to the value of VALUEFORM). +All the VALUEFORMs are evalled before any symbols are bound. +usage: (let VARLIST BODY...) */) + (args) Lisp_Object args; { Lisp_Object *temps, tem; @@ -816,21 +939,21 @@ All the VALUEFORMs are evalled before any symbols are bound.") } DEFUN ("while", Fwhile, Swhile, 1, UNEVALLED, 0, - "If TEST yields non-nil, eval BODY... and repeat.\n\ -The order of execution is thus TEST, BODY, TEST, BODY and so on\n\ -until TEST returns nil.") - (args) + doc: /* If TEST yields non-nil, eval BODY... and repeat. +The order of execution is thus TEST, BODY, TEST, BODY and so on +until TEST returns nil. +usage: (while TEST BODY...) */) + (args) Lisp_Object args; { - Lisp_Object test, body, tem; + Lisp_Object test, body; struct gcpro gcpro1, gcpro2; GCPRO2 (test, body); test = Fcar (args); body = Fcdr (args); - while (tem = Feval (test), - (!EQ (Vmocklisp_arguments, Qt) ? XINT (tem) : !NILP (tem))) + while (!NILP (Feval (test))) { QUIT; Fprogn (body); @@ -841,13 +964,14 @@ until TEST returns nil.") } DEFUN ("macroexpand", Fmacroexpand, Smacroexpand, 1, 2, 0, - "Return result of expanding macros at top level of FORM.\n\ -If FORM is not a macro call, it is returned unchanged.\n\ -Otherwise, the macro is expanded and the expansion is considered\n\ -in place of FORM. When a non-macro-call results, it is returned.\n\n\ -The second optional arg ENVIRONMENT species an environment of macro\n\ -definitions to shadow the loaded ones for use in file byte-compilation.") - (form, environment) + doc: /* Return result of expanding macros at top level of FORM. +If FORM is not a macro call, it is returned unchanged. +Otherwise, the macro is expanded and the expansion is considered +in place of FORM. When a non-macro-call results, it is returned. + +The second optional arg ENVIRONMENT specifies an environment of macro +definitions to shadow the loaded ones for use in file byte-compilation. */) + (form, environment) Lisp_Object form; Lisp_Object environment; { @@ -919,14 +1043,15 @@ definitions to shadow the loaded ones for use in file byte-compilation.") } DEFUN ("catch", Fcatch, Scatch, 1, UNEVALLED, 0, - "Eval BODY allowing nonlocal exits using `throw'.\n\ -TAG is evalled to get the tag to use; it must not be nil.\n\ -\n\ -Then the BODY is executed.\n\ -Within BODY, (throw TAG) with same tag exits BODY and exits this `catch'.\n\ -If no throw happens, `catch' returns the value of the last BODY form.\n\ -If a throw happens, it specifies the value to return from `catch'.") - (args) + doc: /* Eval BODY allowing nonlocal exits using `throw'. +TAG is evalled to get the tag to use; it must not be nil. + +Then the BODY is executed. +Within BODY, (throw TAG) with same tag exits BODY and exits this `catch'. +If no throw happens, `catch' returns the value of the last BODY form. +If a throw happens, it specifies the value to return from `catch'. +usage: (catch TAG BODY...) */) + (args) Lisp_Object args; { register Lisp_Object tag; @@ -1029,9 +1154,9 @@ unwind_to_catch (catch, value) } DEFUN ("throw", Fthrow, Sthrow, 2, 2, 0, - "Throw to the catch for TAG and return VALUE from it.\n\ -Both TAG and VALUE are evalled.") - (tag, value) + doc: /* Throw to the catch for TAG and return VALUE from it. +Both TAG and VALUE are evalled. */) + (tag, value) register Lisp_Object tag, value; { register struct catchtag *c; @@ -1050,11 +1175,12 @@ Both TAG and VALUE are evalled.") DEFUN ("unwind-protect", Funwind_protect, Sunwind_protect, 1, UNEVALLED, 0, - "Do BODYFORM, protecting with UNWINDFORMS.\n\ -If BODYFORM completes normally, its value is returned\n\ -after executing the UNWINDFORMS.\n\ -If BODYFORM exits nonlocally, the UNWINDFORMS are executed anyway.") - (args) + doc: /* Do BODYFORM, protecting with UNWINDFORMS. +If BODYFORM completes normally, its value is returned +after executing the UNWINDFORMS. +If BODYFORM exits nonlocally, the UNWINDFORMS are executed anyway. +usage: (unwind-protect BODYFORM UNWINDFORMS...) */) + (args) Lisp_Object args; { Lisp_Object val; @@ -1074,36 +1200,39 @@ If BODYFORM exits nonlocally, the UNWINDFORMS are executed anyway.") struct handler *handlerlist; DEFUN ("condition-case", Fcondition_case, Scondition_case, 2, UNEVALLED, 0, - "Regain control when an error is signaled.\n\ -executes BODYFORM and returns its value if no error happens.\n\ -Each element of HANDLERS looks like (CONDITION-NAME BODY...)\n\ -where the BODY is made of Lisp expressions.\n\n\ -A handler is applicable to an error\n\ -if CONDITION-NAME is one of the error's condition names.\n\ -If an error happens, the first applicable handler is run.\n\ -\n\ -The car of a handler may be a list of condition names\n\ -instead of a single condition name.\n\ -\n\ -When a handler handles an error,\n\ -control returns to the condition-case and the handler BODY... is executed\n\ -with VAR bound to (SIGNALED-CONDITIONS . SIGNAL-DATA).\n\ -VAR may be nil; then you do not get access to the signal information.\n\ -\n\ -The value of the last BODY form is returned from the condition-case.\n\ -See also the function `signal' for more info.") - (args) + doc: /* Regain control when an error is signaled. +Executes BODYFORM and returns its value if no error happens. +Each element of HANDLERS looks like (CONDITION-NAME BODY...) +where the BODY is made of Lisp expressions. + +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. + +The car of a handler may be a list of condition names +instead of a single condition name. + +When a handler handles an error, +control returns to the condition-case and the handler BODY... is executed +with VAR bound to (SIGNALED-CONDITIONS . SIGNAL-DATA). +VAR may be nil; then you do not get access to the signal information. + +The value of the last BODY form is returned from the condition-case. +See also the function `signal' for more info. +usage: (condition-case VAR BODYFORM HANDLERS...) */) + (args) Lisp_Object args; { Lisp_Object val; struct catchtag c; struct handler h; - register Lisp_Object var, bodyform, handlers; + register Lisp_Object bodyform, handlers; + volatile Lisp_Object var; var = Fcar (args); bodyform = Fcar (Fcdr (args)); handlers = Fcdr (Fcdr (args)); - CHECK_SYMBOL (var, 0); + CHECK_SYMBOL (var); for (val = handlers; ! NILP (val); val = Fcdr (val)) { @@ -1172,10 +1301,14 @@ internal_condition_case (bfun, handlers, hfun) struct catchtag c; struct handler h; +#if 0 /* Can't do this check anymore because realize_basic_faces has + to BLOCK_INPUT, and can call Lisp. What's really needed is a + flag indicating that we're currently handling a signal. */ /* Since Fsignal resets this to 0, it had better be 0 now or else we have a potential bug. */ if (interrupt_input_blocked != 0) abort (); +#endif c.tag = Qnil; c.val = Qnil; @@ -1243,21 +1376,68 @@ internal_condition_case_1 (bfun, arg, handlers, hfun) handlerlist = h.next; return val; } + + +/* Like internal_condition_case but call HFUN with NARGS as first, + and ARGS as second argument. */ + +Lisp_Object +internal_condition_case_2 (bfun, nargs, args, handlers, hfun) + Lisp_Object (*bfun) (); + int nargs; + Lisp_Object *args; + Lisp_Object handlers; + Lisp_Object (*hfun) (); +{ + Lisp_Object val; + struct catchtag c; + struct handler h; + + c.tag = Qnil; + c.val = Qnil; + c.backlist = backtrace_list; + c.handlerlist = handlerlist; + c.lisp_eval_depth = lisp_eval_depth; + c.pdlcount = specpdl_ptr - specpdl; + c.poll_suppress_count = poll_suppress_count; + c.gcpro = gcprolist; + c.byte_stack = byte_stack_list; + if (_setjmp (c.jmp)) + { + return (*hfun) (c.val); + } + c.next = catchlist; + catchlist = &c; + h.handler = handlers; + h.var = Qnil; + h.next = handlerlist; + h.tag = &c; + handlerlist = &h; + + val = (*bfun) (nargs, args); + catchlist = c.next; + handlerlist = h.next; + return val; +} + -static Lisp_Object find_handler_clause (); +static Lisp_Object find_handler_clause P_ ((Lisp_Object, Lisp_Object, + Lisp_Object, Lisp_Object, + Lisp_Object *)); DEFUN ("signal", Fsignal, Ssignal, 2, 2, 0, - "Signal an error. Args are ERROR-SYMBOL and associated DATA.\n\ -This function does not return.\n\n\ -An error symbol is a symbol with an `error-conditions' property\n\ -that is a list of condition names.\n\ -A handler for any of those names will get to handle this signal.\n\ -The symbol `error' should normally be one of them.\n\ -\n\ -DATA should be a list. Its elements are printed as part of the error message.\n\ -If the signal is handled, DATA is made available to the handler.\n\ -See also the function `condition-case'.") - (error_symbol, data) + doc: /* Signal an error. Args are ERROR-SYMBOL and associated DATA. +This function does not return. + +An error symbol is a symbol with an `error-conditions' property +that is a list of condition names. +A handler for any of those names will get to handle this signal. +The symbol `error' should normally be one of them. + +DATA should be a list. Its elements are printed as part of the error message. +If the signal is handled, DATA is made available to the handler. +See also the function `condition-case'. */) + (error_symbol, data) Lisp_Object error_symbol, data; { /* When memory is full, ERROR-SYMBOL is nil, @@ -1269,9 +1449,9 @@ See also the function `condition-case'.") Lisp_Object debugger_value; Lisp_Object string; Lisp_Object real_error_symbol; - extern int display_busy_cursor_p; + struct backtrace *bp; - immediate_quit = 0; + immediate_quit = handling_signal = 0; if (gc_in_progress || waiting_for_input) abort (); @@ -1283,8 +1463,8 @@ See also the function `condition-case'.") real_error_symbol = error_symbol; #ifdef HAVE_X_WINDOWS - if (display_busy_cursor_p) - cancel_busy_cursor (); + if (display_hourglass_p) + cancel_hourglass (); #endif /* This hook is used by edebug. */ @@ -1293,6 +1473,19 @@ See also the function `condition-case'.") conditions = Fget (real_error_symbol, Qerror_conditions); + /* Remember from where signal was called. Skip over the frame for + `signal' itself. If a frame for `error' follows, skip that, + too. */ + Vsignaling_function = Qnil; + if (backtrace_list) + { + bp = backtrace_list->next; + if (bp && bp->function && EQ (*bp->function, Qerror)) + bp = bp->next; + if (bp && bp->function) + Vsignaling_function = *bp->function; + } + for (; handlerlist; handlerlist = handlerlist->next) { register Lisp_Object clause; @@ -1380,7 +1573,7 @@ wants_debugger (list, conditions) /* Return 1 if an error with condition-symbols CONDITIONS, and described by SIGNAL-DATA, should skip the debugger - according to debugger-ignore-errors. */ + according to debugger-ignored-errors. */ static int skip_debugger (conditions, data) @@ -1390,8 +1583,8 @@ skip_debugger (conditions, data) int first_string = 1; Lisp_Object error_message; - for (tail = Vdebug_ignored_errors; CONSP (tail); - tail = XCDR (tail)) + error_message = Qnil; + for (tail = Vdebug_ignored_errors; CONSP (tail); tail = XCDR (tail)) { if (STRINGP (XCAR (tail))) { @@ -1400,6 +1593,7 @@ skip_debugger (conditions, data) error_message = Ferror_message_string (data); first_string = 0; } + if (fast_string_match (XCAR (tail), error_message) >= 0) return 1; } @@ -1407,8 +1601,7 @@ skip_debugger (conditions, data) { Lisp_Object contail; - for (contail = conditions; CONSP (contail); - contail = XCDR (contail)) + for (contail = conditions; CONSP (contail); contail = XCDR (contail)) if (EQ (XCAR (tail), XCAR (contail))) return 1; } @@ -1562,25 +1755,29 @@ error (m, a1, a2, a3) string = build_string (buffer); if (allocated) - free (buffer); + xfree (buffer); Fsignal (Qerror, Fcons (string, Qnil)); + abort (); } -DEFUN ("commandp", Fcommandp, Scommandp, 1, 1, 0, - "T if FUNCTION makes provisions for interactive calling.\n\ -This means it contains a description for how to read arguments to give it.\n\ -The value is nil for an invalid function or a symbol with no function\n\ -definition.\n\ -\n\ -Interactively callable functions include strings and vectors (treated\n\ -as keyboard macros), lambda-expressions that contain a top-level call\n\ -to `interactive', autoload definitions made by `autoload' with non-nil\n\ -fourth argument, and some of the built-in functions of Lisp.\n\ -\n\ -Also, a symbol satisfies `commandp' if its function definition does so.") - (function) - Lisp_Object function; +DEFUN ("commandp", Fcommandp, Scommandp, 1, 2, 0, + doc: /* Non-nil if FUNCTION makes provisions for interactive calling. +This means it contains a description for how to read arguments to give it. +The value is nil for an invalid function or a symbol with no function +definition. + +Interactively callable functions include strings and vectors (treated +as keyboard macros), lambda-expressions that contain a top-level call +to `interactive', autoload definitions made by `autoload' with non-nil +fourth argument, and some of the built-in functions of Lisp. + +Also, a symbol satisfies `commandp' if its function definition does so. + +If the optional argument FOR-CALL-INTERACTIVELY is non-nil, +then strins and vectors are not accepted. */) + (function, for_call_interactively) + Lisp_Object function, for_call_interactively; { register Lisp_Object fun; register Lisp_Object funcar; @@ -1605,11 +1802,11 @@ Also, a symbol satisfies `commandp' if its function definition does so.") have an element whose index is COMPILED_INTERACTIVE, which is where the interactive spec is stored. */ else if (COMPILEDP (fun)) - return ((XVECTOR (fun)->size & PSEUDOVECTOR_SIZE_MASK) > COMPILED_INTERACTIVE + return ((ASIZE (fun) & PSEUDOVECTOR_SIZE_MASK) > COMPILED_INTERACTIVE ? Qt : Qnil); /* Strings and vectors are keyboard macros. */ - if (STRINGP (fun) || VECTORP (fun)) + if (NILP (for_call_interactively) && (STRINGP (fun) || VECTORP (fun))) return Qt; /* Lists may represent commands. */ @@ -1620,8 +1817,6 @@ Also, a symbol satisfies `commandp' if its function definition does so.") return Fsignal (Qinvalid_function, Fcons (fun, Qnil)); if (EQ (funcar, Qlambda)) return Fassq (Qinteractive, Fcdr (Fcdr (fun))); - if (EQ (funcar, Qmocklisp)) - return Qt; /* All mocklisp functions can be called interactively */ if (EQ (funcar, Qautoload)) return Fcar (Fcdr (Fcdr (Fcdr (fun)))); else @@ -1630,27 +1825,27 @@ Also, a symbol satisfies `commandp' if its function definition does so.") /* ARGSUSED */ DEFUN ("autoload", Fautoload, Sautoload, 2, 5, 0, - "Define FUNCTION to autoload from FILE.\n\ -FUNCTION is a symbol; FILE is a file name string to pass to `load'.\n\ -Third arg DOCSTRING is documentation for the function.\n\ -Fourth arg INTERACTIVE if non-nil says function can be called interactively.\n\ -Fifth arg TYPE indicates the type of the object:\n\ - nil or omitted says FUNCTION is a function,\n\ - `keymap' says FUNCTION is really a keymap, and\n\ - `macro' or t says FUNCTION is really a macro.\n\ -Third through fifth args give info about the real definition.\n\ -They default to nil.\n\ -If FUNCTION is already defined other than as an autoload,\n\ -this does nothing and returns nil.") - (function, file, docstring, interactive, type) + doc: /* Define FUNCTION to autoload from FILE. +FUNCTION is a symbol; FILE is a file name string to pass to `load'. +Third arg DOCSTRING is documentation for the function. +Fourth arg INTERACTIVE if non-nil says function can be called interactively. +Fifth arg TYPE indicates the type of the object: + nil or omitted says FUNCTION is a function, + `keymap' says FUNCTION is really a keymap, and + `macro' or t says FUNCTION is really a macro. +Third through fifth args give info about the real definition. +They default to nil. +If FUNCTION is already defined other than as an autoload, +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, 0); - CHECK_STRING (file, 1); + CHECK_SYMBOL (function); + CHECK_STRING (file); /* If function is defined and not as an autoload, don't override */ if (!EQ (XSYMBOL (function)->function, Qunbound) @@ -1711,8 +1906,14 @@ do_autoload (fundef, funname) Lisp_Object fun, queue, first, second; struct gcpro gcpro1, gcpro2, gcpro3; + /* This is to make sure that loadup.el gives a clear picture + of what files are preloaded and when. */ + if (! NILP (Vpurify_flag)) + error ("Attempt to autoload %s while preparing to dump", + XSYMBOL (funname)->name->data); + fun = funname; - CHECK_SYMBOL (funname, 0); + CHECK_SYMBOL (funname); GCPRO3 (fun, funname, fundef); /* Preserve the match data. */ @@ -1751,10 +1952,11 @@ do_autoload (fundef, funname) XSYMBOL (funname)->name->data); UNGCPRO; } + DEFUN ("eval", Feval, Seval, 1, 1, 0, - "Evaluate FORM and return its value.") - (form) + doc: /* Evaluate FORM and return its value. */) + (form) Lisp_Object form; { Lisp_Object fun, val, original_fun, original_args; @@ -1762,22 +1964,11 @@ DEFUN ("eval", Feval, Seval, 1, 1, 0, struct backtrace backtrace; struct gcpro gcpro1, gcpro2, gcpro3; - /* Since Fsignal resets this to 0, it had better be 0 now - or else we have a potential bug. */ - if (interrupt_input_blocked != 0) + if (handling_signal) abort (); if (SYMBOLP (form)) - { - if (EQ (Vmocklisp_arguments, Qt)) - return Fsymbol_value (form); - val = Fsymbol_value (form); - if (NILP (val)) - XSETFASTINT (val, 0); - else if (EQ (val, Qt)) - XSETFASTINT (val, 1); - return val; - } + return Fsymbol_value (form); if (!CONSP (form)) return form; @@ -1945,19 +2136,10 @@ DEFUN ("eval", Feval, Seval, 1, 1, 0, val = Feval (apply1 (Fcdr (fun), original_args)); else if (EQ (funcar, Qlambda)) val = apply_lambda (fun, original_args, 1); - else if (EQ (funcar, Qmocklisp)) - val = ml_apply (fun, original_args); else return Fsignal (Qinvalid_function, Fcons (fun, Qnil)); } done: - if (!EQ (Vmocklisp_arguments, Qt)) - { - if (NILP (val)) - XSETFASTINT (val, 0); - else if (EQ (val, Qt)) - XSETFASTINT (val, 1); - } lisp_eval_depth--; if (backtrace.debug_on_exit) val = call_debugger (Fcons (Qexit, Fcons (val, Qnil))); @@ -1966,10 +2148,11 @@ DEFUN ("eval", Feval, Seval, 1, 1, 0, } DEFUN ("apply", Fapply, Sapply, 2, MANY, 0, - "Call FUNCTION with our remaining args, using our last arg as list of args.\n\ -Then return the value FUNCTION returns.\n\ -Thus, (apply '+ 1 2 '(3 4)) returns 10.") - (nargs, args) + doc: /* Call FUNCTION with our remaining args, using our last arg as list of args. +Then return the value FUNCTION returns. +Thus, (apply '+ 1 2 '(3 4)) returns 10. +usage: (apply FUNCTION &rest ARGUMENTS) */) + (nargs, args) int nargs; Lisp_Object *args; { @@ -1982,7 +2165,7 @@ Thus, (apply '+ 1 2 '(3 4)) returns 10.") fun = args [0]; funcall_args = 0; spread_arg = args [nargs - 1]; - CHECK_LIST (spread_arg, nargs); + CHECK_LIST (spread_arg); numargs = XINT (Flength (spread_arg)); @@ -2048,19 +2231,22 @@ Thus, (apply '+ 1 2 '(3 4)) returns 10.") /* Run hook variables in various ways. */ enum run_hooks_condition {to_completion, until_success, until_failure}; - -DEFUN ("run-hooks", Frun_hooks, Srun_hooks, 1, MANY, 0, - "Run each hook in HOOKS. Major mode functions use this.\n\ -Each argument should be a symbol, a hook variable.\n\ -These symbols are processed in the order specified.\n\ -If a hook symbol has a non-nil value, that value may be a function\n\ -or a list of functions to be called to run the hook.\n\ -If the value is a function, it is called with no arguments.\n\ -If it is a list, the elements are called, in order, with no arguments.\n\ -\n\ -To make a hook variable buffer-local, use `make-local-hook',\n\ -not `make-local-variable'.") - (nargs, args) +static Lisp_Object run_hook_with_args P_ ((int, Lisp_Object *, + enum run_hooks_condition)); + +DEFUN ("run-hooks", Frun_hooks, Srun_hooks, 0, MANY, 0, + doc: /* Run each hook in HOOKS. Major mode functions use this. +Each argument should be a symbol, a hook variable. +These symbols are processed in the order specified. +If a hook symbol has a non-nil value, that value may be a function +or a list of functions to be called to run the hook. +If the value is a function, it is called with no arguments. +If it is a list, the elements are called, in order, with no arguments. + +Do not use `make-local-variable' to make a hook variable buffer-local. +Instead, use `add-hook' and specify t for the LOCAL argument. +usage: (run-hooks &rest HOOKS) */) + (nargs, args) int nargs; Lisp_Object *args; { @@ -2077,20 +2263,21 @@ not `make-local-variable'.") } DEFUN ("run-hook-with-args", Frun_hook_with_args, - Srun_hook_with_args, 1, MANY, 0, - "Run HOOK with the specified arguments ARGS.\n\ -HOOK should be a symbol, a hook variable. If HOOK has a non-nil\n\ -value, that value may be a function or a list of functions to be\n\ -called to run the hook. If the value is a function, it is called with\n\ -the given arguments and its return value is returned. If it is a list\n\ -of functions, those functions are called, in order,\n\ -with the given arguments ARGS.\n\ -It is best not to depend on the value return by `run-hook-with-args',\n\ -as that may change.\n\ -\n\ -To make a hook variable buffer-local, use `make-local-hook',\n\ -not `make-local-variable'.") - (nargs, args) + Srun_hook_with_args, 1, MANY, 0, + doc: /* Run HOOK with the specified arguments ARGS. +HOOK should be a symbol, a hook variable. If HOOK has a non-nil +value, that value may be a function or a list of functions to be +called to run the hook. If the value is a function, it is called with +the given arguments and its return value is returned. If it is a list +of functions, those functions are called, in order, +with the given arguments ARGS. +It is best not to depend on the value return by `run-hook-with-args', +as that may change. + +Do not use `make-local-variable' to make a hook variable buffer-local. +Instead, use `add-hook' and specify t for the LOCAL argument. +usage: (run-hook-with-args HOOK &rest ARGS) */) + (nargs, args) int nargs; Lisp_Object *args; { @@ -2098,17 +2285,18 @@ not `make-local-variable'.") } DEFUN ("run-hook-with-args-until-success", Frun_hook_with_args_until_success, - Srun_hook_with_args_until_success, 1, MANY, 0, - "Run HOOK with the specified arguments ARGS.\n\ -HOOK should be a symbol, a hook variable. Its value should\n\ -be a list of functions. We call those functions, one by one,\n\ -passing arguments ARGS to each of them, until one of them\n\ -returns a non-nil value. Then we return that value.\n\ -If all the functions return nil, we return nil.\n\ -\n\ -To make a hook variable buffer-local, use `make-local-hook',\n\ -not `make-local-variable'.") - (nargs, args) + Srun_hook_with_args_until_success, 1, MANY, 0, + doc: /* Run HOOK with the specified arguments ARGS. +HOOK should be a symbol, a hook variable. Its value should +be a list of functions. We call those functions, one by one, +passing arguments ARGS to each of them, until one of them +returns a non-nil value. Then we return that value. +If all the functions return nil, we return nil. + +Do not use `make-local-variable' to make a hook variable buffer-local. +Instead, use `add-hook' and specify t for the LOCAL argument. +usage: (run-hook-with-args-until-success HOOK &rest ARGS) */) + (nargs, args) int nargs; Lisp_Object *args; { @@ -2116,17 +2304,18 @@ not `make-local-variable'.") } DEFUN ("run-hook-with-args-until-failure", Frun_hook_with_args_until_failure, - Srun_hook_with_args_until_failure, 1, MANY, 0, - "Run HOOK with the specified arguments ARGS.\n\ -HOOK should be a symbol, a hook variable. Its value should\n\ -be a list of functions. We call those functions, one by one,\n\ -passing arguments ARGS to each of them, until one of them\n\ -returns nil. Then we return nil.\n\ -If all the functions return non-nil, we return non-nil.\n\ -\n\ -To make a hook variable buffer-local, use `make-local-hook',\n\ -not `make-local-variable'.") - (nargs, args) + Srun_hook_with_args_until_failure, 1, MANY, 0, + doc: /* Run HOOK with the specified arguments ARGS. +HOOK should be a symbol, a hook variable. Its value should +be a list of functions. We call those functions, one by one, +passing arguments ARGS to each of them, until one of them +returns nil. Then we return nil. +If all the functions return non-nil, we return non-nil. + +Do not use `make-local-variable' to make a hook variable buffer-local. +Instead, use `add-hook' and specify t for the LOCAL argument. +usage: (run-hook-with-args-until-failure HOOK &rest ARGS) */) + (nargs, args) int nargs; Lisp_Object *args; { @@ -2141,7 +2330,7 @@ not `make-local-variable'.") The caller (or its caller, etc) must gcpro all of ARGS, except that it isn't necessary to gcpro ARGS[0]. */ -Lisp_Object +static Lisp_Object run_hook_with_args (nargs, args, cond) int nargs; Lisp_Object *args; @@ -2450,10 +2639,11 @@ call6 (fn, arg1, arg2, arg3, arg4, arg5, arg6) } DEFUN ("funcall", Ffuncall, Sfuncall, 1, MANY, 0, - "Call first argument as a function, passing remaining arguments to it.\n\ -Return the value that function returns.\n\ -Thus, (funcall 'cons 'x 'y) returns (x . y).") - (nargs, args) + doc: /* Call first argument as a function, passing remaining arguments to it. +Return the value that function returns. +Thus, (funcall 'cons 'x 'y) returns (x . y). +usage: (funcall FUNCTION &rest ARGUMENTS) */) + (nargs, args) int nargs; Lisp_Object *args; { @@ -2586,8 +2776,6 @@ Thus, (funcall 'cons 'x 'y) returns (x . y).") return Fsignal (Qinvalid_function, Fcons (fun, Qnil)); if (EQ (funcar, Qlambda)) val = funcall_lambda (fun, numargs, args + 1); - else if (EQ (funcar, Qmocklisp)) - val = ml_apply (fun, Flist (numargs, args + 1)); else if (EQ (funcar, Qautoload)) { do_autoload (fun, args[0]); @@ -2653,7 +2841,7 @@ apply_lambda (fun, args, eval_flag) and return the result of evaluation. FUN must be either a lambda-expression or a compiled-code object. */ -Lisp_Object +static Lisp_Object funcall_lambda (fun, nargs, arg_vector) Lisp_Object fun; int nargs; @@ -2663,9 +2851,6 @@ funcall_lambda (fun, nargs, arg_vector) int count = specpdl_ptr - specpdl; int i, optional, rest; - if (NILP (Vmocklisp_arguments)) - specbind (Qmocklisp_arguments, Qt); /* t means NOT mocklisp! */ - if (CONSP (fun)) { syms_left = XCDR (fun); @@ -2675,7 +2860,7 @@ funcall_lambda (fun, nargs, arg_vector) return Fsignal (Qinvalid_function, Fcons (fun, Qnil)); } else if (COMPILEDP (fun)) - syms_left = XVECTOR (fun)->contents[COMPILED_ARGLIST]; + syms_left = AREF (fun, COMPILED_ARGLIST); else abort (); @@ -2718,32 +2903,37 @@ funcall_lambda (fun, nargs, arg_vector) { /* If we have not actually read the bytecode string and constants vector yet, fetch them from the file. */ - if (CONSP (XVECTOR (fun)->contents[COMPILED_BYTECODE])) + if (CONSP (AREF (fun, COMPILED_BYTECODE))) Ffetch_bytecode (fun); - val = Fbyte_code (XVECTOR (fun)->contents[COMPILED_BYTECODE], - XVECTOR (fun)->contents[COMPILED_CONSTANTS], - XVECTOR (fun)->contents[COMPILED_STACK_DEPTH]); + val = Fbyte_code (AREF (fun, COMPILED_BYTECODE), + AREF (fun, COMPILED_CONSTANTS), + AREF (fun, COMPILED_STACK_DEPTH)); } return unbind_to (count, val); } DEFUN ("fetch-bytecode", Ffetch_bytecode, Sfetch_bytecode, - 1, 1, 0, - "If byte-compiled OBJECT is lazy-loaded, fetch it now.") - (object) + 1, 1, 0, + doc: /* If byte-compiled OBJECT is lazy-loaded, fetch it now. */) + (object) Lisp_Object object; { Lisp_Object tem; - if (COMPILEDP (object) - && CONSP (XVECTOR (object)->contents[COMPILED_BYTECODE])) + if (COMPILEDP (object) && CONSP (AREF (object, COMPILED_BYTECODE))) { - tem = read_doc_string (XVECTOR (object)->contents[COMPILED_BYTECODE]); + tem = read_doc_string (AREF (object, COMPILED_BYTECODE)); if (!CONSP (tem)) - error ("invalid byte code"); - XVECTOR (object)->contents[COMPILED_BYTECODE] = XCAR (tem); - XVECTOR (object)->contents[COMPILED_CONSTANTS] = XCDR (tem); + { + tem = AREF (object, COMPILED_BYTECODE); + if (CONSP (tem) && STRINGP (XCAR (tem))) + error ("Invalid byte code in %s", XSTRING (XCAR (tem))->data); + else + error ("Invalid byte code"); + } + AREF (object, COMPILED_BYTECODE) = XCAR (tem); + AREF (object, COMPILED_CONSTANTS) = XCDR (tem); } return object; } @@ -2777,54 +2967,75 @@ specbind (symbol, value) Lisp_Object symbol, value; { Lisp_Object ovalue; + Lisp_Object valcontents; - CHECK_SYMBOL (symbol, 0); + CHECK_SYMBOL (symbol); if (specpdl_ptr == specpdl + specpdl_size) grow_specpdl (); - /* The most common case is that a non-constant symbol with a trivial - value. Make that as fast as we can. */ - if (!MISCP (XSYMBOL (symbol)->value) - && !EQ (symbol, Qnil) - && !EQ (symbol, Qt) - && !(XSYMBOL (symbol)->name->data[0] == ':' - && EQ (XSYMBOL (symbol)->obarray, initial_obarray) - && !EQ (value, symbol))) + /* The most common case is that of a non-constant symbol with a + trivial value. Make that as fast as we can. */ + valcontents = SYMBOL_VALUE (symbol); + if (!MISCP (valcontents) && !SYMBOL_CONSTANT_P (symbol)) { specpdl_ptr->symbol = symbol; - specpdl_ptr->old_value = XSYMBOL (symbol)->value; + specpdl_ptr->old_value = valcontents; specpdl_ptr->func = NULL; ++specpdl_ptr; - XSYMBOL (symbol)->value = value; + SET_SYMBOL_VALUE (symbol, value); } else { + Lisp_Object valcontents; + ovalue = find_symbol_value (symbol); specpdl_ptr->func = 0; specpdl_ptr->old_value = ovalue; - if (BUFFER_LOCAL_VALUEP (XSYMBOL (symbol)->value) - || SOME_BUFFER_LOCAL_VALUEP (XSYMBOL (symbol)->value) - || BUFFER_OBJFWDP (XSYMBOL (symbol)->value)) + valcontents = XSYMBOL (symbol)->value; + + if (BUFFER_LOCAL_VALUEP (valcontents) + || SOME_BUFFER_LOCAL_VALUEP (valcontents) + || BUFFER_OBJFWDP (valcontents)) { - Lisp_Object current_buffer, binding_buffer; - /* For a local variable, record both the symbol and which - buffer's value we are saving. */ + Lisp_Object where, current_buffer; + current_buffer = Fcurrent_buffer (); - binding_buffer = current_buffer; - /* If the variable is not local in this buffer, - we are saving the global value, so restore that. */ - if (NILP (Flocal_variable_p (symbol, binding_buffer))) - binding_buffer = Qnil; - specpdl_ptr->symbol - = Fcons (symbol, Fcons (binding_buffer, current_buffer)); + + /* For a local variable, record both the symbol and which + buffer's or frame's value we are saving. */ + if (!NILP (Flocal_variable_p (symbol, Qnil))) + where = current_buffer; + else if (!BUFFER_OBJFWDP (valcontents) + && XBUFFER_LOCAL_VALUE (valcontents)->found_for_frame) + where = XBUFFER_LOCAL_VALUE (valcontents)->frame; + else + where = Qnil; + + /* We're not using the `unused' slot in the specbinding + structure because this would mean we have to do more + work for simple variables. */ + specpdl_ptr->symbol = Fcons (symbol, Fcons (where, current_buffer)); + + /* If SYMBOL is a per-buffer variable which doesn't have a + buffer-local value here, make the `let' change the global + value by changing the value of SYMBOL in all buffers not + having their own value. This is consistent with what + happens with other buffer-local variables. */ + if (NILP (where) + && BUFFER_OBJFWDP (valcontents)) + { + ++specpdl_ptr; + Fset_default (symbol, value); + return; + } } else specpdl_ptr->symbol = symbol; specpdl_ptr++; if (BUFFER_OBJFWDP (ovalue) || KBOARD_OBJFWDP (ovalue)) - store_symval_forwarding (symbol, ovalue, value); + store_symval_forwarding (symbol, ovalue, value, NULL); else set_internal (symbol, value, 0, 1); } @@ -2857,38 +3068,41 @@ unbind_to (count, value) while (specpdl_ptr != specpdl + count) { --specpdl_ptr; - + if (specpdl_ptr->func != 0) (*specpdl_ptr->func) (specpdl_ptr->old_value); /* Note that a "binding" of nil is really an unwind protect, so in that case the "old value" is a list of forms to evaluate. */ else if (NILP (specpdl_ptr->symbol)) Fprogn (specpdl_ptr->old_value); - /* If the symbol is a list, it is really - (SYMBOL BINDING_BUFFER . CURRENT_BUFFER) - and it indicates we bound a variable that has - buffer-local bindings. */ + /* If the symbol is a list, it is really (SYMBOL WHERE + . CURRENT-BUFFER) where WHERE is either nil, a buffer, or a + frame. If WHERE is a buffer or frame, this indicates we + bound a variable that had a buffer-local or frame-local + binding. WHERE nil means that the variable had the default + value when it was bound. CURRENT-BUFFER is the buffer that + was current when the variable was bound. */ else if (CONSP (specpdl_ptr->symbol)) { - Lisp_Object symbol, buffer; + Lisp_Object symbol, where; symbol = XCAR (specpdl_ptr->symbol); - buffer = XCAR (XCDR (specpdl_ptr->symbol)); + where = XCAR (XCDR (specpdl_ptr->symbol)); - /* Handle restoring a default value. */ - if (NILP (buffer)) + if (NILP (where)) Fset_default (symbol, specpdl_ptr->old_value); - /* Handle restoring a value saved from a live buffer. */ - else - set_internal (symbol, specpdl_ptr->old_value, XBUFFER (buffer), 1); + else if (BUFFERP (where)) + set_internal (symbol, specpdl_ptr->old_value, XBUFFER (where), 1); + else + set_internal (symbol, specpdl_ptr->old_value, NULL, 1); } else { /* If variable has a trivial value (no forwarding), we can just set it. No need to check for constant symbols here, since that was already done by specbind. */ - if (!MISCP (XSYMBOL (specpdl_ptr->symbol)->value)) - XSYMBOL (specpdl_ptr->symbol)->value = specpdl_ptr->old_value; + if (!MISCP (SYMBOL_VALUE (specpdl_ptr->symbol))) + SET_SYMBOL_VALUE (specpdl_ptr->symbol, specpdl_ptr->old_value); else set_internal (specpdl_ptr->symbol, specpdl_ptr->old_value, 0, 1); } @@ -2901,56 +3115,16 @@ unbind_to (count, value) return value; } -#if 0 - -/* Get the value of symbol's global binding, even if that binding - is not now dynamically visible. */ - -Lisp_Object -top_level_value (symbol) - Lisp_Object symbol; -{ - register struct specbinding *ptr = specpdl; - - CHECK_SYMBOL (symbol, 0); - for (; ptr != specpdl_ptr; ptr++) - { - if (EQ (ptr->symbol, symbol)) - return ptr->old_value; - } - return Fsymbol_value (symbol); -} - -Lisp_Object -top_level_set (symbol, newval) - Lisp_Object symbol, newval; -{ - register struct specbinding *ptr = specpdl; - - CHECK_SYMBOL (symbol, 0); - for (; ptr != specpdl_ptr; ptr++) - { - if (EQ (ptr->symbol, symbol)) - { - ptr->old_value = newval; - return newval; - } - } - return Fset (symbol, newval); -} - -#endif /* 0 */ - DEFUN ("backtrace-debug", Fbacktrace_debug, Sbacktrace_debug, 2, 2, 0, - "Set the debug-on-exit flag of eval frame LEVEL levels down to FLAG.\n\ -The debugger is entered when that frame exits, if the flag is non-nil.") - (level, flag) + doc: /* Set the debug-on-exit flag of eval frame LEVEL levels down to FLAG. +The debugger is entered when that frame exits, if the flag is non-nil. */) + (level, flag) Lisp_Object level, flag; { register struct backtrace *backlist = backtrace_list; register int i; - CHECK_NUMBER (level, 0); + CHECK_NUMBER (level); for (i = 0; backlist && i < XINT (level); i++) { @@ -2964,9 +3138,9 @@ The debugger is entered when that frame exits, if the flag is non-nil.") } DEFUN ("backtrace", Fbacktrace, Sbacktrace, 0, 0, "", - "Print a trace of Lisp function calls currently active.\n\ -Output stream used is value of `standard-output'.") - () + doc: /* Print a trace of Lisp function calls currently active. +Output stream used is value of `standard-output'. */) + () { register struct backtrace *backlist = backtrace_list; register int i; @@ -3021,24 +3195,24 @@ Output stream used is value of `standard-output'.") return Qnil; } -DEFUN ("backtrace-frame", Fbacktrace_frame, Sbacktrace_frame, 1, 1, "", - "Return the function and arguments NFRAMES up from current execution point.\n\ -If that frame has not evaluated the arguments yet (or is a special form),\n\ -the value is (nil FUNCTION ARG-FORMS...).\n\ -If that frame has evaluated its arguments and called its function already,\n\ -the value is (t FUNCTION ARG-VALUES...).\n\ -A &rest arg is represented as the tail of the list ARG-VALUES.\n\ -FUNCTION is whatever was supplied as car of evaluated list,\n\ -or a lambda expression for macro calls.\n\ -If NFRAMES is more than the number of frames, the value is nil.") - (nframes) +DEFUN ("backtrace-frame", Fbacktrace_frame, Sbacktrace_frame, 1, 1, NULL, + doc: /* Return the function and arguments NFRAMES up from current execution point. +If that frame has not evaluated the arguments yet (or is a special form), +the value is (nil FUNCTION ARG-FORMS...). +If that frame has evaluated its arguments and called its function already, +the value is (t FUNCTION ARG-VALUES...). +A &rest arg is represented as the tail of the list ARG-VALUES. +FUNCTION is whatever was supplied as car of evaluated list, +or a lambda expression for macro calls. +If NFRAMES is more than the number of frames, the value is nil. */) + (nframes) Lisp_Object nframes; { register struct backtrace *backlist = backtrace_list; register int i; Lisp_Object tem; - CHECK_NATNUM (nframes, 0); + CHECK_NATNUM (nframes); /* Find the frame requested. */ for (i = 0; backlist && i < XFASTINT (nframes); i++) @@ -3058,33 +3232,34 @@ If NFRAMES is more than the number of frames, the value is nil.") return Fcons (Qt, Fcons (*backlist->function, tem)); } } + void syms_of_eval () { DEFVAR_INT ("max-specpdl-size", &max_specpdl_size, - "*Limit on number of Lisp variable bindings & unwind-protects.\n\ -If Lisp code tries to make more than this many at once,\n\ -an error is signaled."); + doc: /* *Limit on number of Lisp variable bindings & unwind-protects. +If Lisp code tries to make more than this many at once, +an error is signaled. */); DEFVAR_INT ("max-lisp-eval-depth", &max_lisp_eval_depth, - "*Limit on depth in `eval', `apply' and `funcall' before error.\n\ -This limit is to catch infinite recursions for you before they cause\n\ -actual stack overflow in C, which would be fatal for Emacs.\n\ -You can safely make it considerably larger than its default value,\n\ -if that proves inconveniently small."); + doc: /* *Limit on depth in `eval', `apply' and `funcall' before error. +This limit is to catch infinite recursions for you before they cause +actual stack overflow in C, which would be fatal for Emacs. +You can safely make it considerably larger than its default value, +if that proves inconveniently small. */); DEFVAR_LISP ("quit-flag", &Vquit_flag, - "Non-nil causes `eval' to abort, unless `inhibit-quit' is non-nil.\n\ -Typing C-g sets `quit-flag' non-nil, regardless of `inhibit-quit'."); + doc: /* Non-nil causes `eval' to abort, unless `inhibit-quit' is non-nil. +Typing C-g sets `quit-flag' non-nil, regardless of `inhibit-quit'. */); Vquit_flag = Qnil; DEFVAR_LISP ("inhibit-quit", &Vinhibit_quit, - "Non-nil inhibits C-g quitting from happening immediately.\n\ -Note that `quit-flag' will still be set by typing C-g,\n\ -so a quit will be signaled as soon as `inhibit-quit' is nil.\n\ -To prevent this happening, set `quit-flag' to nil\n\ -before making `inhibit-quit' nil."); + doc: /* Non-nil inhibits C-g quitting from happening immediately. +Note that `quit-flag' will still be set by typing C-g, +so a quit will be signaled as soon as `inhibit-quit' is nil. +To prevent this happening, set `quit-flag' to nil +before making `inhibit-quit' nil. */); Vinhibit_quit = Qnil; Qinhibit_quit = intern ("inhibit-quit"); @@ -3099,6 +3274,9 @@ before making `inhibit-quit' nil."); Qmacro = intern ("macro"); staticpro (&Qmacro); + Qdeclare = intern ("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"); @@ -3120,75 +3298,85 @@ before making `inhibit-quit' nil."); staticpro (&Qand_optional); DEFVAR_LISP ("stack-trace-on-error", &Vstack_trace_on_error, - "*Non-nil means automatically display a backtrace buffer\n\ -after any error that is handled by the editor command loop.\n\ -If the value is a list, an error only means to display a backtrace\n\ -if one of its condition symbols appears in the list."); + doc: /* *Non-nil means errors display a backtrace buffer. +More precisely, this happens for any error that is handled +by the editor command loop. +If the value is a list, an error only means to display a backtrace +if one of its condition symbols appears in the list. */); Vstack_trace_on_error = Qnil; DEFVAR_LISP ("debug-on-error", &Vdebug_on_error, - "*Non-nil means enter debugger if an error is signaled.\n\ -Does not apply to errors handled by `condition-case'.\n\ -If the value is a list, an error only means to enter the debugger\n\ -if one of its condition symbols appears in the list.\n\ -See also variable `debug-on-quit'."); + doc: /* *Non-nil means enter debugger if an error is signaled. +Does not apply to errors handled by `condition-case' or those +matched by `debug-ignored-errors'. +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'. */); Vdebug_on_error = Qnil; DEFVAR_LISP ("debug-ignored-errors", &Vdebug_ignored_errors, - "*List of errors for which the debugger should not be called.\n\ -Each element may be a condition-name or a regexp that matches error messages.\n\ -If any element applies to a given error, that error skips the debugger\n\ -and just returns to top level.\n\ -This overrides the variable `debug-on-error'.\n\ -It does not apply to errors handled by `condition-case'."); + doc: /* *List of errors for which the debugger should not be called. +Each element may be a condition-name or a regexp that matches error messages. +If any element applies to a given error, that error skips the debugger +and just returns to top level. +This overrides the variable `debug-on-error'. +It does not apply to errors handled by `condition-case'. */); Vdebug_ignored_errors = Qnil; DEFVAR_BOOL ("debug-on-quit", &debug_on_quit, - "*Non-nil means enter debugger if quit is signaled (C-g, for example).\n\ -Does not apply if quit is handled by a `condition-case'."); + 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. */); debug_on_quit = 0; DEFVAR_BOOL ("debug-on-next-call", &debug_on_next_call, - "Non-nil means enter debugger before next `eval', `apply' or `funcall'."); + doc: /* Non-nil means enter debugger before next `eval', `apply' or `funcall'. */); DEFVAR_BOOL ("debugger-may-continue", &debugger_may_continue, - "Non-nil means debugger may continue execution.\n\ -This is nil when the debugger is called under circumstances where it\n\ -might not be safe to continue."); + doc: /* Non-nil means debugger may continue execution. +This is nil when the debugger is called under circumstances where it +might not be safe to continue. */); debugger_may_continue = 1; DEFVAR_LISP ("debugger", &Vdebugger, - "Function to call to invoke debugger.\n\ -If due to frame exit, args are `exit' and the value being returned;\n\ - this function's value will be returned instead of that.\n\ -If due to error, args are `error' and a list of the args to `signal'.\n\ -If due to `apply' or `funcall' entry, one arg, `lambda'.\n\ -If due to `eval' entry, one arg, t."); + doc: /* Function to call to invoke debugger. +If due to frame exit, args are `exit' and the value being returned; + this function's value will be returned instead of that. +If due to error, args are `error' and a list of the args to `signal'. +If due to `apply' or `funcall' entry, one arg, `lambda'. +If due to `eval' entry, one arg, t. */); Vdebugger = Qnil; DEFVAR_LISP ("signal-hook-function", &Vsignal_hook_function, - "If non-nil, this is a function for `signal' to call.\n\ -It receives the same arguments that `signal' was given.\n\ -The Edebug package uses this to regain control."); + doc: /* If non-nil, this is a function for `signal' to call. +It receives the same arguments that `signal' was given. +The Edebug package uses this to regain control. */); Vsignal_hook_function = Qnil; - Qmocklisp_arguments = intern ("mocklisp-arguments"); - staticpro (&Qmocklisp_arguments); - DEFVAR_LISP ("mocklisp-arguments", &Vmocklisp_arguments, - "While in a mocklisp function, the list of its unevaluated args."); - Vmocklisp_arguments = Qt; - DEFVAR_LISP ("debug-on-signal", &Vdebug_on_signal, - "*Non-nil means call the debugger regardless of condition handlers.\n\ -Note that `debug-on-error', `debug-on-quit' and friends\n\ -still determine whether to handle the particular condition."); + doc: /* *Non-nil means call the debugger regardless of condition handlers. +Note that `debug-on-error', `debug-on-quit' and friends +still determine whether to handle the particular condition. */); Vdebug_on_signal = Qnil; + DEFVAR_LISP ("macro-declaration-function", &Vmacro_declaration_function, + doc: /* Function to process declarations in a macro definition. +The function will be called with two args MACRO and DECL. +MACRO is the name of the macro being defined. +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"); staticpro (&Vrun_hooks); staticpro (&Vautoload_queue); Vautoload_queue = Qnil; + staticpro (&Vsignaling_function); + Vsignaling_function = Qnil; defsubr (&Sor); defsubr (&Sand); @@ -3203,6 +3391,7 @@ still determine whether to handle the particular condition."); defsubr (&Sdefun); defsubr (&Sdefmacro); defsubr (&Sdefvar); + defsubr (&Sdefvaralias); defsubr (&Sdefconst); defsubr (&Suser_variable_p); defsubr (&Slet);