Merge from emacs-24, up to 2012-04-10T02:06:19Z!larsi@gnus.org
[bpt/emacs.git] / src / callint.c
index 047fbcd..c70082e 100644 (file)
@@ -1,5 +1,5 @@
 /* Call a Lisp function interactively.
-   Copyright (C) 1985-1986, 1993-1995, 1997, 2000-2011
+   Copyright (C) 1985-1986, 1993-1995, 1997, 2000-2012
                  Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
@@ -27,17 +27,19 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 #include "keyboard.h"
 #include "window.h"
 #include "keymap.h"
+#include "character.h"
 
 Lisp_Object Qminus, Qplus;
 Lisp_Object Qcall_interactively;
-Lisp_Object Qcommand_debug_status;
-Lisp_Object Qenable_recursive_minibuffers;
+static Lisp_Object Qcommand_debug_status;
+static Lisp_Object Qenable_recursive_minibuffers;
 
-Lisp_Object Qhandle_shift_selection;
+static Lisp_Object Qhandle_shift_selection;
 
 Lisp_Object Qmouse_leave_buffer_hook;
 
-Lisp_Object Qlist, Qlet, Qletx, Qsave_excursion, Qprogn, Qif, Qwhen;
+static Lisp_Object Qlist, Qlet, Qletx, Qsave_excursion, Qprogn, Qif;
+Lisp_Object Qwhen;
 static Lisp_Object preserved_fns;
 
 /* Marker used within call-interactively to refer to point.  */
@@ -76,7 +78,7 @@ c -- Character (no input method is used).
 C -- Command name: symbol with interactive function definition.
 d -- Value of point as number.  Does not do I/O.
 D -- Directory name.
-e -- Parametrized event (i.e., one that's a list) that invoked this command.
+e -- Parameterized event (i.e., one that's a list) that invoked this command.
      If used more than once, the Nth `e' returns the Nth parameterized event.
      This skips events that are integers or symbols.
 f -- Existing file name.
@@ -95,7 +97,7 @@ r -- Region: point and mark as 2 numeric args, smallest first.  Does no I/O.
 s -- Any string.  Does not inherit the current input method.
 S -- Any symbol.
 U -- Mouse up event discarded by a previous k or K argument.
-v -- Variable name: symbol that is user-variable-p.
+v -- Variable name: symbol that is `custom-variable-p'.
 x -- Lisp expression read but not evaluated.
 X -- Lisp expression read and evaluated.
 z -- Coding system.
@@ -103,9 +105,10 @@ Z -- Coding system, nil if no prefix arg.
 
 In addition, if the string begins with `*', an error is signaled if
   the buffer is read-only.
-If the string begins with `@', Emacs searches the key sequence which
- invoked the command for its first mouse click (or any other event
- which specifies a window).
+If `@' appears at the beginning of the string, and if the key sequence
+ used to invoke the command includes any mouse events, then the window
+ associated with the first of those events is selected before the
+ command is run.
 If the string begins with `^' and `shift-select-mode' is non-nil,
  Emacs first calls the function `handle-shift-selection'.
 You may use `@', `*', and `^' together.  They are processed in the
@@ -231,7 +234,7 @@ fix_command (Lisp_Object input, Lisp_Object values)
 }
 
 DEFUN ("call-interactively", Fcall_interactively, Scall_interactively, 1, 3, 0,
-       doc: /* Call FUNCTION, reading args according to its interactive calling specs.
+       doc: /* Call FUNCTION, providing args according to its interactive calling specs.
 Return the value FUNCTION returns.
 The function contains a specification of how to do the argument reading.
 In the case of user-defined functions, this is specified by placing a call
@@ -267,13 +270,10 @@ invoke it.  If KEYS is omitted or nil, the return value of
   /* If varies[i] > 0, the i'th argument shouldn't just have its value
      in this call quoted in the command history.  It should be
      recorded as a call to the function named callint_argfuns[varies[i]].  */
-  int *varies;
+  signed char *varies;
 
-  register size_t i;
-  size_t nargs;
+  ptrdiff_t i, nargs;
   int foo;
-  char prompt1[100];
-  char *tem1;
   int arg_from_tty = 0;
   struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5;
   int key_count;
@@ -292,7 +292,7 @@ invoke it.  If KEYS is omitted or nil, the return value of
   else
     {
       CHECK_VECTOR (keys);
-      key_count = XVECTOR (keys)->size;
+      key_count = ASIZE (keys);
     }
 
   /* Save this now, since use of minibuffer will clobber it. */
@@ -337,7 +337,7 @@ invoke it.  If KEYS is omitted or nil, the return value of
     {
       Lisp_Object input;
       Lisp_Object funval = Findirect_function (function, Qt);
-      i = num_input_events;
+      uintmax_t events = num_input_events;
       input = specs;
       /* Compute the arg values using the user's expression.  */
       GCPRO2 (input, filter_specs);
@@ -345,7 +345,7 @@ invoke it.  If KEYS is omitted or nil, the return value of
                     CONSP (funval) && EQ (Qclosure, XCAR (funval))
                     ? Qt : Qnil);
       UNGCPRO;
-      if (i != num_input_events || !NILP (record_flag))
+      if (events != num_input_events || !NILP (record_flag))
        {
          /* We should record this command on the command history.  */
          Lisp_Object values;
@@ -463,9 +463,14 @@ invoke it.  If KEYS is omitted or nil, the return value of
        break;
     }
 
+  if (min (MOST_POSITIVE_FIXNUM,
+          min (PTRDIFF_MAX, SIZE_MAX) / sizeof (Lisp_Object))
+      < nargs)
+    memory_full (SIZE_MAX);
+
   args = (Lisp_Object *) alloca (nargs * sizeof (Lisp_Object));
   visargs = (Lisp_Object *) alloca (nargs * sizeof (Lisp_Object));
-  varies = (int *) alloca (nargs * sizeof (int));
+  varies = (signed char *) alloca (nargs);
 
   for (i = 0; i < nargs; i++)
     {
@@ -484,13 +489,8 @@ invoke it.  If KEYS is omitted or nil, the return value of
   tem = string;
   for (i = 1; *tem; i++)
     {
-      strncpy (prompt1, tem + 1, sizeof prompt1 - 1);
-      prompt1[sizeof prompt1 - 1] = 0;
-      tem1 = strchr (prompt1, '\n');
-      if (tem1) *tem1 = 0;
-
-      visargs[0] = build_string (prompt1);
-      if (strchr (prompt1, '%'))
+      visargs[0] = make_string (tem + 1, strcspn (tem + 1, "\n"));
+      if (strchr (SSDATA (visargs[0]), '%'))
        callint_message = Fformat (i, visargs);
       else
        callint_message = visargs[0];
@@ -528,6 +528,8 @@ invoke it.  If KEYS is omitted or nil, the return value of
          message1_nolog ((char *) 0);
          /* Passing args[i] directly stimulates compiler bug */
          teml = args[i];
+         /* See bug#8479.  */
+         if (! CHARACTERP (teml)) error ("Non-character input-event");
          visargs[i] = Fchar_to_string (teml);
          break;
 
@@ -746,7 +748,7 @@ invoke it.  If KEYS is omitted or nil, the return value of
          break;
 
        case 'v':               /* Variable name: symbol that is
-                                  user-variable-p. */
+                                  custom-variable-p. */
          args[i] = Fread_variable (callint_message, Qnil);
          visargs[i] = last_minibuf_string;
          break;
@@ -785,8 +787,10 @@ invoke it.  If KEYS is omitted or nil, the return value of
             if anyone tries to define one here.  */
        case '+':
        default:
-         error ("Invalid control letter `%c' (%03o) in interactive calling string",
-                *tem, (unsigned char) *tem);
+         error ("Invalid control letter `%c' (#o%03o, #x%04x) in interactive calling string",
+                STRING_CHAR ((unsigned char *) tem),
+                (unsigned) STRING_CHAR ((unsigned char *) tem),
+                (unsigned) STRING_CHAR ((unsigned char *) tem));
        }
 
       if (varies[i] == 0)
@@ -888,41 +892,20 @@ syms_of_callint (void)
                                pure_cons (intern_c_string ("point"),
                                       pure_cons (intern_c_string ("mark"), Qnil))));
 
-  Qlist = intern_c_string ("list");
-  staticpro (&Qlist);
-  Qlet = intern_c_string ("let");
-  staticpro (&Qlet);
-  Qif = intern_c_string ("if");
-  staticpro (&Qif);
-  Qwhen = intern_c_string ("when");
-  staticpro (&Qwhen);
-  Qletx = intern_c_string ("let*");
-  staticpro (&Qletx);
-  Qsave_excursion = intern_c_string ("save-excursion");
-  staticpro (&Qsave_excursion);
-  Qprogn = intern_c_string ("progn");
-  staticpro (&Qprogn);
-
-  Qminus = intern_c_string ("-");
-  staticpro (&Qminus);
-
-  Qplus = intern_c_string ("+");
-  staticpro (&Qplus);
-
-  Qhandle_shift_selection = intern_c_string ("handle-shift-selection");
-  staticpro (&Qhandle_shift_selection);
-
-  Qcall_interactively = intern_c_string ("call-interactively");
-  staticpro (&Qcall_interactively);
-
-  Qcommand_debug_status = intern_c_string ("command-debug-status");
-  staticpro (&Qcommand_debug_status);
-
-  Qenable_recursive_minibuffers = intern_c_string ("enable-recursive-minibuffers");
-  staticpro (&Qenable_recursive_minibuffers);
-
-  Qmouse_leave_buffer_hook = intern_c_string ("mouse-leave-buffer-hook");
-  staticpro (&Qmouse_leave_buffer_hook);
+  DEFSYM (Qlist, "list");
+  DEFSYM (Qlet, "let");
+  DEFSYM (Qif, "if");
+  DEFSYM (Qwhen, "when");
+  DEFSYM (Qletx, "let*");
+  DEFSYM (Qsave_excursion, "save-excursion");
+  DEFSYM (Qprogn, "progn");
+  DEFSYM (Qminus, "-");
+  DEFSYM (Qplus, "+");
+  DEFSYM (Qhandle_shift_selection, "handle-shift-selection");
+  DEFSYM (Qcall_interactively, "call-interactively");
+  DEFSYM (Qcommand_debug_status, "command-debug-status");
+  DEFSYM (Qenable_recursive_minibuffers, "enable-recursive-minibuffers");
+  DEFSYM (Qmouse_leave_buffer_hook, "mouse-leave-buffer-hook");
 
   DEFVAR_KBOARD ("prefix-arg", Vprefix_arg,
                 doc: /* The value of the prefix argument for the next editing command.
@@ -962,7 +945,7 @@ may be set by the debugger as a reminder for itself.  */);
   Vcommand_debug_status = Qnil;
 
   DEFVAR_LISP ("mark-even-if-inactive", Vmark_even_if_inactive,
-              doc: /* *Non-nil means you can use the mark even when inactive.
+              doc: /* Non-nil means you can use the mark even when inactive.
 This option makes a difference in Transient Mark mode.
 When the option is non-nil, deactivation of the mark
 turns off region highlighting, but commands that use the mark