* lisp.h: (XVECTOR_SIZE): Remove. All uses replaced with ASIZE.
[bpt/emacs.git] / src / callint.c
index 33dee69..44d7a02 100644 (file)
@@ -1,6 +1,5 @@
 /* Call a Lisp function interactively.
-   Copyright (C) 1985, 1986, 1993, 1994, 1995, 1997, 2000, 2001, 2002,
-                 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
+   Copyright (C) 1985-1986, 1993-1995, 1997, 2000-2011
                  Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
@@ -31,14 +30,15 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 
 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.  */
@@ -119,18 +119,19 @@ usage: (interactive &optional ARGS)  */)
 
 /* Quotify EXP: if EXP is constant, return it.
    If EXP is not constant, return (quote EXP).  */
-Lisp_Object
+static Lisp_Object
 quotify_arg (register Lisp_Object exp)
 {
-  if (!INTEGERP (exp) && !STRINGP (exp)
-      && !NILP (exp) && !EQ (exp, Qt))
+  if (CONSP (exp)
+      || (SYMBOLP (exp)
+         && !NILP (exp) && !EQ (exp, Qt)))
     return Fcons (Qquote, Fcons (exp, Qnil));
 
   return exp;
 }
 
 /* Modify EXP by quotifying each element (except the first).  */
-Lisp_Object
+static Lisp_Object
 quotify_args (Lisp_Object exp)
 {
   register Lisp_Object tail;
@@ -150,12 +151,12 @@ static void
 check_mark (int for_region)
 {
   Lisp_Object tem;
-  tem = Fmarker_buffer (current_buffer->mark);
+  tem = Fmarker_buffer (BVAR (current_buffer, mark));
   if (NILP (tem) || (XBUFFER (tem) != current_buffer))
     error (for_region ? "The mark is not set now, so there is no region"
           : "The mark is not set now");
   if (!NILP (Vtransient_mark_mode) && NILP (Vmark_even_if_inactive)
-      && NILP (current_buffer->mark_active))
+      && NILP (BVAR (current_buffer, mark_active)))
     xsignal0 (Qmark_inactive);
 }
 
@@ -170,6 +171,9 @@ check_mark (int for_region)
 static void
 fix_command (Lisp_Object input, Lisp_Object values)
 {
+  /* FIXME: Instead of this ugly hack, we should provide a way for an
+     interactive spec to return an expression/function that will re-build the
+     args without user intervention.  */
   if (CONSP (input))
     {
       Lisp_Object car;
@@ -258,16 +262,17 @@ invoke it.  If KEYS is omitted or nil, the return value of
   int next_event;
 
   Lisp_Object prefix_arg;
-  unsigned char *string;
-  unsigned char *tem;
+  char *string;
+  const char *tem;
 
   /* 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;
 
-  register int i, j;
-  int count, foo;
+  register size_t i;
+  size_t nargs;
+  int foo;
   char prompt1[100];
   char *tem1;
   int arg_from_tty = 0;
@@ -281,14 +286,14 @@ invoke it.  If KEYS is omitted or nil, the return value of
   save_this_command = Vthis_command;
   save_this_original_command = Vthis_original_command;
   save_real_this_command = real_this_command;
-  save_last_command = current_kboard->Vlast_command;
+  save_last_command = KVAR (current_kboard, Vlast_command);
 
   if (NILP (keys))
     keys = this_command_keys, key_count = this_command_key_count;
   else
     {
       CHECK_VECTOR (keys);
-      key_count = XVECTOR (keys)->size;
+      key_count = ASIZE (keys);
     }
 
   /* Save this now, since use of minibuffer will clobber it. */
@@ -326,17 +331,20 @@ invoke it.  If KEYS is omitted or nil, the return value of
     {
       /* Make a copy of string so that if a GC relocates specs,
         `string' will still be valid.  */
-      string = (unsigned char *) alloca (SBYTES (specs) + 1);
-      memcpy (string, SDATA (specs), SBYTES (specs) + 1);
+      string = (char *) alloca (SBYTES (specs) + 1);
+      memcpy (string, SSDATA (specs), SBYTES (specs) + 1);
     }
   else
     {
       Lisp_Object input;
+      Lisp_Object funval = Findirect_function (function, Qt);
       i = num_input_events;
       input = specs;
       /* Compute the arg values using the user's expression.  */
       GCPRO2 (input, filter_specs);
-      specs = Feval (specs);
+      specs = Feval (specs,
+                    CONSP (funval) && EQ (Qclosure, XCAR (funval))
+                    ? Qt : Qnil);
       UNGCPRO;
       if (i != num_input_events || !NILP (record_flag))
        {
@@ -364,7 +372,7 @@ invoke it.  If KEYS is omitted or nil, the return value of
       Vthis_command = save_this_command;
       Vthis_original_command = save_this_original_command;
       real_this_command= save_real_this_command;
-      current_kboard->Vlast_command = save_last_command;
+      KVAR (current_kboard, Vlast_command) = save_last_command;
 
       temporarily_switch_to_single_kboard (NULL);
       return unbind_to (speccount, apply1 (function, specs));
@@ -386,11 +394,11 @@ invoke it.  If KEYS is omitted or nil, the return value of
       else if (*string == '*')
        {
          string++;
-         if (!NILP (current_buffer->read_only))
+         if (!NILP (BVAR (current_buffer, read_only)))
            {
              if (!NILP (record_flag))
                {
-                 unsigned char *p = string;
+                 char *p = string;
                  while (*p)
                    {
                      if (! (*p == 'r' || *p == 'p' || *p == 'P'
@@ -409,25 +417,24 @@ invoke it.  If KEYS is omitted or nil, the return value of
        string++;
       else if (*string == '@')
        {
-         Lisp_Object event, tem;
+         Lisp_Object event, w;
 
          event = (next_event < key_count
                   ? AREF (keys, next_event)
                   : Qnil);
          if (EVENT_HAS_PARAMETERS (event)
-             && (tem = XCDR (event), CONSP (tem))
-             && (tem = XCAR (tem), CONSP (tem))
-             && (tem = XCAR (tem), WINDOWP (tem)))
+             && (w = XCDR (event), CONSP (w))
+             && (w = XCAR (w), CONSP (w))
+             && (w = XCAR (w), WINDOWP (w)))
            {
-             if (MINI_WINDOW_P (XWINDOW (tem))
-                 && ! (minibuf_level > 0 && EQ (tem, minibuf_window)))
+             if (MINI_WINDOW_P (XWINDOW (w))
+                 && ! (minibuf_level > 0 && EQ (w, minibuf_window)))
                error ("Attempt to select inactive minibuffer window");
 
              /* If the current buffer wants to clean up, let it.  */
-             if (!NILP (Vmouse_leave_buffer_hook))
-               call1 (Vrun_hooks, Qmouse_leave_buffer_hook);
+              Frun_hooks (1, &Qmouse_leave_buffer_hook);
 
-             Fselect_window (tem, Qnil);
+             Fselect_window (w, Qnil);
            }
          string++;
        }
@@ -439,30 +446,29 @@ invoke it.  If KEYS is omitted or nil, the return value of
       else break;
     }
 
-  /* Count the number of arguments the interactive spec would have
-     us give to the function.  */
+  /* Count the number of arguments, which is one plus the number of arguments
+     the interactive spec would have us give to the function.  */
   tem = string;
-  for (j = 0; *tem;)
+  for (nargs = 1; *tem; )
     {
       /* 'r' specifications ("point and mark as 2 numeric args")
         produce *two* arguments.  */
       if (*tem == 'r')
-       j += 2;
+       nargs += 2;
       else
-       j++;
-      tem = (unsigned char *) strchr (tem, '\n');
+       nargs++;
+      tem = strchr (tem, '\n');
       if (tem)
        ++tem;
       else
        break;
     }
-  count = j;
 
-  args = (Lisp_Object *) alloca ((count + 1) * sizeof (Lisp_Object));
-  visargs = (Lisp_Object *) alloca ((count + 1) * sizeof (Lisp_Object));
-  varies = (int *) alloca ((count + 1) * sizeof (int));
+  args = (Lisp_Object *) alloca (nargs * sizeof (Lisp_Object));
+  visargs = (Lisp_Object *) alloca (nargs * sizeof (Lisp_Object));
+  varies = (int *) alloca (nargs * sizeof (int));
 
-  for (i = 0; i < (count + 1); i++)
+  for (i = 0; i < nargs; i++)
     {
       args[i] = Qnil;
       visargs[i] = Qnil;
@@ -470,8 +476,8 @@ invoke it.  If KEYS is omitted or nil, the return value of
     }
 
   GCPRO5 (prefix_arg, function, *args, *visargs, up_event);
-  gcpro3.nvars = (count + 1);
-  gcpro4.nvars = (count + 1);
+  gcpro3.nvars = nargs;
+  gcpro4.nvars = nargs;
 
   if (!NILP (enable))
     specbind (Qenable_recursive_minibuffers, Qt);
@@ -544,7 +550,7 @@ invoke it.  If KEYS is omitted or nil, the return value of
 
        case 'D':               /* Directory name. */
          args[i] = Fread_file_name (callint_message, Qnil,
-                                    current_buffer->directory, Qlambda, Qnil,
+                                    BVAR (current_buffer, directory), Qlambda, Qnil,
                                     Qfile_directory_p);
          break;
 
@@ -662,7 +668,7 @@ invoke it.  If KEYS is omitted or nil, the return value of
        case 'm':               /* Value of mark.  Does not do I/O.  */
          check_mark (0);
          /* visargs[i] = Qnil; */
-         args[i] = current_buffer->mark;
+         args[i] = BVAR (current_buffer, mark);
          varies[i] = 2;
          break;
 
@@ -680,7 +686,7 @@ invoke it.  If KEYS is omitted or nil, the return value of
            int first = 1;
            do
              {
-               Lisp_Object tem;
+               Lisp_Object str;
                if (! first)
                  {
                    message ("Please enter a number.");
@@ -688,13 +694,13 @@ invoke it.  If KEYS is omitted or nil, the return value of
                  }
                first = 0;
 
-               tem = Fread_from_minibuffer (callint_message,
+               str = Fread_from_minibuffer (callint_message,
                                             Qnil, Qnil, Qnil, Qnil, Qnil,
                                             Qnil);
-               if (! STRINGP (tem) || SCHARS (tem) == 0)
+               if (! STRINGP (str) || SCHARS (str) == 0)
                  args[i] = Qnil;
                else
-                 args[i] = Fread (tem);
+                 args[i] = Fread (str);
              }
            while (! NUMBERP (args[i]));
          }
@@ -718,11 +724,11 @@ invoke it.  If KEYS is omitted or nil, the return value of
          check_mark (1);
          set_marker_both (point_marker, Qnil, PT, PT_BYTE);
          /* visargs[i+1] = Qnil; */
-         foo = marker_position (current_buffer->mark);
+         foo = marker_position (BVAR (current_buffer, mark));
          /* visargs[i] = Qnil; */
-         args[i] = PT < foo ? point_marker : current_buffer->mark;
+         args[i] = PT < foo ? point_marker : BVAR (current_buffer, mark);
          varies[i] = 3;
-         args[++i] = PT > foo ? point_marker : current_buffer->mark;
+         args[++i] = PT > foo ? point_marker : BVAR (current_buffer, mark);
          varies[i] = 4;
          break;
 
@@ -781,7 +787,7 @@ invoke it.  If KEYS is omitted or nil, the return value of
        case '+':
        default:
          error ("Invalid control letter `%c' (%03o) in interactive calling string",
-                *tem, *tem);
+                *tem, (unsigned char) *tem);
        }
 
       if (varies[i] == 0)
@@ -790,9 +796,9 @@ invoke it.  If KEYS is omitted or nil, the return value of
       if (NILP (visargs[i]) && STRINGP (args[i]))
        visargs[i] = args[i];
 
-      tem = (unsigned char *) strchr (tem, '\n');
+      tem = strchr (tem, '\n');
       if (tem) tem++;
-      else tem = (unsigned char *) "";
+      else tem = "";
     }
   unbind_to (speccount, Qnil);
 
@@ -803,14 +809,14 @@ invoke it.  If KEYS is omitted or nil, the return value of
   if (arg_from_tty || !NILP (record_flag))
     {
       visargs[0] = function;
-      for (i = 1; i < count + 1; i++)
+      for (i = 1; i < nargs; i++)
        {
          if (varies[i] > 0)
            visargs[i] = Fcons (intern (callint_argfuns[varies[i]]), Qnil);
          else
            visargs[i] = quotify_arg (args[i]);
        }
-      Vcommand_history = Fcons (Flist (count + 1, visargs),
+      Vcommand_history = Fcons (Flist (nargs, visargs),
                                Vcommand_history);
       /* Don't keep command history around forever.  */
       if (INTEGERP (Vhistory_length) && XINT (Vhistory_length) > 0)
@@ -823,7 +829,7 @@ invoke it.  If KEYS is omitted or nil, the return value of
 
   /* If we used a marker to hold point, mark, or an end of the region,
      temporarily, convert it to an integer now.  */
-  for (i = 1; i <= count; i++)
+  for (i = 1; i < nargs; i++)
     if (varies[i] >= 1 && varies[i] <= 4)
       XSETINT (args[i], marker_position (args[i]));
 
@@ -833,14 +839,14 @@ invoke it.  If KEYS is omitted or nil, the return value of
   Vthis_command = save_this_command;
   Vthis_original_command = save_this_original_command;
   real_this_command= save_real_this_command;
-  current_kboard->Vlast_command = save_last_command;
+  KVAR (current_kboard, Vlast_command) = save_last_command;
 
   {
     Lisp_Object val;
     specbind (Qcommand_debug_status, Qnil);
 
     temporarily_switch_to_single_kboard (NULL);
-    val = Ffuncall (count + 1, args);
+    val = Ffuncall (nargs, args);
     UNGCPRO;
     return unbind_to (speccount, val);
   }