aboutsummaryrefslogtreecommitdiffstats
path: root/src/editfns.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/editfns.c')
-rw-r--r--src/editfns.c187
1 files changed, 166 insertions, 21 deletions
diff --git a/src/editfns.c b/src/editfns.c
index 43d4aa2aaa2..15510779603 100644
--- a/src/editfns.c
+++ b/src/editfns.c
@@ -52,7 +52,7 @@ Boston, MA 02110-1301, USA. */
52 52
53#include "intervals.h" 53#include "intervals.h"
54#include "buffer.h" 54#include "buffer.h"
55#include "charset.h" 55#include "character.h"
56#include "coding.h" 56#include "coding.h"
57#include "frame.h" 57#include "frame.h"
58#include "window.h" 58#include "window.h"
@@ -210,11 +210,9 @@ usage: (char-to-string CHAR) */)
210 int len; 210 int len;
211 unsigned char str[MAX_MULTIBYTE_LENGTH]; 211 unsigned char str[MAX_MULTIBYTE_LENGTH];
212 212
213 CHECK_NUMBER (character); 213 CHECK_CHARACTER (character);
214 214
215 len = (SINGLE_BYTE_CHAR_P (XFASTINT (character)) 215 len = CHAR_STRING (XFASTINT (character), str);
216 ? (*str = (unsigned char)(XFASTINT (character)), 1)
217 : char_to_string (XFASTINT (character), str));
218 return make_string_from_bytes (str, 1, len); 216 return make_string_from_bytes (str, 1, len);
219} 217}
220 218
@@ -2155,7 +2153,7 @@ general_insert_function (insert_func, insert_from_string_func,
2155 for (argnum = 0; argnum < nargs; argnum++) 2153 for (argnum = 0; argnum < nargs; argnum++)
2156 { 2154 {
2157 val = args[argnum]; 2155 val = args[argnum];
2158 if (INTEGERP (val)) 2156 if (CHARACTERP (val))
2159 { 2157 {
2160 unsigned char str[MAX_MULTIBYTE_LENGTH]; 2158 unsigned char str[MAX_MULTIBYTE_LENGTH];
2161 int len; 2159 int len;
@@ -2164,7 +2162,7 @@ general_insert_function (insert_func, insert_from_string_func,
2164 len = CHAR_STRING (XFASTINT (val), str); 2162 len = CHAR_STRING (XFASTINT (val), str);
2165 else 2163 else
2166 { 2164 {
2167 str[0] = (SINGLE_BYTE_CHAR_P (XINT (val)) 2165 str[0] = (ASCII_CHAR_P (XINT (val))
2168 ? XINT (val) 2166 ? XINT (val)
2169 : multibyte_char_to_unibyte (XINT (val), Qnil)); 2167 : multibyte_char_to_unibyte (XINT (val), Qnil));
2170 len = 1; 2168 len = 1;
@@ -2331,6 +2329,29 @@ from adjoining text, if those properties are sticky. */)
2331 return Qnil; 2329 return Qnil;
2332} 2330}
2333 2331
2332DEFUN ("insert-byte", Finsert_byte, Sinsert_byte, 2, 3, 0,
2333 doc: /* Insert COUNT (second arg) copies of BYTE (first arg).
2334Both arguments are required.
2335BYTE is a number of the range 0..255.
2336
2337If BYTE is 128..255 and the current buffer is multibyte, the
2338corresponding eight-bit character is inserted.
2339
2340Point, and before-insertion markers, are relocated as in the function `insert'.
2341The optional third arg INHERIT, if non-nil, says to inherit text properties
2342from adjoining text, if those properties are sticky. */)
2343 (byte, count, inherit)
2344 Lisp_Object byte, count, inherit;
2345{
2346 CHECK_NUMBER (byte);
2347 if (XINT (byte) < 0 || XINT (byte) > 255)
2348 args_out_of_range_3 (byte, make_number (0), make_number (255));
2349 if (XINT (byte) >= 128
2350 && ! NILP (current_buffer->enable_multibyte_characters))
2351 XSETFASTINT (byte, BYTE8_TO_CHAR (XINT (byte)));
2352 return Finsert_char (byte, count, inherit);
2353}
2354
2334 2355
2335/* Making strings from buffer contents. */ 2356/* Making strings from buffer contents. */
2336 2357
@@ -2892,12 +2913,73 @@ Both characters must have the same length of multi-byte form. */)
2892 return Qnil; 2913 return Qnil;
2893} 2914}
2894 2915
2916
2917static Lisp_Object check_translation P_ ((int, int, int, Lisp_Object));
2918
2919/* Helper function for Ftranslate_region_internal.
2920
2921 Check if a character sequence at POS (POS_BYTE) matches an element
2922 of VAL. VAL is a list (([FROM-CHAR ...] . TO) ...). If a matching
2923 element is found, return it. Otherwise return Qnil. */
2924
2925static Lisp_Object
2926check_translation (pos, pos_byte, end, val)
2927 int pos, pos_byte, end;
2928 Lisp_Object val;
2929{
2930 int buf_size = 16, buf_used = 0;
2931 int *buf = alloca (sizeof (int) * buf_size);
2932
2933 for (; CONSP (val); val = XCDR (val))
2934 {
2935 Lisp_Object elt;
2936 int len, i;
2937
2938 elt = XCAR (val);
2939 if (! CONSP (elt))
2940 continue;
2941 elt = XCAR (elt);
2942 if (! VECTORP (elt))
2943 continue;
2944 len = ASIZE (elt);
2945 if (len <= end - pos)
2946 {
2947 for (i = 0; i < len; i++)
2948 {
2949 if (buf_used <= i)
2950 {
2951 unsigned char *p = BYTE_POS_ADDR (pos_byte);
2952 int len;
2953
2954 if (buf_used == buf_size)
2955 {
2956 int *newbuf;
2957
2958 buf_size += 16;
2959 newbuf = alloca (sizeof (int) * buf_size);
2960 memcpy (newbuf, buf, sizeof (int) * buf_used);
2961 buf = newbuf;
2962 }
2963 buf[buf_used++] = STRING_CHAR_AND_LENGTH (p, 0, len);
2964 pos_byte += len;
2965 }
2966 if (XINT (AREF (elt, i)) != buf[i])
2967 break;
2968 }
2969 if (i == len)
2970 return XCAR (val);
2971 }
2972 }
2973 return Qnil;
2974}
2975
2976
2895DEFUN ("translate-region-internal", Ftranslate_region_internal, 2977DEFUN ("translate-region-internal", Ftranslate_region_internal,
2896 Stranslate_region_internal, 3, 3, 0, 2978 Stranslate_region_internal, 3, 3, 0,
2897 doc: /* Internal use only. 2979 doc: /* Internal use only.
2898From START to END, translate characters according to TABLE. 2980From START to END, translate characters according to TABLE.
2899TABLE is a string; the Nth character in it is the mapping 2981TABLE is a string or a char-table; the Nth character in it is the
2900for the character with code N. 2982mapping for the character with code N.
2901It returns the number of characters changed. */) 2983It returns the number of characters changed. */)
2902 (start, end, table) 2984 (start, end, table)
2903 Lisp_Object start; 2985 Lisp_Object start;
@@ -2911,10 +2993,13 @@ It returns the number of characters changed. */)
2911 int pos, pos_byte, end_pos; 2993 int pos, pos_byte, end_pos;
2912 int multibyte = !NILP (current_buffer->enable_multibyte_characters); 2994 int multibyte = !NILP (current_buffer->enable_multibyte_characters);
2913 int string_multibyte; 2995 int string_multibyte;
2996 Lisp_Object val;
2914 2997
2915 validate_region (&start, &end); 2998 validate_region (&start, &end);
2916 if (CHAR_TABLE_P (table)) 2999 if (CHAR_TABLE_P (table))
2917 { 3000 {
3001 if (! EQ (XCHAR_TABLE (table)->purpose, Qtranslation_table))
3002 error ("Not a translation table");
2918 size = MAX_CHAR; 3003 size = MAX_CHAR;
2919 tt = NULL; 3004 tt = NULL;
2920 } 3005 }
@@ -2925,14 +3010,14 @@ It returns the number of characters changed. */)
2925 if (! multibyte && (SCHARS (table) < SBYTES (table))) 3010 if (! multibyte && (SCHARS (table) < SBYTES (table)))
2926 table = string_make_unibyte (table); 3011 table = string_make_unibyte (table);
2927 string_multibyte = SCHARS (table) < SBYTES (table); 3012 string_multibyte = SCHARS (table) < SBYTES (table);
2928 size = SCHARS (table); 3013 size = SBYTES (table);
2929 tt = SDATA (table); 3014 tt = SDATA (table);
2930 } 3015 }
2931 3016
2932 pos = XINT (start); 3017 pos = XINT (start);
2933 pos_byte = CHAR_TO_BYTE (pos); 3018 pos_byte = CHAR_TO_BYTE (pos);
2934 end_pos = XINT (end); 3019 end_pos = XINT (end);
2935 modify_region (current_buffer, pos, XINT (end), 0); 3020 modify_region (current_buffer, pos, end_pos, 0);
2936 3021
2937 cnt = 0; 3022 cnt = 0;
2938 for (; pos < end_pos; ) 3023 for (; pos < end_pos; )
@@ -2941,6 +3026,7 @@ It returns the number of characters changed. */)
2941 unsigned char *str, buf[MAX_MULTIBYTE_LENGTH]; 3026 unsigned char *str, buf[MAX_MULTIBYTE_LENGTH];
2942 int len, str_len; 3027 int len, str_len;
2943 int oc; 3028 int oc;
3029 Lisp_Object val;
2944 3030
2945 if (multibyte) 3031 if (multibyte)
2946 oc = STRING_CHAR_AND_LENGTH (p, MAX_MULTIBYTE_LENGTH, len); 3032 oc = STRING_CHAR_AND_LENGTH (p, MAX_MULTIBYTE_LENGTH, len);
@@ -2955,7 +3041,7 @@ It returns the number of characters changed. */)
2955 if (string_multibyte) 3041 if (string_multibyte)
2956 { 3042 {
2957 str = tt + string_char_to_byte (table, oc); 3043 str = tt + string_char_to_byte (table, oc);
2958 nc = STRING_CHAR_AND_LENGTH (str, MAX_MULTIBYTE_LENGTH, 3044 nc = STRING_CHAR_AND_LENGTH (str, MAX_MULTIBYTE_LENGTH,
2959 str_len); 3045 str_len);
2960 } 3046 }
2961 else 3047 else
@@ -2963,7 +3049,7 @@ It returns the number of characters changed. */)
2963 nc = tt[oc]; 3049 nc = tt[oc];
2964 if (! ASCII_BYTE_P (nc) && multibyte) 3050 if (! ASCII_BYTE_P (nc) && multibyte)
2965 { 3051 {
2966 str_len = CHAR_STRING (nc, buf); 3052 str_len = BYTE8_STRING (nc, buf);
2967 str = buf; 3053 str = buf;
2968 } 3054 }
2969 else 3055 else
@@ -2975,28 +3061,34 @@ It returns the number of characters changed. */)
2975 } 3061 }
2976 else 3062 else
2977 { 3063 {
2978 Lisp_Object val;
2979 int c; 3064 int c;
2980 3065
2981 nc = oc; 3066 nc = oc;
2982 val = CHAR_TABLE_REF (table, oc); 3067 val = CHAR_TABLE_REF (table, oc);
2983 if (INTEGERP (val) 3068 if (CHARACTERP (val)
2984 && (c = XINT (val), CHAR_VALID_P (c, 0))) 3069 && (c = XINT (val), CHAR_VALID_P (c, 0)))
2985 { 3070 {
2986 nc = c; 3071 nc = c;
2987 str_len = CHAR_STRING (nc, buf); 3072 str_len = CHAR_STRING (nc, buf);
2988 str = buf; 3073 str = buf;
2989 } 3074 }
3075 else if (VECTORP (val) || (CONSP (val)))
3076 {
3077 /* VAL is [TO_CHAR ...] or (([FROM-CHAR ...] . TO) ...)
3078 where TO is TO-CHAR or [TO-CHAR ...]. */
3079 nc = -1;
3080 }
2990 } 3081 }
2991 3082
2992 if (nc != oc) 3083 if (nc != oc && nc >= 0)
2993 { 3084 {
3085 /* Simple one char to one char translation. */
2994 if (len != str_len) 3086 if (len != str_len)
2995 { 3087 {
2996 Lisp_Object string; 3088 Lisp_Object string;
2997 3089
2998 /* This is less efficient, because it moves the gap, 3090 /* This is less efficient, because it moves the gap,
2999 but it should multibyte characters correctly. */ 3091 but it should handle multibyte characters correctly. */
3000 string = make_multibyte_string (str, 1, str_len); 3092 string = make_multibyte_string (str, 1, str_len);
3001 replace_range (pos, pos + 1, string, 1, 0, 1); 3093 replace_range (pos, pos + 1, string, 1, 0, 1);
3002 len = str_len; 3094 len = str_len;
@@ -3011,6 +3103,46 @@ It returns the number of characters changed. */)
3011 } 3103 }
3012 ++cnt; 3104 ++cnt;
3013 } 3105 }
3106 else if (nc < 0)
3107 {
3108 Lisp_Object string;
3109
3110 if (CONSP (val))
3111 {
3112 val = check_translation (pos, pos_byte, end_pos, val);
3113 if (NILP (val))
3114 {
3115 pos_byte += len;
3116 pos++;
3117 continue;
3118 }
3119 /* VAL is ([FROM-CHAR ...] . TO). */
3120 len = ASIZE (XCAR (val));
3121 val = XCDR (val);
3122 }
3123 else
3124 len = 1;
3125
3126 if (VECTORP (val))
3127 {
3128 int i;
3129
3130 string = Fmake_string (make_number (ASIZE (val)),
3131 AREF (val, 0));
3132 for (i = 1; i < ASIZE (val); i++)
3133 Faset (string, make_number (i), AREF (val, i));
3134 }
3135 else
3136 {
3137 string = Fmake_string (make_number (1), val);
3138 }
3139 replace_range (pos, pos + len, string, 1, 0, 1);
3140 pos_byte += SBYTES (string);
3141 pos += SCHARS (string);
3142 cnt += SCHARS (string);
3143 end_pos += SCHARS (string) - len;
3144 continue;
3145 }
3014 } 3146 }
3015 pos_byte += len; 3147 pos_byte += len;
3016 pos++; 3148 pos++;
@@ -3608,8 +3740,8 @@ usage: (format STRING &rest OBJECTS) */)
3608 thissize = 30 + (precision[n] > 0 ? precision[n] : 0); 3740 thissize = 30 + (precision[n] > 0 ? precision[n] : 0);
3609 if (*format == 'c') 3741 if (*format == 'c')
3610 { 3742 {
3611 if (! SINGLE_BYTE_CHAR_P (XINT (args[n])) 3743 if (! ASCII_CHAR_P (XINT (args[n]))
3612 /* Note: No one can remember why we have to treat 3744 /* Note: No one can remeber why we have to treat
3613 the character 0 as a multibyte character here. 3745 the character 0 as a multibyte character here.
3614 But, until it causes a real problem, let's 3746 But, until it causes a real problem, let's
3615 don't change it. */ 3747 don't change it. */
@@ -4030,8 +4162,20 @@ Case is ignored if `case-fold-search' is non-nil in the current buffer. */)
4030 /* Do these in separate statements, 4162 /* Do these in separate statements,
4031 then compare the variables. 4163 then compare the variables.
4032 because of the way DOWNCASE uses temp variables. */ 4164 because of the way DOWNCASE uses temp variables. */
4033 i1 = DOWNCASE (XFASTINT (c1)); 4165 i1 = XFASTINT (c1);
4034 i2 = DOWNCASE (XFASTINT (c2)); 4166 if (NILP (current_buffer->enable_multibyte_characters)
4167 && ! ASCII_CHAR_P (i1))
4168 {
4169 MAKE_CHAR_MULTIBYTE (i1);
4170 }
4171 i2 = XFASTINT (c2);
4172 if (NILP (current_buffer->enable_multibyte_characters)
4173 && ! ASCII_CHAR_P (i2))
4174 {
4175 MAKE_CHAR_MULTIBYTE (i2);
4176 }
4177 i1 = DOWNCASE (i1);
4178 i2 = DOWNCASE (i2);
4035 return (i1 == i2 ? Qt : Qnil); 4179 return (i1 == i2 ? Qt : Qnil);
4036} 4180}
4037 4181
@@ -4526,6 +4670,7 @@ functions if all the text being accessed has this property. */);
4526 defsubr (&Sinsert_and_inherit); 4670 defsubr (&Sinsert_and_inherit);
4527 defsubr (&Sinsert_and_inherit_before_markers); 4671 defsubr (&Sinsert_and_inherit_before_markers);
4528 defsubr (&Sinsert_char); 4672 defsubr (&Sinsert_char);
4673 defsubr (&Sinsert_byte);
4529 4674
4530 defsubr (&Suser_login_name); 4675 defsubr (&Suser_login_name);
4531 defsubr (&Suser_real_login_name); 4676 defsubr (&Suser_real_login_name);