From 0074baf4515c8c6b6f84df7658e357f4900e3890 Mon Sep 17 00:00:00 2001 From: Pierre Le Marre Date: Tue, 19 Dec 2023 07:28:52 +0100 Subject: [PATCH] keysyms: Add XKB_KEYSYM_NAME_MAX_SIZE for internal use Currently there is no indication of the maximum length of keysym names. This is statically known, so add the new *internal* following API: `XKB_KEYSYM_NAME_MAX_SIZE`. --- scripts/update-headers.py | 14 +++++++++++--- src/keysym.h | 2 ++ src/keysym.h.jinja | 2 ++ src/text.c | 5 +++-- test/common.c | 3 ++- test/compose.c | 3 ++- test/keysym.c | 14 +++++++++----- tools/compile-compose.c | 3 ++- tools/how-to-type.c | 3 ++- tools/tools-common.c | 6 +++++- 10 files changed, 40 insertions(+), 15 deletions(-) diff --git a/scripts/update-headers.py b/scripts/update-headers.py index 18085e73e..ece9438ef 100755 --- a/scripts/update-headers.py +++ b/scripts/update-headers.py @@ -19,20 +19,28 @@ def load_keysyms(path: Path) -> dict[str, int]: keysym_max = 0 min_unicode_keysym = 0x01000100 max_unicode_keysym = 0x0110FFFF - keysyms = set() + canonical_names: dict[int, str] = {} + max_unicode_name = "U10FFFF" + max_keysym_name = "0x1fffffff" # XKB_KEYSYM_MAX with path.open("rt", encoding="utf-8") as fd: for line in fd: if m := KEYSYM_PATTERN.match(line): value = int(m.group("value"), 16) - keysyms.add(value) keysym_min = min(keysym_min, value) keysym_max = max(keysym_max, value) + if value not in canonical_names: + canonical_names[value] = m.group("name") return { "XKB_KEYSYM_MIN_ASSIGNED": min(keysym_min, min_unicode_keysym), "XKB_KEYSYM_MAX_ASSIGNED": max(keysym_max, max_unicode_keysym), "XKB_KEYSYM_MIN_EXPLICIT": keysym_min, "XKB_KEYSYM_MAX_EXPLICIT": keysym_max, - "XKB_KEYSYM_COUNT_EXPLICIT": len(keysyms), + "XKB_KEYSYM_COUNT_EXPLICIT": len(canonical_names), + "XKB_KEYSYM_NAME_MAX_SIZE": max( + max(len(name) for name in canonical_names.values()), + len(max_unicode_name), + len(max_keysym_name), + ), } diff --git a/src/keysym.h b/src/keysym.h index 18bdede4e..9454a89f4 100644 --- a/src/keysym.h +++ b/src/keysym.h @@ -76,6 +76,8 @@ #define XKB_KEYSYM_UNICODE_MIN 0x01000100 /** Maximum Unicode keysym, correspoding to the maximum Unicode code point */ #define XKB_KEYSYM_UNICODE_MAX 0x0110ffff +/** Maximum keysym name length */ +#define XKB_KEYSYM_NAME_MAX_SIZE 27 bool xkb_keysym_is_assigned(xkb_keysym_t ks); diff --git a/src/keysym.h.jinja b/src/keysym.h.jinja index d67622e1e..d94ef8595 100644 --- a/src/keysym.h.jinja +++ b/src/keysym.h.jinja @@ -76,6 +76,8 @@ #define XKB_KEYSYM_UNICODE_MIN 0x01000100 /** Maximum Unicode keysym, correspoding to the maximum Unicode code point */ #define XKB_KEYSYM_UNICODE_MAX 0x0110ffff +/** Maximum keysym name length */ +#define XKB_KEYSYM_NAME_MAX_SIZE {{ XKB_KEYSYM_NAME_MAX_SIZE }} bool xkb_keysym_is_assigned(xkb_keysym_t ks); diff --git a/src/text.c b/src/text.c index 290a5ae24..0cab3b722 100644 --- a/src/text.c +++ b/src/text.c @@ -27,6 +27,7 @@ #include "config.h" #include "keymap.h" +#include "keysym.h" #include "text.h" bool @@ -235,8 +236,8 @@ ActionTypeText(enum xkb_action_type type) const char * KeysymText(struct xkb_context *ctx, xkb_keysym_t sym) { - char *buffer = xkb_context_get_buffer(ctx, 64); - xkb_keysym_get_name(sym, buffer, 64); + char *buffer = xkb_context_get_buffer(ctx, XKB_KEYSYM_NAME_MAX_SIZE); + xkb_keysym_get_name(sym, buffer, XKB_KEYSYM_NAME_MAX_SIZE); return buffer; } diff --git a/test/common.c b/test/common.c index cb911e802..24d2ca6a1 100644 --- a/test/common.c +++ b/test/common.c @@ -47,6 +47,7 @@ #include "test.h" #include "utils.h" +#include "src/keysym.h" /* * Test a sequence of keysyms, resulting from a sequence of key presses, @@ -76,7 +77,7 @@ test_key_seq_va(struct xkb_keymap *keymap, va_list ap) const xkb_keysym_t *syms; xkb_keysym_t sym; unsigned int nsyms, i; - char ksbuf[64]; + char ksbuf[XKB_KEYSYM_NAME_MAX_SIZE]; fprintf(stderr, "----\n"); diff --git a/test/compose.c b/test/compose.c index 56e2e2c60..8508ea97f 100644 --- a/test/compose.c +++ b/test/compose.c @@ -28,6 +28,7 @@ #include "test.h" #include "src/utf8.h" +#include "src/keysym.h" #include "src/compose/parser.h" #include "src/compose/dump.h" @@ -73,7 +74,7 @@ test_compose_seq_va(struct xkb_compose_table *table, va_list ap) { int ret; struct xkb_compose_state *state; - char buffer[64]; + char buffer[XKB_KEYSYM_NAME_MAX_SIZE]; state = xkb_compose_state_new(table, XKB_COMPOSE_STATE_NO_FLAGS); assert(state); diff --git a/test/keysym.c b/test/keysym.c index 9b60fd474..7170ed3fb 100644 --- a/test/keysym.c +++ b/test/keysym.c @@ -56,7 +56,7 @@ test_casestring(const char *string, xkb_keysym_t expected) static int test_keysym(xkb_keysym_t keysym, const char *expected) { - char s[16]; + char s[XKB_KEYSYM_NAME_MAX_SIZE]; xkb_keysym_get_name(keysym, s, sizeof(s)); @@ -117,11 +117,11 @@ get_keysym_name(xkb_keysym_t keysym, char *buffer, size_t size) static int test_utf32_to_keysym(uint32_t ucs, xkb_keysym_t expected) { - char expected_name[64]; - char actual_name[64]; + char expected_name[XKB_KEYSYM_NAME_MAX_SIZE]; + char actual_name[XKB_KEYSYM_NAME_MAX_SIZE]; xkb_keysym_t actual = xkb_utf32_to_keysym(ucs); - get_keysym_name(expected, expected_name, 64); - get_keysym_name(actual, actual_name, 64); + get_keysym_name(expected, expected_name, XKB_KEYSYM_NAME_MAX_SIZE); + get_keysym_name(actual, actual_name, XKB_KEYSYM_NAME_MAX_SIZE); fprintf(stderr, "Code point 0x%lx: expected keysym: %s, actual: %s\n\n", (unsigned long)ucs, expected_name, actual_name); @@ -183,6 +183,10 @@ main(void) char utf8[7]; int needed = xkb_keysym_to_utf8(ks, utf8, sizeof(utf8)); assert(0 <= needed && needed <= 5); + /* Check maximum name length */ + char name[XKB_KEYSYM_NAME_MAX_SIZE]; + needed = xkb_keysym_iterator_get_name(iter, name, sizeof(name)); + assert(0 < needed && (size_t)needed <= sizeof(name)); } iter = xkb_keysym_iterator_unref(iter); assert(ks_prev == XKB_KEYSYM_MAX_ASSIGNED); diff --git a/tools/compile-compose.c b/tools/compile-compose.c index 2c5bac3c4..6f37d5762 100644 --- a/tools/compile-compose.c +++ b/tools/compile-compose.c @@ -31,6 +31,7 @@ #include "xkbcommon/xkbcommon-keysyms.h" #include "xkbcommon/xkbcommon-compose.h" #include "src/compose/dump.h" +#include "src/keysym.h" static void usage(FILE *fp, char *progname) @@ -57,7 +58,7 @@ print_compose_table_entry(struct xkb_compose_table_entry *entry) { size_t nsyms; const xkb_keysym_t *syms = xkb_compose_table_entry_sequence(entry, &nsyms); - char buf[128]; + char buf[XKB_KEYSYM_NAME_MAX_SIZE]; for (size_t i = 0; i < nsyms; i++) { xkb_keysym_get_name(syms[i], buf, sizeof(buf)); printf("<%s>", buf); diff --git a/tools/how-to-type.c b/tools/how-to-type.c index 91ebd000e..72aea1bee 100644 --- a/tools/how-to-type.c +++ b/tools/how-to-type.c @@ -30,6 +30,7 @@ #include #include "xkbcommon/xkbcommon.h" +#include "src/keysym.h" #define ARRAY_SIZE(arr) ((sizeof(arr) / sizeof(*(arr)))) @@ -57,7 +58,7 @@ main(int argc, char *argv[]) uint32_t codepoint; xkb_keysym_t keysym; int ret; - char name[200]; + char name[XKB_KEYSYM_NAME_MAX_SIZE]; struct xkb_keymap *keymap = NULL; xkb_keycode_t min_keycode, max_keycode; xkb_mod_index_t num_mods; diff --git a/tools/tools-common.c b/tools/tools-common.c index b163438fe..5113cbab9 100644 --- a/tools/tools-common.c +++ b/tools/tools-common.c @@ -49,6 +49,8 @@ #endif #include "tools-common.h" +#include "src/utils.h" +#include "src/keysym.h" static void print_keycode(struct xkb_keymap *keymap, const char* prefix, @@ -155,7 +157,9 @@ tools_print_keycode_state(char *prefix, xkb_keysym_t sym; const xkb_keysym_t *syms; int nsyms; - char s[16]; + // FIXME: this buffer is used for xkb_compose_state_get_utf8, + // which can have a length up to 256. Need to import this constant from compose. + char s[MAX(16, XKB_KEYSYM_NAME_MAX_SIZE)]; xkb_layout_index_t layout; enum xkb_compose_status status;