diff options
Diffstat (limited to 'src/data.c')
| -rw-r--r-- | src/data.c | 123 |
1 files changed, 62 insertions, 61 deletions
diff --git a/src/data.c b/src/data.c index 57d7753e393..cf01d38036d 100644 --- a/src/data.c +++ b/src/data.c | |||
| @@ -2148,61 +2148,62 @@ bool-vector. IDX starts at 0. */) | |||
| 2148 | CHECK_CHARACTER (idx); | 2148 | CHECK_CHARACTER (idx); |
| 2149 | CHAR_TABLE_SET (array, idxval, newelt); | 2149 | CHAR_TABLE_SET (array, idxval, newelt); |
| 2150 | } | 2150 | } |
| 2151 | else if (STRING_MULTIBYTE (array)) | 2151 | else |
| 2152 | { | 2152 | { |
| 2153 | EMACS_INT idxval_byte, prev_bytes, new_bytes, nbytes; | 2153 | int c; |
| 2154 | unsigned char workbuf[MAX_MULTIBYTE_LENGTH], *p0 = workbuf, *p1; | ||
| 2155 | 2154 | ||
| 2156 | if (idxval < 0 || idxval >= SCHARS (array)) | 2155 | if (idxval < 0 || idxval >= SCHARS (array)) |
| 2157 | args_out_of_range (array, idx); | 2156 | args_out_of_range (array, idx); |
| 2158 | CHECK_CHARACTER (newelt); | 2157 | CHECK_CHARACTER (newelt); |
| 2158 | c = XFASTINT (newelt); | ||
| 2159 | 2159 | ||
| 2160 | nbytes = SBYTES (array); | 2160 | if (STRING_MULTIBYTE (array)) |
| 2161 | |||
| 2162 | idxval_byte = string_char_to_byte (array, idxval); | ||
| 2163 | p1 = SDATA (array) + idxval_byte; | ||
| 2164 | prev_bytes = BYTES_BY_CHAR_HEAD (*p1); | ||
| 2165 | new_bytes = CHAR_STRING (XINT (newelt), p0); | ||
| 2166 | if (prev_bytes != new_bytes) | ||
| 2167 | { | 2161 | { |
| 2168 | /* We must relocate the string data. */ | 2162 | EMACS_INT idxval_byte, prev_bytes, new_bytes, nbytes; |
| 2169 | EMACS_INT nchars = SCHARS (array); | 2163 | unsigned char workbuf[MAX_MULTIBYTE_LENGTH], *p0 = workbuf, *p1; |
| 2170 | unsigned char *str; | 2164 | |
| 2171 | USE_SAFE_ALLOCA; | 2165 | nbytes = SBYTES (array); |
| 2172 | 2166 | idxval_byte = string_char_to_byte (array, idxval); | |
| 2173 | SAFE_ALLOCA (str, unsigned char *, nbytes); | ||
| 2174 | memcpy (str, SDATA (array), nbytes); | ||
| 2175 | allocate_string_data (XSTRING (array), nchars, | ||
| 2176 | nbytes + new_bytes - prev_bytes); | ||
| 2177 | memcpy (SDATA (array), str, idxval_byte); | ||
| 2178 | p1 = SDATA (array) + idxval_byte; | 2167 | p1 = SDATA (array) + idxval_byte; |
| 2179 | memcpy (p1 + new_bytes, str + idxval_byte + prev_bytes, | 2168 | prev_bytes = BYTES_BY_CHAR_HEAD (*p1); |
| 2180 | nbytes - (idxval_byte + prev_bytes)); | 2169 | new_bytes = CHAR_STRING (c, p0); |
| 2181 | SAFE_FREE (); | 2170 | if (prev_bytes != new_bytes) |
| 2182 | clear_string_char_byte_cache (); | 2171 | { |
| 2172 | /* We must relocate the string data. */ | ||
| 2173 | EMACS_INT nchars = SCHARS (array); | ||
| 2174 | unsigned char *str; | ||
| 2175 | USE_SAFE_ALLOCA; | ||
| 2176 | |||
| 2177 | SAFE_ALLOCA (str, unsigned char *, nbytes); | ||
| 2178 | memcpy (str, SDATA (array), nbytes); | ||
| 2179 | allocate_string_data (XSTRING (array), nchars, | ||
| 2180 | nbytes + new_bytes - prev_bytes); | ||
| 2181 | memcpy (SDATA (array), str, idxval_byte); | ||
| 2182 | p1 = SDATA (array) + idxval_byte; | ||
| 2183 | memcpy (p1 + new_bytes, str + idxval_byte + prev_bytes, | ||
| 2184 | nbytes - (idxval_byte + prev_bytes)); | ||
| 2185 | SAFE_FREE (); | ||
| 2186 | clear_string_char_byte_cache (); | ||
| 2187 | } | ||
| 2188 | while (new_bytes--) | ||
| 2189 | *p1++ = *p0++; | ||
| 2183 | } | 2190 | } |
| 2184 | while (new_bytes--) | 2191 | else |
| 2185 | *p1++ = *p0++; | ||
| 2186 | } | ||
| 2187 | else | ||
| 2188 | { | ||
| 2189 | if (idxval < 0 || idxval >= SCHARS (array)) | ||
| 2190 | args_out_of_range (array, idx); | ||
| 2191 | CHECK_NUMBER (newelt); | ||
| 2192 | |||
| 2193 | if (XINT (newelt) >= 0 && ! SINGLE_BYTE_CHAR_P (XINT (newelt))) | ||
| 2194 | { | 2192 | { |
| 2195 | int i; | 2193 | if (! SINGLE_BYTE_CHAR_P (c)) |
| 2196 | 2194 | { | |
| 2197 | for (i = SBYTES (array) - 1; i >= 0; i--) | 2195 | int i; |
| 2198 | if (SREF (array, i) >= 0x80) | 2196 | |
| 2199 | args_out_of_range (array, newelt); | 2197 | for (i = SBYTES (array) - 1; i >= 0; i--) |
| 2200 | /* ARRAY is an ASCII string. Convert it to a multibyte | 2198 | if (SREF (array, i) >= 0x80) |
| 2201 | string, and try `aset' again. */ | 2199 | args_out_of_range (array, newelt); |
| 2202 | STRING_SET_MULTIBYTE (array); | 2200 | /* ARRAY is an ASCII string. Convert it to a multibyte |
| 2203 | return Faset (array, idx, newelt); | 2201 | string, and try `aset' again. */ |
| 2202 | STRING_SET_MULTIBYTE (array); | ||
| 2203 | return Faset (array, idx, newelt); | ||
| 2204 | } | ||
| 2205 | SSET (array, idxval, c); | ||
| 2204 | } | 2206 | } |
| 2205 | SSET (array, idxval, XINT (newelt)); | ||
| 2206 | } | 2207 | } |
| 2207 | 2208 | ||
| 2208 | return newelt; | 2209 | return newelt; |
| @@ -2502,18 +2503,18 @@ enum arithop | |||
| 2502 | Amin | 2503 | Amin |
| 2503 | }; | 2504 | }; |
| 2504 | 2505 | ||
| 2505 | static Lisp_Object float_arith_driver (double, size_t, enum arithop, | 2506 | static Lisp_Object float_arith_driver (double, ptrdiff_t, enum arithop, |
| 2506 | size_t, Lisp_Object *); | 2507 | ptrdiff_t, Lisp_Object *); |
| 2507 | static Lisp_Object | 2508 | static Lisp_Object |
| 2508 | arith_driver (enum arithop code, size_t nargs, register Lisp_Object *args) | 2509 | arith_driver (enum arithop code, ptrdiff_t nargs, Lisp_Object *args) |
| 2509 | { | 2510 | { |
| 2510 | register Lisp_Object val; | 2511 | register Lisp_Object val; |
| 2511 | register size_t argnum; | 2512 | ptrdiff_t argnum; |
| 2512 | register EMACS_INT accum = 0; | 2513 | register EMACS_INT accum = 0; |
| 2513 | register EMACS_INT next; | 2514 | register EMACS_INT next; |
| 2514 | 2515 | ||
| 2515 | int overflow = 0; | 2516 | int overflow = 0; |
| 2516 | size_t ok_args; | 2517 | ptrdiff_t ok_args; |
| 2517 | EMACS_INT ok_accum; | 2518 | EMACS_INT ok_accum; |
| 2518 | 2519 | ||
| 2519 | switch (SWITCH_ENUM_CAST (code)) | 2520 | switch (SWITCH_ENUM_CAST (code)) |
| @@ -2617,8 +2618,8 @@ arith_driver (enum arithop code, size_t nargs, register Lisp_Object *args) | |||
| 2617 | #define isnan(x) ((x) != (x)) | 2618 | #define isnan(x) ((x) != (x)) |
| 2618 | 2619 | ||
| 2619 | static Lisp_Object | 2620 | static Lisp_Object |
| 2620 | float_arith_driver (double accum, register size_t argnum, enum arithop code, | 2621 | float_arith_driver (double accum, ptrdiff_t argnum, enum arithop code, |
| 2621 | size_t nargs, register Lisp_Object *args) | 2622 | ptrdiff_t nargs, Lisp_Object *args) |
| 2622 | { | 2623 | { |
| 2623 | register Lisp_Object val; | 2624 | register Lisp_Object val; |
| 2624 | double next; | 2625 | double next; |
| @@ -2680,7 +2681,7 @@ float_arith_driver (double accum, register size_t argnum, enum arithop code, | |||
| 2680 | DEFUN ("+", Fplus, Splus, 0, MANY, 0, | 2681 | DEFUN ("+", Fplus, Splus, 0, MANY, 0, |
| 2681 | doc: /* Return sum of any number of arguments, which are numbers or markers. | 2682 | doc: /* Return sum of any number of arguments, which are numbers or markers. |
| 2682 | usage: (+ &rest NUMBERS-OR-MARKERS) */) | 2683 | usage: (+ &rest NUMBERS-OR-MARKERS) */) |
| 2683 | (size_t nargs, Lisp_Object *args) | 2684 | (ptrdiff_t nargs, Lisp_Object *args) |
| 2684 | { | 2685 | { |
| 2685 | return arith_driver (Aadd, nargs, args); | 2686 | return arith_driver (Aadd, nargs, args); |
| 2686 | } | 2687 | } |
| @@ -2690,7 +2691,7 @@ DEFUN ("-", Fminus, Sminus, 0, MANY, 0, | |||
| 2690 | With one arg, negates it. With more than one arg, | 2691 | With one arg, negates it. With more than one arg, |
| 2691 | subtracts all but the first from the first. | 2692 | subtracts all but the first from the first. |
| 2692 | usage: (- &optional NUMBER-OR-MARKER &rest MORE-NUMBERS-OR-MARKERS) */) | 2693 | usage: (- &optional NUMBER-OR-MARKER &rest MORE-NUMBERS-OR-MARKERS) */) |
| 2693 | (size_t nargs, Lisp_Object *args) | 2694 | (ptrdiff_t nargs, Lisp_Object *args) |
| 2694 | { | 2695 | { |
| 2695 | return arith_driver (Asub, nargs, args); | 2696 | return arith_driver (Asub, nargs, args); |
| 2696 | } | 2697 | } |
| @@ -2698,7 +2699,7 @@ usage: (- &optional NUMBER-OR-MARKER &rest MORE-NUMBERS-OR-MARKERS) */) | |||
| 2698 | DEFUN ("*", Ftimes, Stimes, 0, MANY, 0, | 2699 | DEFUN ("*", Ftimes, Stimes, 0, MANY, 0, |
| 2699 | doc: /* Return product of any number of arguments, which are numbers or markers. | 2700 | doc: /* Return product of any number of arguments, which are numbers or markers. |
| 2700 | usage: (* &rest NUMBERS-OR-MARKERS) */) | 2701 | usage: (* &rest NUMBERS-OR-MARKERS) */) |
| 2701 | (size_t nargs, Lisp_Object *args) | 2702 | (ptrdiff_t nargs, Lisp_Object *args) |
| 2702 | { | 2703 | { |
| 2703 | return arith_driver (Amult, nargs, args); | 2704 | return arith_driver (Amult, nargs, args); |
| 2704 | } | 2705 | } |
| @@ -2707,9 +2708,9 @@ DEFUN ("/", Fquo, Squo, 2, MANY, 0, | |||
| 2707 | doc: /* Return first argument divided by all the remaining arguments. | 2708 | doc: /* Return first argument divided by all the remaining arguments. |
| 2708 | The arguments must be numbers or markers. | 2709 | The arguments must be numbers or markers. |
| 2709 | usage: (/ DIVIDEND DIVISOR &rest DIVISORS) */) | 2710 | usage: (/ DIVIDEND DIVISOR &rest DIVISORS) */) |
| 2710 | (size_t nargs, Lisp_Object *args) | 2711 | (ptrdiff_t nargs, Lisp_Object *args) |
| 2711 | { | 2712 | { |
| 2712 | size_t argnum; | 2713 | ptrdiff_t argnum; |
| 2713 | for (argnum = 2; argnum < nargs; argnum++) | 2714 | for (argnum = 2; argnum < nargs; argnum++) |
| 2714 | if (FLOATP (args[argnum])) | 2715 | if (FLOATP (args[argnum])) |
| 2715 | return float_arith_driver (0, 0, Adiv, nargs, args); | 2716 | return float_arith_driver (0, 0, Adiv, nargs, args); |
| @@ -2791,7 +2792,7 @@ DEFUN ("max", Fmax, Smax, 1, MANY, 0, | |||
| 2791 | doc: /* Return largest of all the arguments (which must be numbers or markers). | 2792 | doc: /* Return largest of all the arguments (which must be numbers or markers). |
| 2792 | The value is always a number; markers are converted to numbers. | 2793 | The value is always a number; markers are converted to numbers. |
| 2793 | usage: (max NUMBER-OR-MARKER &rest NUMBERS-OR-MARKERS) */) | 2794 | usage: (max NUMBER-OR-MARKER &rest NUMBERS-OR-MARKERS) */) |
| 2794 | (size_t nargs, Lisp_Object *args) | 2795 | (ptrdiff_t nargs, Lisp_Object *args) |
| 2795 | { | 2796 | { |
| 2796 | return arith_driver (Amax, nargs, args); | 2797 | return arith_driver (Amax, nargs, args); |
| 2797 | } | 2798 | } |
| @@ -2800,7 +2801,7 @@ DEFUN ("min", Fmin, Smin, 1, MANY, 0, | |||
| 2800 | doc: /* Return smallest of all the arguments (which must be numbers or markers). | 2801 | doc: /* Return smallest of all the arguments (which must be numbers or markers). |
| 2801 | The value is always a number; markers are converted to numbers. | 2802 | The value is always a number; markers are converted to numbers. |
| 2802 | usage: (min NUMBER-OR-MARKER &rest NUMBERS-OR-MARKERS) */) | 2803 | usage: (min NUMBER-OR-MARKER &rest NUMBERS-OR-MARKERS) */) |
| 2803 | (size_t nargs, Lisp_Object *args) | 2804 | (ptrdiff_t nargs, Lisp_Object *args) |
| 2804 | { | 2805 | { |
| 2805 | return arith_driver (Amin, nargs, args); | 2806 | return arith_driver (Amin, nargs, args); |
| 2806 | } | 2807 | } |
| @@ -2809,7 +2810,7 @@ DEFUN ("logand", Flogand, Slogand, 0, MANY, 0, | |||
| 2809 | doc: /* Return bitwise-and of all the arguments. | 2810 | doc: /* Return bitwise-and of all the arguments. |
| 2810 | Arguments may be integers, or markers converted to integers. | 2811 | Arguments may be integers, or markers converted to integers. |
| 2811 | usage: (logand &rest INTS-OR-MARKERS) */) | 2812 | usage: (logand &rest INTS-OR-MARKERS) */) |
| 2812 | (size_t nargs, Lisp_Object *args) | 2813 | (ptrdiff_t nargs, Lisp_Object *args) |
| 2813 | { | 2814 | { |
| 2814 | return arith_driver (Alogand, nargs, args); | 2815 | return arith_driver (Alogand, nargs, args); |
| 2815 | } | 2816 | } |
| @@ -2818,7 +2819,7 @@ DEFUN ("logior", Flogior, Slogior, 0, MANY, 0, | |||
| 2818 | doc: /* Return bitwise-or of all the arguments. | 2819 | doc: /* Return bitwise-or of all the arguments. |
| 2819 | Arguments may be integers, or markers converted to integers. | 2820 | Arguments may be integers, or markers converted to integers. |
| 2820 | usage: (logior &rest INTS-OR-MARKERS) */) | 2821 | usage: (logior &rest INTS-OR-MARKERS) */) |
| 2821 | (size_t nargs, Lisp_Object *args) | 2822 | (ptrdiff_t nargs, Lisp_Object *args) |
| 2822 | { | 2823 | { |
| 2823 | return arith_driver (Alogior, nargs, args); | 2824 | return arith_driver (Alogior, nargs, args); |
| 2824 | } | 2825 | } |
| @@ -2827,7 +2828,7 @@ DEFUN ("logxor", Flogxor, Slogxor, 0, MANY, 0, | |||
| 2827 | doc: /* Return bitwise-exclusive-or of all the arguments. | 2828 | doc: /* Return bitwise-exclusive-or of all the arguments. |
| 2828 | Arguments may be integers, or markers converted to integers. | 2829 | Arguments may be integers, or markers converted to integers. |
| 2829 | usage: (logxor &rest INTS-OR-MARKERS) */) | 2830 | usage: (logxor &rest INTS-OR-MARKERS) */) |
| 2830 | (size_t nargs, Lisp_Object *args) | 2831 | (ptrdiff_t nargs, Lisp_Object *args) |
| 2831 | { | 2832 | { |
| 2832 | return arith_driver (Alogxor, nargs, args); | 2833 | return arith_driver (Alogxor, nargs, args); |
| 2833 | } | 2834 | } |