merge_modes.c.jinja 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716
  1. /*
  2. * WARNING: This file is automatically generated by: {{ script }}
  3. * Do not edit manually!
  4. */
  5. /*
  6. * Copyright © 2024-2025 Pierre Le Marre <dev@wismill.eu>
  7. * SPDX-License-Identifier: MIT
  8. */
  9. #include "config.h"
  10. #include <assert.h>
  11. #include <limits.h>
  12. #include <stdbool.h>
  13. #include <stdio.h>
  14. #include <stdlib.h>
  15. #include "test.h"
  16. #include "utils.h"
  17. {% if not compiler.is_default %}
  18. #include "external_xkb_compilers.h"
  19. {% endif %}
  20. enum update_files {
  21. NO_UPDATE = 0,
  22. UPDATE_USING_TEST_INPUT,
  23. UPDATE_USING_TEST_OUTPUT
  24. };
  25. #define GOLDEN_TESTS_OUTPUTS "keymaps/merge-modes/"
  26. {% if compiler.is_default %}
  27. /* xkbcommon buffer compiler */
  28. static struct xkb_keymap *
  29. compile_buffer(struct xkb_context *context, enum xkb_keymap_format format,
  30. const char *buf, size_t len, void *private)
  31. {
  32. return test_compile_buffer(context, format, buf, len);
  33. }
  34. static bool
  35. test_compile(struct xkb_context *ctx, const char* xkb_root,
  36. const char *test_title,
  37. const char *keymap_str, size_t keymap_len,
  38. const char *path, bool update)
  39. {
  40. return test_compile_output(ctx, XKB_KEYMAP_FORMAT_TEXT_V2,
  41. XKB_KEYMAP_USE_ORIGINAL_FORMAT, compile_buffer,
  42. NULL, test_title, keymap_str, keymap_len,
  43. path, !!update);
  44. }
  45. {% else %}
  46. /* Third-party compiler: {{ compiler.name }} */
  47. struct compile_buffer_{{ compiler.name }}_data {
  48. const char* xkb_root;
  49. };
  50. static int
  51. compile_buffer_{{ compiler.name }}(const char *buf, size_t len, void *private,
  52. char* *out, size_t *out_size)
  53. {
  54. struct compile_buffer_{{ compiler.name }}_data *data = private;
  55. {% if compiler.name == "xkbcomp" %}
  56. /* Xorg xkbcomp */
  57. return compile_with_xkbcomp(NULL, data->xkb_root, buf, len, out, out_size);
  58. {% elif compiler.name == "kbvm" %}
  59. /* kbvm */
  60. return compile_with_kbvm(data->xkb_root, buf, len, out, out_size);
  61. {% else %}
  62. #error "Unsupported compiler: {{ compiler.name }}"
  63. {% endif %}
  64. }
  65. static bool
  66. test_compile(struct xkb_context *ctx, const char* xkb_root,
  67. const char *test_title,
  68. const char *keymap_str, size_t keymap_len,
  69. const char *path, bool update)
  70. {
  71. struct compile_buffer_{{ compiler.name }}_data data = { .xkb_root = xkb_root };
  72. return test_third_pary_compile_output(compile_buffer_{{ compiler.name}},
  73. &data, test_title,
  74. keymap_str, keymap_len,
  75. path, !!update);
  76. }
  77. {% endif %}
  78. struct keymap_test_data {
  79. const char* title;
  80. const char* file;
  81. const char* keymap;
  82. const char* expected;
  83. };
  84. {% if compiler.extended_syntax %}
  85. static void
  86. test_vmods(struct xkb_context *ctx, const char* xkb_root,
  87. enum update_files update) {
  88. #define BASE_VMODS \
  89. "virtual_modifiers U1, U2, U3, U4, U5, U6;\n" \
  90. "virtual_modifiers Z1=none, Z2=none, Z3=none, Z4=none, Z5=none, Z6=none;\n"\
  91. "virtual_modifiers M1=0x1000, M2=0x2000, M3=0x3000, " \
  92. "M4=0x4000, M5=0x5000, M6=0x6000;\n"
  93. const struct keymap_test_data tests[] = {
  94. /*
  95. * Change virtual modifiers in same component
  96. */
  97. {
  98. .title = "same-component-include-default-augment",
  99. .keymap =
  100. "xkb_keymap {\n"
  101. " xkb_types \"\" {\n"
  102. " include \"merge_modes_vmods(base)|merge_modes_vmods(new)\"\n"
  103. " };\n"
  104. " xkb_compat \"\" { interpret.repeat= True; };\n"
  105. "};",
  106. .file = "same-component-include-default-augment",
  107. },
  108. {
  109. .title = "same-component-include-default-override",
  110. .keymap =
  111. "xkb_keymap {\n"
  112. " xkb_types \"\" {\n"
  113. " include \"merge_modes_vmods(base)+merge_modes_vmods(new)\"\n"
  114. " };\n"
  115. " xkb_compat \"\" { interpret.repeat= True; };\n"
  116. "};",
  117. .file = "same-component-include-default-override",
  118. },
  119. /*
  120. * Change virtual modifiers in another component
  121. */
  122. {
  123. .title = "other-component-direct",
  124. .keymap =
  125. "xkb_keymap {\n"
  126. " xkb_types {\n"
  127. BASE_VMODS
  128. " };\n"
  129. " xkb_compat \"\" {\n"
  130. " augment virtual_modifiers U1, U2=none, U3=0x300000;\n"
  131. " override virtual_modifiers U4, U5=none, U6=0x600000;\n"
  132. " augment virtual_modifiers Z1, Z2=none, Z3=0x310000;\n"
  133. " override virtual_modifiers Z4, Z5=none, Z6=0x610000;\n"
  134. " augment virtual_modifiers M1, M2=none, M3=0x320000;\n"
  135. " override virtual_modifiers M4, M5=none, M6=0x620000;\n"
  136. " };\n"
  137. "};",
  138. .file = "other-component-direct",
  139. },
  140. {
  141. .title = "other-component-include-default",
  142. .keymap =
  143. "xkb_keymap {\n"
  144. " xkb_types \"\" {\n"
  145. BASE_VMODS
  146. " };\n"
  147. " xkb_compat \"\" { include \"merge_modes_vmods(new)\" };\n"
  148. "};",
  149. .file = "same-component-include-default-override",
  150. },
  151. {
  152. .title = "other-component-include-augment",
  153. .keymap =
  154. "xkb_keymap {\n"
  155. " xkb_types \"\" {\n"
  156. BASE_VMODS
  157. " };\n"
  158. " xkb_compat \"\" { augment \"merge_modes_vmods(new)\" };\n"
  159. "};",
  160. .file = "same-component-include-default-augment",
  161. },
  162. {
  163. .title = "other-component-include-override",
  164. .keymap =
  165. "xkb_keymap {\n"
  166. " xkb_types \"\" {\n"
  167. BASE_VMODS
  168. " };\n"
  169. " xkb_compat \"\" { override \"merge_modes_vmods(new)\" };\n"
  170. "};",
  171. .file = "same-component-include-default-override",
  172. },
  173. {
  174. .title = "other-component-include-replace",
  175. .keymap =
  176. "xkb_keymap {\n"
  177. " xkb_types \"\" {\n"
  178. BASE_VMODS
  179. " };\n"
  180. " xkb_compat \"\" { replace \"merge_modes_vmods(new)\" };\n"
  181. "};",
  182. .file = "same-component-include-default-override",
  183. },
  184. };
  185. for (unsigned int k = 0; k < ARRAY_SIZE(tests); k++) {
  186. const struct keymap_test_data* const test = &tests[k];
  187. char title[1024] = { 0 };
  188. snprintf(title, sizeof(title), "%s #%u: %s", __func__, k, test->title);
  189. char path[PATH_MAX] = { 0 };
  190. snprintf(path, sizeof(path),
  191. GOLDEN_TESTS_OUTPUTS "vmods-%s{{ compiler.suffix }}.xkb",
  192. test->file);
  193. assert(test_compile(ctx, xkb_root, title,
  194. test->keymap, strlen(test->keymap),
  195. path, !!update));
  196. }
  197. }
  198. {% endif %}
  199. static void
  200. test_compat(struct xkb_context *ctx, const char* xkb_root,
  201. enum update_files update)
  202. {
  203. // Github Issue #566
  204. const char keymap_str[] =
  205. "xkb_keymap {\n"
  206. " xkb_keycodes { <> = 8; };\n"
  207. " xkb_compat {\n"
  208. " interpret A { repeat = true; };\n"
  209. " interpret A { repeat = true; };\n"
  210. " interpret A { action = SetMods(mods=Mod1); };\n"
  211. " interpret B { repeat = true; };\n"
  212. " interpret B { repeat = true; };\n"
  213. " augment interpret B { action = SetMods(mods=Mod1); };\n"
  214. " interpret C { repeat = true; };\n"
  215. " interpret C { repeat = true; };\n"
  216. " override interpret C { action = SetMods(mods=Mod1); };\n"
  217. " interpret D { repeat = true; };\n"
  218. " interpret D { repeat = true; };\n"
  219. " replace interpret D { action = SetMods(mods=Mod1); };\n"
  220. "\n"
  221. " indicator \"A\" { modifiers=Shift; };\n"
  222. " indicator \"A\" { modifiers=Lock; };\n"
  223. " indicator \"A\" { groups= Group1; };\n"
  224. " indicator \"B\" { modifiers=Shift; };\n"
  225. " indicator \"B\" { modifiers=Lock; };\n"
  226. " augment indicator \"B\" { groups=Group1; };\n"
  227. " indicator \"C\" { modifiers=Shift; };\n"
  228. " indicator \"C\" { modifiers=Lock; };\n"
  229. " override indicator \"C\" { groups=Group1; };\n"
  230. " indicator \"D\" { modifiers=Shift; };\n"
  231. " indicator \"D\" { modifiers=Lock; };\n"
  232. " replace indicator \"D\" { groups=Group1; };\n"
  233. " };\n"
  234. " xkb_symbols { key <> { }; };\n"
  235. "};\n";
  236. assert(test_compile(ctx, xkb_root, "test_merge_mode: compat",
  237. keymap_str, ARRAY_SIZE(keymap_str) - 1,
  238. GOLDEN_TESTS_OUTPUTS "compat{{ compiler.suffix }}.xkb",
  239. !!update));
  240. }
  241. static void
  242. test_merge_modes(struct xkb_context *ctx, const char* xkb_root,
  243. enum update_files update) {
  244. const struct keymap_test_data tests[] = {
  245. {% for group in tests %}
  246. /*
  247. * #{{ loop.index0 }}{{ " " + group.title if group.title else "" }}
  248. */
  249. {% for test in group.tests %}
  250. {
  251. .title = "#{{ loop.index0 }} {{ test.title | escape_quotes }}",
  252. .file = "{{ test.file | string | escape_quotes }}",
  253. .keymap =
  254. {%- for line in test.content.splitlines() +%}
  255. "{{ line | escape_quotes }}\n"
  256. {%- endfor %},
  257. .expected =
  258. {% for line in test.expected.splitlines() %}
  259. "{{ line | escape_quotes }}\n"
  260. {% endfor %}
  261. },
  262. {% endfor %}
  263. {% endfor %}
  264. };
  265. for (unsigned int k = 0; k < ARRAY_SIZE(tests); k++) {
  266. const struct keymap_test_data* const test = &tests[k];
  267. char title[1024] = { 0 };
  268. snprintf(title, sizeof(title), "%s #%u: %s", __func__, k, test->title);
  269. char path[PATH_MAX] = { 0 };
  270. {% if compiler.is_default %}
  271. snprintf(path, sizeof(path), GOLDEN_TESTS_OUTPUTS "%s.xkb", test->file);
  272. {% else %}
  273. snprintf(path, sizeof(path),
  274. GOLDEN_TESTS_OUTPUTS "%02u-%s{{ compiler.suffix }}.xkb",
  275. k, test->file);
  276. {% endif %}
  277. const char* const keymap = (update == UPDATE_USING_TEST_INPUT)
  278. ? test->expected
  279. : test->keymap;
  280. assert(test_compile(ctx, xkb_root, title, keymap, strlen(keymap),
  281. path, !!update));
  282. }
  283. }
  284. static void
  285. test_defaults(struct xkb_context *ctx, const char* xkb_root,
  286. enum update_files update)
  287. {
  288. const struct keymap_test_data tests[] = {
  289. {
  290. .title = "plain",
  291. .file = "plain",
  292. .keymap =
  293. "xkb_keymap {\n"
  294. " xkb_keycodes {\n"
  295. " <A> = 38;\n"
  296. " <S> = 39;\n"
  297. " <D> = 40;\n"
  298. " <F> = 41;\n"
  299. " <G> = 42;\n"
  300. "\n"
  301. " indicator 1 = \"A\";\n"
  302. " indicator 2 = \"B\";\n"
  303. " indicator 3 = \"C\";\n"
  304. " };\n"
  305. " xkb_types {\n"
  306. " type \"ONE_LEVEL\" {\n"
  307. " map[None] = 1;\n"
  308. " };\n"
  309. " type \"ALPHABETIC\" {\n"
  310. " modifiers = Shift + Lock;\n"
  311. " map[Shift] = 2;\n"
  312. " map[Lock] = 2;\n"
  313. " };\n"
  314. " };\n"
  315. " xkb_compat {\n"
  316. " virtual_modifiers M1=0x1000, M2=0x2000, M3=0x4000, M4=0x8000;\n"
  317. "\n"
  318. " interpret.repeat= False;\n"
  319. " // Effective: override\n"
  320. " interpret.repeat= True;\n"
  321. "\n"
  322. " interpret.virtualmod = M1;\n"
  323. " // Effective: override\n"
  324. " interpret.virtualmod = M2;\n"
  325. " // Ineffective: cannot augment previous value\n"
  326. " augment interpret.virtualmod = M3;\n"
  327. "\n"
  328. " SetGroup.group = 1;\n"
  329. " // Effective: override\n"
  330. " SetGroup.group = 2;\n"
  331. " // Ineffective: cannot augment previous value\n"
  332. " augment SetGroup.group = 3;\n"
  333. "\n"
  334. "\n"
  335. " // Effective: *override* every explicit field\n"
  336. " interpret a {\n"
  337. " virtualmod = M4;\n"
  338. " action=SetGroup(group=1);\n"
  339. " };\n"
  340. " interpret A {\n"
  341. " repeat = False;\n"
  342. " virtualmod = M1;\n"
  343. " action=SetMods(mods=M1);\n"
  344. " };\n"
  345. "\n"
  346. "\n"
  347. " // Effective: no previous interpret entry,\n"
  348. " // so *override* every explicit field\n"
  349. " augment interpret s {\n"
  350. " repeat = False;\n"
  351. " action=SetGroup();\n"
  352. " };\n"
  353. " // Only augment fields not set previously (explicit or implicit)\n"
  354. " augment interpret s {\n"
  355. " // Ineffective: cannot augment previous implicit value\n"
  356. " virtualmod = M4;\n"
  357. " // Ineffective: cannot augment previous explicit value\n"
  358. " action=SetGroup(group=4);\n"
  359. " // Effective: no previous value\n"
  360. " useModMapMods=level1;\n"
  361. " };\n"
  362. " augment interpret S {\n"
  363. " action=SetGroup(group=4);\n"
  364. " };\n"
  365. " interpret g {\n"
  366. " virtualmod = M3;\n"
  367. " repeat = False;"
  368. " action = SetGroup(group=3);\n"
  369. " };\n"
  370. " indicator \"C\" {\n"
  371. " modifiers = M3;\n"
  372. " whichmodstate = locked;\n"
  373. " };\n"
  374. "\n"
  375. "\n"
  376. " indicator.modifiers = M1;\n"
  377. " indicator.modifiers = M2;\n"
  378. " augment indicator.modifiers = M3;\n"
  379. " indicator.groups = All - 1;\n"
  380. " indicator.controls = AudibleBell;\n"
  381. "\n"
  382. " indicator \"A\" {\n"
  383. " modifiers = M4;\n"
  384. " whichmodstate = base;\n"
  385. " };\n"
  386. " indicator \"A\" {\n"
  387. " whichmodstate = locked;\n"
  388. " whichgroupstate = locked;\n"
  389. " controls = SlowKeys;\n"
  390. " };\n"
  391. " augment indicator \"B\" {\n"
  392. " modifiers = M4;\n"
  393. " whichmodstate = base;\n"
  394. " };\n"
  395. " augment indicator \"B\" {\n"
  396. " groups = 4;\n"
  397. " whichmodstate = locked;\n"
  398. " whichgroupstate = locked;\n"
  399. " };\n"
  400. " };\n"
  401. " xkb_symbols {\n"
  402. " name[1] = \"xxx\";\n"
  403. " name[1] = \"yyy\";\n"
  404. " augment name[1] = \"zzz\";\n"
  405. "\n"
  406. " key <A> { [a, A] };\n"
  407. " key <S> { [s, S] };\n"
  408. " modifier_map Shift { <A> };\n"
  409. " modifier_map Control { <S> };\n"
  410. "\n"
  411. " key <G> { type = \"ONE_LEVEL\", repeat=true, [g] };"
  412. " modifier_map Mod3 { <G> };\n"
  413. "\n"
  414. " key.repeat = false;\n"
  415. " key.vmods = M1;\n"
  416. " key.vmods = M2;\n"
  417. " augment key.vmods = M3;\n"
  418. "\n"
  419. " key <D> { vmods = M4, [d, D] };\n"
  420. " augment key <F> { vmods = M4, [f, F] };\n"
  421. " augment key <F> { vmods = M1, repeat = true };\n"
  422. " };\n"
  423. "};\n",
  424. .expected =
  425. "xkb_keymap {\n"
  426. " xkb_keycodes {\n"
  427. " <A> = 38;\n"
  428. " <S> = 39;\n"
  429. " <D> = 40;\n"
  430. " <F> = 41;\n"
  431. " indicator 1 = \"A\";\n"
  432. " indicator 2 = \"B\";\n"
  433. " indicator 3 = \"C\";\n"
  434. " };\n"
  435. " xkb_types {\n"
  436. " type \"ONE_LEVEL\" {\n"
  437. " map[None] = 1;\n"
  438. " };\n"
  439. " type \"ALPHABETIC\" {\n"
  440. " modifiers = Shift + Lock;\n"
  441. " map[Shift] = 2;\n"
  442. " map[Lock] = 2;\n"
  443. " };\n"
  444. " };\n"
  445. " xkb_compat {\n"
  446. " virtual_modifiers M1=0x1000, M2=0x2000, M3=0x4000, M4=0x8000;\n"
  447. "\n"
  448. " interpret.repeat= True;\n"
  449. " interpret.virtualmod = M2;\n"
  450. " SetGroup.group = 2;\n"
  451. "\n"
  452. " interpret a {\n"
  453. " virtualmod = M4;\n"
  454. " action=SetGroup(group=1);\n"
  455. " };\n"
  456. " interpret A {\n"
  457. " repeat = False;\n"
  458. " virtualmod = M1;\n"
  459. " action=SetMods(mods=M1);\n"
  460. " };\n"
  461. " interpret s {\n"
  462. " repeat = False;\n"
  463. " action=SetGroup(group=2);\n"
  464. " useModMapMods=level1;\n"
  465. " };\n"
  466. " interpret S {\n"
  467. " action=SetGroup(group=4);"
  468. " };\n"
  469. "\n"
  470. " indicator.modifiers = M2;\n"
  471. " indicator.groups = All - 1;\n"
  472. " indicator.controls = AudibleBell;\n"
  473. "\n"
  474. " indicator \"A\" {\n"
  475. " modifiers = M4;\n"
  476. " whichmodstate = locked;\n"
  477. " whichgroupstate = locked;\n"
  478. " controls = SlowKeys;\n"
  479. " };\n"
  480. " indicator \"B\" {\n"
  481. " modifiers = M4;\n"
  482. " whichmodstate = base;\n"
  483. " whichgroupstate = locked;\n"
  484. " };\n"
  485. " };\n"
  486. " xkb_symbols {\n"
  487. " name[1] = \"yyy\";\n"
  488. "\n"
  489. " key <A> { [a, A] };\n"
  490. " key <S> { [s, S] };\n"
  491. " modifier_map Shift { <A> };\n"
  492. " modifier_map Control { <S> };\n"
  493. "\n"
  494. " key <D> { vmods = M4, repeat = false, [d, D] };\n"
  495. " key <F> { vmods = M4, repeat = true , [f, F] };\n"
  496. " key <G> { type = \"ONE_LEVEL\", repeat=true, vmods=M3, [g] };"
  497. " };\n"
  498. "};\n"
  499. },
  500. {
  501. .title = "include",
  502. .file = "include",
  503. .keymap =
  504. "xkb_keymap {\n"
  505. " xkb_keycodes {\n"
  506. " <A> = 38;\n"
  507. " <S> = 39;\n"
  508. " <D> = 40;\n"
  509. " <F> = 41;\n"
  510. " <G> = 42;\n"
  511. "\n"
  512. " indicator 1 = \"A\";\n"
  513. " indicator 2 = \"B\";\n"
  514. " indicator 3 = \"C\";\n"
  515. " };\n"
  516. " xkb_types {\n"
  517. " type \"ONE_LEVEL\" {\n"
  518. " map[None] = 1;\n"
  519. " };\n"
  520. " type \"ALPHABETIC\" {\n"
  521. " modifiers = Shift + Lock;\n"
  522. " map[Shift] = 2;\n"
  523. " map[Lock] = 2;\n"
  524. " };\n"
  525. " };\n"
  526. " xkb_compat {\n"
  527. " virtual_modifiers M1,M2,M3;"
  528. " interpret.virtualmod = M3;\n"
  529. " indicator.modifiers = M3;\n"
  530. " SetGroup.group = 3;\n"
  531. "\n"
  532. " include \"merge_modes_defaults\"\n"
  533. "\n"
  534. " interpret g {\n"
  535. " action = SetGroup();\n"
  536. " };\n"
  537. " indicator \"C\" {\n"
  538. " whichmodstate = locked;\n"
  539. " };\n"
  540. " };\n"
  541. " xkb_symbols {\n"
  542. " name[1] = \"XXX\";\n"
  543. "\n"
  544. " key.type = \"ONE_LEVEL\";"
  545. "\n"
  546. " include \"merge_modes_defaults\"\n"
  547. "\n"
  548. " key <G> { repeat = true, [g, G] };\n"
  549. " modifier_map Mod3 { <G> };\n"
  550. " };\n"
  551. "};\n",
  552. .expected =
  553. "xkb_keymap {\n"
  554. " xkb_keycodes {\n"
  555. " <A> = 38;\n"
  556. " <S> = 39;\n"
  557. " <D> = 40;\n"
  558. " <F> = 41;\n"
  559. " indicator 1 = \"A\";\n"
  560. " indicator 2 = \"B\";\n"
  561. " indicator 3 = \"C\";\n"
  562. " };\n"
  563. " xkb_types {\n"
  564. " type \"ONE_LEVEL\" {\n"
  565. " map[None] = 1;\n"
  566. " };\n"
  567. " type \"ALPHABETIC\" {\n"
  568. " modifiers = Shift + Lock;\n"
  569. " map[Shift] = 2;\n"
  570. " map[Lock] = 2;\n"
  571. " };\n"
  572. " };\n"
  573. " xkb_compat {\n"
  574. " virtual_modifiers M1=0x1000, M2=0x2000, M3=0x4000, M4=0x8000;\n"
  575. "\n"
  576. " interpret.repeat= True;\n"
  577. " interpret.virtualmod = M2;\n"
  578. " SetGroup.group = 2;\n"
  579. "\n"
  580. " interpret a {\n"
  581. " virtualmod = M4;\n"
  582. " action=SetGroup(group=1);\n"
  583. " };\n"
  584. " interpret A {\n"
  585. " repeat = False;\n"
  586. " virtualmod = M1;\n"
  587. " action=SetMods(mods=M1);\n"
  588. " };\n"
  589. " interpret s {\n"
  590. " repeat = False;\n"
  591. " action=SetGroup(group=2);\n"
  592. " useModMapMods=level1;\n"
  593. " };\n"
  594. " interpret S {\n"
  595. " action=SetGroup(group=4);\n"
  596. " };\n"
  597. "\n"
  598. " indicator.modifiers = M2;\n"
  599. " indicator.groups = All - 1;\n"
  600. " indicator.controls = AudibleBell;\n"
  601. "\n"
  602. " indicator \"A\" {\n"
  603. " modifiers = M4;\n"
  604. " whichmodstate = locked;\n"
  605. " whichgroupstate = locked;\n"
  606. " controls = SlowKeys;\n"
  607. " };\n"
  608. " indicator \"B\" {\n"
  609. " modifiers = M4;\n"
  610. " whichmodstate = base;\n"
  611. " whichgroupstate = locked;\n"
  612. " };\n"
  613. " };\n"
  614. " xkb_symbols {\n"
  615. " name[1] = \"yyy\";\n"
  616. "\n"
  617. " key <A> { [a, A] };\n"
  618. " key <S> { [s, S] };\n"
  619. " modifier_map Shift { <A> };\n"
  620. " modifier_map Control { <S> };\n"
  621. "\n"
  622. " key <D> { vmods = M4, repeat = false, [d, D] };\n"
  623. " key <F> { vmods = M4, repeat = true , [f, F] };\n"
  624. " key <G> { vmods = M3, [g] };\n"
  625. " };\n"
  626. "};\n"
  627. }
  628. };
  629. for (unsigned int k = 0; k < ARRAY_SIZE(tests); k++) {
  630. const struct keymap_test_data* const test = &tests[k];
  631. char title[1024] = { 0 };
  632. snprintf(title, sizeof(title), "%s #%u: %s", __func__, k, test->title);
  633. char path[PATH_MAX] = { 0 };
  634. snprintf(path, sizeof(path), GOLDEN_TESTS_OUTPUTS "defaults-%s{{ compiler.suffix }}.xkb",
  635. test->file);
  636. assert(test_compile(ctx, xkb_root, title,
  637. test->keymap, strlen(test->keymap),
  638. path, !!update));
  639. }
  640. }
  641. int
  642. main(int argc, char *argv[])
  643. {
  644. test_init();
  645. /* Check if we run the tests or just update their outputs */
  646. enum update_files update_output_files = NO_UPDATE;
  647. if (argc > 1) {
  648. if (streq(argv[1], "update")) {
  649. /* Update files with *expected* results */
  650. update_output_files = UPDATE_USING_TEST_INPUT;
  651. } else if (streq(argv[1], "update-obtained")) {
  652. /* Update files with *obtained* results */
  653. update_output_files = UPDATE_USING_TEST_OUTPUT;
  654. } else {
  655. fprintf(stderr, "ERROR: unsupported argument: \"%s\".\n", argv[1]);
  656. exit(EXIT_FAILURE);
  657. }
  658. }
  659. struct xkb_context *ctx = test_get_context(CONTEXT_NO_FLAG);
  660. assert(ctx);
  661. char* xkb_root = test_get_path("");
  662. assert(xkb_root);
  663. {% if compiler.extended_syntax %}
  664. test_vmods(ctx, xkb_root, update_output_files);
  665. {% endif %}
  666. test_compat(ctx, xkb_root, update_output_files);
  667. test_merge_modes(ctx, xkb_root, update_output_files);
  668. test_defaults(ctx, xkb_root, update_output_files);
  669. free(xkb_root);
  670. xkb_context_unref(ctx);
  671. return EXIT_SUCCESS;
  672. }