summaryrefslogtreecommitdiff
path: root/src/keymap.c
diff options
context:
space:
mode:
authorPaul Eggert <eggert@cs.ucla.edu>2020-04-17 14:09:01 -0700
committerPaul Eggert <eggert@cs.ucla.edu>2020-04-17 14:11:30 -0700
commit2cb7e8669c3cdd0f7f0687e01810a3160d6b5c5b (patch)
tree21fd3ca5914224a2478d7c528e68d0ca64ceddc1 /src/keymap.c
parentfadfde5fdf2fd8fc3b3b4ba430a954a89d0cd1fe (diff)
downloademacs-2cb7e8669c3cdd0f7f0687e01810a3160d6b5c5b.tar.gz
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.c144
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'. */)
(Lisp_Object keys, Lisp_Object prefix)
{
ptrdiff_t len = 0;
- EMACS_INT i;
- ptrdiff_t i_byte;
Lisp_Object *args;
- EMACS_INT size = XFIXNUM (Flength (keys));
- Lisp_Object list;
+ EMACS_INT nkeys = XFIXNUM (Flength (keys));
+ EMACS_INT nprefix = XFIXNUM (Flength (prefix));
Lisp_Object sep = build_string (" ");
- Lisp_Object key;
- Lisp_Object result;
- bool add_meta = 0;
+ bool add_meta = false;
USE_SAFE_ALLOCA;
- if (!NILP (prefix))
- size += XFIXNUM (Flength (prefix));
-
/* This has one extra element at the end that we don't pass to Fconcat. */
- EMACS_INT size4;
- if (INT_MULTIPLY_WRAPV (size, 4, &size4))
+ ptrdiff_t size4;
+ if (INT_MULTIPLY_WRAPV (nkeys + nprefix, 4, &size4))
memory_full (SIZE_MAX);
SAFE_ALLOCA_LISP (args, size4);
@@ -2029,81 +2022,76 @@ For an approximate inverse of this, see `kbd'. */)
(mapconcat 'single-key-description keys " ")
but we shouldn't use mapconcat because it can do GC. */
- next_list:
- if (!NILP (prefix))
- list = prefix, prefix = Qnil;
- else if (!NILP (keys))
- list = keys, keys = Qnil;
- else
+ Lisp_Object lists[2] = { prefix, keys };
+ ptrdiff_t listlens[2] = { nprefix, nkeys };
+ for (int li = 0; li < ARRAYELTS (lists); li++)
{
- if (add_meta)
- {
- args[len] = Fsingle_key_description (meta_prefix_char, Qnil);
- result = Fconcat (len + 1, args);
- }
- else if (len == 0)
- result = empty_unibyte_string;
- else
- result = Fconcat (len - 1, args);
- SAFE_FREE ();
- return result;
- }
-
- if (STRINGP (list))
- size = SCHARS (list);
- else if (VECTORP (list))
- size = ASIZE (list);
- else if (CONSP (list))
- size = list_length (list);
- else
- wrong_type_argument (Qarrayp, list);
-
- i = i_byte = 0;
+ Lisp_Object list = lists[li];
+ ptrdiff_t listlen = listlens[li], i_byte = 0;
- while (i < size)
- {
- if (STRINGP (list))
- {
- int c = fetch_string_char_advance (list, &i, &i_byte);
- if (SINGLE_BYTE_CHAR_P (c) && (c & 0200))
- c ^= 0200 | meta_modifier;
- XSETFASTINT (key, c);
- }
- else if (VECTORP (list))
- {
- key = AREF (list, i); i++;
- }
- else
- {
- key = XCAR (list);
- list = XCDR (list);
- i++;
- }
+ if (! (NILP (list) || STRINGP (list) || VECTORP (list) || CONSP (list)))
+ wrong_type_argument (Qarrayp, list);
- if (add_meta)
+ for (ptrdiff_t i = 0; i < listlen; )
{
- if (!FIXNUMP (key)
- || EQ (key, meta_prefix_char)
- || (XFIXNUM (key) & meta_modifier))
+ Lisp_Object key;
+ if (STRINGP (list))
{
- args[len++] = Fsingle_key_description (meta_prefix_char, Qnil);
- args[len++] = sep;
- if (EQ (key, meta_prefix_char))
- continue;
+ int c = fetch_string_char_advance (list, &i, &i_byte);
+ if (SINGLE_BYTE_CHAR_P (c) && (c & 0200))
+ c ^= 0200 | meta_modifier;
+ key = make_fixnum (c);
+ }
+ else if (VECTORP (list))
+ {
+ key = AREF (list, i);
+ i++;
}
else
- XSETINT (key, XFIXNUM (key) | meta_modifier);
- add_meta = 0;
- }
- else if (EQ (key, meta_prefix_char))
- {
- add_meta = 1;
- continue;
+ {
+ key = XCAR (list);
+ list = XCDR (list);
+ i++;
+ }
+
+ if (add_meta)
+ {
+ if (!FIXNUMP (key)
+ || EQ (key, meta_prefix_char)
+ || (XFIXNUM (key) & meta_modifier))
+ {
+ args[len++] = Fsingle_key_description (meta_prefix_char,
+ Qnil);
+ args[len++] = sep;
+ if (EQ (key, meta_prefix_char))
+ continue;
+ }
+ else
+ key = make_fixnum (XFIXNUM (key) | meta_modifier);
+ add_meta = false;
+ }
+ else if (EQ (key, meta_prefix_char))
+ {
+ add_meta = true;
+ continue;
+ }
+ args[len++] = Fsingle_key_description (key, Qnil);
+ args[len++] = sep;
}
- args[len++] = Fsingle_key_description (key, Qnil);
- args[len++] = sep;
}
- goto next_list;
+
+ Lisp_Object result;
+ if (add_meta)
+ {
+ args[len] = Fsingle_key_description (meta_prefix_char, Qnil);
+ result = Fconcat (len + 1, args);
+ }
+ else if (len == 0)
+ result = empty_unibyte_string;
+ else
+ result = Fconcat (len - 1, args);
+ SAFE_FREE ();
+ return result;
}