#define NULL 0
#endif
-#define min(x, y) ((x) < (y) ? (x) : (y))
-#define max(x, y) ((x) > (y) ? (x) : (y))
-
static void insert_from_string_1 P_ ((Lisp_Object, int, int, int, int, int, int));
static void insert_from_buffer_1 ();
static void gap_left P_ ((int, int, int));
/* Make the gap NBYTES_ADDED bytes longer. */
void
-make_gap (nbytes_added)
+make_gap_larger (nbytes_added)
int nbytes_added;
{
Lisp_Object tem;
/* 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);
Vinhibit_quit = tem;
}
+
+
+/* Make the gap NBYTES_REMOVED bytes shorted. */
+
+void
+make_gap_smaller (nbytes_removed)
+ int nbytes_removed;
+{
+ Lisp_Object tem;
+ int real_gap_loc;
+ int real_gap_loc_byte;
+ int real_Z;
+ int real_Z_byte;
+ int real_beg_unchanged;
+ int new_gap_size;
+
+ /* Make sure the gap is at least 20 bytes. */
+ if (GAP_SIZE - nbytes_removed < 20)
+ nbytes_removed = GAP_SIZE - 20;
+
+ /* Prevent quitting in move_gap. */
+ tem = Vinhibit_quit;
+ Vinhibit_quit = Qt;
+
+ real_gap_loc = GPT;
+ real_gap_loc_byte = GPT_BYTE;
+ 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, 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
+ adjusts the markers properly too. */
+ gap_right (Z, Z_BYTE);
+
+ enlarge_buffer_text (current_buffer, -nbytes_removed);
+
+ /* Now restore the desired gap. */
+ 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;
+
+ Vinhibit_quit = tem;
+}
+
+void
+make_gap (nbytes_added)
+ int nbytes_added;
+{
+ if (nbytes_added >= 0)
+ make_gap_larger (nbytes_added);
+#if defined USE_MMAP_FOR_BUFFERS || defined REL_ALLOC || defined DOUG_LEA_MALLOC
+ else
+ make_gap_smaller (-nbytes_added);
+#endif
+}
\f
/* Copy NBYTES bytes of text from FROM_ADDR to TO_ADDR.
FROM_MULTIBYTE says whether the incoming text is multibyte.
register int nchars, nbytes;
int inherit, prepare, before_markers;
{
+ if (nchars == 0)
+ return;
+
if (NILP (current_buffer->enable_multibyte_characters))
nchars = 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
if (! EQ (current_buffer->undo_list, Qt))
deletion = make_buffer_string_both (from, from_byte, to, to_byte, 1);
- if (markers)
- /* Relocate all markers pointing into the new, larger gap
- to point at the end of the text before the gap.
- Do this before recording the deletion,
- so that undo handles this after reinserting the text. */
- adjust_markers_for_delete (from, from_byte, to, to_byte);
-
GAP_SIZE += nbytes_del;
ZV -= nchars_del;
Z -= nchars_del;
adjusting the markers that bound the overlays. */
adjust_overlays_for_delete (from, nchars_del);
adjust_overlays_for_insert (from, inschars);
+
+ /* Adjust markers for the deletion and the insertion. */
if (markers)
- adjust_markers_for_insert (from, from_byte,
- from + inschars, from_byte + outgoing_insbytes,
- 0);
+ adjust_markers_for_replace (from, from_byte, nchars_del, nbytes_del,
+ inschars, outgoing_insbytes);
offset_intervals (current_buffer, from, inschars - nchars_del);
}
DEFUN ("combine-after-change-execute", Fcombine_after_change_execute,
- Scombine_after_change_execute, 0, 0, 0,
- "This function is for use internally in `combine-after-change-calls'.")
- ()
+ Scombine_after_change_execute, 0, 0, 0,
+ doc: /* This function is for use internally in `combine-after-change-calls'. */)
+ ()
{
int count = specpdl_ptr - specpdl;
int beg, end, change;
combine_after_change_buffer = Qnil;
DEFVAR_BOOL ("check-markers-debug-flag", &check_markers_debug_flag,
- "Non-nil means enable debugging checks for invalid marker positions.");
+ 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,
- "Used internally by the `combine-after-change-calls' macro.");
+ doc: /* Used internally by the `combine-after-change-calls' macro. */);
Vcombine_after_change_calls = Qnil;
DEFVAR_BOOL ("inhibit-modification-hooks", &inhibit_modification_hooks,
- "Non-nil means don't run any of the hooks that respond to buffer changes.\n\
-This affects `before-change-functions' and `after-change-functions',\n\
-as well as hooks attached to text properties and overlays.");
+ 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");
staticpro (&Qinhibit_modification_hooks);