]> code.delx.au - gnu-emacs/blobdiff - src/insdel.c
(minibuffer_completion_contents): Add return type.
[gnu-emacs] / src / insdel.c
index efc6aa44b6e571d08874bd811869b675086bd845..5bec29ea926c642e5c5e7bc05072577347114291 100644 (file)
@@ -533,10 +533,13 @@ make_gap_larger (nbytes_added)
 
   /* 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'.  */
+     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 + nbytes_added
-      >= MOST_POSITIVE_FIXNUM)
+  if (Z_BYTE - BEG_BYTE + GAP_SIZE
+      >= (((EMACS_INT) 1 << (min (VALBITS, BITS_PER_INT) - 1)) - 1
+         - nbytes_added))
     error ("Buffer exceeds maximum size");
 
   enlarge_buffer_text (current_buffer, nbytes_added);
@@ -581,7 +584,8 @@ make_gap_smaller (nbytes_removed)
   int real_gap_loc_byte;
   int real_Z;
   int real_Z_byte;
-  int old_gap_size;
+  int real_beg_unchanged;
+  int new_gap_size;
 
   /* Make sure the gap is at least 20 bytes.  */
   if (GAP_SIZE - nbytes_removed < 20)
@@ -593,18 +597,19 @@ make_gap_smaller (nbytes_removed)
 
   real_gap_loc = GPT;
   real_gap_loc_byte = GPT_BYTE;
-  old_gap_size = GAP_SIZE;
+  new_gap_size = GAP_SIZE - nbytes_removed;
   real_Z = Z;
   real_Z_byte = Z_BYTE;
+  real_beg_unchanged = BEG_UNCHANGED;
 
   /* 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, GAP_SIZE - nbytes_removed);
-  GPT += GAP_SIZE - nbytes_removed;
-  GPT_BYTE += GAP_SIZE - nbytes_removed;
-  Z += GAP_SIZE - nbytes_removed;
-  Z_BYTE += GAP_SIZE - nbytes_removed;
+  bzero (GPT_ADDR, new_gap_size);
+  GPT += new_gap_size;
+  GPT_BYTE += new_gap_size;
+  Z += new_gap_size;
+  Z_BYTE += new_gap_size;
   GAP_SIZE = nbytes_removed;
 
   /* Move the unwanted pretend gap to the end of the buffer.  This
@@ -614,11 +619,12 @@ make_gap_smaller (nbytes_removed)
   enlarge_buffer_text (current_buffer, -nbytes_removed);
 
   /* Now restore the desired gap.  */
-  GAP_SIZE = old_gap_size - nbytes_removed;
+  GAP_SIZE = new_gap_size;
   GPT = real_gap_loc;
   GPT_BYTE = real_gap_loc_byte;
   Z = real_Z;
   Z_BYTE = real_Z_byte;
+  BEG_UNCHANGED = real_beg_unchanged;
 
   /* Put an anchor.  */
   *(Z_ADDR) = 0;
@@ -1025,6 +1031,10 @@ insert_1_both (string, nchars, nbytes, inherit, prepare, before_markers)
   if (GPT_BYTE < GPT)
     abort ();
 
+  /* The insert may have been in the unchanged region, so check again. */
+  if (Z - GPT < END_UNCHANGED)
+    END_UNCHANGED = Z - GPT;
+
   adjust_overlays_for_insert (PT, nchars);
   adjust_markers_for_insert (PT, PT_BYTE,
                             PT + nchars, PT_BYTE + nbytes,
@@ -1148,6 +1158,10 @@ insert_from_string_1 (string, pos, pos_byte, nchars, nbytes,
   if (GPT_BYTE < GPT)
     abort ();
 
+  /* The insert may have been in the unchanged region, so check again. */
+  if (Z - GPT < END_UNCHANGED)
+    END_UNCHANGED = Z - GPT;
+
   adjust_overlays_for_insert (PT, nchars);
   adjust_markers_for_insert (PT, PT_BYTE, PT + nchars,
                             PT_BYTE + outgoing_nbytes,
@@ -1295,6 +1309,10 @@ insert_from_buffer_1 (buf, from, nchars, inherit)
   if (GPT_BYTE < GPT)
     abort ();
 
+  /* The insert may have been in the unchanged region, so check again. */
+  if (Z - GPT < END_UNCHANGED)
+    END_UNCHANGED = Z - GPT;
+
   adjust_overlays_for_insert (PT, nchars);
   adjust_markers_for_insert (PT, PT_BYTE, PT + nchars,
                             PT_BYTE + outgoing_nbytes,
@@ -1388,6 +1406,56 @@ adjust_after_replace (from, from_byte, prev_text, len, len_byte)
   MODIFF++;
 }
 
+/* Like adjust_after_replace, but doesn't require PREV_TEXT.
+   This is for use when undo is not enabled in the current buffer.  */
+
+void
+adjust_after_replace_noundo (from, from_byte, nchars_del, nbytes_del, len, len_byte)
+     int from, from_byte, nchars_del, nbytes_del, len, len_byte;
+{
+#ifdef BYTE_COMBINING_DEBUG
+  if (count_combining_before (GPT_ADDR, len_byte, from, from_byte)
+      || count_combining_after (GPT_ADDR, len_byte, from, from_byte))
+    abort ();
+#endif
+
+  /* Update various buffer positions for the new text.  */
+  GAP_SIZE -= len_byte;
+  ZV += len; Z+= len;
+  ZV_BYTE += len_byte; Z_BYTE += len_byte;
+  GPT += len; GPT_BYTE += len_byte;
+  if (GAP_SIZE > 0) *(GPT_ADDR) = 0; /* Put an anchor. */
+
+  if (nchars_del > 0)
+    adjust_markers_for_replace (from, from_byte, nchars_del, nbytes_del,
+                               len, len_byte);
+  else
+    adjust_markers_for_insert (from, from_byte,
+                              from + len, from_byte + len_byte, 0);
+
+  if (len > nchars_del)
+    adjust_overlays_for_insert (from, len - nchars_del);
+  else if (len < nchars_del)
+    adjust_overlays_for_delete (from, nchars_del - len);
+  if (BUF_INTERVALS (current_buffer) != 0)
+    {
+      offset_intervals (current_buffer, from, len - nchars_del);
+    }
+
+  if (from < PT)
+    adjust_point (len - nchars_del, len_byte - nbytes_del);
+
+  /* As byte combining will decrease Z, we must check this again. */
+  if (Z - GPT < END_UNCHANGED)
+    END_UNCHANGED = Z - GPT;
+
+  CHECK_MARKERS ();
+
+  if (len == 0)
+    evaporate_overlays (from);
+  MODIFF++;
+}
+
 /* Record undo information, adjust markers and position keepers for an
    insertion of a text from FROM (FROM_BYTE) to TO (TO_BYTE).  The
    text already exists in the current buffer but character length (TO