diff options
| author | Kenichi Handa | 1998-10-28 07:52:13 +0000 |
|---|---|---|
| committer | Kenichi Handa | 1998-10-28 07:52:13 +0000 |
| commit | 9f3ede3ccc877c3be4a56463a4c85f1edd1549b2 (patch) | |
| tree | 88b078b2f52068f4a222222b4646227a06a00009 /src | |
| parent | 3f5409d35bb98c63ce460bac3ca41a8377a49f36 (diff) | |
| download | emacs-9f3ede3ccc877c3be4a56463a4c85f1edd1549b2.tar.gz emacs-9f3ede3ccc877c3be4a56463a4c85f1edd1549b2.zip | |
(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.
Diffstat (limited to 'src')
| -rw-r--r-- | src/insdel.c | 67 |
1 files changed, 61 insertions, 6 deletions
diff --git a/src/insdel.c b/src/insdel.c index 2258f2c2ab9..70646a2805e 100644 --- a/src/insdel.c +++ b/src/insdel.c | |||
| @@ -78,6 +78,7 @@ void | |||
| 78 | check_markers () | 78 | check_markers () |
| 79 | { | 79 | { |
| 80 | register Lisp_Object tail, prev, next; | 80 | register Lisp_Object tail, prev, next; |
| 81 | int multibyte = ! NILP (current_buffer->enable_multibyte_characters); | ||
| 81 | 82 | ||
| 82 | tail = BUF_MARKERS (current_buffer); | 83 | tail = BUF_MARKERS (current_buffer); |
| 83 | 84 | ||
| @@ -89,6 +90,8 @@ check_markers () | |||
| 89 | abort (); | 90 | abort (); |
| 90 | if (XMARKER (tail)->bytepos > Z_BYTE) | 91 | if (XMARKER (tail)->bytepos > Z_BYTE) |
| 91 | abort (); | 92 | abort (); |
| 93 | if (multibyte && ! CHAR_HEAD_P (FETCH_BYTE (XMARKER (tail)->bytepos))) | ||
| 94 | abort (); | ||
| 92 | 95 | ||
| 93 | tail = XMARKER (tail)->chain; | 96 | tail = XMARKER (tail)->chain; |
| 94 | } | 97 | } |
| @@ -494,6 +497,10 @@ adjust_markers_for_insert (from, from_byte, to, to_byte, | |||
| 494 | Point the marker after the combined character, | 497 | Point the marker after the combined character, |
| 495 | so that undoing the insertion puts it back where it was. */ | 498 | so that undoing the insertion puts it back where it was. */ |
| 496 | m->bytepos += combined_before_bytes; | 499 | m->bytepos += combined_before_bytes; |
| 500 | if (combined_before_bytes == nbytes) | ||
| 501 | /* All new bytes plus combined_after_bytes (if any) | ||
| 502 | are combined. */ | ||
| 503 | m->bytepos += combined_after_bytes; | ||
| 497 | } | 504 | } |
| 498 | } | 505 | } |
| 499 | /* If a marker was pointing into the combining bytes | 506 | /* If a marker was pointing into the combining bytes |
| @@ -906,7 +913,7 @@ count_combining_before (string, length, pos, pos_byte) | |||
| 906 | return 0; | 913 | return 0; |
| 907 | if (length == 0 || CHAR_HEAD_P (*string)) | 914 | if (length == 0 || CHAR_HEAD_P (*string)) |
| 908 | return 0; | 915 | return 0; |
| 909 | if (pos == BEGV) | 916 | if (pos == BEG) |
| 910 | return 0; | 917 | return 0; |
| 911 | c = FETCH_BYTE (pos_byte - 1); | 918 | c = FETCH_BYTE (pos_byte - 1); |
| 912 | if (ASCII_BYTE_P (c)) | 919 | if (ASCII_BYTE_P (c)) |
| @@ -963,12 +970,12 @@ count_combining_after (string, length, pos, pos_byte) | |||
| 963 | else if (!BASE_LEADING_CODE_P (string[i])) | 970 | else if (!BASE_LEADING_CODE_P (string[i])) |
| 964 | return 0; | 971 | return 0; |
| 965 | 972 | ||
| 966 | if (pos == ZV) | 973 | if (pos == Z) |
| 967 | return 0; | 974 | return 0; |
| 968 | c = FETCH_BYTE (pos_byte); | 975 | c = FETCH_BYTE (pos_byte); |
| 969 | if (CHAR_HEAD_P (c)) | 976 | if (CHAR_HEAD_P (c)) |
| 970 | return 0; | 977 | return 0; |
| 971 | while (pos_byte < ZV_BYTE) | 978 | while (pos_byte < Z_BYTE) |
| 972 | { | 979 | { |
| 973 | c = FETCH_BYTE (pos_byte); | 980 | c = FETCH_BYTE (pos_byte); |
| 974 | if (CHAR_HEAD_P (c)) | 981 | if (CHAR_HEAD_P (c)) |
| @@ -1021,6 +1028,16 @@ combine_bytes (pos, pos_byte, nbytes) | |||
| 1021 | /* Only defined if Emacs is compiled with USE_TEXT_PROPERTIES. */ | 1028 | /* Only defined if Emacs is compiled with USE_TEXT_PROPERTIES. */ |
| 1022 | offset_intervals (current_buffer, pos, - nbytes); | 1029 | offset_intervals (current_buffer, pos, - nbytes); |
| 1023 | } | 1030 | } |
| 1031 | |||
| 1032 | /* If we are going to combine bytes at POS which is at a narrowed | ||
| 1033 | region boundary, signal an error. */ | ||
| 1034 | #define CHECK_BYTE_COMBINING_FOR_INSERT(pos) \ | ||
| 1035 | do { \ | ||
| 1036 | if (combined_before_bytes && pos == BEGV \ | ||
| 1037 | || combined_after_bytes && pos == ZV) \ | ||
| 1038 | error ("Byte combining across region boundary inhibitted"); \ | ||
| 1039 | } while (0) | ||
| 1040 | |||
| 1024 | 1041 | ||
| 1025 | /* Insert a sequence of NCHARS chars which occupy NBYTES bytes | 1042 | /* Insert a sequence of NCHARS chars which occupy NBYTES bytes |
| 1026 | starting at STRING. INHERIT, PREPARE and BEFORE_MARKERS | 1043 | starting at STRING. INHERIT, PREPARE and BEFORE_MARKERS |
| @@ -1053,6 +1070,7 @@ insert_1_both (string, nchars, nbytes, inherit, prepare, before_markers) | |||
| 1053 | = count_combining_before (string, nbytes, PT, PT_BYTE); | 1070 | = count_combining_before (string, nbytes, PT, PT_BYTE); |
| 1054 | combined_after_bytes | 1071 | combined_after_bytes |
| 1055 | = count_combining_after (string, nbytes, PT, PT_BYTE); | 1072 | = count_combining_after (string, nbytes, PT, PT_BYTE); |
| 1073 | CHECK_BYTE_COMBINING_FOR_INSERT (PT); | ||
| 1056 | 1074 | ||
| 1057 | /* Record deletion of the surrounding text that combines with | 1075 | /* Record deletion of the surrounding text that combines with |
| 1058 | the insertion. This, together with recording the insertion, | 1076 | the insertion. This, together with recording the insertion, |
| @@ -1239,6 +1257,11 @@ insert_from_string_1 (string, pos, pos_byte, nchars, nbytes, | |||
| 1239 | = count_combining_before (GPT_ADDR, outgoing_nbytes, PT, PT_BYTE); | 1257 | = count_combining_before (GPT_ADDR, outgoing_nbytes, PT, PT_BYTE); |
| 1240 | combined_after_bytes | 1258 | combined_after_bytes |
| 1241 | = count_combining_after (GPT_ADDR, outgoing_nbytes, PT, PT_BYTE); | 1259 | = count_combining_after (GPT_ADDR, outgoing_nbytes, PT, PT_BYTE); |
| 1260 | { | ||
| 1261 | unsigned char save = *(GPT_ADDR); | ||
| 1262 | CHECK_BYTE_COMBINING_FOR_INSERT (PT); | ||
| 1263 | *(GPT_ADDR) = save; | ||
| 1264 | } | ||
| 1242 | 1265 | ||
| 1243 | /* Record deletion of the surrounding text that combines with | 1266 | /* Record deletion of the surrounding text that combines with |
| 1244 | the insertion. This, together with recording the insertion, | 1267 | the insertion. This, together with recording the insertion, |
| @@ -1418,8 +1441,12 @@ insert_from_buffer_1 (buf, from, nchars, inherit) | |||
| 1418 | combined_before_bytes | 1441 | combined_before_bytes |
| 1419 | = count_combining_before (GPT_ADDR, outgoing_nbytes, PT, PT_BYTE); | 1442 | = count_combining_before (GPT_ADDR, outgoing_nbytes, PT, PT_BYTE); |
| 1420 | combined_after_bytes | 1443 | combined_after_bytes |
| 1421 | = count_combining_after (GPT_ADDR, outgoing_nbytes, | 1444 | = count_combining_after (GPT_ADDR, outgoing_nbytes, PT, PT_BYTE); |
| 1422 | PT, PT_BYTE); | 1445 | { |
| 1446 | unsigned char save = *(GPT_ADDR); | ||
| 1447 | CHECK_BYTE_COMBINING_FOR_INSERT (PT); | ||
| 1448 | *(GPT_ADDR) = save; | ||
| 1449 | } | ||
| 1423 | 1450 | ||
| 1424 | /* Record deletion of the surrounding text that combines with | 1451 | /* Record deletion of the surrounding text that combines with |
| 1425 | the insertion. This, together with recording the insertion, | 1452 | the insertion. This, together with recording the insertion, |
| @@ -1561,6 +1588,16 @@ adjust_after_replace (from, from_byte, prev_text, len, len_byte) | |||
| 1561 | nbytes_del = STRING_BYTES (XSTRING (prev_text)); | 1588 | nbytes_del = STRING_BYTES (XSTRING (prev_text)); |
| 1562 | } | 1589 | } |
| 1563 | 1590 | ||
| 1591 | if (combined_before_bytes && from == BEGV | ||
| 1592 | || combined_after_bytes && from == ZV) | ||
| 1593 | { | ||
| 1594 | /* We can't combine bytes nor signal an error here. So, let's | ||
| 1595 | pretend that the new text is just a single space. */ | ||
| 1596 | len = len_byte = 1; | ||
| 1597 | combined_before_bytes = combined_after_bytes = 0; | ||
| 1598 | *(GPT_ADDR) = ' '; | ||
| 1599 | } | ||
| 1600 | |||
| 1564 | if (combined_after_bytes) | 1601 | if (combined_after_bytes) |
| 1565 | { | 1602 | { |
| 1566 | Lisp_Object deletion; | 1603 | Lisp_Object deletion; |
| @@ -1656,6 +1693,10 @@ adjust_after_replace (from, from_byte, prev_text, len, len_byte) | |||
| 1656 | combine_bytes (from, from_byte, combined_before_bytes); | 1693 | combine_bytes (from, from_byte, combined_before_bytes); |
| 1657 | } | 1694 | } |
| 1658 | 1695 | ||
| 1696 | /* As byte combining will decrease Z, we must check this again. */ | ||
| 1697 | if (Z - GPT < end_unchanged) | ||
| 1698 | end_unchanged = Z - GPT; | ||
| 1699 | |||
| 1659 | CHECK_MARKERS (); | 1700 | CHECK_MARKERS (); |
| 1660 | 1701 | ||
| 1661 | if (len == 0) | 1702 | if (len == 0) |
| @@ -1810,6 +1851,11 @@ replace_range (from, to, new, prepare, inherit, markers) | |||
| 1810 | = count_combining_before (GPT_ADDR, outgoing_insbytes, from, from_byte); | 1851 | = count_combining_before (GPT_ADDR, outgoing_insbytes, from, from_byte); |
| 1811 | combined_after_bytes | 1852 | combined_after_bytes |
| 1812 | = count_combining_after (GPT_ADDR, outgoing_insbytes, from, from_byte); | 1853 | = count_combining_after (GPT_ADDR, outgoing_insbytes, from, from_byte); |
| 1854 | { | ||
| 1855 | unsigned char save = *(GPT_ADDR); | ||
| 1856 | CHECK_BYTE_COMBINING_FOR_INSERT (from); | ||
| 1857 | *(GPT_ADDR) = save; | ||
| 1858 | } | ||
| 1813 | 1859 | ||
| 1814 | /* Record deletion of the surrounding text that combines with | 1860 | /* Record deletion of the surrounding text that combines with |
| 1815 | the insertion. This, together with recording the insertion, | 1861 | the insertion. This, together with recording the insertion, |
| @@ -1912,6 +1958,10 @@ replace_range (from, to, new, prepare, inherit, markers) | |||
| 1912 | if (combined_before_bytes) | 1958 | if (combined_before_bytes) |
| 1913 | combine_bytes (from, from_byte, combined_before_bytes); | 1959 | combine_bytes (from, from_byte, combined_before_bytes); |
| 1914 | 1960 | ||
| 1961 | /* As byte combining will decrease Z, we must check this again. */ | ||
| 1962 | if (Z - GPT < end_unchanged) | ||
| 1963 | end_unchanged = Z - GPT; | ||
| 1964 | |||
| 1915 | if (outgoing_insbytes == 0) | 1965 | if (outgoing_insbytes == 0) |
| 1916 | evaporate_overlays (from); | 1966 | evaporate_overlays (from); |
| 1917 | 1967 | ||
| @@ -2063,9 +2113,11 @@ del_range_2 (from, from_byte, to, to_byte) | |||
| 2063 | 2113 | ||
| 2064 | combined_after_bytes | 2114 | combined_after_bytes |
| 2065 | = count_combining_before (BUF_BYTE_ADDRESS (current_buffer, to_byte), | 2115 | = count_combining_before (BUF_BYTE_ADDRESS (current_buffer, to_byte), |
| 2066 | ZV_BYTE - to_byte, from, from_byte); | 2116 | Z_BYTE - to_byte, from, from_byte); |
| 2067 | if (combined_after_bytes) | 2117 | if (combined_after_bytes) |
| 2068 | { | 2118 | { |
| 2119 | if (to == ZV_BYTE) | ||
| 2120 | error ("Byte combining across region boundary inhibitted"); | ||
| 2069 | from_byte_1 = from_byte; | 2121 | from_byte_1 = from_byte; |
| 2070 | DEC_POS (from_byte_1); | 2122 | DEC_POS (from_byte_1); |
| 2071 | } | 2123 | } |
| @@ -2152,6 +2204,9 @@ del_range_2 (from, from_byte, to, to_byte) | |||
| 2152 | combine_bytes (from, from_byte, combined_after_bytes); | 2204 | combine_bytes (from, from_byte, combined_after_bytes); |
| 2153 | 2205 | ||
| 2154 | record_insert (GPT - 1, 1); | 2206 | record_insert (GPT - 1, 1); |
| 2207 | |||
| 2208 | if (Z - GPT < end_unchanged) | ||
| 2209 | end_unchanged = Z - GPT; | ||
| 2155 | } | 2210 | } |
| 2156 | 2211 | ||
| 2157 | CHECK_MARKERS (); | 2212 | CHECK_MARKERS (); |