Mercurial > emacs
comparison src/editfns.c @ 21245:6cde55b7c9de
Use STRING_BYTES and SET_STRING_BYTES.
(Ftranspose_regions): Try to handle combining bytes.
author | Richard M. Stallman <rms@gnu.org> |
---|---|
date | Sat, 21 Mar 1998 07:06:55 +0000 |
parents | eba3d61855d0 |
children | 205a5aa4aa2f |
comparison
equal
deleted
inserted
replaced
21244:50929073a0ba | 21245:6cde55b7c9de |
---|---|
144 register Lisp_Object val; | 144 register Lisp_Object val; |
145 register struct Lisp_String *p; | 145 register struct Lisp_String *p; |
146 CHECK_STRING (string, 0); | 146 CHECK_STRING (string, 0); |
147 p = XSTRING (string); | 147 p = XSTRING (string); |
148 if (p->size) | 148 if (p->size) |
149 XSETFASTINT (val, STRING_CHAR (p->data, p->size_byte)); | 149 XSETFASTINT (val, STRING_CHAR (p->data, STRING_BYTES (p))); |
150 else | 150 else |
151 XSETFASTINT (val, 0); | 151 XSETFASTINT (val, 0); |
152 return val; | 152 return val; |
153 } | 153 } |
154 | 154 |
865 | 865 |
866 if (! lisp_time_argument (time, &value)) | 866 if (! lisp_time_argument (time, &value)) |
867 error ("Invalid time specification"); | 867 error ("Invalid time specification"); |
868 | 868 |
869 /* This is probably enough. */ | 869 /* This is probably enough. */ |
870 size = XSTRING (format_string)->size_byte * 6 + 50; | 870 size = STRING_BYTES (XSTRING (format_string)) * 6 + 50; |
871 | 871 |
872 while (1) | 872 while (1) |
873 { | 873 { |
874 char *buf = (char *) alloca (size + 1); | 874 char *buf = (char *) alloca (size + 1); |
875 int result; | 875 int result; |
1292 } | 1292 } |
1293 else if (STRINGP (val)) | 1293 else if (STRINGP (val)) |
1294 { | 1294 { |
1295 (*insert_from_string_func) (val, 0, 0, | 1295 (*insert_from_string_func) (val, 0, 0, |
1296 XSTRING (val)->size, | 1296 XSTRING (val)->size, |
1297 XSTRING (val)->size_byte, | 1297 STRING_BYTES (XSTRING (val)), |
1298 inherit); | 1298 inherit); |
1299 } | 1299 } |
1300 else | 1300 else |
1301 { | 1301 { |
1302 val = wrong_type_argument (Qchar_or_string_p, val); | 1302 val = wrong_type_argument (Qchar_or_string_p, val); |
1894 int pos; | 1894 int pos; |
1895 | 1895 |
1896 validate_region (&start, &end); | 1896 validate_region (&start, &end); |
1897 CHECK_STRING (table, 2); | 1897 CHECK_STRING (table, 2); |
1898 | 1898 |
1899 size = XSTRING (table)->size_byte; | 1899 size = STRING_BYTES (XSTRING (table)); |
1900 tt = XSTRING (table)->data; | 1900 tt = XSTRING (table)->data; |
1901 | 1901 |
1902 pos_byte = CHAR_TO_BYTE (XINT (start)); | 1902 pos_byte = CHAR_TO_BYTE (XINT (start)); |
1903 stop = CHAR_TO_BYTE (XINT (end)); | 1903 stop = CHAR_TO_BYTE (XINT (end)); |
1904 modify_region (current_buffer, XINT (start), XINT (end)); | 1904 modify_region (current_buffer, XINT (start), XINT (end)); |
2108 if (! message_text) | 2108 if (! message_text) |
2109 { | 2109 { |
2110 message_text = (char *)xmalloc (80); | 2110 message_text = (char *)xmalloc (80); |
2111 message_length = 80; | 2111 message_length = 80; |
2112 } | 2112 } |
2113 if (XSTRING (val)->size_byte > message_length) | 2113 if (STRING_BYTES (XSTRING (val)) > message_length) |
2114 { | 2114 { |
2115 message_length = XSTRING (val)->size_byte; | 2115 message_length = STRING_BYTES (XSTRING (val)); |
2116 message_text = (char *)xrealloc (message_text, message_length); | 2116 message_text = (char *)xrealloc (message_text, message_length); |
2117 } | 2117 } |
2118 bcopy (XSTRING (val)->data, message_text, XSTRING (val)->size_byte); | 2118 bcopy (XSTRING (val)->data, message_text, STRING_BYTES (XSTRING (val))); |
2119 message2 (message_text, XSTRING (val)->size_byte, | 2119 message2 (message_text, STRING_BYTES (XSTRING (val)), |
2120 STRING_MULTIBYTE (val)); | 2120 STRING_MULTIBYTE (val)); |
2121 return val; | 2121 return val; |
2122 } | 2122 } |
2123 } | 2123 } |
2124 | 2124 |
2159 if (! message_text) | 2159 if (! message_text) |
2160 { | 2160 { |
2161 message_text = (char *)xmalloc (80); | 2161 message_text = (char *)xmalloc (80); |
2162 message_length = 80; | 2162 message_length = 80; |
2163 } | 2163 } |
2164 if (XSTRING (val)->size_byte > message_length) | 2164 if (STRING_BYTES (XSTRING (val)) > message_length) |
2165 { | 2165 { |
2166 message_length = XSTRING (val)->size_byte; | 2166 message_length = STRING_BYTES (XSTRING (val)); |
2167 message_text = (char *)xrealloc (message_text, message_length); | 2167 message_text = (char *)xrealloc (message_text, message_length); |
2168 } | 2168 } |
2169 bcopy (XSTRING (val)->data, message_text, XSTRING (val)->size_byte); | 2169 bcopy (XSTRING (val)->data, message_text, STRING_BYTES (XSTRING (val))); |
2170 message2 (message_text, XSTRING (val)->size_byte); | 2170 message2 (message_text, STRING_BYTES (XSTRING (val))); |
2171 return val; | 2171 return val; |
2172 #endif /* not HAVE_MENUS */ | 2172 #endif /* not HAVE_MENUS */ |
2173 } | 2173 } |
2174 } | 2174 } |
2175 #ifdef HAVE_MENUS | 2175 #ifdef HAVE_MENUS |
2209 MULTIBYTE is nonzero if the result should be multibyte. */ | 2209 MULTIBYTE is nonzero if the result should be multibyte. */ |
2210 | 2210 |
2211 #define CONVERTED_BYTE_SIZE(MULTIBYTE, STRING) \ | 2211 #define CONVERTED_BYTE_SIZE(MULTIBYTE, STRING) \ |
2212 (((MULTIBYTE) && ! STRING_MULTIBYTE (STRING)) \ | 2212 (((MULTIBYTE) && ! STRING_MULTIBYTE (STRING)) \ |
2213 ? count_size_as_multibyte (XSTRING (STRING)->data, \ | 2213 ? count_size_as_multibyte (XSTRING (STRING)->data, \ |
2214 XSTRING (STRING)->size_byte) \ | 2214 STRING_BYTES (XSTRING (STRING))) \ |
2215 : XSTRING (STRING)->size_byte) | 2215 : STRING_BYTES (XSTRING (STRING))) |
2216 | 2216 |
2217 DEFUN ("format", Fformat, Sformat, 1, MANY, 0, | 2217 DEFUN ("format", Fformat, Sformat, 1, MANY, 0, |
2218 "Format a string out of a control-string and arguments.\n\ | 2218 "Format a string out of a control-string and arguments.\n\ |
2219 The first argument is a control string.\n\ | 2219 The first argument is a control string.\n\ |
2220 The other arguments are substituted into it to make the result, a string.\n\ | 2220 The other arguments are substituted into it to make the result, a string.\n\ |
2263 /* If we start out planning a unibyte result, | 2263 /* If we start out planning a unibyte result, |
2264 and later find it has to be multibyte, we jump back to retry. */ | 2264 and later find it has to be multibyte, we jump back to retry. */ |
2265 retry: | 2265 retry: |
2266 | 2266 |
2267 format = XSTRING (args[0])->data; | 2267 format = XSTRING (args[0])->data; |
2268 end = format + XSTRING (args[0])->size_byte; | 2268 end = format + STRING_BYTES (XSTRING (args[0])); |
2269 longest_format = 0; | 2269 longest_format = 0; |
2270 | 2270 |
2271 /* Make room in result for all the non-%-codes in the control string. */ | 2271 /* Make room in result for all the non-%-codes in the control string. */ |
2272 total = 5 + CONVERTED_BYTE_SIZE (multibyte, args[0]); | 2272 total = 5 + CONVERTED_BYTE_SIZE (multibyte, args[0]); |
2273 | 2273 |
2346 { | 2346 { |
2347 multibyte = 1; | 2347 multibyte = 1; |
2348 goto retry; | 2348 goto retry; |
2349 } | 2349 } |
2350 args[n] = Fchar_to_string (args[n]); | 2350 args[n] = Fchar_to_string (args[n]); |
2351 thissize = XSTRING (args[n])->size_byte; | 2351 thissize = STRING_BYTES (XSTRING (args[n])); |
2352 } | 2352 } |
2353 } | 2353 } |
2354 #ifdef LISP_FLOAT_TYPE | 2354 #ifdef LISP_FLOAT_TYPE |
2355 else if (FLOATP (args[n]) && *format != 's') | 2355 else if (FLOATP (args[n]) && *format != 's') |
2356 { | 2356 { |
2427 | 2427 |
2428 if (STRINGP (args[n])) | 2428 if (STRINGP (args[n])) |
2429 { | 2429 { |
2430 int padding, nbytes; | 2430 int padding, nbytes; |
2431 int width = strwidth (XSTRING (args[n])->data, | 2431 int width = strwidth (XSTRING (args[n])->data, |
2432 XSTRING (args[n])->size_byte); | 2432 STRING_BYTES (XSTRING (args[n]))); |
2433 | 2433 |
2434 /* If spec requires it, pad on right with spaces. */ | 2434 /* If spec requires it, pad on right with spaces. */ |
2435 padding = minlen - width; | 2435 padding = minlen - width; |
2436 if (! negative) | 2436 if (! negative) |
2437 while (padding-- > 0) | 2437 while (padding-- > 0) |
2439 *p++ = ' '; | 2439 *p++ = ' '; |
2440 nchars++; | 2440 nchars++; |
2441 } | 2441 } |
2442 | 2442 |
2443 nbytes = copy_text (XSTRING (args[n])->data, p, | 2443 nbytes = copy_text (XSTRING (args[n])->data, p, |
2444 XSTRING (args[n])->size_byte, | 2444 STRING_BYTES (XSTRING (args[n])), |
2445 STRING_MULTIBYTE (args[n]), multibyte); | 2445 STRING_MULTIBYTE (args[n]), multibyte); |
2446 p += nbytes; | 2446 p += nbytes; |
2447 nchars += XSTRING (args[n])->size; | 2447 nchars += XSTRING (args[n])->size; |
2448 | 2448 |
2449 if (negative) | 2449 if (negative) |
2648 { | 2648 { |
2649 register int start1, end1, start2, end2; | 2649 register int start1, end1, start2, end2; |
2650 int start1_byte, start2_byte, len1_byte, len2_byte; | 2650 int start1_byte, start2_byte, len1_byte, len2_byte; |
2651 int gap, len1, len_mid, len2; | 2651 int gap, len1, len_mid, len2; |
2652 unsigned char *start1_addr, *start2_addr, *temp; | 2652 unsigned char *start1_addr, *start2_addr, *temp; |
2653 int combined_before_bytes_1, combined_after_bytes_1; | |
2654 int combined_before_bytes_2, combined_after_bytes_2; | |
2655 struct gcpro gcpro1, gcpro2; | |
2653 | 2656 |
2654 #ifdef USE_TEXT_PROPERTIES | 2657 #ifdef USE_TEXT_PROPERTIES |
2655 INTERVAL cur_intv, tmp_interval1, tmp_interval_mid, tmp_interval2; | 2658 INTERVAL cur_intv, tmp_interval1, tmp_interval_mid, tmp_interval2; |
2656 cur_intv = BUF_INTERVALS (current_buffer); | 2659 cur_intv = BUF_INTERVALS (current_buffer); |
2657 #endif /* USE_TEXT_PROPERTIES */ | 2660 #endif /* USE_TEXT_PROPERTIES */ |
2678 | 2681 |
2679 len1 = end1 - start1; | 2682 len1 = end1 - start1; |
2680 len2 = end2 - start2; | 2683 len2 = end2 - start2; |
2681 | 2684 |
2682 if (start2 < end1) | 2685 if (start2 < end1) |
2683 error ("Transposed regions not properly ordered"); | 2686 error ("Transposed regions overlap"); |
2684 else if (start1 == end1 || start2 == end2) | 2687 else if (start1 == end1 || start2 == end2) |
2685 error ("Transposed region may not be of length 0"); | 2688 error ("Transposed region has length 0"); |
2686 | 2689 |
2687 /* The possibilities are: | 2690 /* The possibilities are: |
2688 1. Adjacent (contiguous) regions, or separate but equal regions | 2691 1. Adjacent (contiguous) regions, or separate but equal regions |
2689 (no, really equal, in this case!), or | 2692 (no, really equal, in this case!), or |
2690 2. Separate regions of unequal size. | 2693 2. Separate regions of unequal size. |
2718 | 2721 |
2719 start1_byte = CHAR_TO_BYTE (start1); | 2722 start1_byte = CHAR_TO_BYTE (start1); |
2720 start2_byte = CHAR_TO_BYTE (start2); | 2723 start2_byte = CHAR_TO_BYTE (start2); |
2721 len1_byte = CHAR_TO_BYTE (end1) - start1_byte; | 2724 len1_byte = CHAR_TO_BYTE (end1) - start1_byte; |
2722 len2_byte = CHAR_TO_BYTE (end2) - start2_byte; | 2725 len2_byte = CHAR_TO_BYTE (end2) - start2_byte; |
2726 | |
2727 if (end1 == start2) | |
2728 { | |
2729 combined_before_bytes_2 | |
2730 = count_combining_before (BYTE_POS_ADDR (start2_byte), | |
2731 len2_byte, start1, start1_byte); | |
2732 combined_before_bytes_1 | |
2733 = count_combining_before (BYTE_POS_ADDR (start1_byte), | |
2734 len1_byte, end2, start2_byte + len2_byte); | |
2735 combined_after_bytes_1 | |
2736 = count_combining_after (BYTE_POS_ADDR (start1_byte), | |
2737 len1_byte, end2, start2_byte + len2_byte); | |
2738 combined_after_bytes_2 = 0; | |
2739 } | |
2740 else | |
2741 { | |
2742 combined_before_bytes_2 | |
2743 = count_combining_before (BYTE_POS_ADDR (start2_byte), | |
2744 len2_byte, start1, start1_byte); | |
2745 combined_before_bytes_1 | |
2746 = count_combining_before (BYTE_POS_ADDR (start1_byte), | |
2747 len1_byte, start2, start2_byte); | |
2748 combined_after_bytes_2 | |
2749 = count_combining_after (BYTE_POS_ADDR (start2_byte), | |
2750 len2_byte, end1, start1_byte + len1_byte); | |
2751 combined_after_bytes_1 | |
2752 = count_combining_after (BYTE_POS_ADDR (start1_byte), | |
2753 len1_byte, end2, start2_byte + len2_byte); | |
2754 } | |
2755 | |
2756 /* If any combining is going to happen, do this the stupid way, | |
2757 because replace handles combining properly. */ | |
2758 if (combined_before_bytes_1 || combined_before_bytes_2 | |
2759 || combined_after_bytes_1 || combined_after_bytes_2) | |
2760 { | |
2761 Lisp_Object text1, text2; | |
2762 | |
2763 text1 = text2 = Qnil; | |
2764 GCPRO2 (text1, text2); | |
2765 | |
2766 text1 = make_buffer_string_both (start1, start1_byte, | |
2767 end1, start1_byte + len1_byte, 1); | |
2768 text2 = make_buffer_string_both (start2, start2_byte, | |
2769 end2, start2_byte + len2_byte, 1); | |
2770 | |
2771 transpose_markers (start1, end1, start2, end2, | |
2772 start1_byte, start1_byte + len1_byte, | |
2773 start2_byte, start2_byte + len2_byte); | |
2774 | |
2775 replace_range (text1, start2, end2, 1, 0, 1); | |
2776 replace_range (text2, start1, end1, 1, 0, 1); | |
2777 | |
2778 UNGCPRO; | |
2779 return Qnil; | |
2780 } | |
2723 | 2781 |
2724 /* Hmmm... how about checking to see if the gap is large | 2782 /* Hmmm... how about checking to see if the gap is large |
2725 enough to use as the temporary storage? That would avoid an | 2783 enough to use as the temporary storage? That would avoid an |
2726 allocation... interesting. Later, don't fool with it now. */ | 2784 allocation... interesting. Later, don't fool with it now. */ |
2727 | 2785 |