diff options
author | Paul Eggert <eggert@cs.ucla.edu> | 2020-04-11 18:35:35 -0700 |
---|---|---|
committer | Paul Eggert <eggert@cs.ucla.edu> | 2020-04-11 19:00:27 -0700 |
commit | 43282a6772630275259dbc7560913c07f72eb06e (patch) | |
tree | ab213ea3904d25fb0142817765c501d7add95c0d /src/character.h | |
parent | 7abfb6475716e3002c30d10ead0c309b4fed6992 (diff) | |
download | emacs-43282a6772630275259dbc7560913c07f72eb06e.tar.gz |
Remove UNSIGNED_CMP
I added this macro in 2011 to fix some signedness comparison bugs.
However, it’s a weird macro and the bugs can be fixed in a
more-straightforward way. This helps performance slightly (0.5%) on my
platform (Fedora 31 x86-64, GCC 9.3.1 with -O2).
* src/casefiddle.c (do_casify_natnum): Use simple comparison
instead of UNSIGNED_CMP.
* src/character.h (CHAR_VALID_P, SINGLE_BYTE_CHAR_P, CHAR_STRING):
* src/composite.h (COMPOSITION_ENCODE_RULE_VALID):
* src/lisp.h (ASCII_CHAR_P):
Now an inline function, and uses simple comparison instead of
UNSIGNED_CMP.
* src/dispextern.h (FACE_FROM_ID, FACE_FROM_ID_OR_NULL)
(IMAGE_FROM_ID, IMAGE_OPT_FROM_ID): Move these to ...
* src/frame.h (FACE_FROM_ID, FACE_FROM_ID_OR_NULL)
(IMAGE_FROM_ID, IMAGE_OPT_FROM_ID): ... here, and make them
inline functions that no longer use UNSIGNED_CMP.
* src/keyboard.c (read_char): UNSIGNED_CMP is not needed here
since XFIXNAT always returns a nonnegative value.
* src/lisp.h (UNSIGNED_CMP): Remove; no longer used.
Diffstat (limited to 'src/character.h')
-rw-r--r-- | src/character.h | 55 |
1 files changed, 38 insertions, 17 deletions
diff --git a/src/character.h b/src/character.h index 3642a540448..7639b018cb0 100644 --- a/src/character.h +++ b/src/character.h @@ -80,6 +80,8 @@ enum OBJECT_REPLACEMENT_CHARACTER = 0xFFFC, }; +extern int char_string (unsigned, unsigned char *); + /* UTF-8 encodings. Use \x escapes, so they are portable to pre-C11 compilers and can be concatenated with ordinary string literals. */ #define uLSQM "\xE2\x80\x98" /* U+2018 LEFT SINGLE QUOTATION MARK */ @@ -126,7 +128,11 @@ enum #define CHARACTERP(x) (FIXNATP (x) && XFIXNAT (x) <= MAX_CHAR) /* Nonzero iff C is valid as a character code. */ -#define CHAR_VALID_P(c) UNSIGNED_CMP (c, <=, MAX_CHAR) +INLINE bool +CHAR_VALID_P (intmax_t c) +{ + return 0 <= c && c <= MAX_CHAR; +} /* Check if Lisp object X is a character or not. */ #define CHECK_CHARACTER(x) \ @@ -145,7 +151,11 @@ enum } while (false) /* Nonzero iff C is a character of code less than 0x100. */ -#define SINGLE_BYTE_CHAR_P(c) UNSIGNED_CMP (c, <, 0x100) +INLINE bool +SINGLE_BYTE_CHAR_P (intmax_t c) +{ + return 0 <= c && c < 0x100; +} /* Nonzero if character C has a printable glyph. */ #define CHAR_PRINTABLE_P(c) \ @@ -176,20 +186,32 @@ enum allocate at least MAX_MULTIBYTE_LENGTH bytes area at P in advance. Returns the length of the multibyte form. */ -#define CHAR_STRING(c, p) \ - (UNSIGNED_CMP (c, <=, MAX_1_BYTE_CHAR) \ - ? ((p)[0] = (c), \ - 1) \ - : UNSIGNED_CMP (c, <=, MAX_2_BYTE_CHAR) \ - ? ((p)[0] = (0xC0 | ((c) >> 6)), \ - (p)[1] = (0x80 | ((c) & 0x3F)), \ - 2) \ - : UNSIGNED_CMP (c, <=, MAX_3_BYTE_CHAR) \ - ? ((p)[0] = (0xE0 | ((c) >> 12)), \ - (p)[1] = (0x80 | (((c) >> 6) & 0x3F)), \ - (p)[2] = (0x80 | ((c) & 0x3F)), \ - 3) \ - : verify_expr (sizeof (c) <= sizeof (unsigned), char_string (c, p))) +INLINE int +CHAR_STRING (int c, unsigned char *p) +{ + eassume (0 <= c); + if (c <= MAX_1_BYTE_CHAR) + { + p[0] = c; + return 1; + } + if (c <= MAX_2_BYTE_CHAR) + { + p[0] = 0xC0 | (c >> 6); + p[1] = 0x80 | (c & 0x3F); + return 2; + } + if (c <= MAX_3_BYTE_CHAR) + { + p[0] = 0xE0 | (c >> 12); + p[1] = 0x80 | ((c >> 6) & 0x3F); + p[2] = 0x80 | (c & 0x3F); + return 3; + } + int len = char_string (c, p); + eassume (0 < len && len <= MAX_MULTIBYTE_LENGTH); + return len; +} /* Store multibyte form of byte B in P. The caller should allocate at least MAX_MULTIBYTE_LENGTH bytes area at P in advance. Returns the @@ -657,7 +679,6 @@ typedef enum { } unicode_category_t; extern EMACS_INT char_resolve_modifier_mask (EMACS_INT) ATTRIBUTE_CONST; -extern int char_string (unsigned, unsigned char *); extern int string_char (const unsigned char *, const unsigned char **, int *); |