X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/5d8ea1203d1e659bc77d953784a85a6e7da0ce95..1260aef1aea35be161846b0411aa387ade44e35f:/src/character.c diff --git a/src/character.c b/src/character.c index e4ff3d7922..fb9b8a9b93 100644 --- a/src/character.c +++ b/src/character.c @@ -35,6 +35,7 @@ along with GNU Emacs. If not, see . */ #include #include +#include #include "lisp.h" #include "character.h" #include "buffer.h" @@ -50,7 +51,7 @@ along with GNU Emacs. If not, see . */ Lisp_Object Qcharacterp; -Lisp_Object Qauto_fill_chars; +static Lisp_Object Qauto_fill_chars; /* Char-table of information about which character to unify to which Unicode character. Mainly used by the macro MAYBE_UNIFY_CHAR. */ @@ -122,7 +123,7 @@ char_string (unsigned int c, unsigned char *p) if (c & CHAR_MODIFIER_MASK) { - c = (unsigned) char_resolve_modifier_mask ((int) c); + c = char_resolve_modifier_mask (c); /* If C still has any modifier bits, just ignore it. */ c &= ~CHAR_MODIFIER_MASK; } @@ -156,17 +157,17 @@ char_string (unsigned int c, unsigned char *p) bytes = BYTE8_STRING (c, p); } else - error ("Invalid character: %d", c); + error ("Invalid character: %x", c); return bytes; } -/* Return a character whose multibyte form is at P. Set LEN is not +/* Return a character whose multibyte form is at P. If LEN is not NULL, it must be a pointer to integer. In that case, set *LEN to - the byte length of the multibyte form. If ADVANCED is not NULL, is + the byte length of the multibyte form. If ADVANCED is not NULL, it must be a pointer to unsigned char. In that case, set *ADVANCED to - the ending address (i.e. the starting address of the next + the ending address (i.e., the starting address of the next character) of the multibyte form. */ int @@ -206,11 +207,10 @@ string_char (const unsigned char *p, const unsigned char **advanced, int *len) } -/* Translate character C by translation table TABLE. If C is - negative, translate a character specified by CHARSET and CODE. If - no translation is found in TABLE, return the untranslated - character. If TABLE is a list, elements are char tables. In this - case, translace C by all tables. */ +/* Translate character C by translation table TABLE. If no translation is + found in TABLE, return the untranslated character. If TABLE is a list, + elements are char tables. In that case, recursively translate C by all the + tables in the list. */ int translate_char (Lisp_Object table, int c) @@ -232,13 +232,10 @@ translate_char (Lisp_Object table, int c) } /* Convert ASCII or 8-bit character C to unibyte. If C is none of - them, return (C & 0xFF). - - The argument REV_TBL is now ignored. It will be removed in the - future. */ + them, return (C & 0xFF). */ int -multibyte_char_to_unibyte (int c, Lisp_Object rev_tbl) +multibyte_char_to_unibyte (int c) { if (c < 0x80) return c; @@ -261,7 +258,8 @@ multibyte_char_to_unibyte_safe (int c) } DEFUN ("characterp", Fcharacterp, Scharacterp, 1, 2, 0, - doc: /* Return non-nil if OBJECT is a character. */) + doc: /* Return non-nil if OBJECT is a character. +usage: (characterp OBJECT) */) (Lisp_Object object, Lisp_Object ignore) { return (CHARACTERP (object) ? Qt : Qnil); @@ -328,7 +326,7 @@ usage: (char-width CHAR) */) disp = dp ? DISP_CHAR_VECTOR (dp, c) : Qnil; if (VECTORP (disp)) - width = ASIZE (disp); + width = sanitize_char_width (ASIZE (disp)); else width = CHAR_WIDTH (c); @@ -360,7 +358,7 @@ c_string_width (const unsigned char *str, EMACS_INT len, int precision, { val = DISP_CHAR_VECTOR (dp, c); if (VECTORP (val)) - thiswidth = XVECTOR (val)->size; + thiswidth = sanitize_char_width (ASIZE (val)); else thiswidth = CHAR_WIDTH (c); } @@ -408,7 +406,7 @@ strwidth (const char *str, EMACS_INT len) in *NCHARS and *NBYTES respectively. */ EMACS_INT -lisp_string_width (Lisp_Object string, int precision, +lisp_string_width (Lisp_Object string, EMACS_INT precision, EMACS_INT *nchars, EMACS_INT *nbytes) { EMACS_INT len = SCHARS (string); @@ -423,9 +421,9 @@ lisp_string_width (Lisp_Object string, int precision, while (i < len) { - int chars, bytes, thiswidth; + EMACS_INT chars, bytes, thiswidth; Lisp_Object val; - int cmp_id; + ptrdiff_t cmp_id; EMACS_INT ignore, end; if (find_composition (i, -1, &ignore, &end, &val, string) @@ -441,7 +439,11 @@ lisp_string_width (Lisp_Object string, int precision, int c; if (multibyte) - c = STRING_CHAR_AND_LENGTH (str + i_byte, bytes); + { + int cbytes; + c = STRING_CHAR_AND_LENGTH (str + i_byte, cbytes); + bytes = cbytes; + } else c = str[i_byte], bytes = 1; chars = 1; @@ -449,7 +451,7 @@ lisp_string_width (Lisp_Object string, int precision, { val = DISP_CHAR_VECTOR (dp, c); if (VECTORP (val)) - thiswidth = XVECTOR (val)->size; + thiswidth = sanitize_char_width (ASIZE (val)); else thiswidth = CHAR_WIDTH (c); } @@ -459,8 +461,14 @@ lisp_string_width (Lisp_Object string, int precision, } } - if (precision > 0 - && (width + thiswidth > precision)) + if (precision <= 0) + { +#ifdef emacs + if (INT_ADD_OVERFLOW (width, thiswidth)) + string_overflow (); +#endif + } + else if (precision - width < thiswidth) { *nchars = i; *nbytes = i_byte; @@ -469,7 +477,7 @@ lisp_string_width (Lisp_Object string, int precision, i += chars; i_byte += bytes; width += thiswidth; - } + } if (precision > 0) { @@ -497,19 +505,6 @@ usage: (string-width STRING) */) return val; } -DEFUN ("char-direction", Fchar_direction, Schar_direction, 1, 1, 0, - doc: /* Return the direction of CHAR. -The returned value is 0 for left-to-right and 1 for right-to-left. -usage: (char-direction CHAR) */) - (Lisp_Object ch) -{ - int c; - - CHECK_CHARACTER (ch); - c = XINT (ch); - return CHAR_TABLE_REF (Vchar_direction_table, c); -} - /* Return the number of characters in the NBYTES bytes at PTR. This works by looking at the contents and checking for multibyte sequences while assuming that there's no invalid sequence. @@ -521,7 +516,7 @@ chars_in_text (const unsigned char *ptr, EMACS_INT nbytes) { /* current_buffer is null at early stages of Emacs initialization. */ if (current_buffer == 0 - || NILP (B_ (current_buffer, enable_multibyte_characters))) + || NILP (BVAR (current_buffer, enable_multibyte_characters))) return nbytes; return multibyte_chars_in_text (ptr, nbytes); @@ -678,18 +673,23 @@ str_as_multibyte (unsigned char *str, EMACS_INT len, EMACS_INT nbytes, `str_to_multibyte'. */ EMACS_INT -parse_str_to_multibyte (const unsigned char *str, EMACS_INT len) +count_size_as_multibyte (const unsigned char *str, EMACS_INT len) { const unsigned char *endp = str + len; EMACS_INT bytes; for (bytes = 0; str < endp; str++) - bytes += (*str < 0x80) ? 1 : 2; + { + int n = *str < 0x80 ? 1 : 2; + if (INT_ADD_OVERFLOW (bytes, n)) + string_overflow (); + bytes += n; + } return bytes; } -/* Convert unibyte text at STR of NBYTES bytes to a multibyte text +/* Convert unibyte text at STR of BYTES bytes to a multibyte text that contains the same single-byte characters. It actually converts all 8-bit characters to multibyte forms. It is assured that we can use LEN bytes at STR as a work area and that is @@ -761,7 +761,7 @@ str_as_unibyte (unsigned char *str, EMACS_INT bytes) corresponding byte and store in DST. CHARS is the number of characters in SRC. The value is the number of bytes stored in DST. Usually, the value is the same as CHARS, but is less than it if SRC - contains a non-ASCII, non-eight-bit characater. If ACCEPT_LATIN_1 + contains a non-ASCII, non-eight-bit character. If ACCEPT_LATIN_1 is nonzero, a Latin-1 character is accepted and converted to a byte of that character code. Note: Currently the arg ACCEPT_LATIN_1 is not used. */ @@ -786,7 +786,7 @@ str_to_unibyte (const unsigned char *src, unsigned char *dst, EMACS_INT chars, i } -EMACS_INT +static EMACS_INT string_count_byte8 (Lisp_Object string) { int multibyte = STRING_MULTIBYTE (string); @@ -839,8 +839,8 @@ string_escape_byte8 (Lisp_Object string) if (multibyte) { if ((MOST_POSITIVE_FIXNUM - nchars) / 3 < byte8_count - || (MOST_POSITIVE_FIXNUM - nbytes) / 2 < byte8_count) - error ("Maximum string size exceeded"); + || (STRING_BYTES_BOUND - nbytes) / 2 < byte8_count) + string_overflow (); /* Convert 2-byte sequence of byte8 chars to 4-byte octal. */ val = make_uninit_multibyte_string (nchars + byte8_count * 3, @@ -848,8 +848,9 @@ string_escape_byte8 (Lisp_Object string) } else { - if ((MOST_POSITIVE_FIXNUM - nchars) / 3 < byte8_count) - error ("Maximum string size exceeded"); + if ((STRING_BYTES_BOUND - nbytes) / 3 < byte8_count) + string_overflow (); + /* Convert 1-byte sequence of byte8 chars to 4-byte octal. */ val = make_uninit_string (nbytes + byte8_count * 3); } @@ -893,14 +894,15 @@ DEFUN ("string", Fstring, Sstring, 0, MANY, 0, doc: /* Concatenate all the argument characters and make the result a string. usage: (string &rest CHARACTERS) */) - (int n, Lisp_Object *args) + (ptrdiff_t n, Lisp_Object *args) { - int i, c; + ptrdiff_t i; + int c; unsigned char *buf, *p; Lisp_Object str; USE_SAFE_ALLOCA; - SAFE_ALLOCA (buf, unsigned char *, MAX_MULTIBYTE_LENGTH * n); + SAFE_NALLOCA (buf, MAX_MULTIBYTE_LENGTH, n); p = buf; for (i = 0; i < n; i++) @@ -918,9 +920,10 @@ usage: (string &rest CHARACTERS) */) DEFUN ("unibyte-string", Funibyte_string, Sunibyte_string, 0, MANY, 0, doc: /* Concatenate all the argument bytes and make the result a unibyte string. usage: (unibyte-string &rest BYTES) */) - (int n, Lisp_Object *args) + (ptrdiff_t n, Lisp_Object *args) { - int i, c; + ptrdiff_t i; + int c; unsigned char *buf, *p; Lisp_Object str; USE_SAFE_ALLOCA; @@ -987,7 +990,7 @@ character is not ASCII nor 8-bit character, an error is signalled. */) pos = XFASTINT (position); p = CHAR_POS_ADDR (pos); } - if (NILP (B_ (current_buffer, enable_multibyte_characters))) + if (NILP (BVAR (current_buffer, enable_multibyte_characters))) return make_number (*p); } else @@ -1039,7 +1042,6 @@ syms_of_character (void) defsubr (&Smultibyte_char_to_unibyte); defsubr (&Schar_width); defsubr (&Sstring_width); - defsubr (&Schar_direction); defsubr (&Sstring); defsubr (&Sunibyte_string); defsubr (&Schar_resolve_modifiers); @@ -1068,10 +1070,6 @@ A char-table for width (columns) of each character. */); char_table_set_range (Vchar_width_table, MAX_5_BYTE_CHAR + 1, MAX_CHAR, make_number (4)); - DEFVAR_LISP ("char-direction-table", Vchar_direction_table, - doc: /* A char-table for direction of each character. */); - Vchar_direction_table = Fmake_char_table (Qnil, make_number (1)); - DEFVAR_LISP ("printable-chars", Vprintable_chars, doc: /* A char-table for each printable character. */); Vprintable_chars = Fmake_char_table (Qnil, Qnil);