/* 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);
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)
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
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;
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,
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,
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,
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