Trailing whitespace deleted.
[bpt/emacs.git] / src / callint.c
index d172c11..4552b22 100644 (file)
@@ -51,7 +51,7 @@ Lisp_Object Vmark_even_if_inactive;
 
 Lisp_Object Vmouse_leave_buffer_hook, Qmouse_leave_buffer_hook;
 
-Lisp_Object Qlist, Qlet, Qletx, Qsave_excursion;
+Lisp_Object Qlist, Qlet, Qletx, Qsave_excursion, Qprogn;
 static Lisp_Object preserved_fns;
 
 /* Marker used within call-interactively to refer to point.  */
@@ -196,9 +196,10 @@ supply if the command inquires which events were used to invoke it.  */)
   Lisp_Object fun;
   Lisp_Object funcar;
   Lisp_Object specs;
+  Lisp_Object filter_specs;
   Lisp_Object teml;
   Lisp_Object enable;
-  int speccount = specpdl_ptr - specpdl;
+  int speccount = SPECPDL_INDEX ();
 
   /* The index of the next element of this_command_keys to examine for
      the 'e' interactive code.  */
@@ -220,6 +221,7 @@ supply if the command inquires which events were used to invoke it.  */)
   int arg_from_tty = 0;
   struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
   int key_count;
+  int record_then_fail = 0;
 
   if (NILP (keys))
     keys = this_command_keys, key_count = this_command_key_count;
@@ -243,6 +245,10 @@ supply if the command inquires which events were used to invoke it.  */)
 
   specs = Qnil;
   string = 0;
+  /* The idea of FILTER_SPECS is to provide away to
+     specify how to represent the arguments in command history.
+     The feature is not fully implemented.  */
+  filter_specs = Qnil;
 
   /* Decode the kind of function.  Either handle it and return,
      or go to `lose' if not interactive, or go to `retry'
@@ -278,19 +284,20 @@ supply if the command inquires which events were used to invoke it.  */)
       specs = Fassq (Qinteractive, Fcdr (XCDR (fun)));
       if (NILP (specs))
        goto lose;
+      filter_specs = Fnth (make_number (1), specs);
       specs = Fcar (Fcdr (specs));
     }
   else
     goto lose;
 
-  /* If either specs or string is set to a string, use it.  */
+  /* If either SPECS or STRING is set to a string, use it.  */
   if (STRINGP (specs))
     {
       /* Make a copy of string so that if a GC relocates specs,
         `string' will still be valid.  */
-      string = (unsigned char *) alloca (STRING_BYTES (XSTRING (specs)) + 1);
-      bcopy (XSTRING (specs)->data, string,
-            STRING_BYTES (XSTRING (specs)) + 1);
+      string = (unsigned char *) alloca (SBYTES (specs) + 1);
+      bcopy (SDATA (specs), string,
+            SBYTES (specs) + 1);
     }
   else if (string == 0)
     {
@@ -298,7 +305,9 @@ supply if the command inquires which events were used to invoke it.  */)
       i = num_input_events;
       input = specs;
       /* Compute the arg values using the user's expression.  */
+      GCPRO2 (input, filter_specs);
       specs = Feval (specs);
+      UNGCPRO;
       if (i != num_input_events || !NILP (record_flag))
        {
          /* We should record this command on the command history.  */
@@ -315,7 +324,8 @@ supply if the command inquires which events were used to invoke it.  */)
              car = XCAR (input);
              /* Skip through certain special forms.  */
              while (EQ (car, Qlet) || EQ (car, Qletx)
-                    || EQ (car, Qsave_excursion))
+                    || EQ (car, Qsave_excursion)
+                    || EQ (car, Qprogn))
                {
                  while (CONSP (XCDR (input)))
                    input = XCDR (input);
@@ -364,7 +374,7 @@ supply if the command inquires which events were used to invoke it.  */)
   for (next_event = 0; next_event < key_count; next_event++)
     if (EVENT_HAS_PARAMETERS (XVECTOR (keys)->contents[next_event]))
       break;
-  
+
   /* Handle special starting chars `*' and `@'.  Also `-'.  */
   /* Note that `+' is reserved for user extensions.  */
   while (1)
@@ -375,7 +385,22 @@ supply if the command inquires which events were used to invoke it.  */)
        {
          string++;
          if (!NILP (current_buffer->read_only))
-           Fbarf_if_buffer_read_only ();
+           {
+             if (!NILP (record_flag))
+               {
+                 unsigned char *p = string;
+                 while (*p)
+                   {
+                     if (! (*p == 'r' || *p == 'p' || *p == 'P'
+                            || *p == '\n'))
+                       Fbarf_if_buffer_read_only ();
+                     p++;
+                   }
+                 record_then_fail = 1;
+               }
+             else
+               Fbarf_if_buffer_read_only ();
+           }
        }
       /* Ignore this for semi-compatibility with Lucid.  */
       else if (*string == '-')
@@ -384,7 +409,9 @@ supply if the command inquires which events were used to invoke it.  */)
        {
          Lisp_Object event;
 
-         event = XVECTOR (keys)->contents[next_event];
+         event = (next_event < key_count
+                  ? XVECTOR (keys)->contents[next_event]
+                  : Qnil);
          if (EVENT_HAS_PARAMETERS (event)
              && (event = XCDR (event), CONSP (event))
              && (event = XCAR (event), CONSP (event))
@@ -453,7 +480,7 @@ supply if the command inquires which events were used to invoke it.  */)
        argstrings[j]
          = (EQ (visargs[j], Qnil)
             ? (unsigned char *) ""
-            : XSTRING (visargs[j])->data);
+            : SDATA (visargs[j]));
 
       /* Process the format-string in prompt1, putting the output
         into callint_message.  Make callint_message bigger if necessary.
@@ -464,7 +491,7 @@ supply if the command inquires which events were used to invoke it.  */)
          int nchars = doprnt (callint_message, callint_message_size,
                               prompt1, (char *)0,
                               j - 1, (char **) argstrings + 1);
-         if (nchars < callint_message_size)
+         if (nchars < callint_message_size - 1)
            break;
          callint_message_size *= 2;
          callint_message
@@ -541,7 +568,7 @@ supply if the command inquires which events were used to invoke it.  */)
 
        case 'k':               /* Key sequence. */
          {
-           int speccount1 = specpdl_ptr - specpdl;
+           int speccount1 = SPECPDL_INDEX ();
            specbind (Qcursor_in_echo_area, Qt);
            args[i] = Fread_key_sequence (build_string (callint_message),
                                          Qnil, Qnil, Qnil, Qnil);
@@ -569,7 +596,7 @@ supply if the command inquires which events were used to invoke it.  */)
 
        case 'K':               /* Key sequence to be defined. */
          {
-           int speccount1 = specpdl_ptr - specpdl;
+           int speccount1 = SPECPDL_INDEX ();
            specbind (Qcursor_in_echo_area, Qt);
            args[i] = Fread_key_sequence (build_string (callint_message),
                                          Qnil, Qt, Qnil, Qnil);
@@ -599,7 +626,7 @@ supply if the command inquires which events were used to invoke it.  */)
          if (next_event >= key_count)
            error ("%s must be bound to an event with parameters",
                   (SYMBOLP (function)
-                   ? (char *) XSTRING (SYMBOL_NAME (function))->data
+                   ? (char *) SDATA (SYMBOL_NAME (function))
                    : "command"));
          args[i] = XVECTOR (keys)->contents[next_event++];
          varies[i] = -1;
@@ -644,7 +671,7 @@ supply if the command inquires which events were used to invoke it.  */)
                tem = Fread_from_minibuffer (build_string (callint_message),
                                             Qnil, Qnil, Qnil, Qnil, Qnil,
                                             Qnil);
-               if (! STRINGP (tem) || XSTRING (tem)->size == 0)
+               if (! STRINGP (tem) || SCHARS (tem) == 0)
                  args[i] = Qnil;
                else
                  args[i] = Fread (tem);
@@ -780,6 +807,9 @@ supply if the command inquires which events were used to invoke it.  */)
     if (varies[i] >= 1 && varies[i] <= 4)
       XSETINT (args[i], marker_position (args[i]));
 
+  if (record_then_fail)
+    Fbarf_if_buffer_read_only ();
+
   single_kboard_state ();
 
   {
@@ -836,6 +866,8 @@ syms_of_callint ()
   staticpro (&Qletx);
   Qsave_excursion = intern ("save-excursion");
   staticpro (&Qsave_excursion);
+  Qprogn = intern ("progn");
+  staticpro (&Qprogn);
 
   Qminus = intern ("-");
   staticpro (&Qminus);