aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/fns.c173
1 files changed, 104 insertions, 69 deletions
diff --git a/src/fns.c b/src/fns.c
index ed513098ee3..639ee5d95ed 100644
--- a/src/fns.c
+++ b/src/fns.c
@@ -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\
1072If STRING is unibyte, the result is STRING itself.\n\ 1072If STRING is unibyte, the result is STRING itself.\n\
1073Otherwise it is a newly created string, with no text properties.") 1073Otherwise it is a newly created string, with no text properties.\n\
1074If STRING is multibyte and contains a character of charset `binary',\n\
1075it 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\
1092If STRING is multibyte, the result is STRING itself.\n\ 1097If STRING is multibyte, the result is STRING itself.\n\
1093Otherwise it is a newly created string, with no text properties.") 1098Otherwise it is a newly created string, with no text properties.\n\
1099If STRING is unibyte and contains an individual 8-bit byte (i.e. not\n\
1100part of multibyte form), it is converted to the corresponding\n\
1101multibyte 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
3103static int base64_encode_1 P_ ((const char *, char *, int, int)); 3106static int base64_encode_1 P_ ((const char *, char *, int, int, int));
3104static int base64_decode_1 P_ ((const char *, char *, int)); 3107static int base64_decode_1 P_ ((const char *, char *, int));
3105 3108
3106DEFUN ("base64-encode-region", Fbase64_encode_region, Sbase64_encode_region, 3109DEFUN ("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
3201static int 3222static int
3202base64_encode_1 (from, to, length, line_break) 3223base64_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