diff options
| author | Paul Eggert | 2020-04-17 14:09:01 -0700 |
|---|---|---|
| committer | Paul Eggert | 2020-04-17 14:11:30 -0700 |
| commit | 2cb7e8669c3cdd0f7f0687e01810a3160d6b5c5b (patch) | |
| tree | 21fd3ca5914224a2478d7c528e68d0ca64ceddc1 /src/keymap.c | |
| parent | fadfde5fdf2fd8fc3b3b4ba430a954a89d0cd1fe (diff) | |
| download | emacs-2cb7e8669c3cdd0f7f0687e01810a3160d6b5c5b.tar.gz emacs-2cb7e8669c3cdd0f7f0687e01810a3160d6b5c5b.zip | |
Port recent character.h changes to --with-wide-int
* src/fns.c (mapcar1):
* src/keymap.c (Fkey_description):
* src/syntax.c (scan_lists):
Prefer ptrdiff_t to EMACS_INT where either will do; this fixes
newly-introduced type errors on --with-wide-int platforms where
ptrdiff_t is narrower than EMACS_INT.
* src/keymap.c (Fkey_description): Rework for clarity; remove goto.
* src/syntax.c (scan_words, Fforward_comment, scan_lists)):
Fix unlikely integer overflow problems that can occur on
--with-wide-int platforms, and that were caught by the recent
character.h changes.
Diffstat (limited to 'src/keymap.c')
| -rw-r--r-- | src/keymap.c | 144 |
1 files changed, 66 insertions, 78 deletions
diff --git a/src/keymap.c b/src/keymap.c index 8a6881a54e6..51433e2b5ce 100644 --- a/src/keymap.c +++ b/src/keymap.c | |||
| @@ -2005,23 +2005,16 @@ For an approximate inverse of this, see `kbd'. */) | |||
| 2005 | (Lisp_Object keys, Lisp_Object prefix) | 2005 | (Lisp_Object keys, Lisp_Object prefix) |
| 2006 | { | 2006 | { |
| 2007 | ptrdiff_t len = 0; | 2007 | ptrdiff_t len = 0; |
| 2008 | EMACS_INT i; | ||
| 2009 | ptrdiff_t i_byte; | ||
| 2010 | Lisp_Object *args; | 2008 | Lisp_Object *args; |
| 2011 | EMACS_INT size = XFIXNUM (Flength (keys)); | 2009 | EMACS_INT nkeys = XFIXNUM (Flength (keys)); |
| 2012 | Lisp_Object list; | 2010 | EMACS_INT nprefix = XFIXNUM (Flength (prefix)); |
| 2013 | Lisp_Object sep = build_string (" "); | 2011 | Lisp_Object sep = build_string (" "); |
| 2014 | Lisp_Object key; | 2012 | bool add_meta = false; |
| 2015 | Lisp_Object result; | ||
| 2016 | bool add_meta = 0; | ||
| 2017 | USE_SAFE_ALLOCA; | 2013 | USE_SAFE_ALLOCA; |
| 2018 | 2014 | ||
| 2019 | if (!NILP (prefix)) | ||
| 2020 | size += XFIXNUM (Flength (prefix)); | ||
| 2021 | |||
| 2022 | /* This has one extra element at the end that we don't pass to Fconcat. */ | 2015 | /* This has one extra element at the end that we don't pass to Fconcat. */ |
| 2023 | EMACS_INT size4; | 2016 | ptrdiff_t size4; |
| 2024 | if (INT_MULTIPLY_WRAPV (size, 4, &size4)) | 2017 | if (INT_MULTIPLY_WRAPV (nkeys + nprefix, 4, &size4)) |
| 2025 | memory_full (SIZE_MAX); | 2018 | memory_full (SIZE_MAX); |
| 2026 | SAFE_ALLOCA_LISP (args, size4); | 2019 | SAFE_ALLOCA_LISP (args, size4); |
| 2027 | 2020 | ||
| @@ -2029,81 +2022,76 @@ For an approximate inverse of this, see `kbd'. */) | |||
| 2029 | (mapconcat 'single-key-description keys " ") | 2022 | (mapconcat 'single-key-description keys " ") |
| 2030 | but we shouldn't use mapconcat because it can do GC. */ | 2023 | but we shouldn't use mapconcat because it can do GC. */ |
| 2031 | 2024 | ||
| 2032 | next_list: | 2025 | Lisp_Object lists[2] = { prefix, keys }; |
| 2033 | if (!NILP (prefix)) | 2026 | ptrdiff_t listlens[2] = { nprefix, nkeys }; |
| 2034 | list = prefix, prefix = Qnil; | 2027 | for (int li = 0; li < ARRAYELTS (lists); li++) |
| 2035 | else if (!NILP (keys)) | ||
| 2036 | list = keys, keys = Qnil; | ||
| 2037 | else | ||
| 2038 | { | 2028 | { |
| 2039 | if (add_meta) | 2029 | Lisp_Object list = lists[li]; |
| 2040 | { | 2030 | ptrdiff_t listlen = listlens[li], i_byte = 0; |
| 2041 | args[len] = Fsingle_key_description (meta_prefix_char, Qnil); | ||
| 2042 | result = Fconcat (len + 1, args); | ||
| 2043 | } | ||
| 2044 | else if (len == 0) | ||
| 2045 | result = empty_unibyte_string; | ||
| 2046 | else | ||
| 2047 | result = Fconcat (len - 1, args); | ||
| 2048 | SAFE_FREE (); | ||
| 2049 | return result; | ||
| 2050 | } | ||
| 2051 | |||
| 2052 | if (STRINGP (list)) | ||
| 2053 | size = SCHARS (list); | ||
| 2054 | else if (VECTORP (list)) | ||
| 2055 | size = ASIZE (list); | ||
| 2056 | else if (CONSP (list)) | ||
| 2057 | size = list_length (list); | ||
| 2058 | else | ||
| 2059 | wrong_type_argument (Qarrayp, list); | ||
| 2060 | |||
| 2061 | i = i_byte = 0; | ||
| 2062 | 2031 | ||
| 2063 | while (i < size) | 2032 | if (! (NILP (list) || STRINGP (list) || VECTORP (list) || CONSP (list))) |
| 2064 | { | 2033 | wrong_type_argument (Qarrayp, list); |
| 2065 | if (STRINGP (list)) | ||
| 2066 | { | ||
| 2067 | int c = fetch_string_char_advance (list, &i, &i_byte); | ||
| 2068 | if (SINGLE_BYTE_CHAR_P (c) && (c & 0200)) | ||
| 2069 | c ^= 0200 | meta_modifier; | ||
| 2070 | XSETFASTINT (key, c); | ||
| 2071 | } | ||
| 2072 | else if (VECTORP (list)) | ||
| 2073 | { | ||
| 2074 | key = AREF (list, i); i++; | ||
| 2075 | } | ||
| 2076 | else | ||
| 2077 | { | ||
| 2078 | key = XCAR (list); | ||
| 2079 | list = XCDR (list); | ||
| 2080 | i++; | ||
| 2081 | } | ||
| 2082 | 2034 | ||
| 2083 | if (add_meta) | 2035 | for (ptrdiff_t i = 0; i < listlen; ) |
| 2084 | { | 2036 | { |
| 2085 | if (!FIXNUMP (key) | 2037 | Lisp_Object key; |
| 2086 | || EQ (key, meta_prefix_char) | 2038 | if (STRINGP (list)) |
| 2087 | || (XFIXNUM (key) & meta_modifier)) | ||
| 2088 | { | 2039 | { |
| 2089 | args[len++] = Fsingle_key_description (meta_prefix_char, Qnil); | 2040 | int c = fetch_string_char_advance (list, &i, &i_byte); |
| 2090 | args[len++] = sep; | 2041 | if (SINGLE_BYTE_CHAR_P (c) && (c & 0200)) |
| 2091 | if (EQ (key, meta_prefix_char)) | 2042 | c ^= 0200 | meta_modifier; |
| 2092 | continue; | 2043 | key = make_fixnum (c); |
| 2044 | } | ||
| 2045 | else if (VECTORP (list)) | ||
| 2046 | { | ||
| 2047 | key = AREF (list, i); | ||
| 2048 | i++; | ||
| 2093 | } | 2049 | } |
| 2094 | else | 2050 | else |
| 2095 | XSETINT (key, XFIXNUM (key) | meta_modifier); | 2051 | { |
| 2096 | add_meta = 0; | 2052 | key = XCAR (list); |
| 2097 | } | 2053 | list = XCDR (list); |
| 2098 | else if (EQ (key, meta_prefix_char)) | 2054 | i++; |
| 2099 | { | 2055 | } |
| 2100 | add_meta = 1; | 2056 | |
| 2101 | continue; | 2057 | if (add_meta) |
| 2058 | { | ||
| 2059 | if (!FIXNUMP (key) | ||
| 2060 | || EQ (key, meta_prefix_char) | ||
| 2061 | || (XFIXNUM (key) & meta_modifier)) | ||
| 2062 | { | ||
| 2063 | args[len++] = Fsingle_key_description (meta_prefix_char, | ||
| 2064 | Qnil); | ||
| 2065 | args[len++] = sep; | ||
| 2066 | if (EQ (key, meta_prefix_char)) | ||
| 2067 | continue; | ||
| 2068 | } | ||
| 2069 | else | ||
| 2070 | key = make_fixnum (XFIXNUM (key) | meta_modifier); | ||
| 2071 | add_meta = false; | ||
| 2072 | } | ||
| 2073 | else if (EQ (key, meta_prefix_char)) | ||
| 2074 | { | ||
| 2075 | add_meta = true; | ||
| 2076 | continue; | ||
| 2077 | } | ||
| 2078 | args[len++] = Fsingle_key_description (key, Qnil); | ||
| 2079 | args[len++] = sep; | ||
| 2102 | } | 2080 | } |
| 2103 | args[len++] = Fsingle_key_description (key, Qnil); | ||
| 2104 | args[len++] = sep; | ||
| 2105 | } | 2081 | } |
| 2106 | goto next_list; | 2082 | |
| 2083 | Lisp_Object result; | ||
| 2084 | if (add_meta) | ||
| 2085 | { | ||
| 2086 | args[len] = Fsingle_key_description (meta_prefix_char, Qnil); | ||
| 2087 | result = Fconcat (len + 1, args); | ||
| 2088 | } | ||
| 2089 | else if (len == 0) | ||
| 2090 | result = empty_unibyte_string; | ||
| 2091 | else | ||
| 2092 | result = Fconcat (len - 1, args); | ||
| 2093 | SAFE_FREE (); | ||
| 2094 | return result; | ||
| 2107 | } | 2095 | } |
| 2108 | 2096 | ||
| 2109 | 2097 | ||