log.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420
  1. /*
  2. * Copyright © 2012 Ran Benita <ran234@gmail.com>
  3. * SPDX-License-Identifier: MIT
  4. */
  5. #include "config.h"
  6. #include "test-config.h"
  7. #include <locale.h>
  8. #include "context.h"
  9. #include "darray.h"
  10. #include "log.h"
  11. #include "messages-codes.h"
  12. #include "test.h"
  13. #ifdef __GNUC__
  14. #pragma GCC diagnostic ignored "-Wmissing-format-attribute"
  15. #endif
  16. static void
  17. test_basic(void)
  18. {
  19. int ret;
  20. ret = setenv("XKB_LOG_LEVEL", "warn", 1);
  21. assert(ret == 0);
  22. ret = setenv("XKB_LOG_VERBOSITY", "5", 1);
  23. assert(ret == 0);
  24. struct xkb_context *ctx = test_get_context(CONTEXT_NO_FLAG);
  25. assert(ctx);
  26. darray_char log_string;
  27. darray_init(log_string);
  28. xkb_context_set_user_data(ctx, &log_string);
  29. xkb_context_set_log_fn(ctx, log_fn);
  30. log_warn(ctx, XKB_LOG_MESSAGE_NO_ID, "first warning: %d\n", 87);
  31. log_info(ctx, XKB_LOG_MESSAGE_NO_ID, "first info\n");
  32. log_dbg(ctx, XKB_LOG_MESSAGE_NO_ID, "first debug: %s\n", "hello");
  33. log_err(ctx, XKB_LOG_MESSAGE_NO_ID, "first error: %lu\n", 115415UL);
  34. log_vrb(ctx, 5, XKB_LOG_MESSAGE_NO_ID, "first verbose 5\n");
  35. xkb_context_set_log_level(ctx, XKB_LOG_LEVEL_DEBUG);
  36. log_warn(ctx, XKB_LOG_MESSAGE_NO_ID, "second warning: %d\n", 87);
  37. log_dbg(ctx, XKB_LOG_MESSAGE_NO_ID, "second debug: %s %s\n", "hello", "world");
  38. log_info(ctx, XKB_LOG_MESSAGE_NO_ID, "second info\n");
  39. log_err(ctx, XKB_ERROR_MALFORMED_NUMBER_LITERAL, "second error: %lu\n", 115415UL);
  40. log_vrb(ctx, 6, XKB_LOG_MESSAGE_NO_ID, "second verbose 6\n");
  41. xkb_context_set_log_verbosity(ctx, XKB_LOG_VERBOSITY_MINIMAL);
  42. xkb_context_set_log_level(ctx, XKB_LOG_LEVEL_CRITICAL);
  43. log_warn(ctx, XKB_LOG_MESSAGE_NO_ID, "third warning: %d\n", 87);
  44. log_dbg(ctx, XKB_LOG_MESSAGE_NO_ID, "third debug: %s %s\n", "hello", "world");
  45. log_info(ctx, XKB_LOG_MESSAGE_NO_ID, "third info\n");
  46. log_err(ctx, XKB_LOG_MESSAGE_NO_ID, "third error: %lu\n", 115415UL);
  47. log_vrb(ctx, 0, XKB_LOG_MESSAGE_NO_ID, "third verbose 0\n");
  48. printf("%s", darray_items(log_string));
  49. assert(streq(darray_items(log_string),
  50. "warning: first warning: 87\n"
  51. "error: first error: 115415\n"
  52. "warning: first verbose 5\n"
  53. "warning: second warning: 87\n"
  54. "debug: second debug: hello world\n"
  55. "info: second info\n"
  56. "error: [XKB-034] second error: 115415\n"));
  57. xkb_context_unref(ctx);
  58. darray_free(log_string);
  59. }
  60. struct test_data {
  61. const char * const input;
  62. const char * const log;
  63. bool error;
  64. };
  65. static void
  66. test_keymaps(void)
  67. {
  68. struct xkb_context *ctx = test_get_context(CONTEXT_NO_FLAG);
  69. assert(ctx);
  70. darray_char log_string;
  71. darray_init(log_string);
  72. xkb_context_set_user_data(ctx, &log_string);
  73. xkb_context_set_log_fn(ctx, log_fn);
  74. xkb_context_set_log_level(ctx, XKB_LOG_LEVEL_WARNING);
  75. xkb_context_set_log_verbosity(ctx, XKB_LOG_VERBOSITY_COMPREHENSIVE);
  76. const struct test_data keymaps[] = {
  77. {
  78. .input = "",
  79. .log = "error: [XKB-822] Failed to parse input xkb string\n",
  80. .error = true
  81. },
  82. {
  83. .input = " ",
  84. .log = "error: [XKB-822] Failed to parse input xkb string\n",
  85. .error = true
  86. },
  87. {
  88. .input = "\n",
  89. .log = "error: [XKB-822] Failed to parse input xkb string\n",
  90. .error = true
  91. },
  92. {
  93. .input = "xkb_keymap {\n",
  94. .log =
  95. "error: [XKB-769] (input string):1:12: syntax error, unexpected end of file\n"
  96. "error: [XKB-822] Failed to parse input xkb string\n",
  97. .error = true
  98. },
  99. {
  100. .input =
  101. "xkb_keymap \"\\j\"\n"
  102. " { xkb_symbols = {};\n"
  103. "};",
  104. .log =
  105. "warning: [XKB-645] (input string):1:12: unknown escape sequence \"\\j\" in string literal\n"
  106. "error: [XKB-769] (input string):2:16: syntax error, unexpected =, expecting {\n"
  107. "error: [XKB-822] Failed to parse input xkb string\n",
  108. .error = true
  109. },
  110. {
  111. .input =
  112. "xkb_keymap {\n"
  113. " xkb_keycodes { <> = 1; };\n"
  114. " xkb_symbols { key <> { [\"\xC3\xBC\xff\"] }; };\n"
  115. "};",
  116. .log =
  117. "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"
  118. "error: [XKB-822] Failed to parse input xkb string\n",
  119. .error = true
  120. },
  121. /* Extra lines & spaces intented to check the file positions */
  122. {
  123. .input =
  124. "xkb_keymap {\n"
  125. " xkb_keycodes {\n"
  126. " <> = 1;\n"
  127. "\n"
  128. " alias <1> = <>;\n"
  129. " alias <1> =\n"
  130. " <>;\n"
  131. " };\n"
  132. " xkb_types \"\\400x\\j\" { };\n"
  133. " xkb_compat {\n"
  134. " interpret invalidKeysym +\n"
  135. " Any { repeat = true; };\n"
  136. " };\n"
  137. " xkb_symbols { key <> {[0x30, leftshoe]}; };\n"
  138. "};",
  139. .log =
  140. "warning: [XKB-193] (input string):9:13: invalid octal escape sequence \"\\400\" in string literal\n"
  141. "warning: [XKB-645] (input string):9:13: unknown escape sequence \"\\j\" in string literal\n"
  142. "warning: [XKB-107] (input string):11:15: unrecognized keysym \"invalidKeysym\"\n"
  143. "warning: [XKB-489] (input string):14:26: numeric keysym \"0x0030\" (48)\n"
  144. "warning: [XKB-301] (input string):14:32: deprecated keysym \"leftshoe\".\n"
  145. "warning: [XKB-523] Alias of <1> for <> declared more than once; First definition ignored\n"
  146. "warning: [XKB-286] The type \"TWO_LEVEL\" for key '<>' group 1 was not previously defined; Using the default type\n"
  147. "warning: [XKB-516] Type \"ONE_LEVEL\" has 1 levels, but <> has 2 levels; Ignoring extra symbols\n",
  148. .error = false
  149. },
  150. /* Deprecated */
  151. {
  152. .input =
  153. "default deprecated xkb_keymap {\n"
  154. " xkb_symbols {};\n"
  155. " deprecated xkb_types {};\n"
  156. "};",
  157. .log =
  158. "warning: [XKB-021] (input string):3:26: deprecated section: \"(unnamed map)\"\n",
  159. .error = false
  160. },
  161. /* Invalid action fields */
  162. {
  163. .input =
  164. "default xkb_keymap {\n"
  165. " xkb_compat {\n"
  166. " NoAction.data = 1;\n"
  167. " interpret VoidSymbol { action= VoidAction(data=<garbage>); };\n"
  168. " };\n"
  169. "};",
  170. .log =
  171. "error: [XKB-563] The \"NoAction\" action takes no argument, but got \"data\" field; Action definition ignored\n"
  172. "error: [XKB-563] The \"VoidAction\" action takes no argument, but got \"data\" field; Action definition ignored\n"
  173. "error: Failed to compile xkb_compatibility\n"
  174. "error: [XKB-822] Failed to compile keymap\n",
  175. .error = true
  176. },
  177. /* Invalid action fields */
  178. {
  179. .input =
  180. "default xkb_keymap {\n"
  181. " xkb_keycodes { <> = 1; };\n"
  182. " xkb_symbols {\n"
  183. " NoAction.data = 1;\n"
  184. " key <> { [TerminateServer(data=<garbage>)] };\n"
  185. " };\n"
  186. "};",
  187. .log =
  188. "error: [XKB-563] The \"NoAction\" action takes no argument, but got \"data\" field; Action definition ignored\n"
  189. "error: [XKB-563] The \"Terminate\" action takes no argument, but got \"data\" field; Action definition ignored\n"
  190. "error: [XKB-796] Illegal action definition for <>; Action for group 1/level 1 ignored\n"
  191. "error: Failed to compile xkb_symbols\n"
  192. "error: [XKB-822] Failed to compile keymap\n",
  193. .error = true
  194. },
  195. /* Unsupported legacy X11 actions */
  196. {
  197. .input =
  198. "default xkb_keymap {\n"
  199. " xkb_compat {\n"
  200. /* This is a valid entry */
  201. " interpret ISO_Lock+AnyOf(all) {\n"
  202. " action= ISOLock(modifiers=modMapMods,affect=all);\n"
  203. " };\n"
  204. /* This uses invalid field, but we do not check fields of
  205. * legacy actions */
  206. " interpret VoidSymbol+AnyOf(all) {\n"
  207. " action= DeviceButton(data=<garbage>);\n"
  208. " };\n"
  209. " };\n"
  210. "};",
  211. .log =
  212. "warning: [XKB-362] Unsupported legacy action type \"ISOLock\".\n"
  213. "warning: [XKB-362] Unsupported legacy action type \"DeviceButton\".\n",
  214. .error = false
  215. },
  216. /* Invalid global var */
  217. {
  218. .input =
  219. "default xkb_keymap {\n"
  220. " xkb_keycodes { foobar; };\n"
  221. "};",
  222. .log =
  223. "error: [XKB-639] Default defined for unknown field \"foobar\"; Ignored\n"
  224. "error: Failed to compile xkb_keycodes\n"
  225. "error: [XKB-822] Failed to compile keymap\n",
  226. .error = true
  227. },
  228. {
  229. .input =
  230. "default xkb_keymap {\n"
  231. " xkb_types { foobar; };\n"
  232. "};",
  233. .log =
  234. "error: [XKB-639] Default defined for unknown field \"foobar\"; Ignored\n"
  235. "error: Failed to compile xkb_types\n"
  236. "error: [XKB-822] Failed to compile keymap\n",
  237. .error = true
  238. },
  239. {
  240. .input =
  241. "default xkb_keymap {\n"
  242. " xkb_compat { foobar; };\n"
  243. "};",
  244. .log =
  245. "error: [XKB-639] Default defined for unknown field \"foobar\"; Ignored\n"
  246. "error: Failed to compile xkb_compatibility\n"
  247. "error: [XKB-822] Failed to compile keymap\n",
  248. .error = true
  249. },
  250. {
  251. .input =
  252. "default xkb_keymap {\n"
  253. " xkb_symbols { foobar; };\n"
  254. "};",
  255. .log =
  256. "error: [XKB-639] Default defined for unknown field \"foobar\"; Ignored\n"
  257. "error: Failed to compile xkb_symbols\n"
  258. "error: [XKB-822] Failed to compile keymap\n",
  259. .error = true
  260. },
  261. };
  262. for (unsigned int k = 0; k < ARRAY_SIZE(keymaps); k++) {
  263. fprintf(stderr, "------\n*** %s: #%u ***\n", __func__, k);
  264. struct xkb_keymap *keymap =
  265. test_compile_buffer(ctx, XKB_KEYMAP_FORMAT_TEXT_V1,
  266. keymaps[k].input, strlen(keymaps[k].input));
  267. assert_printf(keymaps[k].error ^ !!keymap,
  268. "%s\n", darray_items(log_string));
  269. xkb_keymap_unref(keymap);
  270. assert_printf(streq_not_null(darray_items(log_string), keymaps[k].log),
  271. "Expected:\n%s\nGot:\n%s\n",
  272. keymaps[k].log, darray_items(log_string));
  273. darray_size(log_string) = 0;
  274. }
  275. xkb_context_unref(ctx);
  276. darray_free(log_string);
  277. }
  278. static void
  279. test_compose(void)
  280. {
  281. struct xkb_context *ctx = test_get_context(CONTEXT_NO_FLAG);
  282. assert(ctx);
  283. darray_char log_string;
  284. darray_init(log_string);
  285. xkb_context_set_user_data(ctx, &log_string);
  286. xkb_context_set_log_fn(ctx, log_fn);
  287. xkb_context_set_log_level(ctx, XKB_LOG_LEVEL_WARNING);
  288. xkb_context_set_log_verbosity(ctx, XKB_LOG_VERBOSITY_VERBOSE);
  289. const struct test_data composes[] = {
  290. {
  291. .input = "",
  292. .log = NULL,
  293. .error = false
  294. },
  295. {
  296. .input = "\n",
  297. .log = NULL,
  298. .error = false
  299. },
  300. {
  301. .input = "\xff\n",
  302. .log =
  303. "error: [XKB-542] (input string):1:1: unexpected non-ASCII character.\n"
  304. "error: [XKB-542] (input string):1:1: This could be a file encoding issue. Supported file encodings are ASCII and UTF-8.\n"
  305. "error: (input string):1:1: failed to parse file\n",
  306. .error = true
  307. },
  308. {
  309. .input =
  310. "<leftshoe> : x\n"
  311. "include \"x\"\n",
  312. .log =
  313. "warning: [XKB-301] (input string):1:1: deprecated keysym \"leftshoe\".\n"
  314. "error: (input string):2:9: failed to open included Compose file \"x\": No such file or directory\n"
  315. "error: (input string):2:9: failed to parse file\n",
  316. .error = true
  317. },
  318. {
  319. .input =
  320. "<a> : \"a\"\n"
  321. "\n"
  322. "<b> : \"i\\j\\xk\n"
  323. "<0x30> : \"\\400\" invalidKeysym\n"
  324. "<0> <1> <2> <3> <4> <5> <6> <7> <8> <9> <leftshoe> : \"\"\n",
  325. .log =
  326. "warning: [XKB-645] (input string):3:7: unknown escape sequence \"\\j\" in string literal\n"
  327. "warning: [XKB-193] (input string):3:7: illegal hexadecimal escape sequence \"\\x\" in string literal\n"
  328. "error: [XKB-685] (input string):3:7: unterminated string literal\n"
  329. "warning: [XKB-193] (input string):4:10: illegal octal escape sequence \"\\400\" in string literal\n"
  330. "error: (input string):4:17: unrecognized keysym \"invalidKeysym\" on right-hand side\n"
  331. "warning: [XKB-301] (input string):5:41: deprecated keysym \"leftshoe\".\n"
  332. "warning: [XKB-685] (input string):5:41: too many keysyms (11) on left-hand side; skipping line\n",
  333. .error = false
  334. },
  335. {
  336. .input =
  337. ":\n"
  338. "<a> :\n"
  339. "#\n"
  340. "<c> : \"a\" \"b\"\n"
  341. "<d> : a b\n",
  342. .log =
  343. "warning: (input string):1:1: expected at least one keysym on left-hand side; skipping line\n"
  344. "warning: [XKB-685] (input string):2:5: right-hand side must have at least one of string or keysym; skipping line\n"
  345. "warning: (input string):4:11: right-hand side can have at most one string; skipping line\n"
  346. "error: [XKB-685] (input string):5:9: unrecognized modifier \"b\"\n",
  347. .error = false
  348. },
  349. {
  350. .input =
  351. "<a> : a\n"
  352. "<a> : a\n"
  353. "<b> : b\n"
  354. "<b> <c> : x\n"
  355. "<c> <d> : y\n"
  356. "<c> : c\n",
  357. .log =
  358. "warning: (input string):2:7: this compose sequence is a duplicate of another; skipping line\n"
  359. "warning: (input string):4:11: a sequence already exists which is a prefix of this sequence; overriding\n"
  360. "warning: (input string):6:11: this compose sequence is a prefix of another; overriding\n",
  361. .error = false
  362. }
  363. };
  364. for (unsigned int k = 0; k < ARRAY_SIZE(composes); k++) {
  365. fprintf(stderr, "------\n*** %s: #%u ***\n", __func__, k);
  366. struct xkb_compose_table *table = xkb_compose_table_new_from_buffer(
  367. ctx, composes[k].input, strlen(composes[k].input), "",
  368. XKB_COMPOSE_FORMAT_TEXT_V1,
  369. XKB_COMPOSE_COMPILE_NO_FLAGS
  370. );
  371. assert(composes[k].error ^ !!table);
  372. xkb_compose_table_unref(table);
  373. assert_printf(streq_null(darray_items(log_string), composes[k].log),
  374. "Expected:\n%s\nGot:\n%s\n",
  375. darray_items(log_string), composes[k].log);
  376. darray_size(log_string) = 0;
  377. }
  378. xkb_context_unref(ctx);
  379. darray_free(log_string);
  380. }
  381. int
  382. main(void)
  383. {
  384. test_init();
  385. /* We really need to be locale-independent here */
  386. setlocale(LC_ALL, "C");
  387. test_basic();
  388. test_keymaps();
  389. test_compose();
  390. return EXIT_SUCCESS;
  391. }