From 3249223f8e17ed380e0c38b305b7d46ce4d69d4c Mon Sep 17 00:00:00 2001 From: Pierre Le Marre Date: Thu, 30 Jan 2025 07:58:20 +0100 Subject: [PATCH] test: Add check for keymap and compose compilation logs --- src/compose/parser.c | 4 +- test/log.c | 232 +++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 225 insertions(+), 11 deletions(-) diff --git a/src/compose/parser.c b/src/compose/parser.c index 9bf2c23c..7ad848fe 100644 --- a/src/compose/parser.c +++ b/src/compose/parser.c @@ -665,7 +665,7 @@ parse(struct xkb_compose_table *table, struct scanner *s, goto error; } check_deprecated_keysyms(scanner_warn, s, s->ctx, - keysym, val.string.str, val.string.str, "%s", "\n"); + keysym, val.string.str, val.string.str, "%s", ""); if (production.len + 1 > MAX_LHS_LEN) { scanner_warn(s, XKB_LOG_MESSAGE_NO_ID, "too many keysyms (%d) on left-hand side; skipping line", @@ -749,7 +749,7 @@ lhs_mod_list_tok: { goto error; } check_deprecated_keysyms(scanner_warn, s, s->ctx, - keysym, val.string.str, val.string.str, "%s", "\n"); + keysym, val.string.str, val.string.str, "%s", ""); if (production.has_keysym) { scanner_warn(s, XKB_LOG_MESSAGE_NO_ID, "right-hand side can have at most one keysym; " diff --git a/test/log.c b/test/log.c index fdcf9608..4516c508 100644 --- a/test/log.c +++ b/test/log.c @@ -68,22 +68,19 @@ log_fn(struct xkb_context *ctx, enum xkb_log_level level, free(s); } -int -main(void) +static void +test_basic(void) { - darray_char log_string; - struct xkb_context *ctx; int ret; - - test_init(); - ret = setenv("XKB_LOG_LEVEL", "warn", 1); assert(ret == 0); ret = setenv("XKB_LOG_VERBOSITY", "5", 1); assert(ret == 0); - ctx = test_get_context(0); + + struct xkb_context *ctx = test_get_context(CONTEXT_NO_FLAG); assert(ctx); + darray_char log_string; darray_init(log_string); xkb_context_set_user_data(ctx, &log_string); xkb_context_set_log_fn(ctx, log_fn); @@ -122,5 +119,222 @@ main(void) xkb_context_unref(ctx); darray_free(log_string); - return 0; +} + +struct test_data { + const char * const input; + const char * const log; + bool error; +}; + +static void +test_keymaps(void) +{ + struct xkb_context *ctx = test_get_context(CONTEXT_NO_FLAG); + assert(ctx); + + darray_char log_string; + darray_init(log_string); + xkb_context_set_user_data(ctx, &log_string); + xkb_context_set_log_fn(ctx, log_fn); + + xkb_context_set_log_level(ctx, XKB_LOG_LEVEL_WARNING); + xkb_context_set_log_verbosity(ctx, 10); + + const struct test_data keymaps[] = { + { + .input = "", + .log = "error: [XKB-822] Failed to parse input xkb string\n", + .error = true + }, + { + .input = " ", + .log = "error: [XKB-822] Failed to parse input xkb string\n", + .error = true + }, + { + .input = "\n", + .log = "error: [XKB-822] Failed to parse input xkb string\n", + .error = true + }, + { + .input = "xkb_keymap {\n", + .log = + "error: [XKB-769] (input string):1:12: syntax error\n" + "error: [XKB-822] Failed to parse input xkb string\n", + .error = true + }, + { + .input = + "xkb_keymap \"\\j\"\n" + " { symbols = { };\n" + "};", + .log = + "warning: [XKB-645] (input string):1:12: unknown escape sequence (\\j) in string literal\n" + "error: [XKB-769] (input string):2:4: syntax error\n" + "error: [XKB-822] Failed to parse input xkb string\n", + .error = true + }, + { + .input = + "xkb_keymap {\n" + " xkb_keycodes {\n" + " <> = 1;\n" + "\n" + " alias <1> = <>;\n" + " alias <1> =\n" + " <>;\n" + " };\n" + " xkb_types \"\\400x\\j\" { };\n" + " xkb_compat {\n" + " interpret invalidKeysym +\n" + " Any { repeat = true; };\n" + " };\n" + " xkb_symbols { key <> {[0x30, leftshoe]}; };\n" + "};", + .log = + "warning: [XKB-193] (input string):9:13: invalid octal escape sequence (\\400) in string literal\n" + "warning: [XKB-645] (input string):9:13: unknown escape sequence (\\j) in string literal\n" + "warning: [XKB-107] (input string):11:15: unrecognized keysym \"invalidKeysym\"\n" + "warning: [XKB-489] (input string):14:26: numeric keysym \"0x30\" (48)\n" + "warning: [XKB-301] (input string):14:32: deprecated keysym \"leftshoe\".\n" + "warning: [XKB-433] No map in include statement, but \"(input string)\" contains several; Using first defined map, \"(unnamed)\"\n" + "warning: [XKB-523] Alias of <1> for <> declared more than once; First definition ignored\n" + "warning: [XKB-286] The type \"TWO_LEVEL\" for key '<>' group 1 was not previously defined; Using the default type\n" + "warning: [XKB-516] Type \"default\" has 1 levels, but <> has 2 levels; Ignoring extra symbols\n", + .error = false + } + }; + + for (unsigned int k = 0; k < ARRAY_SIZE(keymaps); k++) { + fprintf(stderr, "------\n*** %s: #%u ***\n", __func__, k); + struct xkb_keymap *keymap = + test_compile_buffer(ctx, keymaps[k].input, strlen(keymaps[k].input)); + assert(keymaps[k].error ^ !!keymap); + xkb_keymap_unref(keymap); + assert_printf(streq_not_null(darray_items(log_string), keymaps[k].log), + "Expected:\n%s\nGot:\n%s\n", + darray_items(log_string), keymaps[k].log); + darray_free(log_string); + } + + xkb_context_unref(ctx); +} + +static void +test_compose(void) +{ + struct xkb_context *ctx = test_get_context(CONTEXT_NO_FLAG); + assert(ctx); + + darray_char log_string; + darray_init(log_string); + xkb_context_set_user_data(ctx, &log_string); + xkb_context_set_log_fn(ctx, log_fn); + + xkb_context_set_log_level(ctx, XKB_LOG_LEVEL_WARNING); + xkb_context_set_log_verbosity(ctx, 10); + + const struct test_data composes[] = { + { + .input = "", + .log = NULL, + .error = false + }, + { + .input = "\n", + .log = NULL, + .error = false + }, + { + .input = "\xff\n", + .log = + "error: (input string):1:1: unexpected non-ASCII character.\n" + "error: (input string):1:1: This could be a file encoding issue. Supported file encodings are ASCII and UTF-8.\n" + "error: (input string):1:1: failed to parse file\n", + .error = true + }, + { + .input = + " : x\n" + "include \"x\"\n", + .log = + "warning: [XKB-301] (input string):1:1: deprecated keysym \"leftshoe\".\n" + "error: (input string):2:9: failed to open included Compose file \"x\": No such file or directory\n" + "error: (input string):2:9: failed to parse file\n", + .error = true + }, + { + .input = + " : \"a\"\n" + "\n" + " : \"i\\j\\xk\n" + "<0x30> : \"\\400\" invalidKeysym\n" + "<0> <1> <2> <3> <4> <5> <6> <7> <8> <9> : \"\"\n", + .log = + "warning: [XKB-645] (input string):3:7: unknown escape sequence (\\j) in string literal\n" + "warning: [XKB-193] (input string):3:7: illegal hexadecimal escape sequence (\\x) in string literal\n" + "error: (input string):3:7: unterminated string literal\n" + "warning: [XKB-193] (input string):4:10: illegal octal escape sequence (\\400) in string literal\n" + "error: (input string):4:17: unrecognized keysym \"invalidKeysym\" on right-hand side\n" + "warning: [XKB-301] (input string):5:41: deprecated keysym \"leftshoe\".\n" + "warning: (input string):5:41: too many keysyms (11) on left-hand side; skipping line\n", + .error = false + }, + { + .input = + ":\n" + " :\n" + "#\n" + " : \"a\" \"b\"\n" + " : a b\n", + .log = + "warning: (input string):1:1: expected at least one keysym on left-hand side; skipping line\n" + "warning: (input string):2:5: right-hand side must have at least one of string or keysym; skipping line\n" + "warning: (input string):4:11: right-hand side can have at most one string; skipping line\n" + "error: (input string):5:9: unrecognized modifier \"b\"\n", + .error = false + }, + { + .input = + " : a\n" + " : a\n" + " : b\n" + " : x\n" + " : y\n" + " : c\n", + .log = + "warning: (input string):2:7: this compose sequence is a duplicate of another; skipping line\n" + "warning: (input string):4:11: a sequence already exists which is a prefix of this sequence; overriding\n" + "warning: (input string):6:11: this compose sequence is a prefix of another; skipping line\n", + .error = false + } + }; + + for (unsigned int k = 0; k < ARRAY_SIZE(composes); k++) { + fprintf(stderr, "------\n*** %s: #%u ***\n", __func__, k); + struct xkb_compose_table *table = xkb_compose_table_new_from_buffer( + ctx, composes[k].input, strlen(composes[k].input), "", + XKB_COMPOSE_FORMAT_TEXT_V1, + XKB_COMPOSE_COMPILE_NO_FLAGS + ); + assert(composes[k].error ^ !!table); + xkb_compose_table_unref(table); + assert_printf(streq_null(darray_items(log_string), composes[k].log), + "Expected:\n%s\nGot:\n%s\n", + darray_items(log_string), composes[k].log); + darray_free(log_string); + } + + xkb_context_unref(ctx); +} + +int +main(void) +{ + test_init(); + test_basic(); + test_keymaps(); + test_compose(); + return EXIT_SUCCESS; }