diff options
| author | Paul Eggert | 2017-07-05 17:51:31 -0700 |
|---|---|---|
| committer | Paul Eggert | 2017-07-05 18:59:31 -0700 |
| commit | d6662694d05be03fdd070353637dd22a324c8b7a (patch) | |
| tree | 3823cc192290478c041db63121c88afebfccbc13 /src | |
| parent | 24faf6b0d2fe990e9334dd2e3238f749fec87897 (diff) | |
| download | emacs-d6662694d05be03fdd070353637dd22a324c8b7a.tar.gz emacs-d6662694d05be03fdd070353637dd22a324c8b7a.zip | |
Convert hex digits more systematically
This makes the code a bit smaller and presumably faster, as
it substitutes a single lookup for conditional jumps.
* src/character.c (hexdigit): New constant.
(syms_of_character) [HEXDIGIT_IS_CONST]: Initialize it.
* src/character.h (HEXDIGIT_CONST, HEXDIGIT_IS_CONST): New macros.
(hexdigit): New decl.
(char_hexdigit): New inline function.
* src/charset.c: Do not include c-ctype.h.
* src/charset.c (read_hex):
* src/editfns.c (styled_format):
* src/image.c (xbm_scan):
* src/lread.c (read_escape):
* src/regex.c (ISXDIGIT) [emacs]:
Use char_hexdigit insted of doing it by hand.
Diffstat (limited to 'src')
| -rw-r--r-- | src/character.c | 17 | ||||
| -rw-r--r-- | src/character.h | 18 | ||||
| -rw-r--r-- | src/charset.c | 12 | ||||
| -rw-r--r-- | src/editfns.c | 6 | ||||
| -rw-r--r-- | src/image.c | 9 | ||||
| -rw-r--r-- | src/lread.c | 25 | ||||
| -rw-r--r-- | src/regex.c | 4 |
7 files changed, 52 insertions, 39 deletions
diff --git a/src/character.c b/src/character.c index cf460540725..1c6020ee468 100644 --- a/src/character.c +++ b/src/character.c | |||
| @@ -1050,9 +1050,26 @@ blankp (int c) | |||
| 1050 | return XINT (category) == UNICODE_CATEGORY_Zs; /* separator, space */ | 1050 | return XINT (category) == UNICODE_CATEGORY_Zs; /* separator, space */ |
| 1051 | } | 1051 | } |
| 1052 | 1052 | ||
| 1053 | signed char HEXDIGIT_CONST hexdigit[UCHAR_MAX + 1] = | ||
| 1054 | { | ||
| 1055 | #if HEXDIGIT_IS_CONST | ||
| 1056 | [0 ... UCHAR_MAX] = -1, | ||
| 1057 | #endif | ||
| 1058 | ['0'] = 0, ['1'] = 1, ['2'] = 2, ['3'] = 3, ['4'] = 4, | ||
| 1059 | ['5'] = 5, ['6'] = 6, ['7'] = 7, ['8'] = 8, ['9'] = 9, | ||
| 1060 | ['A'] = 10, ['B'] = 11, ['C'] = 12, ['D'] = 13, ['E'] = 14, ['F'] = 15, | ||
| 1061 | ['a'] = 10, ['b'] = 11, ['c'] = 12, ['d'] = 13, ['e'] = 14, ['f'] = 15 | ||
| 1062 | }; | ||
| 1063 | |||
| 1053 | void | 1064 | void |
| 1054 | syms_of_character (void) | 1065 | syms_of_character (void) |
| 1055 | { | 1066 | { |
| 1067 | #if !HEXDIGIT_IS_CONST | ||
| 1068 | /* Set the non-hex digit values to -1. */ | ||
| 1069 | for (int i = 0; i <= UCHAR_MAX; i++) | ||
| 1070 | hexdigit[i] -= i != '0' && !hexdigit[i]; | ||
| 1071 | #endif | ||
| 1072 | |||
| 1056 | DEFSYM (Qcharacterp, "characterp"); | 1073 | DEFSYM (Qcharacterp, "characterp"); |
| 1057 | DEFSYM (Qauto_fill_chars, "auto-fill-chars"); | 1074 | DEFSYM (Qauto_fill_chars, "auto-fill-chars"); |
| 1058 | 1075 | ||
diff --git a/src/character.h b/src/character.h index 62d252e91ba..b073a0dd1e4 100644 --- a/src/character.h +++ b/src/character.h | |||
| @@ -700,6 +700,24 @@ char_table_translate (Lisp_Object obj, int ch) | |||
| 700 | return CHARACTERP (obj) ? XINT (obj) : ch; | 700 | return CHARACTERP (obj) ? XINT (obj) : ch; |
| 701 | } | 701 | } |
| 702 | 702 | ||
| 703 | #if defined __GNUC__ && !defined __STRICT_ANSI__ | ||
| 704 | # define HEXDIGIT_CONST const | ||
| 705 | # define HEXDIGIT_IS_CONST true | ||
| 706 | #else | ||
| 707 | # define HEXDIGIT_CONST | ||
| 708 | # define HEXDIGIT_IS_CONST false | ||
| 709 | #endif | ||
| 710 | extern signed char HEXDIGIT_CONST hexdigit[]; | ||
| 711 | |||
| 712 | /* If C is a hexadecimal digit ('0'-'9', 'a'-'f', 'A'-'F'), return its | ||
| 713 | value (0-15). Otherwise return -1. */ | ||
| 714 | |||
| 715 | INLINE int | ||
| 716 | char_hexdigit (int c) | ||
| 717 | { | ||
| 718 | return 0 <= c && c <= UCHAR_MAX ? hexdigit[c] : -1; | ||
| 719 | } | ||
| 720 | |||
| 703 | INLINE_HEADER_END | 721 | INLINE_HEADER_END |
| 704 | 722 | ||
| 705 | #endif /* EMACS_CHARACTER_H */ | 723 | #endif /* EMACS_CHARACTER_H */ |
diff --git a/src/charset.c b/src/charset.c index d0840f7d2a9..9c3b8db2a53 100644 --- a/src/charset.c +++ b/src/charset.c | |||
| @@ -33,7 +33,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 33 | #include <unistd.h> | 33 | #include <unistd.h> |
| 34 | #include <limits.h> | 34 | #include <limits.h> |
| 35 | #include <sys/types.h> | 35 | #include <sys/types.h> |
| 36 | #include <c-ctype.h> | ||
| 37 | #include "lisp.h" | 36 | #include "lisp.h" |
| 38 | #include "character.h" | 37 | #include "character.h" |
| 39 | #include "charset.h" | 38 | #include "charset.h" |
| @@ -434,14 +433,15 @@ read_hex (FILE *fp, bool *eof, bool *overflow) | |||
| 434 | return 0; | 433 | return 0; |
| 435 | } | 434 | } |
| 436 | n = 0; | 435 | n = 0; |
| 437 | while (c_isxdigit (c = getc_unlocked (fp))) | 436 | while (true) |
| 438 | { | 437 | { |
| 438 | c = getc_unlocked (fp); | ||
| 439 | int digit = char_hexdigit (c); | ||
| 440 | if (digit < 0) | ||
| 441 | break; | ||
| 439 | if (INT_LEFT_SHIFT_OVERFLOW (n, 4)) | 442 | if (INT_LEFT_SHIFT_OVERFLOW (n, 4)) |
| 440 | *overflow = 1; | 443 | *overflow = 1; |
| 441 | n = ((n << 4) | 444 | n = (n << 4) + digit; |
| 442 | | (c - ('0' <= c && c <= '9' ? '0' | ||
| 443 | : 'A' <= c && c <= 'F' ? 'A' - 10 | ||
| 444 | : 'a' - 10))); | ||
| 445 | } | 445 | } |
| 446 | if (c != EOF) | 446 | if (c != EOF) |
| 447 | ungetc (c, fp); | 447 | ungetc (c, fp); |
diff --git a/src/editfns.c b/src/editfns.c index da99c055b54..d599fcfec80 100644 --- a/src/editfns.c +++ b/src/editfns.c | |||
| @@ -4704,10 +4704,8 @@ styled_format (ptrdiff_t nargs, Lisp_Object *args, bool message) | |||
| 4704 | char src0 = src[0]; | 4704 | char src0 = src[0]; |
| 4705 | int exponent_bytes = 0; | 4705 | int exponent_bytes = 0; |
| 4706 | bool signedp = src0 == '-' || src0 == '+' || src0 == ' '; | 4706 | bool signedp = src0 == '-' || src0 == '+' || src0 == ' '; |
| 4707 | if (zero_flag | 4707 | unsigned char after_sign = src[signedp]; |
| 4708 | && ((src[signedp] >= '0' && src[signedp] <= '9') | 4708 | if (zero_flag && 0 <= char_hexdigit (after_sign)) |
| 4709 | || (src[signedp] >= 'a' && src[signedp] <= 'f') | ||
| 4710 | || (src[signedp] >= 'A' && src[signedp] <= 'F'))) | ||
| 4711 | { | 4709 | { |
| 4712 | leading_zeros += padding; | 4710 | leading_zeros += padding; |
| 4713 | padding = 0; | 4711 | padding = 0; |
diff --git a/src/image.c b/src/image.c index 07c4769e9e3..6b748ba2af6 100644 --- a/src/image.c +++ b/src/image.c | |||
| @@ -2595,13 +2595,8 @@ xbm_scan (char **s, char *end, char *sval, int *ival) | |||
| 2595 | while (*s < end) | 2595 | while (*s < end) |
| 2596 | { | 2596 | { |
| 2597 | c = *(*s)++; | 2597 | c = *(*s)++; |
| 2598 | if (c_isdigit (c)) | 2598 | digit = char_hexdigit (c); |
| 2599 | digit = c - '0'; | 2599 | if (digit < 0) |
| 2600 | else if (c >= 'a' && c <= 'f') | ||
| 2601 | digit = c - 'a' + 10; | ||
| 2602 | else if (c >= 'A' && c <= 'F') | ||
| 2603 | digit = c - 'A' + 10; | ||
| 2604 | else | ||
| 2605 | break; | 2600 | break; |
| 2606 | value = 16 * value + digit; | 2601 | value = 16 * value + digit; |
| 2607 | } | 2602 | } |
diff --git a/src/lread.c b/src/lread.c index 182f96223a5..7c554ba8536 100644 --- a/src/lread.c +++ b/src/lread.c | |||
| @@ -2426,25 +2426,13 @@ read_escape (Lisp_Object readcharfun, bool stringp) | |||
| 2426 | while (1) | 2426 | while (1) |
| 2427 | { | 2427 | { |
| 2428 | c = READCHAR; | 2428 | c = READCHAR; |
| 2429 | if (c >= '0' && c <= '9') | 2429 | int digit = char_hexdigit (c); |
| 2430 | { | 2430 | if (digit < 0) |
| 2431 | i *= 16; | ||
| 2432 | i += c - '0'; | ||
| 2433 | } | ||
| 2434 | else if ((c >= 'a' && c <= 'f') | ||
| 2435 | || (c >= 'A' && c <= 'F')) | ||
| 2436 | { | ||
| 2437 | i *= 16; | ||
| 2438 | if (c >= 'a' && c <= 'f') | ||
| 2439 | i += c - 'a' + 10; | ||
| 2440 | else | ||
| 2441 | i += c - 'A' + 10; | ||
| 2442 | } | ||
| 2443 | else | ||
| 2444 | { | 2431 | { |
| 2445 | UNREAD (c); | 2432 | UNREAD (c); |
| 2446 | break; | 2433 | break; |
| 2447 | } | 2434 | } |
| 2435 | i = (i << 4) + digit; | ||
| 2448 | /* Allow hex escapes as large as ?\xfffffff, because some | 2436 | /* Allow hex escapes as large as ?\xfffffff, because some |
| 2449 | packages use them to denote characters with modifiers. */ | 2437 | packages use them to denote characters with modifiers. */ |
| 2450 | if ((CHAR_META | (CHAR_META - 1)) < i) | 2438 | if ((CHAR_META | (CHAR_META - 1)) < i) |
| @@ -2474,11 +2462,10 @@ read_escape (Lisp_Object readcharfun, bool stringp) | |||
| 2474 | c = READCHAR; | 2462 | c = READCHAR; |
| 2475 | /* `isdigit' and `isalpha' may be locale-specific, which we don't | 2463 | /* `isdigit' and `isalpha' may be locale-specific, which we don't |
| 2476 | want. */ | 2464 | want. */ |
| 2477 | if (c >= '0' && c <= '9') i = (i << 4) + (c - '0'); | 2465 | int digit = char_hexdigit (c); |
| 2478 | else if (c >= 'a' && c <= 'f') i = (i << 4) + (c - 'a') + 10; | 2466 | if (digit < 0) |
| 2479 | else if (c >= 'A' && c <= 'F') i = (i << 4) + (c - 'A') + 10; | ||
| 2480 | else | ||
| 2481 | error ("Non-hex digit used for Unicode escape"); | 2467 | error ("Non-hex digit used for Unicode escape"); |
| 2468 | i = (i << 4) + digit; | ||
| 2482 | } | 2469 | } |
| 2483 | if (i > 0x10FFFF) | 2470 | if (i > 0x10FFFF) |
| 2484 | error ("Non-Unicode character: 0x%x", i); | 2471 | error ("Non-Unicode character: 0x%x", i); |
diff --git a/src/regex.c b/src/regex.c index 240a91f2ba8..fb48765c96c 100644 --- a/src/regex.c +++ b/src/regex.c | |||
| @@ -306,9 +306,7 @@ enum syntaxcode { Swhitespace = 0, Sword = 1, Ssymbol = 2 }; | |||
| 306 | /* In Emacs, these are only used for single-byte characters. */ | 306 | /* In Emacs, these are only used for single-byte characters. */ |
| 307 | # define ISDIGIT(c) ((c) >= '0' && (c) <= '9') | 307 | # define ISDIGIT(c) ((c) >= '0' && (c) <= '9') |
| 308 | # define ISCNTRL(c) ((c) < ' ') | 308 | # define ISCNTRL(c) ((c) < ' ') |
| 309 | # define ISXDIGIT(c) (((c) >= '0' && (c) <= '9') \ | 309 | # define ISXDIGIT(c) (0 <= char_hexdigit (c)) |
| 310 | || ((c) >= 'a' && (c) <= 'f') \ | ||
| 311 | || ((c) >= 'A' && (c) <= 'F')) | ||
| 312 | 310 | ||
| 313 | /* The rest must handle multibyte characters. */ | 311 | /* The rest must handle multibyte characters. */ |
| 314 | 312 | ||