]> code.delx.au - gnu-emacs/blobdiff - src/macros.c
Avoid long futile looping on a TTY under huge values of hscroll.
[gnu-emacs] / src / macros.c
index d90b31b503f6d940da0c041c3d0ced9b462286e5..7c8bc4c13b895067e6aae64a775f334044792574 100644 (file)
@@ -1,6 +1,6 @@
 /* Keyboard macros.
 
-Copyright (C) 1985-1986, 1993, 2000-2011  Free Software Foundation, Inc.
+Copyright (C) 1985-1986, 1993, 2000-2012  Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
 
@@ -23,18 +23,20 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 #include "lisp.h"
 #include "macros.h"
 #include "commands.h"
+#include "character.h"
 #include "buffer.h"
 #include "window.h"
 #include "keyboard.h"
 
-Lisp_Object Qexecute_kbd_macro, Qkbd_macro_termination_hook;
+Lisp_Object Qexecute_kbd_macro;
+static Lisp_Object Qkbd_macro_termination_hook;
 
 /* Number of successful iterations so far
    for innermost keyboard macro.
    This is not bound at each level,
    so after an error, it describes the innermost interrupted macro.  */
 
-int executing_kbd_macro_iterations;
+EMACS_INT executing_kbd_macro_iterations;
 
 /* This is the macro that was executing.
    This is not bound at each level,
@@ -61,19 +63,19 @@ macro before appending to it. */)
 
   if (!current_kboard->kbd_macro_buffer)
     {
-      current_kboard->kbd_macro_bufsize = 30;
       current_kboard->kbd_macro_buffer
        = (Lisp_Object *)xmalloc (30 * sizeof (Lisp_Object));
+      current_kboard->kbd_macro_bufsize = 30;
     }
   update_mode_lines++;
   if (NILP (append))
     {
       if (current_kboard->kbd_macro_bufsize > 200)
        {
-         current_kboard->kbd_macro_bufsize = 30;
          current_kboard->kbd_macro_buffer
            = (Lisp_Object *)xrealloc (current_kboard->kbd_macro_buffer,
                                       30 * sizeof (Lisp_Object));
+         current_kboard->kbd_macro_bufsize = 30;
        }
       current_kboard->kbd_macro_ptr = current_kboard->kbd_macro_buffer;
       current_kboard->kbd_macro_end = current_kboard->kbd_macro_buffer;
@@ -81,7 +83,8 @@ macro before appending to it. */)
     }
   else
     {
-      int i, len;
+      ptrdiff_t i;
+      EMACS_INT len;
       int cvt;
 
       /* Check the type of last-kbd-macro in case Lisp code changed it.  */
@@ -93,10 +96,14 @@ macro before appending to it. */)
         has put another macro there.  */
       if (current_kboard->kbd_macro_bufsize < len + 30)
        {
-         current_kboard->kbd_macro_bufsize = len + 30;
-         current_kboard->kbd_macro_buffer
-           = (Lisp_Object *)xrealloc (current_kboard->kbd_macro_buffer,
-                                      (len + 30) * sizeof (Lisp_Object));
+         if (PTRDIFF_MAX < MOST_POSITIVE_FIXNUM + 30
+             && PTRDIFF_MAX < len + 30)
+           memory_full (SIZE_MAX);
+         current_kboard->kbd_macro_buffer =
+           xpalloc (current_kboard->kbd_macro_buffer,
+                    &current_kboard->kbd_macro_bufsize,
+                    len + 30 - current_kboard->kbd_macro_bufsize, -1,
+                    sizeof *current_kboard->kbd_macro_buffer);
        }
 
       /* Must convert meta modifier when copying string to vector.  */
@@ -170,11 +177,11 @@ each iteration of the macro.  Iteration stops if LOOPFUNC returns nil.  */)
 
   if (XFASTINT (repeat) == 0)
     Fexecute_kbd_macro (KVAR (current_kboard, Vlast_kbd_macro), repeat, loopfunc);
-  else
+  else if (XINT (repeat) > 1)
     {
       XSETINT (repeat, XINT (repeat)-1);
-      if (XINT (repeat) > 0)
-       Fexecute_kbd_macro (KVAR (current_kboard, Vlast_kbd_macro), repeat, loopfunc);
+      Fexecute_kbd_macro (KVAR (current_kboard, Vlast_kbd_macro),
+                         repeat, loopfunc);
     }
   return Qnil;
 }
@@ -190,14 +197,17 @@ store_kbd_macro_char (Lisp_Object c)
     {
       if (kb->kbd_macro_ptr - kb->kbd_macro_buffer == kb->kbd_macro_bufsize)
        {
-         int ptr_offset, end_offset, nbytes;
+         ptrdiff_t ptr_offset, end_offset, nbytes;
 
          ptr_offset = kb->kbd_macro_ptr - kb->kbd_macro_buffer;
          end_offset = kb->kbd_macro_end - kb->kbd_macro_buffer;
-         kb->kbd_macro_bufsize *= 2;
-         nbytes = kb->kbd_macro_bufsize * sizeof *kb->kbd_macro_buffer;
+         if (min (PTRDIFF_MAX, SIZE_MAX) / sizeof *kb->kbd_macro_buffer / 2
+             < kb->kbd_macro_bufsize)
+           memory_full (SIZE_MAX);
+         nbytes = kb->kbd_macro_bufsize * (2 * sizeof *kb->kbd_macro_buffer);
          kb->kbd_macro_buffer
            = (Lisp_Object *) xrealloc (kb->kbd_macro_buffer, nbytes);
+         kb->kbd_macro_bufsize *= 2;
          kb->kbd_macro_ptr = kb->kbd_macro_buffer + ptr_offset;
          kb->kbd_macro_end = kb->kbd_macro_buffer + end_offset;
        }
@@ -250,7 +260,7 @@ each iteration of the macro.  Iteration stops if LOOPFUNC returns nil.  */)
      from before this macro started.  */
   Vthis_command = KVAR (current_kboard, Vlast_command);
   /* C-x z after the macro should repeat the macro.  */
-  real_this_command = KVAR (current_kboard, Vlast_kbd_macro);
+  Vreal_this_command = KVAR (current_kboard, Vlast_kbd_macro);
 
   if (! NILP (KVAR (current_kboard, defining_kbd_macro)))
     error ("Can't execute anonymous macro while defining one");
@@ -277,7 +287,7 @@ pop_kbd_macro (Lisp_Object info)
   Vexecuting_kbd_macro = XCAR (info);
   tem = XCDR (info);
   executing_kbd_macro_index = XINT (XCAR (tem));
-  real_this_command = XCDR (tem);
+  Vreal_this_command = XCDR (tem);
   Frun_hooks (1, &Qkbd_macro_termination_hook);
   return Qnil;
 }
@@ -293,10 +303,10 @@ each iteration of the macro.  Iteration stops if LOOPFUNC returns nil.  */)
 {
   Lisp_Object final;
   Lisp_Object tem;
-  int pdlcount = SPECPDL_INDEX ();
-  int repeat = 1;
+  ptrdiff_t pdlcount = SPECPDL_INDEX ();
+  EMACS_INT repeat = 1;
   struct gcpro gcpro1, gcpro2;
-  int success_count = 0;
+  EMACS_INT success_count = 0;
 
   executing_kbd_macro_iterations = 0;
 
@@ -312,7 +322,7 @@ each iteration of the macro.  Iteration stops if LOOPFUNC returns nil.  */)
 
   tem = Fcons (Vexecuting_kbd_macro,
               Fcons (make_number (executing_kbd_macro_index),
-                     real_this_command));
+                     Vreal_this_command));
   record_unwind_protect (pop_kbd_macro, tem);
 
   GCPRO2 (final, loopfunc);
@@ -343,7 +353,7 @@ each iteration of the macro.  Iteration stops if LOOPFUNC returns nil.  */)
 
   executing_kbd_macro = Qnil;
 
-  real_this_command = Vexecuting_kbd_macro;
+  Vreal_this_command = Vexecuting_kbd_macro;
 
   UNGCPRO;
   return unbind_to (pdlcount, Qnil);
@@ -359,15 +369,13 @@ init_macros (void)
 void
 syms_of_macros (void)
 {
-  Qexecute_kbd_macro = intern_c_string ("execute-kbd-macro");
-  staticpro (&Qexecute_kbd_macro);
+  DEFSYM (Qexecute_kbd_macro, "execute-kbd-macro");
 
   DEFVAR_LISP ("kbd-macro-termination-hook", Vkbd_macro_termination_hook,
                doc: /* Normal hook run whenever a keyboard macro terminates.
 This is run whether the macro ends normally or prematurely due to an error.  */);
   Vkbd_macro_termination_hook = Qnil;
-  Qkbd_macro_termination_hook = intern_c_string ("kbd-macro-termination-hook");
-  staticpro (&Qkbd_macro_termination_hook);
+  DEFSYM (Qkbd_macro_termination_hook, "kbd-macro-termination-hook");
 
   defsubr (&Sstart_kbd_macro);
   defsubr (&Send_kbd_macro);
@@ -391,4 +399,3 @@ This is nil when not executing a keyboard macro.  */);
   DEFVAR_KBOARD ("last-kbd-macro", Vlast_kbd_macro,
                 doc: /* Last kbd macro defined, as a string or vector; nil if none defined.  */);
 }
-