| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420 |
- /*
- * Copyright © 2012 Ran Benita <ran234@gmail.com>
- * SPDX-License-Identifier: MIT
- */
- #include "config.h"
- #include "test-config.h"
- #include <locale.h>
- #include "context.h"
- #include "darray.h"
- #include "log.h"
- #include "messages-codes.h"
- #include "test.h"
- #ifdef __GNUC__
- #pragma GCC diagnostic ignored "-Wmissing-format-attribute"
- #endif
- static void
- test_basic(void)
- {
- int ret;
- ret = setenv("XKB_LOG_LEVEL", "warn", 1);
- assert(ret == 0);
- ret = setenv("XKB_LOG_VERBOSITY", "5", 1);
- assert(ret == 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);
- log_warn(ctx, XKB_LOG_MESSAGE_NO_ID, "first warning: %d\n", 87);
- log_info(ctx, XKB_LOG_MESSAGE_NO_ID, "first info\n");
- log_dbg(ctx, XKB_LOG_MESSAGE_NO_ID, "first debug: %s\n", "hello");
- log_err(ctx, XKB_LOG_MESSAGE_NO_ID, "first error: %lu\n", 115415UL);
- log_vrb(ctx, 5, XKB_LOG_MESSAGE_NO_ID, "first verbose 5\n");
- xkb_context_set_log_level(ctx, XKB_LOG_LEVEL_DEBUG);
- log_warn(ctx, XKB_LOG_MESSAGE_NO_ID, "second warning: %d\n", 87);
- log_dbg(ctx, XKB_LOG_MESSAGE_NO_ID, "second debug: %s %s\n", "hello", "world");
- log_info(ctx, XKB_LOG_MESSAGE_NO_ID, "second info\n");
- log_err(ctx, XKB_ERROR_MALFORMED_NUMBER_LITERAL, "second error: %lu\n", 115415UL);
- log_vrb(ctx, 6, XKB_LOG_MESSAGE_NO_ID, "second verbose 6\n");
- xkb_context_set_log_verbosity(ctx, XKB_LOG_VERBOSITY_MINIMAL);
- xkb_context_set_log_level(ctx, XKB_LOG_LEVEL_CRITICAL);
- log_warn(ctx, XKB_LOG_MESSAGE_NO_ID, "third warning: %d\n", 87);
- log_dbg(ctx, XKB_LOG_MESSAGE_NO_ID, "third debug: %s %s\n", "hello", "world");
- log_info(ctx, XKB_LOG_MESSAGE_NO_ID, "third info\n");
- log_err(ctx, XKB_LOG_MESSAGE_NO_ID, "third error: %lu\n", 115415UL);
- log_vrb(ctx, 0, XKB_LOG_MESSAGE_NO_ID, "third verbose 0\n");
- printf("%s", darray_items(log_string));
- assert(streq(darray_items(log_string),
- "warning: first warning: 87\n"
- "error: first error: 115415\n"
- "warning: first verbose 5\n"
- "warning: second warning: 87\n"
- "debug: second debug: hello world\n"
- "info: second info\n"
- "error: [XKB-034] second error: 115415\n"));
- xkb_context_unref(ctx);
- darray_free(log_string);
- }
- 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, XKB_LOG_VERBOSITY_COMPREHENSIVE);
- 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, unexpected end of file\n"
- "error: [XKB-822] Failed to parse input xkb string\n",
- .error = true
- },
- {
- .input =
- "xkb_keymap \"\\j\"\n"
- " { xkb_symbols = {};\n"
- "};",
- .log =
- "warning: [XKB-645] (input string):1:12: unknown escape sequence \"\\j\" in string literal\n"
- "error: [XKB-769] (input string):2:16: syntax error, unexpected =, expecting {\n"
- "error: [XKB-822] Failed to parse input xkb string\n",
- .error = true
- },
- {
- .input =
- "xkb_keymap {\n"
- " xkb_keycodes { <> = 1; };\n"
- " xkb_symbols { key <> { [\"\xC3\xBC\xff\"] }; };\n"
- "};",
- .log =
- "error: [XKB-542] (input string):3:26: Cannot convert string to keysyms: Invalid UTF-8 encoding starting at byte position 3 (code point position: 2).\n"
- "error: [XKB-822] Failed to parse input xkb string\n",
- .error = true
- },
- /* Extra lines & spaces intented to check the file positions */
- {
- .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 \"0x0030\" (48)\n"
- "warning: [XKB-301] (input string):14:32: deprecated keysym \"leftshoe\".\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 \"ONE_LEVEL\" has 1 levels, but <> has 2 levels; Ignoring extra symbols\n",
- .error = false
- },
- /* Deprecated */
- {
- .input =
- "default deprecated xkb_keymap {\n"
- " xkb_symbols {};\n"
- " deprecated xkb_types {};\n"
- "};",
- .log =
- "warning: [XKB-021] (input string):3:26: deprecated section: \"(unnamed map)\"\n",
- .error = false
- },
- /* Invalid action fields */
- {
- .input =
- "default xkb_keymap {\n"
- " xkb_compat {\n"
- " NoAction.data = 1;\n"
- " interpret VoidSymbol { action= VoidAction(data=<garbage>); };\n"
- " };\n"
- "};",
- .log =
- "error: [XKB-563] The \"NoAction\" action takes no argument, but got \"data\" field; Action definition ignored\n"
- "error: [XKB-563] The \"VoidAction\" action takes no argument, but got \"data\" field; Action definition ignored\n"
- "error: Failed to compile xkb_compatibility\n"
- "error: [XKB-822] Failed to compile keymap\n",
- .error = true
- },
- /* Invalid action fields */
- {
- .input =
- "default xkb_keymap {\n"
- " xkb_keycodes { <> = 1; };\n"
- " xkb_symbols {\n"
- " NoAction.data = 1;\n"
- " key <> { [TerminateServer(data=<garbage>)] };\n"
- " };\n"
- "};",
- .log =
- "error: [XKB-563] The \"NoAction\" action takes no argument, but got \"data\" field; Action definition ignored\n"
- "error: [XKB-563] The \"Terminate\" action takes no argument, but got \"data\" field; Action definition ignored\n"
- "error: [XKB-796] Illegal action definition for <>; Action for group 1/level 1 ignored\n"
- "error: Failed to compile xkb_symbols\n"
- "error: [XKB-822] Failed to compile keymap\n",
- .error = true
- },
- /* Unsupported legacy X11 actions */
- {
- .input =
- "default xkb_keymap {\n"
- " xkb_compat {\n"
- /* This is a valid entry */
- " interpret ISO_Lock+AnyOf(all) {\n"
- " action= ISOLock(modifiers=modMapMods,affect=all);\n"
- " };\n"
- /* This uses invalid field, but we do not check fields of
- * legacy actions */
- " interpret VoidSymbol+AnyOf(all) {\n"
- " action= DeviceButton(data=<garbage>);\n"
- " };\n"
- " };\n"
- "};",
- .log =
- "warning: [XKB-362] Unsupported legacy action type \"ISOLock\".\n"
- "warning: [XKB-362] Unsupported legacy action type \"DeviceButton\".\n",
- .error = false
- },
- /* Invalid global var */
- {
- .input =
- "default xkb_keymap {\n"
- " xkb_keycodes { foobar; };\n"
- "};",
- .log =
- "error: [XKB-639] Default defined for unknown field \"foobar\"; Ignored\n"
- "error: Failed to compile xkb_keycodes\n"
- "error: [XKB-822] Failed to compile keymap\n",
- .error = true
- },
- {
- .input =
- "default xkb_keymap {\n"
- " xkb_types { foobar; };\n"
- "};",
- .log =
- "error: [XKB-639] Default defined for unknown field \"foobar\"; Ignored\n"
- "error: Failed to compile xkb_types\n"
- "error: [XKB-822] Failed to compile keymap\n",
- .error = true
- },
- {
- .input =
- "default xkb_keymap {\n"
- " xkb_compat { foobar; };\n"
- "};",
- .log =
- "error: [XKB-639] Default defined for unknown field \"foobar\"; Ignored\n"
- "error: Failed to compile xkb_compatibility\n"
- "error: [XKB-822] Failed to compile keymap\n",
- .error = true
- },
- {
- .input =
- "default xkb_keymap {\n"
- " xkb_symbols { foobar; };\n"
- "};",
- .log =
- "error: [XKB-639] Default defined for unknown field \"foobar\"; Ignored\n"
- "error: Failed to compile xkb_symbols\n"
- "error: [XKB-822] Failed to compile keymap\n",
- .error = true
- },
- };
- 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, XKB_KEYMAP_FORMAT_TEXT_V1,
- keymaps[k].input, strlen(keymaps[k].input));
- assert_printf(keymaps[k].error ^ !!keymap,
- "%s\n", darray_items(log_string));
- xkb_keymap_unref(keymap);
- assert_printf(streq_not_null(darray_items(log_string), keymaps[k].log),
- "Expected:\n%s\nGot:\n%s\n",
- keymaps[k].log, darray_items(log_string));
- darray_size(log_string) = 0;
- }
- xkb_context_unref(ctx);
- darray_free(log_string);
- }
- 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, XKB_LOG_VERBOSITY_VERBOSE);
- const struct test_data composes[] = {
- {
- .input = "",
- .log = NULL,
- .error = false
- },
- {
- .input = "\n",
- .log = NULL,
- .error = false
- },
- {
- .input = "\xff\n",
- .log =
- "error: [XKB-542] (input string):1:1: unexpected non-ASCII character.\n"
- "error: [XKB-542] (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 =
- "<leftshoe> : 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> : \"a\"\n"
- "\n"
- "<b> : \"i\\j\\xk\n"
- "<0x30> : \"\\400\" invalidKeysym\n"
- "<0> <1> <2> <3> <4> <5> <6> <7> <8> <9> <leftshoe> : \"\"\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: [XKB-685] (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: [XKB-685] (input string):5:41: too many keysyms (11) on left-hand side; skipping line\n",
- .error = false
- },
- {
- .input =
- ":\n"
- "<a> :\n"
- "#\n"
- "<c> : \"a\" \"b\"\n"
- "<d> : a b\n",
- .log =
- "warning: (input string):1:1: expected at least one keysym on left-hand side; skipping line\n"
- "warning: [XKB-685] (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: [XKB-685] (input string):5:9: unrecognized modifier \"b\"\n",
- .error = false
- },
- {
- .input =
- "<a> : a\n"
- "<a> : a\n"
- "<b> : b\n"
- "<b> <c> : x\n"
- "<c> <d> : y\n"
- "<c> : 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; overriding\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_size(log_string) = 0;
- }
- xkb_context_unref(ctx);
- darray_free(log_string);
- }
- int
- main(void)
- {
- test_init();
- /* We really need to be locale-independent here */
- setlocale(LC_ALL, "C");
- test_basic();
- test_keymaps();
- test_compose();
- return EXIT_SUCCESS;
- }
|