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