diff options
| author | Kenichi Handa | 2002-07-31 07:04:55 +0000 |
|---|---|---|
| committer | Kenichi Handa | 2002-07-31 07:04:55 +0000 |
| commit | a3a303df4e5c81d27c1f787e806edf75d93b0c2c (patch) | |
| tree | 13bc9ea57089c3c0050815be398a57293f8e481b /src | |
| parent | d1a6e8e738f36120bb625765e65cc2e1e90281d6 (diff) | |
| download | emacs-a3a303df4e5c81d27c1f787e806edf75d93b0c2c.tar.gz emacs-a3a303df4e5c81d27c1f787e806edf75d93b0c2c.zip | |
(Qas, Qmake, Qto): New variables.
(Fset_buffer_multibyte): New optional arg METHOD. Caller changed.
(syms_of_buffer): Intern and staticpro Qas, Qmake, and Qto.
Diffstat (limited to 'src')
| -rw-r--r-- | src/buffer.c | 76 |
1 files changed, 65 insertions, 11 deletions
diff --git a/src/buffer.c b/src/buffer.c index f050305de59..b00bb5b06c2 100644 --- a/src/buffer.c +++ b/src/buffer.c | |||
| @@ -2012,15 +2012,30 @@ advance_to_char_boundary (byte_pos) | |||
| 2012 | return byte_pos; | 2012 | return byte_pos; |
| 2013 | } | 2013 | } |
| 2014 | 2014 | ||
| 2015 | |||
| 2016 | /* Symbols used as the 2nd arg of Fset_buffer_multibyte. */ | ||
| 2017 | static Lisp_Object Qas, Qmake, Qto; | ||
| 2018 | |||
| 2019 | |||
| 2015 | DEFUN ("set-buffer-multibyte", Fset_buffer_multibyte, Sset_buffer_multibyte, | 2020 | DEFUN ("set-buffer-multibyte", Fset_buffer_multibyte, Sset_buffer_multibyte, |
| 2016 | 1, 1, 0, | 2021 | 1, 2, 0, |
| 2017 | doc: /* Set the multibyte flag of the current buffer to FLAG. | 2022 | doc: /* Set the multibyte flag of the current buffer to FLAG. |
| 2018 | If FLAG is t, this makes the buffer a multibyte buffer. | 2023 | If FLAG is t, this makes the buffer a multibyte buffer. |
| 2019 | If FLAG is nil, this makes the buffer a single-byte buffer. | 2024 | If FLAG is nil, this makes the buffer a unibyte buffer. |
| 2020 | The buffer contents remain unchanged as a sequence of bytes | 2025 | |
| 2021 | but the contents viewed as characters do change. */) | 2026 | Optional second arg METHOD specifies how to convert the byte sequence |
| 2022 | (flag) | 2027 | of the buffer. |
| 2023 | Lisp_Object flag; | 2028 | |
| 2029 | If it is nil or `as', the buffer contents remain unchanged as a | ||
| 2030 | sequence of bytes but the contents viewed as characters do change. | ||
| 2031 | |||
| 2032 | If it is `make', convert each character by unibyte-char-to-multibyte | ||
| 2033 | or multibyte-char-to-unibyte. | ||
| 2034 | |||
| 2035 | If it is `to', convert each character by byte-to-char or | ||
| 2036 | char-to-byte. */) | ||
| 2037 | (flag, method) | ||
| 2038 | Lisp_Object flag, method; | ||
| 2024 | { | 2039 | { |
| 2025 | Lisp_Object tail, markers; | 2040 | Lisp_Object tail, markers; |
| 2026 | struct buffer *other; | 2041 | struct buffer *other; |
| @@ -2029,6 +2044,13 @@ but the contents viewed as characters do change. */) | |||
| 2029 | int narrowed = (BEG != begv || Z != zv); | 2044 | int narrowed = (BEG != begv || Z != zv); |
| 2030 | int modified_p = !NILP (Fbuffer_modified_p (Qnil)); | 2045 | int modified_p = !NILP (Fbuffer_modified_p (Qnil)); |
| 2031 | 2046 | ||
| 2047 | CHECK_SYMBOL (method); | ||
| 2048 | if (NILP (method)) | ||
| 2049 | method = Qas; | ||
| 2050 | else if (! EQ (method, Qas) && ! EQ (method, Qmake) && ! EQ (method, Qto)) | ||
| 2051 | error ("Invalid unibyte<->multibyte conversion method: %s", | ||
| 2052 | XSYMBOL (method)->name->data); | ||
| 2053 | |||
| 2032 | if (current_buffer->base_buffer) | 2054 | if (current_buffer->base_buffer) |
| 2033 | error ("Cannot do `set-buffer-multibyte' on an indirect buffer"); | 2055 | error ("Cannot do `set-buffer-multibyte' on an indirect buffer"); |
| 2034 | 2056 | ||
| @@ -2105,11 +2127,27 @@ but the contents viewed as characters do change. */) | |||
| 2105 | zv -= bytes; | 2127 | zv -= bytes; |
| 2106 | stop = Z; | 2128 | stop = Z; |
| 2107 | } | 2129 | } |
| 2108 | else | 2130 | else if (EQ (method, Qas)) |
| 2109 | { | 2131 | { |
| 2110 | bytes = BYTES_BY_CHAR_HEAD (*p); | 2132 | bytes = BYTES_BY_CHAR_HEAD (*p); |
| 2111 | p += bytes, pos += bytes; | 2133 | p += bytes, pos += bytes; |
| 2112 | } | 2134 | } |
| 2135 | else | ||
| 2136 | { | ||
| 2137 | /* Delete all bytes for this character but the last one, | ||
| 2138 | and change the last one to the unibyte code. */ | ||
| 2139 | c = STRING_CHAR_AND_LENGTH (p, stop - pos, bytes); | ||
| 2140 | bytes--; | ||
| 2141 | del_range_2 (pos, pos, pos + bytes, pos + bytes, 0); | ||
| 2142 | p = GAP_END_ADDR; | ||
| 2143 | *p++ = CHAR_TO_BYTE (c); | ||
| 2144 | pos++; | ||
| 2145 | if (begv > pos) | ||
| 2146 | begv -= bytes; | ||
| 2147 | if (zv > pos) | ||
| 2148 | zv -= bytes; | ||
| 2149 | stop = Z; | ||
| 2150 | } | ||
| 2113 | } | 2151 | } |
| 2114 | if (narrowed) | 2152 | if (narrowed) |
| 2115 | Fnarrow_to_region (make_number (begv), make_number (zv)); | 2153 | Fnarrow_to_region (make_number (begv), make_number (zv)); |
| @@ -2124,7 +2162,8 @@ but the contents viewed as characters do change. */) | |||
| 2124 | Ex: We change this: "...abc\302 _GAP_ \241def..." | 2162 | Ex: We change this: "...abc\302 _GAP_ \241def..." |
| 2125 | to: "...abc _GAP_ \302\241def..." */ | 2163 | to: "...abc _GAP_ \302\241def..." */ |
| 2126 | 2164 | ||
| 2127 | if (GPT_BYTE > 1 && GPT_BYTE < Z_BYTE | 2165 | if (EQ (method, Qas) |
| 2166 | && GPT_BYTE > 1 && GPT_BYTE < Z_BYTE | ||
| 2128 | && ! CHAR_HEAD_P (*(GAP_END_ADDR))) | 2167 | && ! CHAR_HEAD_P (*(GAP_END_ADDR))) |
| 2129 | { | 2168 | { |
| 2130 | unsigned char *p = GPT_ADDR - 1; | 2169 | unsigned char *p = GPT_ADDR - 1; |
| @@ -2157,12 +2196,20 @@ but the contents viewed as characters do change. */) | |||
| 2157 | stop = Z; | 2196 | stop = Z; |
| 2158 | } | 2197 | } |
| 2159 | 2198 | ||
| 2160 | if ((bytes = MULTIBYTE_LENGTH (p, pend)) > 0) | 2199 | if (ASCII_BYTE_P (*p)) |
| 2200 | p++, pos++; | ||
| 2201 | else if (method == Qas | ||
| 2202 | && (bytes = MULTIBYTE_LENGTH (p, pend)) > 0) | ||
| 2161 | p += bytes, pos += bytes; | 2203 | p += bytes, pos += bytes; |
| 2162 | else | 2204 | else |
| 2163 | { | 2205 | { |
| 2164 | unsigned char tmp[MAX_MULTIBYTE_LENGTH]; | 2206 | unsigned char tmp[MAX_MULTIBYTE_LENGTH]; |
| 2165 | int c = BYTE8_TO_CHAR (*p); | 2207 | int c; |
| 2208 | |||
| 2209 | if (method == Qmake) | ||
| 2210 | c = unibyte_char_to_multibyte (*p); | ||
| 2211 | else | ||
| 2212 | c = BYTE8_TO_CHAR (*p); | ||
| 2166 | 2213 | ||
| 2167 | bytes = CHAR_STRING (c, tmp); | 2214 | bytes = CHAR_STRING (c, tmp); |
| 2168 | *p = tmp[0]; | 2215 | *p = tmp[0]; |
| @@ -4979,7 +5026,7 @@ init_buffer () | |||
| 4979 | 5026 | ||
| 4980 | Fset_buffer (Fget_buffer_create (build_string ("*scratch*"))); | 5027 | Fset_buffer (Fget_buffer_create (build_string ("*scratch*"))); |
| 4981 | if (NILP (buffer_defaults.enable_multibyte_characters)) | 5028 | if (NILP (buffer_defaults.enable_multibyte_characters)) |
| 4982 | Fset_buffer_multibyte (Qnil); | 5029 | Fset_buffer_multibyte (Qnil, Qnil); |
| 4983 | 5030 | ||
| 4984 | /* If PWD is accurate, use it instead of calling getwd. PWD is | 5031 | /* If PWD is accurate, use it instead of calling getwd. PWD is |
| 4985 | sometimes a nicer name, and using it may avoid a fatal error if a | 5032 | sometimes a nicer name, and using it may avoid a fatal error if a |
| @@ -5073,6 +5120,13 @@ syms_of_buffer () | |||
| 5073 | Qafter_change_functions = intern ("after-change-functions"); | 5120 | Qafter_change_functions = intern ("after-change-functions"); |
| 5074 | staticpro (&Qafter_change_functions); | 5121 | staticpro (&Qafter_change_functions); |
| 5075 | 5122 | ||
| 5123 | Qas = intern ("as"); | ||
| 5124 | staticpro (&Qas); | ||
| 5125 | Qmake = intern ("make"); | ||
| 5126 | staticpro (&Qmake); | ||
| 5127 | Qto = intern ("to"); | ||
| 5128 | staticpro (&Qto); | ||
| 5129 | |||
| 5076 | Fput (Qprotected_field, Qerror_conditions, | 5130 | Fput (Qprotected_field, Qerror_conditions, |
| 5077 | Fcons (Qprotected_field, Fcons (Qerror, Qnil))); | 5131 | Fcons (Qprotected_field, Fcons (Qerror, Qnil))); |
| 5078 | Fput (Qprotected_field, Qerror_message, | 5132 | Fput (Qprotected_field, Qerror_message, |