Merge from trunk
[bpt/emacs.git] / src / insdel.c
index eaf899c..db76f77 100644 (file)
@@ -1,6 +1,5 @@
 /* Buffer insertion/deletion and gap motion for GNU Emacs.
-   Copyright (C) 1985, 1986, 1993, 1994, 1995, 1997, 1998, 1999, 2000, 2001,
-                 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
+   Copyright (C) 1985-1986, 1993-1995, 1997-2011
                  Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
@@ -20,6 +19,7 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 
 
 #include <config.h>
+#include <setjmp.h>
 #include "lisp.h"
 #include "intervals.h"
 #include "buffer.h"
@@ -50,11 +50,7 @@ static void adjust_markers_for_replace (EMACS_INT, EMACS_INT, EMACS_INT,
                                        EMACS_INT, EMACS_INT, EMACS_INT);
 static void adjust_point (EMACS_INT nchars, EMACS_INT nbytes);
 
-Lisp_Object Fcombine_after_change_execute ();
-
-/* Non-nil means don't call the after-change-functions right away,
-   just record an element in Vcombine_after_change_calls_list.  */
-Lisp_Object Vcombine_after_change_calls;
+Lisp_Object Fcombine_after_change_execute (void);
 
 /* List of elements of the form (BEG-UNCHANGED END-UNCHANGED CHANGE-AMOUNT)
    describing changes which happened while combine_after_change_calls
@@ -72,19 +68,14 @@ Lisp_Object combine_after_change_list;
 Lisp_Object combine_after_change_buffer;
 
 Lisp_Object Qinhibit_modification_hooks;
-
 \f
-/* Check all markers in the current buffer, looking for something invalid.  */
-
-static int check_markers_debug_flag;
-
 #define CHECK_MARKERS()                                \
   if (check_markers_debug_flag)                        \
     check_markers ();                          \
   else
 
 void
-check_markers ()
+check_markers (void)
 {
   register struct Lisp_Marker *tail;
   int multibyte = ! NILP (current_buffer->enable_multibyte_characters);
@@ -163,28 +154,9 @@ gap_left (EMACS_INT charpos, EMACS_INT bytepos, int newgap)
       /* Move at most 32000 chars before checking again for a quit.  */
       if (i > 32000)
        i = 32000;
-#ifdef GAP_USE_BCOPY
-      if (i >= 128
-         /* bcopy is safe if the two areas of memory do not overlap
-            or on systems where bcopy is always safe for moving upward.  */
-         && (BCOPY_UPWARD_SAFE
-             || to - from >= 128))
-       {
-         /* If overlap is not safe, avoid it by not moving too many
-            characters at once.  */
-         if (!BCOPY_UPWARD_SAFE && i > to - from)
-           i = to - from;
-         new_s1 -= i;
-         from -= i, to -= i;
-         bcopy (from, to, i);
-       }
-      else
-#endif
-       {
-         new_s1 -= i;
-         while (--i >= 0)
-           *--to = *--from;
-       }
+      new_s1 -= i;
+      from -= i, to -= i;
+      memmove (to, from, i);
     }
 
   /* Adjust markers, and buffer data structure, to put the gap at BYTEPOS.
@@ -237,28 +209,9 @@ gap_right (EMACS_INT charpos, EMACS_INT bytepos)
       /* Move at most 32000 chars before checking again for a quit.  */
       if (i > 32000)
        i = 32000;
-#ifdef GAP_USE_BCOPY
-      if (i >= 128
-         /* bcopy is safe if the two areas of memory do not overlap
-            or on systems where bcopy is always safe for moving downward.  */
-         && (BCOPY_DOWNWARD_SAFE
-             || from - to >= 128))
-       {
-         /* If overlap is not safe, avoid it by not moving too many
-            characters at once.  */
-         if (!BCOPY_DOWNWARD_SAFE && i > from - to)
-           i = from - to;
-         new_s1 += i;
-         bcopy (from, to, i);
-         from += i, to += i;
-       }
-      else
-#endif
-       {
-         new_s1 += i;
-         while (--i >= 0)
-           *to++ = *from++;
-       }
+      new_s1 += i;
+      memmove (to, from, i);
+      from += i, to += i;
     }
 
   adjust_markers_gap_motion (GPT_BYTE + GAP_SIZE, bytepos + GAP_SIZE,
@@ -369,14 +322,14 @@ adjust_markers_for_delete (EMACS_INT from, EMACS_INT from_byte,
               re-inserted text after undoing a deletion, and must be
               adjusted to move them to the correct place.  */
              XSETMISC (marker, m);
-           record_marker_adjustment (marker, from - charpos);
+             record_marker_adjustment (marker, from - charpos);
            }
          else if (charpos < to)
            { /* Before-insertion markers will automatically move forward
               upon re-inserting the deleted text, so we have to arrange
               for them to move backward to the correct position.  */
              XSETMISC (marker, m);
-           record_marker_adjustment (marker, charpos - to);
+             record_marker_adjustment (marker, to - charpos);
            }
          m->charpos = from;
          m->bytepos = from_byte;
@@ -436,7 +389,7 @@ adjust_markers_for_insert (EMACS_INT from, EMACS_INT from_byte,
     }
 
   /* Adjusting only markers whose insertion-type is t may result in
-     - disordered start and end in overlays, and 
+     - disordered start and end in overlays, and
      - disordered overlays in the slot `overlays_before' of current_buffer.  */
   if (adjusted)
     {
@@ -511,16 +464,16 @@ make_gap_larger (EMACS_INT nbytes_added)
   /* If we have to get more space, get enough to last a while.  */
   nbytes_added += 2000;
 
-  /* Don't allow a buffer size that won't fit in an int
-     even if it will fit in a Lisp integer.
-     That won't work because so many places use `int'.
-
-     Make sure we don't introduce overflows in the calculation.  */
-
-  if (Z_BYTE - BEG_BYTE + GAP_SIZE
-      >= (((EMACS_INT) 1 << (min (VALBITS, BITS_PER_INT) - 1)) - 1
-         - nbytes_added))
-    error ("Buffer exceeds maximum size");
+  { EMACS_INT total_size = Z_BYTE - BEG_BYTE + GAP_SIZE + nbytes_added;
+    if (total_size < 0
+       /* Don't allow a buffer size that won't fit in a Lisp integer.  */
+       || total_size != XINT (make_number (total_size))
+       /* Don't allow a buffer size that won't fit in an int
+          even if it will fit in a Lisp integer.
+          That won't work because so many places still use `int'.  */
+       || total_size != (EMACS_INT) (int) total_size)
+      error ("Buffer exceeds maximum size");
+  }
 
   enlarge_buffer_text (current_buffer, nbytes_added);
 
@@ -584,7 +537,7 @@ make_gap_smaller (EMACS_INT nbytes_removed)
   /* Pretend that the last unwanted part of the gap is the entire gap,
      and that the first desired part of the gap is part of the buffer
      text.  */
-  bzero (GPT_ADDR, new_gap_size);
+  memset (GPT_ADDR, 0, new_gap_size);
   GPT += new_gap_size;
   GPT_BYTE += new_gap_size;
   Z += new_gap_size;
@@ -635,7 +588,7 @@ copy_text (const unsigned char *from_addr, unsigned char *to_addr,
 {
   if (from_multibyte == to_multibyte)
     {
-      bcopy (from_addr, to_addr, nbytes);
+      memcpy (to_addr, from_addr, nbytes);
       return nbytes;
     }
   else if (from_multibyte)
@@ -647,7 +600,7 @@ copy_text (const unsigned char *from_addr, unsigned char *to_addr,
       while (bytes_left > 0)
        {
          int thislen, c;
-         c = STRING_CHAR_AND_LENGTH (from_addr, bytes_left, thislen);
+         c = STRING_CHAR_AND_LENGTH (from_addr, thislen);
          if (! ASCII_CHAR_P (c))
            c &= 0xFF;
          *to_addr++ = c;
@@ -666,9 +619,9 @@ copy_text (const unsigned char *from_addr, unsigned char *to_addr,
        {
          int c = *from_addr++;
 
-         if (c >= 0200)
+         if (!ASCII_CHAR_P (c))
            {
-             c = unibyte_char_to_multibyte (c);
+             c = BYTE8_TO_CHAR (c);
              to_addr += CHAR_STRING (c, to_addr);
              nbytes--;
            }
@@ -694,11 +647,11 @@ count_size_as_multibyte (const unsigned char *ptr, EMACS_INT nbytes)
     {
       unsigned int c = *ptr++;
 
-      if (c < 0200)
+      if (ASCII_CHAR_P (c))
        outgoing_nbytes++;
       else
        {
-         c = unibyte_char_to_multibyte (c);
+         c = BYTE8_TO_CHAR (c);
          outgoing_nbytes += CHAR_BYTES (c);
        }
     }
@@ -715,11 +668,11 @@ count_size_as_multibyte (const unsigned char *ptr, EMACS_INT nbytes)
    prepare_to_modify_buffer could relocate the text.  */
 
 void
-insert (const unsigned char *string, EMACS_INT nbytes)
+insert (const char *string, EMACS_INT nbytes)
 {
   if (nbytes > 0)
     {
-      EMACS_INT len = chars_in_text (string, nbytes), opoint;
+      EMACS_INT len = chars_in_text ((unsigned char *) string, nbytes), opoint;
       insert_1_both (string, len, nbytes, 0, 1, 0);
       opoint = PT - len;
       signal_after_change (opoint, 0, len);
@@ -730,11 +683,11 @@ insert (const unsigned char *string, EMACS_INT nbytes)
 /* Likewise, but inherit text properties from neighboring characters.  */
 
 void
-insert_and_inherit (const unsigned char *string, EMACS_INT nbytes)
+insert_and_inherit (const char *string, EMACS_INT nbytes)
 {
   if (nbytes > 0)
     {
-      EMACS_INT len = chars_in_text (string, nbytes), opoint;
+      EMACS_INT len = chars_in_text ((unsigned char *) string, nbytes), opoint;
       insert_1_both (string, len, nbytes, 1, 1, 0);
       opoint = PT - len;
       signal_after_change (opoint, 0, len);
@@ -758,7 +711,7 @@ insert_char (int c)
       str[0] = c;
     }
 
-  insert (str, len);
+  insert ((char *) str, len);
 }
 
 /* Insert the null-terminated string S before point.  */
@@ -775,11 +728,11 @@ insert_string (const char *s)
    since gc could happen and relocate it.  */
 
 void
-insert_before_markers (const unsigned char *string, EMACS_INT nbytes)
+insert_before_markers (const char *string, EMACS_INT nbytes)
 {
   if (nbytes > 0)
     {
-      EMACS_INT len = chars_in_text (string, nbytes), opoint;
+      EMACS_INT len = chars_in_text ((unsigned char *) string, nbytes), opoint;
       insert_1_both (string, len, nbytes, 0, 1, 1);
       opoint = PT - len;
       signal_after_change (opoint, 0, len);
@@ -790,12 +743,12 @@ insert_before_markers (const unsigned char *string, EMACS_INT nbytes)
 /* Likewise, but inherit text properties from neighboring characters.  */
 
 void
-insert_before_markers_and_inherit (const unsigned char *string,
+insert_before_markers_and_inherit (const char *string,
                                   EMACS_INT nbytes)
 {
   if (nbytes > 0)
     {
-      EMACS_INT len = chars_in_text (string, nbytes), opoint;
+      EMACS_INT len = chars_in_text ((unsigned char *) string, nbytes), opoint;
       insert_1_both (string, len, nbytes, 1, 1, 1);
       opoint = PT - len;
       signal_after_change (opoint, 0, len);
@@ -806,11 +759,11 @@ insert_before_markers_and_inherit (const unsigned char *string,
 /* Subroutine used by the insert functions above.  */
 
 void
-insert_1 (const unsigned char *string, EMACS_INT nbytes,
+insert_1 (const char *string, EMACS_INT nbytes,
          int inherit, int prepare, int before_markers)
 {
-  insert_1_both (string, chars_in_text (string, nbytes), nbytes,
-                inherit, prepare, before_markers);
+  insert_1_both (string, chars_in_text ((unsigned char *) string, nbytes),
+                nbytes, inherit, prepare, before_markers);
 }
 
 \f
@@ -842,7 +795,7 @@ count_combining_before (const unsigned char *string, EMACS_INT length,
   len = 1;
   p = BYTE_POS_ADDR (pos_byte - 1);
   while (! CHAR_HEAD_P (*p)) p--, len++;
-  if (! BASE_LEADING_CODE_P (*p)) /* case (3) */
+  if (! LEADING_CODE_P (*p)) /* case (3) */
     return 0;
 
   combining_bytes = BYTES_BY_CHAR_HEAD (*p) - len;
@@ -905,7 +858,7 @@ count_combining_after (const unsigned char *string,
       i = pos_byte - 2;
       while (i >= 0 && ! CHAR_HEAD_P (p[i]))
        i--;
-      if (i < 0 || !BASE_LEADING_CODE_P (p[i]))
+      if (i < 0 || !LEADING_CODE_P (p[i]))
        return 0;
 
       bytes = BYTES_BY_CHAR_HEAD (p[i]);
@@ -913,7 +866,7 @@ count_combining_after (const unsigned char *string,
              ? 0
              : bytes - (pos_byte - 1 - i + length));
     }
-  if (!BASE_LEADING_CODE_P (string[i]))
+  if (!LEADING_CODE_P (string[i]))
     return 0;
 
   bytes = BYTES_BY_CHAR_HEAD (string[i]) - (length - i);
@@ -931,7 +884,7 @@ count_combining_after (const unsigned char *string,
    are the same as in insert_1.  */
 
 void
-insert_1_both (const unsigned char *string,
+insert_1_both (const char *string,
               EMACS_INT nchars, EMACS_INT nbytes,
               int inherit, int prepare, int before_markers)
 {
@@ -965,7 +918,7 @@ insert_1_both (const unsigned char *string,
   MODIFF++;
   CHARS_MODIFF = MODIFF;
 
-  bcopy (string, GPT_ADDR, nbytes);
+  memcpy (GPT_ADDR, string, nbytes);
 
   GAP_SIZE -= nbytes;
   GPT += nchars;
@@ -1006,7 +959,7 @@ insert_1_both (const unsigned char *string,
    copy them into the buffer.
 
    It does not work to use `insert' for this, because a GC could happen
-   before we bcopy the stuff into the buffer, and relocate the string
+   before we copy the stuff into the buffer, and relocate the string
    without insert noticing.  */
 
 void
@@ -1181,7 +1134,7 @@ insert_from_gap (EMACS_INT nchars, EMACS_INT nbytes)
    into the current buffer.
 
    It does not work to use `insert' for this, because a malloc could happen
-   and relocate BUF's text before the bcopy happens.  */
+   and relocate BUF's text before the copy happens.  */
 
 void
 insert_from_buffer (struct buffer *buf,
@@ -1665,7 +1618,7 @@ replace_range (EMACS_INT from, EMACS_INT to, Lisp_Object new,
 void
 replace_range_2 (EMACS_INT from, EMACS_INT from_byte,
                 EMACS_INT to, EMACS_INT to_byte,
-                char *ins, EMACS_INT inschars, EMACS_INT insbytes,
+                const char *ins, EMACS_INT inschars, EMACS_INT insbytes,
                 int markers)
 {
   EMACS_INT nbytes_del, nchars_del;
@@ -1711,7 +1664,7 @@ replace_range_2 (EMACS_INT from, EMACS_INT from_byte,
     make_gap (insbytes - GAP_SIZE);
 
   /* Copy the replacement text into the buffer.  */
-  bcopy (ins, GPT_ADDR, insbytes);
+  memcpy (GPT_ADDR, ins, insbytes);
 
 #ifdef BYTE_COMBINING_DEBUG
   /* We have copied text into the gap, but we have not marked
@@ -2084,6 +2037,24 @@ prepare_to_modify_buffer (EMACS_INT start, EMACS_INT end,
           base_buffer->filename);
 #endif /* not CLASH_DETECTION */
 
+  /* If `select-active-regions' is non-nil, save the region text.  */
+  if (!NILP (current_buffer->mark_active)
+      && !inhibit_modification_hooks
+      && XMARKER (current_buffer->mark)->buffer
+      && NILP (Vsaved_region_selection)
+      && (EQ (Vselect_active_regions, Qonly)
+         ? EQ (CAR_SAFE (Vtransient_mark_mode), Qonly)
+         : (!NILP (Vselect_active_regions)
+            && !NILP (Vtransient_mark_mode))))
+    {
+      EMACS_INT b = XMARKER (current_buffer->mark)->charpos;
+      EMACS_INT e = PT;
+      if (b < e)
+       Vsaved_region_selection = make_buffer_string (b, e, 0);
+      else if (b > e)
+       Vsaved_region_selection = make_buffer_string (e, b, 0);
+    }
+
   signal_before_change (start, end, preserve_ptr);
 
   if (current_buffer->newline_cache)
@@ -2131,8 +2102,7 @@ prepare_to_modify_buffer (EMACS_INT start, EMACS_INT end,
    NO-ERROR-FLAG is nil if there was an error,
    anything else meaning no error (so this function does nothing).  */
 Lisp_Object
-reset_var_on_error (val)
-     Lisp_Object val;
+reset_var_on_error (Lisp_Object val)
 {
   if (NILP (XCDR (val)))
     Fset (XCAR (val), Qnil);
@@ -2296,8 +2266,7 @@ signal_after_change (EMACS_INT charpos, EMACS_INT lendel, EMACS_INT lenins)
 }
 
 Lisp_Object
-Fcombine_after_change_execute_1 (val)
-     Lisp_Object val;
+Fcombine_after_change_execute_1 (Lisp_Object val)
 {
   Vcombine_after_change_calls = val;
   return val;
@@ -2306,7 +2275,7 @@ Fcombine_after_change_execute_1 (val)
 DEFUN ("combine-after-change-execute", Fcombine_after_change_execute,
        Scombine_after_change_execute, 0, 0, 0,
        doc: /* This function is for use internally in `combine-after-change-calls'.  */)
-     ()
+  (void)
 {
   int count = SPECPDL_INDEX ();
   EMACS_INT beg, end, change;
@@ -2389,30 +2358,27 @@ DEFUN ("combine-after-change-execute", Fcombine_after_change_execute,
 }
 \f
 void
-syms_of_insdel ()
+syms_of_insdel (void)
 {
   staticpro (&combine_after_change_list);
   staticpro (&combine_after_change_buffer);
   combine_after_change_list = Qnil;
   combine_after_change_buffer = Qnil;
 
-  DEFVAR_BOOL ("check-markers-debug-flag", &check_markers_debug_flag,
+  DEFVAR_BOOL ("check-markers-debug-flag", check_markers_debug_flag,
               doc: /* Non-nil means enable debugging checks for invalid marker positions.  */);
   check_markers_debug_flag = 0;
-  DEFVAR_LISP ("combine-after-change-calls", &Vcombine_after_change_calls,
+  DEFVAR_LISP ("combine-after-change-calls", Vcombine_after_change_calls,
               doc: /* Used internally by the `combine-after-change-calls' macro.  */);
   Vcombine_after_change_calls = Qnil;
 
-  DEFVAR_BOOL ("inhibit-modification-hooks", &inhibit_modification_hooks,
+  DEFVAR_BOOL ("inhibit-modification-hooks", inhibit_modification_hooks,
               doc: /* Non-nil means don't run any of the hooks that respond to buffer changes.
 This affects `before-change-functions' and `after-change-functions',
 as well as hooks attached to text properties and overlays.  */);
   inhibit_modification_hooks = 0;
-  Qinhibit_modification_hooks = intern ("inhibit-modification-hooks");
+  Qinhibit_modification_hooks = intern_c_string ("inhibit-modification-hooks");
   staticpro (&Qinhibit_modification_hooks);
 
   defsubr (&Scombine_after_change_execute);
 }
-
-/* arch-tag: 9b34b886-47d7-465e-a234-299af411b23d
-   (do not change this comment) */