diff options
| author | Kenichi Handa | 2000-05-19 23:59:50 +0000 |
|---|---|---|
| committer | Kenichi Handa | 2000-05-19 23:59:50 +0000 |
| commit | 2efdd1b92e19b2db5ae036673f4031d55115aa79 (patch) | |
| tree | 0dfaa189202dee81af6f683330a6a9670b12246d | |
| parent | 8c3b944144e8570089939774cdc7adb569f915b7 (diff) | |
| download | emacs-2efdd1b92e19b2db5ae036673f4031d55115aa79.tar.gz emacs-2efdd1b92e19b2db5ae036673f4031d55115aa79.zip | |
(concat): Handle 8-bit characters correctly.
(Fstring_as_unibyte): Be sure to make all 8-bit characters in
unibyte in the result.
(Fstring_as_multibyte): Be sure to make all 8-bit characters in
valid multibyte form in the result.
(map_char_table): Use MAKE_CHAR instead of MAKE_NON_ASCII_CHAR.
(Fbase64_encode_region, Fbase64_encode_string): If base64_encode_1
return -1, signal an error.
(base64_encode_1): New arg MULTIBYTE. Get each character by
CHAR_STRING_AND_LENGTH if MULTIBYTE is nonzero. If a multibyte
character is found, return -1.
(Fbase64_decode_region): Delete codes for handling byte-combining.
Treat each decoded byte as a unibyte character.
(Fbase64_decode_string): Return unibyte string.
(Fcompare_strings, concat, string_byte_to_char): Use
FETCH_STRING_CHAR_ADVANCE_NO_CHECK instead off
FETCH_STRING_CHAR_ADVANCE.
(Fstring_lessp): Use FETCH_STRING_CHAR_ADVANCE unconditionally.
(mapcar1): If SEQ is string, always use FETCH_STRING_CHAR_ADVANCE.
| -rw-r--r-- | src/fns.c | 173 |
1 files changed, 104 insertions, 69 deletions
| @@ -290,7 +290,7 @@ If string STR1 is greater, the value is a positive number N;\n\ | |||
| 290 | int c1, c2; | 290 | int c1, c2; |
| 291 | 291 | ||
| 292 | if (STRING_MULTIBYTE (str1)) | 292 | if (STRING_MULTIBYTE (str1)) |
| 293 | FETCH_STRING_CHAR_ADVANCE (c1, str1, i1, i1_byte); | 293 | FETCH_STRING_CHAR_ADVANCE_NO_CHECK (c1, str1, i1, i1_byte); |
| 294 | else | 294 | else |
| 295 | { | 295 | { |
| 296 | c1 = XSTRING (str1)->data[i1++]; | 296 | c1 = XSTRING (str1)->data[i1++]; |
| @@ -298,7 +298,7 @@ If string STR1 is greater, the value is a positive number N;\n\ | |||
| 298 | } | 298 | } |
| 299 | 299 | ||
| 300 | if (STRING_MULTIBYTE (str2)) | 300 | if (STRING_MULTIBYTE (str2)) |
| 301 | FETCH_STRING_CHAR_ADVANCE (c2, str2, i2, i2_byte); | 301 | FETCH_STRING_CHAR_ADVANCE_NO_CHECK (c2, str2, i2, i2_byte); |
| 302 | else | 302 | else |
| 303 | { | 303 | { |
| 304 | c2 = XSTRING (str2)->data[i2++]; | 304 | c2 = XSTRING (str2)->data[i2++]; |
| @@ -367,15 +367,8 @@ Symbols are also allowed; their print names are used instead.") | |||
| 367 | characters, not just the bytes. */ | 367 | characters, not just the bytes. */ |
| 368 | int c1, c2; | 368 | int c1, c2; |
| 369 | 369 | ||
| 370 | if (STRING_MULTIBYTE (s1)) | 370 | FETCH_STRING_CHAR_ADVANCE (c1, s1, i1, i1_byte); |
| 371 | FETCH_STRING_CHAR_ADVANCE (c1, s1, i1, i1_byte); | 371 | FETCH_STRING_CHAR_ADVANCE (c2, s2, i2, i2_byte); |
| 372 | else | ||
| 373 | c1 = XSTRING (s1)->data[i1++]; | ||
| 374 | |||
| 375 | if (STRING_MULTIBYTE (s2)) | ||
| 376 | FETCH_STRING_CHAR_ADVANCE (c2, s2, i2, i2_byte); | ||
| 377 | else | ||
| 378 | c2 = XSTRING (s2)->data[i2++]; | ||
| 379 | 372 | ||
| 380 | if (c1 != c2) | 373 | if (c1 != c2) |
| 381 | return c1 < c2 ? Qt : Qnil; | 374 | return c1 < c2 ? Qt : Qnil; |
| @@ -625,7 +618,7 @@ concat (nargs, args, target_type, last_special) | |||
| 625 | wrong_type_argument (Qintegerp, ch); | 618 | wrong_type_argument (Qintegerp, ch); |
| 626 | this_len_byte = CHAR_BYTES (XINT (ch)); | 619 | this_len_byte = CHAR_BYTES (XINT (ch)); |
| 627 | result_len_byte += this_len_byte; | 620 | result_len_byte += this_len_byte; |
| 628 | if (this_len_byte > 1) | 621 | if (!SINGLE_BYTE_CHAR_P (XINT (ch))) |
| 629 | some_multibyte = 1; | 622 | some_multibyte = 1; |
| 630 | } | 623 | } |
| 631 | else if (BOOL_VECTOR_P (this) && XBOOL_VECTOR (this)->size > 0) | 624 | else if (BOOL_VECTOR_P (this) && XBOOL_VECTOR (this)->size > 0) |
| @@ -638,7 +631,7 @@ concat (nargs, args, target_type, last_special) | |||
| 638 | wrong_type_argument (Qintegerp, ch); | 631 | wrong_type_argument (Qintegerp, ch); |
| 639 | this_len_byte = CHAR_BYTES (XINT (ch)); | 632 | this_len_byte = CHAR_BYTES (XINT (ch)); |
| 640 | result_len_byte += this_len_byte; | 633 | result_len_byte += this_len_byte; |
| 641 | if (this_len_byte > 1) | 634 | if (!SINGLE_BYTE_CHAR_P (XINT (ch))) |
| 642 | some_multibyte = 1; | 635 | some_multibyte = 1; |
| 643 | } | 636 | } |
| 644 | else if (STRINGP (this)) | 637 | else if (STRINGP (this)) |
| @@ -753,9 +746,9 @@ concat (nargs, args, target_type, last_special) | |||
| 753 | int c; | 746 | int c; |
| 754 | if (STRING_MULTIBYTE (this)) | 747 | if (STRING_MULTIBYTE (this)) |
| 755 | { | 748 | { |
| 756 | FETCH_STRING_CHAR_ADVANCE (c, this, | 749 | FETCH_STRING_CHAR_ADVANCE_NO_CHECK (c, this, |
| 757 | thisindex, | 750 | thisindex, |
| 758 | thisindex_byte); | 751 | thisindex_byte); |
| 759 | XSETFASTINT (elt, c); | 752 | XSETFASTINT (elt, c); |
| 760 | } | 753 | } |
| 761 | else | 754 | else |
| @@ -799,7 +792,12 @@ concat (nargs, args, target_type, last_special) | |||
| 799 | CHECK_NUMBER (elt, 0); | 792 | CHECK_NUMBER (elt, 0); |
| 800 | if (SINGLE_BYTE_CHAR_P (XINT (elt))) | 793 | if (SINGLE_BYTE_CHAR_P (XINT (elt))) |
| 801 | { | 794 | { |
| 802 | XSTRING (val)->data[toindex_byte++] = XINT (elt); | 795 | if (some_multibyte) |
| 796 | toindex_byte | ||
| 797 | += CHAR_STRING (XINT (elt), | ||
| 798 | XSTRING (val)->data + toindex_byte); | ||
| 799 | else | ||
| 800 | XSTRING (val)->data[toindex_byte++] = XINT (elt); | ||
| 803 | if (some_multibyte | 801 | if (some_multibyte |
| 804 | && toindex_byte > 0 | 802 | && toindex_byte > 0 |
| 805 | && count_combining (XSTRING (val)->data, | 803 | && count_combining (XSTRING (val)->data, |
| @@ -886,7 +884,8 @@ string_char_to_byte (string, char_index) | |||
| 886 | while (best_below < char_index) | 884 | while (best_below < char_index) |
| 887 | { | 885 | { |
| 888 | int c; | 886 | int c; |
| 889 | FETCH_STRING_CHAR_ADVANCE (c, string, best_below, best_below_byte); | 887 | FETCH_STRING_CHAR_ADVANCE_NO_CHECK (c, string, |
| 888 | best_below, best_below_byte); | ||
| 890 | } | 889 | } |
| 891 | i = best_below; | 890 | i = best_below; |
| 892 | i_byte = best_below_byte; | 891 | i_byte = best_below_byte; |
| @@ -958,7 +957,8 @@ string_byte_to_char (string, byte_index) | |||
| 958 | while (best_below_byte < byte_index) | 957 | while (best_below_byte < byte_index) |
| 959 | { | 958 | { |
| 960 | int c; | 959 | int c; |
| 961 | FETCH_STRING_CHAR_ADVANCE (c, string, best_below, best_below_byte); | 960 | FETCH_STRING_CHAR_ADVANCE_NO_CHECK (c, string, |
| 961 | best_below, best_below_byte); | ||
| 962 | } | 962 | } |
| 963 | i = best_below; | 963 | i = best_below; |
| 964 | i_byte = best_below_byte; | 964 | i_byte = best_below_byte; |
| @@ -1070,7 +1070,9 @@ DEFUN ("string-as-unibyte", Fstring_as_unibyte, Sstring_as_unibyte, | |||
| 1070 | 1, 1, 0, | 1070 | 1, 1, 0, |
| 1071 | "Return a unibyte string with the same individual bytes as STRING.\n\ | 1071 | "Return a unibyte string with the same individual bytes as STRING.\n\ |
| 1072 | If STRING is unibyte, the result is STRING itself.\n\ | 1072 | If STRING is unibyte, the result is STRING itself.\n\ |
| 1073 | Otherwise it is a newly created string, with no text properties.") | 1073 | Otherwise it is a newly created string, with no text properties.\n\ |
| 1074 | If STRING is multibyte and contains a character of charset `binary',\n\ | ||
| 1075 | it is converted to the corresponding single byte.") | ||
| 1074 | (string) | 1076 | (string) |
| 1075 | Lisp_Object string; | 1077 | Lisp_Object string; |
| 1076 | { | 1078 | { |
| @@ -1078,10 +1080,13 @@ Otherwise it is a newly created string, with no text properties.") | |||
| 1078 | 1080 | ||
| 1079 | if (STRING_MULTIBYTE (string)) | 1081 | if (STRING_MULTIBYTE (string)) |
| 1080 | { | 1082 | { |
| 1081 | string = Fcopy_sequence (string); | 1083 | int bytes = STRING_BYTES (XSTRING (string)); |
| 1082 | XSTRING (string)->size = STRING_BYTES (XSTRING (string)); | 1084 | unsigned char *str = (unsigned char *) xmalloc (bytes); |
| 1083 | XSTRING (string)->intervals = NULL_INTERVAL; | 1085 | |
| 1084 | SET_STRING_BYTES (XSTRING (string), -1); | 1086 | bcopy (XSTRING (string)->data, str, bytes); |
| 1087 | bytes = str_as_unibyte (str, bytes); | ||
| 1088 | string = make_unibyte_string (str, bytes); | ||
| 1089 | xfree (str); | ||
| 1085 | } | 1090 | } |
| 1086 | return string; | 1091 | return string; |
| 1087 | } | 1092 | } |
| @@ -1090,7 +1095,10 @@ DEFUN ("string-as-multibyte", Fstring_as_multibyte, Sstring_as_multibyte, | |||
| 1090 | 1, 1, 0, | 1095 | 1, 1, 0, |
| 1091 | "Return a multibyte string with the same individual bytes as STRING.\n\ | 1096 | "Return a multibyte string with the same individual bytes as STRING.\n\ |
| 1092 | If STRING is multibyte, the result is STRING itself.\n\ | 1097 | If STRING is multibyte, the result is STRING itself.\n\ |
| 1093 | Otherwise it is a newly created string, with no text properties.") | 1098 | Otherwise it is a newly created string, with no text properties.\n\ |
| 1099 | If STRING is unibyte and contains an individual 8-bit byte (i.e. not\n\ | ||
| 1100 | part of multibyte form), it is converted to the corresponding\n\ | ||
| 1101 | multibyte character of charset `binary'.") | ||
| 1094 | (string) | 1102 | (string) |
| 1095 | Lisp_Object string; | 1103 | Lisp_Object string; |
| 1096 | { | 1104 | { |
| @@ -1098,12 +1106,19 @@ Otherwise it is a newly created string, with no text properties.") | |||
| 1098 | 1106 | ||
| 1099 | if (! STRING_MULTIBYTE (string)) | 1107 | if (! STRING_MULTIBYTE (string)) |
| 1100 | { | 1108 | { |
| 1101 | int nbytes = STRING_BYTES (XSTRING (string)); | 1109 | Lisp_Object new_string; |
| 1102 | int newlen = multibyte_chars_in_text (XSTRING (string)->data, nbytes); | 1110 | int nchars, nbytes; |
| 1103 | 1111 | ||
| 1104 | string = Fcopy_sequence (string); | 1112 | parse_str_as_multibyte (XSTRING (string)->data, |
| 1105 | XSTRING (string)->size = newlen; | 1113 | STRING_BYTES (XSTRING (string)), |
| 1106 | XSTRING (string)->size_byte = nbytes; | 1114 | &nchars, &nbytes); |
| 1115 | new_string = make_uninit_multibyte_string (nchars, nbytes); | ||
| 1116 | bcopy (XSTRING (string)->data, XSTRING (new_string)->data, | ||
| 1117 | STRING_BYTES (XSTRING (string))); | ||
| 1118 | if (nbytes != STRING_BYTES (XSTRING (string))) | ||
| 1119 | str_as_multibyte (XSTRING (new_string)->data, nbytes, | ||
| 1120 | STRING_BYTES (XSTRING (string)), NULL); | ||
| 1121 | string = new_string; | ||
| 1107 | XSTRING (string)->intervals = NULL_INTERVAL; | 1122 | XSTRING (string)->intervals = NULL_INTERVAL; |
| 1108 | } | 1123 | } |
| 1109 | return string; | 1124 | return string; |
| @@ -2374,7 +2389,7 @@ map_char_table (c_function, function, subtable, arg, depth, indices) | |||
| 2374 | elt = XCHAR_TABLE (subtable)->defalt; | 2389 | elt = XCHAR_TABLE (subtable)->defalt; |
| 2375 | c1 = depth >= 1 ? XFASTINT (indices[1]) : 0; | 2390 | c1 = depth >= 1 ? XFASTINT (indices[1]) : 0; |
| 2376 | c2 = depth >= 2 ? XFASTINT (indices[2]) : 0; | 2391 | c2 = depth >= 2 ? XFASTINT (indices[2]) : 0; |
| 2377 | c = MAKE_NON_ASCII_CHAR (charset, c1, c2); | 2392 | c = MAKE_CHAR (charset, c1, c2); |
| 2378 | if (c_function) | 2393 | if (c_function) |
| 2379 | (*c_function) (arg, make_number (c), elt); | 2394 | (*c_function) (arg, make_number (c), elt); |
| 2380 | else | 2395 | else |
| @@ -2513,20 +2528,8 @@ mapcar1 (leni, vals, fn, seq) | |||
| 2513 | vals[i] = dummy; | 2528 | vals[i] = dummy; |
| 2514 | } | 2529 | } |
| 2515 | } | 2530 | } |
| 2516 | else if (STRINGP (seq) && ! STRING_MULTIBYTE (seq)) | ||
| 2517 | { | ||
| 2518 | /* Single-byte string. */ | ||
| 2519 | for (i = 0; i < leni; i++) | ||
| 2520 | { | ||
| 2521 | XSETFASTINT (dummy, XSTRING (seq)->data[i]); | ||
| 2522 | dummy = call1 (fn, dummy); | ||
| 2523 | if (vals) | ||
| 2524 | vals[i] = dummy; | ||
| 2525 | } | ||
| 2526 | } | ||
| 2527 | else if (STRINGP (seq)) | 2531 | else if (STRINGP (seq)) |
| 2528 | { | 2532 | { |
| 2529 | /* Multi-byte string. */ | ||
| 2530 | int i_byte; | 2533 | int i_byte; |
| 2531 | 2534 | ||
| 2532 | for (i = 0, i_byte = 0; i < leni;) | 2535 | for (i = 0, i_byte = 0; i < leni;) |
| @@ -3100,7 +3103,7 @@ static short base64_char_to_value[128] = | |||
| 3100 | base64 characters. */ | 3103 | base64 characters. */ |
| 3101 | 3104 | ||
| 3102 | 3105 | ||
| 3103 | static int base64_encode_1 P_ ((const char *, char *, int, int)); | 3106 | static int base64_encode_1 P_ ((const char *, char *, int, int, int)); |
| 3104 | static int base64_decode_1 P_ ((const char *, char *, int)); | 3107 | static int base64_decode_1 P_ ((const char *, char *, int)); |
| 3105 | 3108 | ||
| 3106 | DEFUN ("base64-encode-region", Fbase64_encode_region, Sbase64_encode_region, | 3109 | DEFUN ("base64-encode-region", Fbase64_encode_region, Sbase64_encode_region, |
| @@ -3135,10 +3138,19 @@ into shorter lines.") | |||
| 3135 | else | 3138 | else |
| 3136 | encoded = (char *) xmalloc (allength); | 3139 | encoded = (char *) xmalloc (allength); |
| 3137 | encoded_length = base64_encode_1 (BYTE_POS_ADDR (ibeg), encoded, length, | 3140 | encoded_length = base64_encode_1 (BYTE_POS_ADDR (ibeg), encoded, length, |
| 3138 | NILP (no_line_break)); | 3141 | NILP (no_line_break), |
| 3142 | !NILP (current_buffer->enable_multibyte_characters)); | ||
| 3139 | if (encoded_length > allength) | 3143 | if (encoded_length > allength) |
| 3140 | abort (); | 3144 | abort (); |
| 3141 | 3145 | ||
| 3146 | if (encoded_length < 0) | ||
| 3147 | { | ||
| 3148 | /* The encoding wasn't possible. */ | ||
| 3149 | if (length > MAX_ALLOCA) | ||
| 3150 | xfree (encoded); | ||
| 3151 | error ("Base64 encoding failed"); | ||
| 3152 | } | ||
| 3153 | |||
| 3142 | /* Now we have encoded the region, so we insert the new contents | 3154 | /* Now we have encoded the region, so we insert the new contents |
| 3143 | and delete the old. (Insert first in order to preserve markers.) */ | 3155 | and delete the old. (Insert first in order to preserve markers.) */ |
| 3144 | SET_PT_BOTH (XFASTINT (beg), ibeg); | 3156 | SET_PT_BOTH (XFASTINT (beg), ibeg); |
| @@ -3187,10 +3199,19 @@ into shorter lines.") | |||
| 3187 | encoded = (char *) xmalloc (allength); | 3199 | encoded = (char *) xmalloc (allength); |
| 3188 | 3200 | ||
| 3189 | encoded_length = base64_encode_1 (XSTRING (string)->data, | 3201 | encoded_length = base64_encode_1 (XSTRING (string)->data, |
| 3190 | encoded, length, NILP (no_line_break)); | 3202 | encoded, length, NILP (no_line_break), |
| 3203 | STRING_MULTIBYTE (string)); | ||
| 3191 | if (encoded_length > allength) | 3204 | if (encoded_length > allength) |
| 3192 | abort (); | 3205 | abort (); |
| 3193 | 3206 | ||
| 3207 | if (encoded_length < 0) | ||
| 3208 | { | ||
| 3209 | /* The encoding wasn't possible. */ | ||
| 3210 | if (length > MAX_ALLOCA) | ||
| 3211 | xfree (encoded); | ||
| 3212 | error ("Base64 encoding failed"); | ||
| 3213 | } | ||
| 3214 | |||
| 3194 | encoded_string = make_unibyte_string (encoded, encoded_length); | 3215 | encoded_string = make_unibyte_string (encoded, encoded_length); |
| 3195 | if (allength > MAX_ALLOCA) | 3216 | if (allength > MAX_ALLOCA) |
| 3196 | xfree (encoded); | 3217 | xfree (encoded); |
| @@ -3199,20 +3220,30 @@ into shorter lines.") | |||
| 3199 | } | 3220 | } |
| 3200 | 3221 | ||
| 3201 | static int | 3222 | static int |
| 3202 | base64_encode_1 (from, to, length, line_break) | 3223 | base64_encode_1 (from, to, length, line_break, multibyte) |
| 3203 | const char *from; | 3224 | const char *from; |
| 3204 | char *to; | 3225 | char *to; |
| 3205 | int length; | 3226 | int length; |
| 3206 | int line_break; | 3227 | int line_break; |
| 3228 | int multibyte; | ||
| 3207 | { | 3229 | { |
| 3208 | int counter = 0, i = 0; | 3230 | int counter = 0, i = 0; |
| 3209 | char *e = to; | 3231 | char *e = to; |
| 3210 | unsigned char c; | 3232 | unsigned char c; |
| 3211 | unsigned int value; | 3233 | unsigned int value; |
| 3234 | int bytes; | ||
| 3212 | 3235 | ||
| 3213 | while (i < length) | 3236 | while (i < length) |
| 3214 | { | 3237 | { |
| 3215 | c = from[i++]; | 3238 | if (multibyte) |
| 3239 | { | ||
| 3240 | c = STRING_CHAR_AND_LENGTH (from + i, length - i, bytes); | ||
| 3241 | if (!SINGLE_BYTE_CHAR_P (c)) | ||
| 3242 | return -1; | ||
| 3243 | i += bytes; | ||
| 3244 | } | ||
| 3245 | else | ||
| 3246 | c = from[i++]; | ||
| 3216 | 3247 | ||
| 3217 | /* Wrap line every 76 characters. */ | 3248 | /* Wrap line every 76 characters. */ |
| 3218 | 3249 | ||
| @@ -3242,7 +3273,13 @@ base64_encode_1 (from, to, length, line_break) | |||
| 3242 | break; | 3273 | break; |
| 3243 | } | 3274 | } |
| 3244 | 3275 | ||
| 3245 | c = from[i++]; | 3276 | if (multibyte) |
| 3277 | { | ||
| 3278 | c = STRING_CHAR_AND_LENGTH (from + i, length - i, bytes); | ||
| 3279 | i += bytes; | ||
| 3280 | } | ||
| 3281 | else | ||
| 3282 | c = from[i++]; | ||
| 3246 | 3283 | ||
| 3247 | *e++ = base64_value_to_char[value | (0x0f & c >> 4)]; | 3284 | *e++ = base64_value_to_char[value | (0x0f & c >> 4)]; |
| 3248 | value = (0x0f & c) << 2; | 3285 | value = (0x0f & c) << 2; |
| @@ -3256,7 +3293,13 @@ base64_encode_1 (from, to, length, line_break) | |||
| 3256 | break; | 3293 | break; |
| 3257 | } | 3294 | } |
| 3258 | 3295 | ||
| 3259 | c = from[i++]; | 3296 | if (multibyte) |
| 3297 | { | ||
| 3298 | c = STRING_CHAR_AND_LENGTH (from + i, length - i, bytes); | ||
| 3299 | i += bytes; | ||
| 3300 | } | ||
| 3301 | else | ||
| 3302 | c = from[i++]; | ||
| 3260 | 3303 | ||
| 3261 | *e++ = base64_value_to_char[value | (0x03 & c >> 6)]; | 3304 | *e++ = base64_value_to_char[value | (0x03 & c >> 6)]; |
| 3262 | *e++ = base64_value_to_char[0x3f & c]; | 3305 | *e++ = base64_value_to_char[0x3f & c]; |
| @@ -3305,27 +3348,19 @@ If the region can't be decoded, signal an error and don't modify the buffer.") | |||
| 3305 | error ("Base64 decoding failed"); | 3348 | error ("Base64 decoding failed"); |
| 3306 | } | 3349 | } |
| 3307 | 3350 | ||
| 3351 | inserted_chars = decoded_length; | ||
| 3352 | if (!NILP (current_buffer->enable_multibyte_characters)) | ||
| 3353 | decoded_length = str_to_multibyte (decoded, length, decoded_length); | ||
| 3354 | |||
| 3308 | /* Now we have decoded the region, so we insert the new contents | 3355 | /* Now we have decoded the region, so we insert the new contents |
| 3309 | and delete the old. (Insert first in order to preserve markers.) */ | 3356 | and delete the old. (Insert first in order to preserve markers.) */ |
| 3310 | /* We insert two spaces, then insert the decoded text in between | 3357 | TEMP_SET_PT_BOTH (XFASTINT (beg), ibeg); |
| 3311 | them, at last, delete those extra two spaces. This is to avoid | 3358 | insert_1_both (decoded, inserted_chars, decoded_length, 0, 1, 0); |
| 3312 | byte combining while inserting. */ | ||
| 3313 | TEMP_SET_PT_BOTH (XFASTINT (beg), ibeg); | ||
| 3314 | insert_1_both (" ", 2, 2, 0, 1, 0); | ||
| 3315 | TEMP_SET_PT_BOTH (XFASTINT (beg) + 1, ibeg + 1); | ||
| 3316 | insert (decoded, decoded_length); | ||
| 3317 | inserted_chars = PT - (XFASTINT (beg) + 1); | ||
| 3318 | if (length > MAX_ALLOCA) | 3359 | if (length > MAX_ALLOCA) |
| 3319 | xfree (decoded); | 3360 | xfree (decoded); |
| 3320 | /* At first delete the original text. This never causes byte | 3361 | /* Delete the original text. */ |
| 3321 | combining. */ | 3362 | del_range_both (PT, PT_BYTE, XFASTINT (end) + inserted_chars, |
| 3322 | del_range_both (PT + 1, PT_BYTE + 1, XFASTINT (end) + inserted_chars + 2, | 3363 | iend + decoded_length, 1); |
| 3323 | iend + decoded_length + 2, 1); | ||
| 3324 | /* Next delete the extra spaces. This will cause byte combining | ||
| 3325 | error. */ | ||
| 3326 | del_range_both (PT, PT_BYTE, PT + 1, PT_BYTE + 1, 0); | ||
| 3327 | del_range_both (XFASTINT (beg), ibeg, XFASTINT (beg) + 1, ibeg + 1, 0); | ||
| 3328 | inserted_chars = PT - XFASTINT (beg); | ||
| 3329 | 3364 | ||
| 3330 | /* If point was outside of the region, restore it exactly; else just | 3365 | /* If point was outside of the region, restore it exactly; else just |
| 3331 | move to the beginning of the region. */ | 3366 | move to the beginning of the region. */ |
| @@ -3361,7 +3396,7 @@ DEFUN ("base64-decode-string", Fbase64_decode_string, Sbase64_decode_string, | |||
| 3361 | if (decoded_length > length) | 3396 | if (decoded_length > length) |
| 3362 | abort (); | 3397 | abort (); |
| 3363 | else if (decoded_length >= 0) | 3398 | else if (decoded_length >= 0) |
| 3364 | decoded_string = make_string (decoded, decoded_length); | 3399 | decoded_string = make_unibyte_string (decoded, decoded_length); |
| 3365 | else | 3400 | else |
| 3366 | decoded_string = Qnil; | 3401 | decoded_string = Qnil; |
| 3367 | 3402 | ||