# HG changeset patch # User Kenichi Handa # Date 909561133 0 # Node ID 25baa4bda79dd35b3b2cbb1ac8ec43192d954783 # Parent 077655e1e014766117c8f4bf220690d2517d100a (check_markers): Check if markers are at character boundry. (adjust_markers_for_insert): Fix previous change. (count_combining_before): Don't limit the check at BEGV. (count_combining_after): Don't limit the check at ZV. (CHECK_BYTE_COMBINING_FOR_INSERT): New macro. (insert_1_both): Call CHECK_BYTE_COMBINING_FOR_INSERT. (insert_from_string_1): Likewise. (insert_from_buffer_1): Likewise. (adjust_after_replace): Inhibit bytes combined across region boundary. Update end_unchanged correctly. (replace_range): Call CHECK_BYTE_COMBINING_FOR_INSERT. Update end_unchanged correctly. (del_range_2): Inhibit bytes combined across region boundary. Update end_unchanged correctly. diff -r 077655e1e014 -r 25baa4bda79d src/insdel.c --- a/src/insdel.c Wed Oct 28 07:52:13 1998 +0000 +++ b/src/insdel.c Wed Oct 28 07:52:13 1998 +0000 @@ -78,6 +78,7 @@ check_markers () { register Lisp_Object tail, prev, next; + int multibyte = ! NILP (current_buffer->enable_multibyte_characters); tail = BUF_MARKERS (current_buffer); @@ -89,6 +90,8 @@ abort (); if (XMARKER (tail)->bytepos > Z_BYTE) abort (); + if (multibyte && ! CHAR_HEAD_P (FETCH_BYTE (XMARKER (tail)->bytepos))) + abort (); tail = XMARKER (tail)->chain; } @@ -494,6 +497,10 @@ 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 @@ -906,7 +913,7 @@ 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)) @@ -963,12 +970,12 @@ 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)) @@ -1021,6 +1028,16 @@ /* 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) + /* Insert a sequence of NCHARS chars which occupy NBYTES bytes starting at STRING. INHERIT, PREPARE and BEFORE_MARKERS @@ -1053,6 +1070,7 @@ = 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, @@ -1239,6 +1257,11 @@ = 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, @@ -1418,8 +1441,12 @@ 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, @@ -1561,6 +1588,16 @@ 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; @@ -1656,6 +1693,10 @@ 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) @@ -1810,6 +1851,11 @@ = 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, @@ -1912,6 +1958,10 @@ 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); @@ -2063,9 +2113,11 @@ 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); } @@ -2152,6 +2204,9 @@ combine_bytes (from, from_byte, combined_after_bytes); record_insert (GPT - 1, 1); + + if (Z - GPT < end_unchanged) + end_unchanged = Z - GPT; } CHECK_MARKERS ();