aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorKenichi Handa2000-05-19 23:50:26 +0000
committerKenichi Handa2000-05-19 23:50:26 +0000
commita9bcded1f3d845d5dd65a52d749477ecf5aa3f93 (patch)
tree003bbe0e5457724f5116910fd81bfd85c1f342fa /src
parent9eac9d597c990e4b57c2ca079e5b57f2eb1270ae (diff)
downloademacs-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.c120
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;