check_markers ()
{
register Lisp_Object tail, prev, next;
+ int multibyte = ! NILP (current_buffer->enable_multibyte_characters);
tail = BUF_MARKERS (current_buffer);
abort ();
if (XMARKER (tail)->bytepos > Z_BYTE)
abort ();
+ if (multibyte && ! CHAR_HEAD_P (FETCH_BYTE (XMARKER (tail)->bytepos)))
+ abort ();
tail = XMARKER (tail)->chain;
}
Point the marker after the combined character,
so that undoing the insertion puts it back where it was. */
m->bytepos += combined_before_bytes;
+ if (combined_before_bytes == nbytes)
+ /* All new bytes plus combined_after_bytes (if any)
+ are combined. */
+ m->bytepos += combined_after_bytes;
}
}
/* If a marker was pointing into the combining bytes
return 0;
if (length == 0 || CHAR_HEAD_P (*string))
return 0;
- if (pos == BEGV)
+ if (pos == BEG)
return 0;
c = FETCH_BYTE (pos_byte - 1);
if (ASCII_BYTE_P (c))
else if (!BASE_LEADING_CODE_P (string[i]))
return 0;
- if (pos == ZV)
+ if (pos == Z)
return 0;
c = FETCH_BYTE (pos_byte);
if (CHAR_HEAD_P (c))
return 0;
- while (pos_byte < ZV_BYTE)
+ while (pos_byte < Z_BYTE)
{
c = FETCH_BYTE (pos_byte);
if (CHAR_HEAD_P (c))
/* Only defined if Emacs is compiled with USE_TEXT_PROPERTIES. */
offset_intervals (current_buffer, pos, - nbytes);
}
+
+/* If we are going to combine bytes at POS which is at a narrowed
+ region boundary, signal an error. */
+#define CHECK_BYTE_COMBINING_FOR_INSERT(pos) \
+ do { \
+ if (combined_before_bytes && pos == BEGV \
+ || combined_after_bytes && pos == ZV) \
+ error ("Byte combining across region boundary inhibitted"); \
+ } while (0)
+
\f
/* Insert a sequence of NCHARS chars which occupy NBYTES bytes
starting at STRING. INHERIT, PREPARE and BEFORE_MARKERS
= count_combining_before (string, nbytes, PT, PT_BYTE);
combined_after_bytes
= count_combining_after (string, nbytes, PT, PT_BYTE);
+ CHECK_BYTE_COMBINING_FOR_INSERT (PT);
/* Record deletion of the surrounding text that combines with
the insertion. This, together with recording the insertion,
= count_combining_before (GPT_ADDR, outgoing_nbytes, PT, PT_BYTE);
combined_after_bytes
= count_combining_after (GPT_ADDR, outgoing_nbytes, PT, PT_BYTE);
+ {
+ unsigned char save = *(GPT_ADDR);
+ CHECK_BYTE_COMBINING_FOR_INSERT (PT);
+ *(GPT_ADDR) = save;
+ }
/* Record deletion of the surrounding text that combines with
the insertion. This, together with recording the insertion,
combined_before_bytes
= count_combining_before (GPT_ADDR, outgoing_nbytes, PT, PT_BYTE);
combined_after_bytes
- = count_combining_after (GPT_ADDR, outgoing_nbytes,
- PT, PT_BYTE);
+ = count_combining_after (GPT_ADDR, outgoing_nbytes, PT, PT_BYTE);
+ {
+ unsigned char save = *(GPT_ADDR);
+ CHECK_BYTE_COMBINING_FOR_INSERT (PT);
+ *(GPT_ADDR) = save;
+ }
/* Record deletion of the surrounding text that combines with
the insertion. This, together with recording the insertion,
nbytes_del = STRING_BYTES (XSTRING (prev_text));
}
+ if (combined_before_bytes && from == BEGV
+ || combined_after_bytes && from == ZV)
+ {
+ /* We can't combine bytes nor signal an error here. So, let's
+ pretend that the new text is just a single space. */
+ len = len_byte = 1;
+ combined_before_bytes = combined_after_bytes = 0;
+ *(GPT_ADDR) = ' ';
+ }
+
if (combined_after_bytes)
{
Lisp_Object deletion;
combine_bytes (from, from_byte, combined_before_bytes);
}
+ /* 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)
= count_combining_before (GPT_ADDR, outgoing_insbytes, from, from_byte);
combined_after_bytes
= count_combining_after (GPT_ADDR, outgoing_insbytes, from, from_byte);
+ {
+ unsigned char save = *(GPT_ADDR);
+ CHECK_BYTE_COMBINING_FOR_INSERT (from);
+ *(GPT_ADDR) = save;
+ }
/* Record deletion of the surrounding text that combines with
the insertion. This, together with recording the insertion,
if (combined_before_bytes)
combine_bytes (from, from_byte, combined_before_bytes);
+ /* As byte combining will decrease Z, we must check this again. */
+ if (Z - GPT < end_unchanged)
+ end_unchanged = Z - GPT;
+
if (outgoing_insbytes == 0)
evaporate_overlays (from);
combined_after_bytes
= count_combining_before (BUF_BYTE_ADDRESS (current_buffer, to_byte),
- ZV_BYTE - to_byte, from, from_byte);
+ Z_BYTE - to_byte, from, from_byte);
if (combined_after_bytes)
{
+ if (to == ZV_BYTE)
+ error ("Byte combining across region boundary inhibitted");
from_byte_1 = from_byte;
DEC_POS (from_byte_1);
}
combine_bytes (from, from_byte, combined_after_bytes);
record_insert (GPT - 1, 1);
+
+ if (Z - GPT < end_unchanged)
+ end_unchanged = Z - GPT;
}
CHECK_MARKERS ();