diff options
| author | Kenichi Handa | 2000-05-19 23:50:26 +0000 |
|---|---|---|
| committer | Kenichi Handa | 2000-05-19 23:50:26 +0000 |
| commit | a9bcded1f3d845d5dd65a52d749477ecf5aa3f93 (patch) | |
| tree | 003bbe0e5457724f5116910fd81bfd85c1f342fa /src | |
| parent | 9eac9d597c990e4b57c2ca079e5b57f2eb1270ae (diff) | |
| download | emacs-a9bcded1f3d845d5dd65a52d749477ecf5aa3f93.tar.gz emacs-a9bcded1f3d845d5dd65a52d749477ecf5aa3f93.zip | |
(advance_to_char_boundary): Don't use DEC_POS to find a
apparent char boundary.
(Fset_buffer_multibyte): Convert 8-bit characters in the range
0x80..0x9F to/from multibyte form.
Diffstat (limited to 'src')
| -rw-r--r-- | src/buffer.c | 120 |
1 files changed, 115 insertions, 5 deletions
diff --git a/src/buffer.c b/src/buffer.c index 6550d6ac342..9587ec7d77c 100644 --- a/src/buffer.c +++ b/src/buffer.c | |||
| @@ -1843,8 +1843,17 @@ advance_to_char_boundary (byte_pos) | |||
| 1843 | { | 1843 | { |
| 1844 | /* We should advance BYTE_POS only when C is a constituent of a | 1844 | /* We should advance BYTE_POS only when C is a constituent of a |
| 1845 | multibyte sequence. */ | 1845 | multibyte sequence. */ |
| 1846 | DEC_POS (byte_pos); | 1846 | int orig_byte_pos = byte_pos; |
| 1847 | |||
| 1848 | do | ||
| 1849 | { | ||
| 1850 | byte_pos--; | ||
| 1851 | c = FETCH_BYTE (byte_pos); | ||
| 1852 | } | ||
| 1853 | while (! CHAR_HEAD_P (c) && byte_pos > BEG); | ||
| 1847 | INC_POS (byte_pos); | 1854 | INC_POS (byte_pos); |
| 1855 | if (byte_pos < orig_byte_pos) | ||
| 1856 | byte_pos = orig_byte_pos; | ||
| 1848 | /* If C is a constituent of a multibyte sequence, BYTE_POS was | 1857 | /* If C is a constituent of a multibyte sequence, BYTE_POS was |
| 1849 | surely advance to the correct character boundary. If C is | 1858 | surely advance to the correct character boundary. If C is |
| 1850 | not, BYTE_POS was unchanged. */ | 1859 | not, BYTE_POS was unchanged. */ |
| @@ -1865,6 +1874,9 @@ but the contents viewed as characters do change.") | |||
| 1865 | { | 1874 | { |
| 1866 | Lisp_Object tail, markers; | 1875 | Lisp_Object tail, markers; |
| 1867 | struct buffer *other; | 1876 | struct buffer *other; |
| 1877 | int undo_enabled_p = !EQ (current_buffer->undo_list, Qt); | ||
| 1878 | int begv = BEGV, zv = ZV; | ||
| 1879 | int narrowed = (BEG != begv || Z != zv); | ||
| 1868 | 1880 | ||
| 1869 | if (current_buffer->base_buffer) | 1881 | if (current_buffer->base_buffer) |
| 1870 | error ("Cannot do `set-buffer-multibyte' on an indirect buffer"); | 1882 | error ("Cannot do `set-buffer-multibyte' on an indirect buffer"); |
| @@ -1875,14 +1887,20 @@ but the contents viewed as characters do change.") | |||
| 1875 | 1887 | ||
| 1876 | /* It would be better to update the list, | 1888 | /* It would be better to update the list, |
| 1877 | but this is good enough for now. */ | 1889 | but this is good enough for now. */ |
| 1878 | if (! EQ (current_buffer->undo_list, Qt)) | 1890 | if (undo_enabled_p) |
| 1879 | current_buffer->undo_list = Qnil; | 1891 | current_buffer->undo_list = Qt; |
| 1880 | 1892 | ||
| 1881 | /* If the cached position is for this buffer, clear it out. */ | 1893 | /* If the cached position is for this buffer, clear it out. */ |
| 1882 | clear_charpos_cache (current_buffer); | 1894 | clear_charpos_cache (current_buffer); |
| 1883 | 1895 | ||
| 1896 | if (narrowed) | ||
| 1897 | Fwiden (); | ||
| 1898 | |||
| 1884 | if (NILP (flag)) | 1899 | if (NILP (flag)) |
| 1885 | { | 1900 | { |
| 1901 | int pos, stop; | ||
| 1902 | unsigned char *p; | ||
| 1903 | |||
| 1886 | /* Do this first, so it can use CHAR_TO_BYTE | 1904 | /* Do this first, so it can use CHAR_TO_BYTE |
| 1887 | to calculate the old correspondences. */ | 1905 | to calculate the old correspondences. */ |
| 1888 | set_intervals_multibyte (0); | 1906 | set_intervals_multibyte (0); |
| @@ -1901,12 +1919,54 @@ but the contents viewed as characters do change.") | |||
| 1901 | XMARKER (tail)->charpos = XMARKER (tail)->bytepos; | 1919 | XMARKER (tail)->charpos = XMARKER (tail)->bytepos; |
| 1902 | tail = XMARKER (tail)->chain; | 1920 | tail = XMARKER (tail)->chain; |
| 1903 | } | 1921 | } |
| 1922 | |||
| 1923 | /* Convert multibyte form of 8-bit characters to unibyte. */ | ||
| 1924 | pos = BEG; | ||
| 1925 | stop = GPT; | ||
| 1926 | p = BEG_ADDR; | ||
| 1927 | while (1) | ||
| 1928 | { | ||
| 1929 | int c, bytes; | ||
| 1930 | |||
| 1931 | if (pos == stop) | ||
| 1932 | { | ||
| 1933 | if (pos == Z) | ||
| 1934 | break; | ||
| 1935 | p = GAP_END_ADDR; | ||
| 1936 | stop = Z; | ||
| 1937 | } | ||
| 1938 | if (MULTIBYTE_STR_AS_UNIBYTE_P (p, bytes)) | ||
| 1939 | p += bytes, pos += bytes; | ||
| 1940 | else | ||
| 1941 | { | ||
| 1942 | c = STRING_CHAR (p, stop - pos); | ||
| 1943 | /* Delete all bytes for this 8-bit character but the | ||
| 1944 | last one, and change the last one to the charcter | ||
| 1945 | code. */ | ||
| 1946 | bytes--; | ||
| 1947 | del_range_2 (pos, pos, pos + bytes, pos + bytes, 0); | ||
| 1948 | p = GAP_END_ADDR; | ||
| 1949 | *p++ = c; | ||
| 1950 | pos++; | ||
| 1951 | if (begv > pos) | ||
| 1952 | begv -= bytes; | ||
| 1953 | if (zv > pos) | ||
| 1954 | zv -= bytes; | ||
| 1955 | stop = Z; | ||
| 1956 | } | ||
| 1957 | } | ||
| 1958 | if (narrowed) | ||
| 1959 | Fnarrow_to_region (make_number (begv), make_number (zv)); | ||
| 1904 | } | 1960 | } |
| 1905 | else | 1961 | else |
| 1906 | { | 1962 | { |
| 1963 | int pt = PT; | ||
| 1964 | int pos, stop; | ||
| 1965 | unsigned char *p; | ||
| 1966 | |||
| 1907 | /* Be sure not to have a multibyte sequence striding over the GAP. | 1967 | /* Be sure not to have a multibyte sequence striding over the GAP. |
| 1908 | Ex: We change this: "...abc\201\241\241 _GAP_ \241\241\241..." | 1968 | Ex: We change this: "...abc\201 _GAP_ \241def..." |
| 1909 | to: "...abc _GAP_ \201\241\241\241\241\241..." */ | 1969 | to: "...abc _GAP_ \201\241def..." */ |
| 1910 | 1970 | ||
| 1911 | if (GPT_BYTE > 1 && GPT_BYTE < Z_BYTE | 1971 | if (GPT_BYTE > 1 && GPT_BYTE < Z_BYTE |
| 1912 | && ! CHAR_HEAD_P (*(GAP_END_ADDR))) | 1972 | && ! CHAR_HEAD_P (*(GAP_END_ADDR))) |
| @@ -1922,6 +1982,53 @@ but the contents viewed as characters do change.") | |||
| 1922 | } | 1982 | } |
| 1923 | } | 1983 | } |
| 1924 | 1984 | ||
| 1985 | /* Make the buffer contents valid as multibyte by converting | ||
| 1986 | 8-bit characters to multibyte form. */ | ||
| 1987 | pos = BEG; | ||
| 1988 | stop = GPT; | ||
| 1989 | p = BEG_ADDR; | ||
| 1990 | while (1) | ||
| 1991 | { | ||
| 1992 | int bytes; | ||
| 1993 | |||
| 1994 | if (pos == stop) | ||
| 1995 | { | ||
| 1996 | if (pos == Z) | ||
| 1997 | break; | ||
| 1998 | p = GAP_END_ADDR; | ||
| 1999 | stop = Z; | ||
| 2000 | } | ||
| 2001 | |||
| 2002 | if (UNIBYTE_STR_AS_MULTIBYTE_P (p, stop - pos, bytes)) | ||
| 2003 | p += bytes, pos += bytes; | ||
| 2004 | else | ||
| 2005 | { | ||
| 2006 | unsigned char tmp[MAX_MULTIBYTE_LENGTH]; | ||
| 2007 | |||
| 2008 | bytes = CHAR_STRING (*p, tmp); | ||
| 2009 | *p = tmp[0]; | ||
| 2010 | TEMP_SET_PT_BOTH (pos + 1, pos + 1); | ||
| 2011 | bytes--; | ||
| 2012 | insert_1_both (tmp + 1, bytes, bytes, 1, 0, 0); | ||
| 2013 | /* Now the gap is after the just inserted data. */ | ||
| 2014 | pos = GPT; | ||
| 2015 | p = GAP_END_ADDR; | ||
| 2016 | if (pos <= begv) | ||
| 2017 | begv += bytes; | ||
| 2018 | if (pos <= zv) | ||
| 2019 | zv += bytes; | ||
| 2020 | if (pos <= pt) | ||
| 2021 | pt += bytes; | ||
| 2022 | stop = Z; | ||
| 2023 | } | ||
| 2024 | } | ||
| 2025 | |||
| 2026 | if (pt != PT) | ||
| 2027 | TEMP_SET_PT (pt); | ||
| 2028 | |||
| 2029 | if (narrowed) | ||
| 2030 | Fnarrow_to_region (make_number (begv), make_number (zv)); | ||
| 2031 | |||
| 1925 | /* Do this first, so that chars_in_text asks the right question. | 2032 | /* Do this first, so that chars_in_text asks the right question. |
| 1926 | set_intervals_multibyte needs it too. */ | 2033 | set_intervals_multibyte needs it too. */ |
| 1927 | current_buffer->enable_multibyte_characters = Qt; | 2034 | current_buffer->enable_multibyte_characters = Qt; |
| @@ -1982,6 +2089,9 @@ but the contents viewed as characters do change.") | |||
| 1982 | set_intervals_multibyte (1); | 2089 | set_intervals_multibyte (1); |
| 1983 | } | 2090 | } |
| 1984 | 2091 | ||
| 2092 | if (undo_enabled_p) | ||
| 2093 | current_buffer->undo_list = Qnil; | ||
| 2094 | |||
| 1985 | /* Changing the multibyteness of a buffer means that all windows | 2095 | /* Changing the multibyteness of a buffer means that all windows |
| 1986 | showing that buffer must be updated thoroughly. */ | 2096 | showing that buffer must be updated thoroughly. */ |
| 1987 | current_buffer->prevent_redisplay_optimizations_p = 1; | 2097 | current_buffer->prevent_redisplay_optimizations_p = 1; |