aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorKenichi Handa2004-04-07 07:23:24 +0000
committerKenichi Handa2004-04-07 07:23:24 +0000
commitf555f8cfb679efc5816a1dcb336b310135020608 (patch)
treec7ad5f5729c096a4aeb715ae26f29b0e83a5ff2c /src
parent350cd166ce580a8e2bd8ec1f8e0b8d27d6ece32e (diff)
downloademacs-f555f8cfb679efc5816a1dcb336b310135020608.tar.gz
emacs-f555f8cfb679efc5816a1dcb336b310135020608.zip
Sync to HEAD.
(check_translation): New function. (Ftranslate_region_internal): Handle M:N mapping.
Diffstat (limited to 'src')
-rw-r--r--src/editfns.c215
1 files changed, 167 insertions, 48 deletions
diff --git a/src/editfns.c b/src/editfns.c
index 01797acbdf4..ace0f1f8835 100644
--- a/src/editfns.c
+++ b/src/editfns.c
@@ -1,5 +1,5 @@
1/* Lisp functions pertaining to editing. 1/* Lisp functions pertaining to editing.
2 Copyright (C) 1985,86,87,89,93,94,95,96,97,98, 1999, 2000, 2001, 02, 2003 2 Copyright (C) 1985,86,87,89,93,94,95,96,97,98,1999,2000,01,02,03,2004
3 Free Software Foundation, Inc. 3 Free Software Foundation, Inc.
4 4
5This file is part of GNU Emacs. 5This file is part of GNU Emacs.
@@ -294,7 +294,7 @@ region_limit (beginningp)
294 if (NILP (m)) 294 if (NILP (m))
295 error ("The mark is not set now, so there is no region"); 295 error ("The mark is not set now, so there is no region");
296 296
297 if ((PT < XFASTINT (m)) == beginningp) 297 if ((PT < XFASTINT (m)) == (beginningp != 0))
298 m = make_number (PT); 298 m = make_number (PT);
299 return m; 299 return m;
300} 300}
@@ -1133,7 +1133,7 @@ DEFUN ("eolp", Feolp, Seolp, 0, 0, 0,
1133 1133
1134DEFUN ("char-after", Fchar_after, Schar_after, 0, 1, 0, 1134DEFUN ("char-after", Fchar_after, Schar_after, 0, 1, 0,
1135 doc: /* Return character in current buffer at position POS. 1135 doc: /* Return character in current buffer at position POS.
1136POS is an integer or a marker. 1136POS is an integer or a marker and defaults to point.
1137If POS is out of range, the value is nil. */) 1137If POS is out of range, the value is nil. */)
1138 (pos) 1138 (pos)
1139 Lisp_Object pos; 1139 Lisp_Object pos;
@@ -1166,7 +1166,7 @@ If POS is out of range, the value is nil. */)
1166 1166
1167DEFUN ("char-before", Fchar_before, Schar_before, 0, 1, 0, 1167DEFUN ("char-before", Fchar_before, Schar_before, 0, 1, 0,
1168 doc: /* Return character in current buffer preceding position POS. 1168 doc: /* Return character in current buffer preceding position POS.
1169POS is an integer or a marker. 1169POS is an integer or a marker and defaults to point.
1170If POS is out of range, the value is nil. */) 1170If POS is out of range, the value is nil. */)
1171 (pos) 1171 (pos)
1172 Lisp_Object pos; 1172 Lisp_Object pos;
@@ -1660,6 +1660,9 @@ for example, a DAY of 0 means the day preceding the given month.
1660Year numbers less than 100 are treated just like other year numbers. 1660Year numbers less than 100 are treated just like other year numbers.
1661If you want them to stand for years in this century, you must do that yourself. 1661If you want them to stand for years in this century, you must do that yourself.
1662 1662
1663Years before 1970 are not guaranteed to work. On some systems,
1664year values as low as 1901 do work.
1665
1663usage: (encode-time SECOND MINUTE HOUR DAY MONTH YEAR &optional ZONE) */) 1666usage: (encode-time SECOND MINUTE HOUR DAY MONTH YEAR &optional ZONE) */)
1664 (nargs, args) 1667 (nargs, args)
1665 int nargs; 1668 int nargs;
@@ -2752,13 +2755,73 @@ Both characters must have the same length of multi-byte form. */)
2752 return Qnil; 2755 return Qnil;
2753} 2756}
2754 2757
2758
2759static Lisp_Object check_translation P_ ((int, int, int, Lisp_Object));
2760
2761/* Helper function for Ftranslate_region_internal.
2762
2763 Check if a character sequence at POS (POS_BYTE) matches an element
2764 of VAL. VAL is a list (([FROM-CHAR ...] . TO) ...). If a matching
2765 element is found, return it. Otherwise return Qnil. */
2766
2767static Lisp_Object
2768check_translation (pos, pos_byte, end, val)
2769 int pos, pos_byte, end;
2770 Lisp_Object val;
2771{
2772 int buf_size = 16, buf_used = 0;
2773 int *buf = alloca (sizeof (int) * buf_size);
2774
2775 for (; CONSP (val); val = XCDR (val))
2776 {
2777 Lisp_Object elt;
2778 int len, i;
2779
2780 elt = XCAR (val);
2781 if (! CONSP (elt))
2782 continue;
2783 elt = XCAR (elt);
2784 if (! VECTORP (elt))
2785 continue;
2786 len = ASIZE (elt);
2787 if (len <= end - pos)
2788 {
2789 for (i = 0; i < len; i++)
2790 {
2791 if (buf_used <= i)
2792 {
2793 unsigned char *p = BYTE_POS_ADDR (pos_byte);
2794 int len;
2795
2796 if (buf_used == buf_size)
2797 {
2798 int *newbuf;
2799
2800 buf_size += 16;
2801 newbuf = alloca (sizeof (int) * buf_size);
2802 memcpy (newbuf, buf, sizeof (int) * buf_used);
2803 buf = newbuf;
2804 }
2805 buf[buf_used++] = STRING_CHAR_AND_LENGTH (p, 0, len);
2806 pos_byte += len;
2807 }
2808 if (XINT (AREF (elt, i)) != buf[i])
2809 break;
2810 }
2811 if (i == len)
2812 return XCAR (val);
2813 }
2814 }
2815 return Qnil;
2816}
2817
2818
2755DEFUN ("translate-region-internal", Ftranslate_region_internal, 2819DEFUN ("translate-region-internal", Ftranslate_region_internal,
2756 Stranslate_region_internal, 3, 3, 0, 2820 Stranslate_region_internal, 3, 3, 0,
2757 doc: /* Internal use only. 2821 doc: /* Internal use only.
2758From START to END, translate characters according to TABLE. 2822From START to END, translate characters according to TABLE.
2759TABLE is a string; the Nth character in it is the mapping 2823TABLE is a string or a char-table; the Nth character in it is the
2760for the character with code N. 2824mapping for the character with code N.
2761This function does not alter multibyte characters.
2762It returns the number of characters changed. */) 2825It returns the number of characters changed. */)
2763 (start, end, table) 2826 (start, end, table)
2764 Lisp_Object start; 2827 Lisp_Object start;
@@ -2769,14 +2832,18 @@ It returns the number of characters changed. */)
2769 register int nc; /* New character. */ 2832 register int nc; /* New character. */
2770 int cnt; /* Number of changes made. */ 2833 int cnt; /* Number of changes made. */
2771 int size; /* Size of translate table. */ 2834 int size; /* Size of translate table. */
2772 int pos, pos_byte; 2835 int pos, pos_byte, end_pos;
2773 int multibyte = !NILP (current_buffer->enable_multibyte_characters); 2836 int multibyte = !NILP (current_buffer->enable_multibyte_characters);
2774 int string_multibyte; 2837 int string_multibyte;
2775 Lisp_Object val; 2838 Lisp_Object val;
2776 2839
2777 validate_region (&start, &end); 2840 validate_region (&start, &end);
2778 if (CHAR_TABLE_P (table)) 2841 if (CHAR_TABLE_P (table))
2779 tt = NULL; 2842 {
2843 if (! EQ (XCHAR_TABLE (table)->purpose, Qtranslation_table))
2844 error ("Not a translation table");
2845 tt = NULL;
2846 }
2780 else 2847 else
2781 { 2848 {
2782 CHECK_STRING (table); 2849 CHECK_STRING (table);
@@ -2792,18 +2859,20 @@ It returns the number of characters changed. */)
2792 2859
2793 pos = XINT (start); 2860 pos = XINT (start);
2794 pos_byte = CHAR_TO_BYTE (pos); 2861 pos_byte = CHAR_TO_BYTE (pos);
2795 modify_region (current_buffer, XINT (start), XINT (end)); 2862 end_pos = XINT (end);
2863 modify_region (current_buffer, pos, end_pos);
2796 2864
2797 cnt = 0; 2865 cnt = 0;
2798 for (; pos < XINT (end); ) 2866 for (; pos < end_pos; )
2799 { 2867 {
2800 register unsigned char *p = BYTE_POS_ADDR (pos_byte); 2868 register unsigned char *p = BYTE_POS_ADDR (pos_byte);
2801 unsigned char *str, buf[MAX_MULTIBYTE_LENGTH]; 2869 unsigned char *str, buf[MAX_MULTIBYTE_LENGTH];
2802 int len, str_len; 2870 int len, str_len;
2803 int oc; 2871 int oc;
2872 Lisp_Object val;
2804 2873
2805 if (multibyte) 2874 if (multibyte)
2806 nc = oc = STRING_CHAR_AND_LENGTH (p, stop - pos_byte, len); 2875 nc = oc = STRING_CHAR_AND_LENGTH (p, 0, len);
2807 else 2876 else
2808 nc = oc = *p, len = 1; 2877 nc = oc = *p, len = 1;
2809 if (tt) 2878 if (tt)
@@ -2824,8 +2893,6 @@ It returns the number of characters changed. */)
2824 } 2893 }
2825 else 2894 else
2826 { 2895 {
2827 Lisp_Object val;
2828
2829 val = CHAR_TABLE_REF (table, oc); 2896 val = CHAR_TABLE_REF (table, oc);
2830 if (CHARACTERP (val)) 2897 if (CHARACTERP (val))
2831 { 2898 {
@@ -2833,29 +2900,79 @@ It returns the number of characters changed. */)
2833 str_len = CHAR_STRING (nc, buf); 2900 str_len = CHAR_STRING (nc, buf);
2834 str = buf; 2901 str = buf;
2835 } 2902 }
2903 else if (VECTORP (val) || (CONSP (val)))
2904 {
2905 /* VAL is [TO_CHAR ...] or (([FROM-CHAR ...] . TO) ...)
2906 where TO is TO-CHAR or [TO-CHAR ...]. */
2907 nc = -1;
2908 }
2836 } 2909 }
2837 2910
2838 if (nc != oc) 2911 if (nc != oc)
2839 { 2912 {
2840 if (len != str_len) 2913 if (nc >= 0)
2841 { 2914 {
2842 Lisp_Object string; 2915 /* Simple one char to one char translation. */
2916 if (len != str_len)
2917 {
2918 Lisp_Object string;
2843 2919
2844 /* This is less efficient, because it moves the gap, 2920 /* This is less efficient, because it moves the gap,
2845 but it should multibyte characters correctly. */ 2921 but it should handle multibyte characters correctly. */
2846 string = make_multibyte_string (str, 1, str_len); 2922 string = make_multibyte_string (str, 1, str_len);
2847 replace_range (pos, pos + 1, string, 1, 0, 1); 2923 replace_range (pos, pos + 1, string, 1, 0, 1);
2848 len = str_len; 2924 len = str_len;
2925 }
2926 else
2927 {
2928 record_change (pos, 1);
2929 while (str_len-- > 0)
2930 *p++ = *str++;
2931 signal_after_change (pos, 1, 1);
2932 update_compositions (pos, pos + 1, CHECK_BORDER);
2933 }
2934 ++cnt;
2849 } 2935 }
2850 else 2936 else
2851 { 2937 {
2852 record_change (pos, 1); 2938 Lisp_Object string;
2853 while (str_len-- > 0) 2939
2854 *p++ = *str++; 2940 if (CONSP (val))
2855 signal_after_change (pos, 1, 1); 2941 {
2856 update_compositions (pos, pos + 1, CHECK_BORDER); 2942 val = check_translation (pos, pos_byte, end_pos, val);
2943 if (NILP (val))
2944 {
2945 pos_byte += len;
2946 pos++;
2947 continue;
2948 }
2949 /* VAL is ([FROM-CHAR ...] . TO). */
2950 len = ASIZE (XCAR (val));
2951 val = XCDR (val);
2952 }
2953 else
2954 len = 1;
2955
2956 if (VECTORP (val))
2957 {
2958 int i;
2959
2960 string = Fmake_string (make_number (ASIZE (val)),
2961 AREF (val, 0));
2962 for (i = 1; i < ASIZE (val); i++)
2963 Faset (string, make_number (i), AREF (val, i));
2964 }
2965 else
2966 {
2967 string = Fmake_string (make_number (1), val);
2968 }
2969 replace_range (pos, pos + len, string, 1, 0, 1);
2970 pos_byte += SBYTES (string);
2971 pos += SCHARS (string);
2972 cnt += SCHARS (string);
2973 end_pos += SCHARS (string) - len;
2974 continue;
2857 } 2975 }
2858 ++cnt;
2859 } 2976 }
2860 pos_byte += len; 2977 pos_byte += len;
2861 pos++; 2978 pos++;
@@ -3231,6 +3348,10 @@ It may contain %-sequences meaning to substitute the next argument.
3231 The argument used for %d, %o, %x, %e, %f, %g or %c must be a number. 3348 The argument used for %d, %o, %x, %e, %f, %g or %c must be a number.
3232Use %% to put a single % into the output. 3349Use %% to put a single % into the output.
3233 3350
3351The basic structure of a %-sequence is
3352 % <flags> <width> <precision> character
3353where flags is [- #0]+, width is [0-9]+, and precision is .[0-9]+
3354
3234usage: (format STRING &rest OBJECTS) */) 3355usage: (format STRING &rest OBJECTS) */)
3235 (nargs, args) 3356 (nargs, args)
3236 int nargs; 3357 int nargs;
@@ -3315,7 +3436,7 @@ usage: (format STRING &rest OBJECTS) */)
3315 int i; 3436 int i;
3316 info = (struct info *) alloca (nbytes); 3437 info = (struct info *) alloca (nbytes);
3317 bzero (info, nbytes); 3438 bzero (info, nbytes);
3318 for (i = 0; i <= nargs; i++) 3439 for (i = 0; i < nargs; i++)
3319 info[i].start = -1; 3440 info[i].start = -1;
3320 discarded = (char *) alloca (SBYTES (args[0])); 3441 discarded = (char *) alloca (SBYTES (args[0]));
3321 bzero (discarded, SBYTES (args[0])); 3442 bzero (discarded, SBYTES (args[0]));
@@ -3338,7 +3459,7 @@ usage: (format STRING &rest OBJECTS) */)
3338 3459
3339 where 3460 where
3340 3461
3341 flags ::= [#-* 0]+ 3462 flags ::= [- #0]+
3342 field-width ::= [0-9]+ 3463 field-width ::= [0-9]+
3343 precision ::= '.' [0-9]* 3464 precision ::= '.' [0-9]*
3344 3465
@@ -3350,14 +3471,7 @@ usage: (format STRING &rest OBJECTS) */)
3350 digits to print after the '.' for floats, or the max. 3471 digits to print after the '.' for floats, or the max.
3351 number of chars to print from a string. */ 3472 number of chars to print from a string. */
3352 3473
3353 /* NOTE the handling of specifiers here differs in some ways 3474 while (index ("-0# ", *format))
3354 from the libc model. There are bugs in this code that lead
3355 to incorrect formatting when flags recognized by C but
3356 neither parsed nor rejected here are used. Further
3357 revisions will be made soon. */
3358
3359 /* incorrect list of flags to skip; will be fixed */
3360 while (index ("-*# 0", *format))
3361 ++format; 3475 ++format;
3362 3476
3363 if (*format >= '0' && *format <= '9') 3477 if (*format >= '0' && *format <= '9')
@@ -3485,7 +3599,7 @@ usage: (format STRING &rest OBJECTS) */)
3485 /* Anything but a string, convert to a string using princ. */ 3599 /* Anything but a string, convert to a string using princ. */
3486 register Lisp_Object tem; 3600 register Lisp_Object tem;
3487 tem = Fprin1_to_string (args[n], Qt); 3601 tem = Fprin1_to_string (args[n], Qt);
3488 if (STRING_MULTIBYTE (tem) & ! multibyte) 3602 if (STRING_MULTIBYTE (tem) && ! multibyte)
3489 { 3603 {
3490 multibyte = 1; 3604 multibyte = 1;
3491 goto retry; 3605 goto retry;
@@ -3532,17 +3646,19 @@ usage: (format STRING &rest OBJECTS) */)
3532 discarded[format - format_start] = 1; 3646 discarded[format - format_start] = 1;
3533 format++; 3647 format++;
3534 3648
3535 /* Process a numeric arg and skip it. */ 3649 while (index("-0# ", *format))
3536 /* NOTE atoi is the wrong thing to use here; will be fixed */ 3650 {
3651 if (*format == '-')
3652 {
3653 negative = 1;
3654 }
3655 discarded[format - format_start] = 1;
3656 ++format;
3657 }
3658
3537 minlen = atoi (format); 3659 minlen = atoi (format);
3538 if (minlen < 0) 3660
3539 minlen = - minlen, negative = 1; 3661 while ((*format >= '0' && *format <= '9') || *format == '.')
3540
3541 /* NOTE the parsing here is not consistent with the first
3542 pass, and neither attempt is what we want to do. Will be
3543 fixed. */
3544 while ((*format >= '0' && *format <= '9')
3545 || *format == '-' || *format == ' ' || *format == '.')
3546 { 3662 {
3547 discarded[format - format_start] = 1; 3663 discarded[format - format_start] = 1;
3548 format++; 3664 format++;
@@ -4358,3 +4474,6 @@ functions if all the text being accessed has this property. */);
4358 defsubr (&Ssave_restriction); 4474 defsubr (&Ssave_restriction);
4359 defsubr (&Stranspose_regions); 4475 defsubr (&Stranspose_regions);
4360} 4476}
4477
4478/* arch-tag: fc3827d8-6f60-4067-b11e-c3218031b018
4479 (do not change this comment) */