diff options
Diffstat (limited to 'test/compose.c')
-rw-r--r-- | test/compose.c | 535 |
1 files changed, 535 insertions, 0 deletions
diff --git a/test/compose.c b/test/compose.c new file mode 100644 index 0000000..5ba5751 --- /dev/null +++ b/test/compose.c @@ -0,0 +1,535 @@ +/* + * Copyright © 2014 Ran Benita <ran234@gmail.com> + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include "config.h" + +#include "xkbcommon/xkbcommon-compose.h" + +#include "test.h" + +static const char * +compose_status_string(enum xkb_compose_status status) +{ + switch (status) { + case XKB_COMPOSE_NOTHING: + return "nothing"; + case XKB_COMPOSE_COMPOSING: + return "composing"; + case XKB_COMPOSE_COMPOSED: + return "composed"; + case XKB_COMPOSE_CANCELLED: + return "cancelled"; + } + + return "<invalid-status>"; +} + +static const char * +feed_result_string(enum xkb_compose_feed_result result) +{ + switch (result) { + case XKB_COMPOSE_FEED_IGNORED: + return "ignored"; + case XKB_COMPOSE_FEED_ACCEPTED: + return "accepted"; + } + + return "<invalid-result>"; +} + +/* + * Feed a sequence of keysyms to a fresh compose state and test the outcome. + * + * The varargs consists of lines in the following format: + * <input keysym> <expected feed result> <expected status> <expected string> <expected keysym> + * Terminated by a line consisting only of XKB_KEY_NoSymbol. + */ +static bool +test_compose_seq_va(struct xkb_compose_table *table, va_list ap) +{ + int ret; + struct xkb_compose_state *state; + char buffer[64]; + + state = xkb_compose_state_new(table, XKB_COMPOSE_STATE_NO_FLAGS); + assert(state); + + for (int i = 1; ; i++) { + xkb_keysym_t input_keysym; + enum xkb_compose_feed_result result, expected_result; + enum xkb_compose_status status, expected_status; + const char *expected_string; + xkb_keysym_t keysym, expected_keysym; + + input_keysym = va_arg(ap, xkb_keysym_t); + if (input_keysym == XKB_KEY_NoSymbol) + break; + + expected_result = va_arg(ap, enum xkb_compose_feed_result); + expected_status = va_arg(ap, enum xkb_compose_status); + expected_string = va_arg(ap, const char *); + expected_keysym = va_arg(ap, xkb_keysym_t); + + result = xkb_compose_state_feed(state, input_keysym); + + if (result != expected_result) { + fprintf(stderr, "after feeding %d keysyms:\n", i); + fprintf(stderr, "expected feed result: %s\n", + feed_result_string(expected_result)); + fprintf(stderr, "got feed result: %s\n", + feed_result_string(result)); + goto fail; + } + + status = xkb_compose_state_get_status(state); + if (status != expected_status) { + fprintf(stderr, "after feeding %d keysyms:\n", i); + fprintf(stderr, "expected status: %s\n", + compose_status_string(expected_status)); + fprintf(stderr, "got status: %s\n", + compose_status_string(status)); + goto fail; + } + + ret = xkb_compose_state_get_utf8(state, buffer, sizeof(buffer)); + if (ret < 0 || (size_t) ret >= sizeof(buffer)) { + fprintf(stderr, "after feeding %d keysyms:\n", i); + fprintf(stderr, "expected string: %s\n", expected_string); + fprintf(stderr, "got error: %d\n", ret); + goto fail; + } + if (!streq(buffer, expected_string)) { + fprintf(stderr, "after feeding %d keysyms:\n", i); + fprintf(stderr, "expected string: %s\n", strempty(expected_string)); + fprintf(stderr, "got string: %s\n", buffer); + goto fail; + } + + keysym = xkb_compose_state_get_one_sym(state); + if (keysym != expected_keysym) { + fprintf(stderr, "after feeding %d keysyms:\n", i); + xkb_keysym_get_name(expected_keysym, buffer, sizeof(buffer)); + fprintf(stderr, "expected keysym: %s\n", buffer); + xkb_keysym_get_name(keysym, buffer, sizeof(buffer)); + fprintf(stderr, "got keysym (%#x): %s\n", keysym, buffer); + goto fail; + } + } + + xkb_compose_state_unref(state); + return true; + +fail: + xkb_compose_state_unref(state); + return false; +} + +static bool +test_compose_seq(struct xkb_compose_table *table, ...) +{ + va_list ap; + bool ok; + va_start(ap, table); + ok = test_compose_seq_va(table, ap); + va_end(ap); + return ok; +} + +static bool +test_compose_seq_buffer(struct xkb_context *ctx, const char *buffer, ...) +{ + va_list ap; + bool ok; + struct xkb_compose_table *table; + table = xkb_compose_table_new_from_buffer(ctx, buffer, strlen(buffer), "", + XKB_COMPOSE_FORMAT_TEXT_V1, + XKB_COMPOSE_COMPILE_NO_FLAGS); + assert(table); + va_start(ap, buffer); + ok = test_compose_seq_va(table, ap); + va_end(ap); + xkb_compose_table_unref(table); + return ok; +} + +static void +test_seqs(struct xkb_context *ctx) +{ + struct xkb_compose_table *table; + char *path; + FILE *file; + + path = test_get_path("compose/en_US.UTF-8/Compose"); + file = fopen(path, "rb"); + assert(file); + free(path); + + table = xkb_compose_table_new_from_file(ctx, file, "", + XKB_COMPOSE_FORMAT_TEXT_V1, + XKB_COMPOSE_COMPILE_NO_FLAGS); + assert(table); + fclose(file); + + assert(test_compose_seq(table, + XKB_KEY_dead_tilde, XKB_COMPOSE_FEED_ACCEPTED, XKB_COMPOSE_COMPOSING, "", XKB_KEY_NoSymbol, + XKB_KEY_space, XKB_COMPOSE_FEED_ACCEPTED, XKB_COMPOSE_COMPOSED, "~", XKB_KEY_asciitilde, + XKB_KEY_NoSymbol)); + + assert(test_compose_seq(table, + XKB_KEY_dead_tilde, XKB_COMPOSE_FEED_ACCEPTED, XKB_COMPOSE_COMPOSING, "", XKB_KEY_NoSymbol, + XKB_KEY_space, XKB_COMPOSE_FEED_ACCEPTED, XKB_COMPOSE_COMPOSED, "~", XKB_KEY_asciitilde, + XKB_KEY_dead_tilde, XKB_COMPOSE_FEED_ACCEPTED, XKB_COMPOSE_COMPOSING, "", XKB_KEY_NoSymbol, + XKB_KEY_space, XKB_COMPOSE_FEED_ACCEPTED, XKB_COMPOSE_COMPOSED, "~", XKB_KEY_asciitilde, + XKB_KEY_NoSymbol)); + + assert(test_compose_seq(table, + XKB_KEY_dead_tilde, XKB_COMPOSE_FEED_ACCEPTED, XKB_COMPOSE_COMPOSING, "", XKB_KEY_NoSymbol, + XKB_KEY_dead_tilde, XKB_COMPOSE_FEED_ACCEPTED, XKB_COMPOSE_COMPOSED, "~", XKB_KEY_asciitilde, + XKB_KEY_NoSymbol)); + + assert(test_compose_seq(table, + XKB_KEY_dead_acute, XKB_COMPOSE_FEED_ACCEPTED, XKB_COMPOSE_COMPOSING, "", XKB_KEY_NoSymbol, + XKB_KEY_space, XKB_COMPOSE_FEED_ACCEPTED, XKB_COMPOSE_COMPOSED, "'", XKB_KEY_apostrophe, + XKB_KEY_Caps_Lock, XKB_COMPOSE_FEED_IGNORED, XKB_COMPOSE_COMPOSED, "'", XKB_KEY_apostrophe, + XKB_KEY_NoSymbol)); + + assert(test_compose_seq(table, + XKB_KEY_dead_acute, XKB_COMPOSE_FEED_ACCEPTED, XKB_COMPOSE_COMPOSING, "", XKB_KEY_NoSymbol, + XKB_KEY_dead_acute, XKB_COMPOSE_FEED_ACCEPTED, XKB_COMPOSE_COMPOSED, "´", XKB_KEY_acute, + XKB_KEY_NoSymbol)); + + assert(test_compose_seq(table, + XKB_KEY_Multi_key, XKB_COMPOSE_FEED_ACCEPTED, XKB_COMPOSE_COMPOSING, "", XKB_KEY_NoSymbol, + XKB_KEY_Shift_L, XKB_COMPOSE_FEED_IGNORED, XKB_COMPOSE_COMPOSING, "", XKB_KEY_NoSymbol, + XKB_KEY_A, XKB_COMPOSE_FEED_ACCEPTED, XKB_COMPOSE_COMPOSING, "", XKB_KEY_NoSymbol, + XKB_KEY_Caps_Lock, XKB_COMPOSE_FEED_IGNORED, XKB_COMPOSE_COMPOSING, "", XKB_KEY_NoSymbol, + XKB_KEY_Control_L, XKB_COMPOSE_FEED_IGNORED, XKB_COMPOSE_COMPOSING, "", XKB_KEY_NoSymbol, + XKB_KEY_T, XKB_COMPOSE_FEED_ACCEPTED, XKB_COMPOSE_COMPOSED, "@", XKB_KEY_at, + XKB_KEY_NoSymbol)); + + assert(test_compose_seq(table, + XKB_KEY_7, XKB_COMPOSE_FEED_ACCEPTED, XKB_COMPOSE_NOTHING, "", XKB_KEY_NoSymbol, + XKB_KEY_a, XKB_COMPOSE_FEED_ACCEPTED, XKB_COMPOSE_NOTHING, "", XKB_KEY_NoSymbol, + XKB_KEY_b, XKB_COMPOSE_FEED_ACCEPTED, XKB_COMPOSE_NOTHING, "", XKB_KEY_NoSymbol, + XKB_KEY_NoSymbol)); + + assert(test_compose_seq(table, + XKB_KEY_Multi_key, XKB_COMPOSE_FEED_ACCEPTED, XKB_COMPOSE_COMPOSING, "", XKB_KEY_NoSymbol, + XKB_KEY_apostrophe, XKB_COMPOSE_FEED_ACCEPTED, XKB_COMPOSE_COMPOSING, "", XKB_KEY_NoSymbol, + XKB_KEY_7, XKB_COMPOSE_FEED_ACCEPTED, XKB_COMPOSE_CANCELLED, "", XKB_KEY_NoSymbol, + XKB_KEY_7, XKB_COMPOSE_FEED_ACCEPTED, XKB_COMPOSE_NOTHING, "", XKB_KEY_NoSymbol, + XKB_KEY_Caps_Lock, XKB_COMPOSE_FEED_IGNORED, XKB_COMPOSE_NOTHING, "", XKB_KEY_NoSymbol, + XKB_KEY_NoSymbol)); + + xkb_compose_table_unref(table); + + /* Make sure one-keysym sequences work. */ + assert(test_compose_seq_buffer(ctx, + "<A> : \"foo\" X \n" + "<B> <A> : \"baz\" Y \n", + XKB_KEY_A, XKB_COMPOSE_FEED_ACCEPTED, XKB_COMPOSE_COMPOSED, "foo", XKB_KEY_X, + XKB_KEY_A, XKB_COMPOSE_FEED_ACCEPTED, XKB_COMPOSE_COMPOSED, "foo", XKB_KEY_X, + XKB_KEY_C, XKB_COMPOSE_FEED_ACCEPTED, XKB_COMPOSE_NOTHING, "", XKB_KEY_NoSymbol, + XKB_KEY_B, XKB_COMPOSE_FEED_ACCEPTED, XKB_COMPOSE_COMPOSING, "", XKB_KEY_NoSymbol, + XKB_KEY_A, XKB_COMPOSE_FEED_ACCEPTED, XKB_COMPOSE_COMPOSED, "baz", XKB_KEY_Y, + XKB_KEY_NoSymbol)); + + /* No sequences at all. */ + assert(test_compose_seq_buffer(ctx, + "", + XKB_KEY_A, XKB_COMPOSE_FEED_ACCEPTED, XKB_COMPOSE_NOTHING, "", XKB_KEY_NoSymbol, + XKB_KEY_B, XKB_COMPOSE_FEED_ACCEPTED, XKB_COMPOSE_NOTHING, "", XKB_KEY_NoSymbol, + XKB_KEY_C, XKB_COMPOSE_FEED_ACCEPTED, XKB_COMPOSE_NOTHING, "", XKB_KEY_NoSymbol, + XKB_KEY_Multi_key, XKB_COMPOSE_FEED_ACCEPTED, XKB_COMPOSE_NOTHING, "", XKB_KEY_NoSymbol, + XKB_KEY_dead_acute, XKB_COMPOSE_FEED_ACCEPTED, XKB_COMPOSE_NOTHING, "", XKB_KEY_NoSymbol, + XKB_KEY_NoSymbol)); + + /* Only keysym - string derived from keysym. */ + assert(test_compose_seq_buffer(ctx, + "<A> <B> : X \n" + "<B> <A> : dollar \n" + "<C> : dead_acute \n", + XKB_KEY_A, XKB_COMPOSE_FEED_ACCEPTED, XKB_COMPOSE_COMPOSING, "", XKB_KEY_NoSymbol, + XKB_KEY_B, XKB_COMPOSE_FEED_ACCEPTED, XKB_COMPOSE_COMPOSED, "X", XKB_KEY_X, + XKB_KEY_B, XKB_COMPOSE_FEED_ACCEPTED, XKB_COMPOSE_COMPOSING, "", XKB_KEY_NoSymbol, + XKB_KEY_A, XKB_COMPOSE_FEED_ACCEPTED, XKB_COMPOSE_COMPOSED, "$", XKB_KEY_dollar, + XKB_KEY_C, XKB_COMPOSE_FEED_ACCEPTED, XKB_COMPOSE_COMPOSED, "", XKB_KEY_dead_acute, + XKB_KEY_NoSymbol)); + + /* Make sure a cancelling keysym doesn't start a new sequence. */ + assert(test_compose_seq_buffer(ctx, + "<A> <B> : X \n" + "<C> <D> : Y \n", + XKB_KEY_A, XKB_COMPOSE_FEED_ACCEPTED, XKB_COMPOSE_COMPOSING, "", XKB_KEY_NoSymbol, + XKB_KEY_C, XKB_COMPOSE_FEED_ACCEPTED, XKB_COMPOSE_CANCELLED, "", XKB_KEY_NoSymbol, + XKB_KEY_D, XKB_COMPOSE_FEED_ACCEPTED, XKB_COMPOSE_NOTHING, "", XKB_KEY_NoSymbol, + XKB_KEY_A, XKB_COMPOSE_FEED_ACCEPTED, XKB_COMPOSE_COMPOSING, "", XKB_KEY_NoSymbol, + XKB_KEY_C, XKB_COMPOSE_FEED_ACCEPTED, XKB_COMPOSE_CANCELLED, "", XKB_KEY_NoSymbol, + XKB_KEY_C, XKB_COMPOSE_FEED_ACCEPTED, XKB_COMPOSE_COMPOSING, "", XKB_KEY_NoSymbol, + XKB_KEY_D, XKB_COMPOSE_FEED_ACCEPTED, XKB_COMPOSE_COMPOSED, "Y", XKB_KEY_Y, + XKB_KEY_NoSymbol)); +} + +static void +test_conflicting(struct xkb_context *ctx) +{ + // new is prefix of old + assert(test_compose_seq_buffer(ctx, + "<A> <B> <C> : \"foo\" A \n" + "<A> <B> : \"bar\" B \n", + XKB_KEY_A, XKB_COMPOSE_FEED_ACCEPTED, XKB_COMPOSE_COMPOSING, "", XKB_KEY_NoSymbol, + XKB_KEY_B, XKB_COMPOSE_FEED_ACCEPTED, XKB_COMPOSE_COMPOSING, "", XKB_KEY_NoSymbol, + XKB_KEY_C, XKB_COMPOSE_FEED_ACCEPTED, XKB_COMPOSE_COMPOSED, "foo", XKB_KEY_A, + XKB_KEY_NoSymbol)); + + // old is a prefix of new + assert(test_compose_seq_buffer(ctx, + "<A> <B> : \"bar\" B \n" + "<A> <B> <C> : \"foo\" A \n", + XKB_KEY_A, XKB_COMPOSE_FEED_ACCEPTED, XKB_COMPOSE_COMPOSING, "", XKB_KEY_NoSymbol, + XKB_KEY_B, XKB_COMPOSE_FEED_ACCEPTED, XKB_COMPOSE_COMPOSING, "", XKB_KEY_NoSymbol, + XKB_KEY_C, XKB_COMPOSE_FEED_ACCEPTED, XKB_COMPOSE_COMPOSED, "foo", XKB_KEY_A, + XKB_KEY_NoSymbol)); + + // new duplicate of old + assert(test_compose_seq_buffer(ctx, + "<A> <B> : \"bar\" B \n" + "<A> <B> : \"bar\" B \n", + XKB_KEY_A, XKB_COMPOSE_FEED_ACCEPTED, XKB_COMPOSE_COMPOSING, "", XKB_KEY_NoSymbol, + XKB_KEY_B, XKB_COMPOSE_FEED_ACCEPTED, XKB_COMPOSE_COMPOSED, "bar", XKB_KEY_B, + XKB_KEY_C, XKB_COMPOSE_FEED_ACCEPTED, XKB_COMPOSE_NOTHING, "", XKB_KEY_NoSymbol, + XKB_KEY_NoSymbol)); + + // new same length as old #1 + assert(test_compose_seq_buffer(ctx, + "<A> <B> : \"foo\" A \n" + "<A> <B> : \"bar\" B \n", + XKB_KEY_A, XKB_COMPOSE_FEED_ACCEPTED, XKB_COMPOSE_COMPOSING, "", XKB_KEY_NoSymbol, + XKB_KEY_B, XKB_COMPOSE_FEED_ACCEPTED, XKB_COMPOSE_COMPOSED, "bar", XKB_KEY_B, + XKB_KEY_NoSymbol)); + + // new same length as old #2 + assert(test_compose_seq_buffer(ctx, + "<A> <B> : \"foo\" A \n" + "<A> <B> : \"foo\" B \n", + XKB_KEY_A, XKB_COMPOSE_FEED_ACCEPTED, XKB_COMPOSE_COMPOSING, "", XKB_KEY_NoSymbol, + XKB_KEY_B, XKB_COMPOSE_FEED_ACCEPTED, XKB_COMPOSE_COMPOSED, "foo", XKB_KEY_B, + XKB_KEY_NoSymbol)); + + // new same length as old #3 + assert(test_compose_seq_buffer(ctx, + "<A> <B> : \"foo\" A \n" + "<A> <B> : \"bar\" A \n", + XKB_KEY_A, XKB_COMPOSE_FEED_ACCEPTED, XKB_COMPOSE_COMPOSING, "", XKB_KEY_NoSymbol, + XKB_KEY_B, XKB_COMPOSE_FEED_ACCEPTED, XKB_COMPOSE_COMPOSED, "bar", XKB_KEY_A, + XKB_KEY_NoSymbol)); +} + +static void +test_state(struct xkb_context *ctx) +{ + struct xkb_compose_table *table; + struct xkb_compose_state *state; + char *path; + FILE *file; + + path = test_get_path("compose/en_US.UTF-8/Compose"); + file = fopen(path, "rb"); + assert(file); + free(path); + + table = xkb_compose_table_new_from_file(ctx, file, "", + XKB_COMPOSE_FORMAT_TEXT_V1, + XKB_COMPOSE_COMPILE_NO_FLAGS); + assert(table); + fclose(file); + + state = xkb_compose_state_new(table, XKB_COMPOSE_STATE_NO_FLAGS); + assert(state); + + assert(xkb_compose_state_get_status(state) == XKB_COMPOSE_NOTHING); + xkb_compose_state_reset(state); + assert(xkb_compose_state_get_status(state) == XKB_COMPOSE_NOTHING); + xkb_compose_state_feed(state, XKB_KEY_NoSymbol); + assert(xkb_compose_state_get_status(state) == XKB_COMPOSE_NOTHING); + xkb_compose_state_feed(state, XKB_KEY_Multi_key); + assert(xkb_compose_state_get_status(state) == XKB_COMPOSE_COMPOSING); + xkb_compose_state_reset(state); + assert(xkb_compose_state_get_status(state) == XKB_COMPOSE_NOTHING); + xkb_compose_state_feed(state, XKB_KEY_Multi_key); + assert(xkb_compose_state_get_status(state) == XKB_COMPOSE_COMPOSING); + xkb_compose_state_feed(state, XKB_KEY_Multi_key); + assert(xkb_compose_state_get_status(state) == XKB_COMPOSE_CANCELLED); + xkb_compose_state_feed(state, XKB_KEY_Multi_key); + assert(xkb_compose_state_get_status(state) == XKB_COMPOSE_COMPOSING); + xkb_compose_state_feed(state, XKB_KEY_Multi_key); + assert(xkb_compose_state_get_status(state) == XKB_COMPOSE_CANCELLED); + xkb_compose_state_reset(state); + assert(xkb_compose_state_get_status(state) == XKB_COMPOSE_NOTHING); + xkb_compose_state_feed(state, XKB_KEY_dead_acute); + assert(xkb_compose_state_get_status(state) == XKB_COMPOSE_COMPOSING); + xkb_compose_state_feed(state, XKB_KEY_A); + assert(xkb_compose_state_get_status(state) == XKB_COMPOSE_COMPOSED); + xkb_compose_state_reset(state); + assert(xkb_compose_state_get_status(state) == XKB_COMPOSE_NOTHING); + xkb_compose_state_feed(state, XKB_KEY_dead_acute); + assert(xkb_compose_state_get_status(state) == XKB_COMPOSE_COMPOSING); + xkb_compose_state_feed(state, XKB_KEY_A); + assert(xkb_compose_state_get_status(state) == XKB_COMPOSE_COMPOSED); + xkb_compose_state_reset(state); + xkb_compose_state_feed(state, XKB_KEY_NoSymbol); + assert(xkb_compose_state_get_status(state) == XKB_COMPOSE_NOTHING); + + xkb_compose_state_unref(state); + xkb_compose_table_unref(table); +} + +static void +test_XCOMPOSEFILE(struct xkb_context *ctx) +{ + struct xkb_compose_table *table; + char *path; + + path = test_get_path("compose/en_US.UTF-8/Compose"); + setenv("XCOMPOSEFILE", path, 1); + free(path); + + table = xkb_compose_table_new_from_locale(ctx, "blabla", + XKB_COMPOSE_COMPILE_NO_FLAGS); + assert(table); + + assert(test_compose_seq(table, + XKB_KEY_dead_tilde, XKB_COMPOSE_FEED_ACCEPTED, XKB_COMPOSE_COMPOSING, "", XKB_KEY_NoSymbol, + XKB_KEY_space, XKB_COMPOSE_FEED_ACCEPTED, XKB_COMPOSE_COMPOSED, "~", XKB_KEY_asciitilde, + XKB_KEY_NoSymbol)); + + xkb_compose_table_unref(table); +} + +static void +test_modifier_syntax(struct xkb_context *ctx) +{ + const char *table_string; + + /* We don't do anything with the modifiers, but make sure we can parse + * them. */ + + assert(test_compose_seq_buffer(ctx, + "None <A> : X \n" + "Shift <B> : Y \n" + "Ctrl <C> : Y \n" + "Alt <D> : Y \n" + "Caps <E> : Y \n" + "Lock <F> : Y \n" + "Shift Ctrl <G> : Y \n" + "~Shift <H> : Y \n" + "~Shift Ctrl <I> : Y \n" + "Shift ~Ctrl <J> : Y \n" + "Shift ~Ctrl ~Alt <K> : Y \n" + "! Shift <B> : Y \n" + "! Ctrl <C> : Y \n" + "! Alt <D> : Y \n" + "! Caps <E> : Y \n" + "! Lock <F> : Y \n" + "! Shift Ctrl <G> : Y \n" + "! ~Shift <H> : Y \n" + "! ~Shift Ctrl <I> : Y \n" + "! Shift ~Ctrl <J> : Y \n" + "! Shift ~Ctrl ~Alt <K> : Y \n" + "<L> ! Shift <M> : Y \n" + "None <N> ! Shift <O> : Y \n" + "None <P> ! Shift <Q> : Y \n", + XKB_KEY_NoSymbol)); + + fprintf(stderr, "<START bad input string>\n"); + table_string = + "! None <A> : X \n" + "! Foo <B> : X \n" + "None ! Shift <C> : X \n" + "! ! <D> : X \n" + "! ~ <E> : X \n" + "! ! <F> : X \n" + "! Ctrl ! Ctrl <G> : X \n" + "<H> ! : X \n" + "<I> None : X \n" + "None None <J> : X \n" + "<K> : !Shift X \n"; + assert(!xkb_compose_table_new_from_buffer(ctx, table_string, + strlen(table_string), "C", + XKB_COMPOSE_FORMAT_TEXT_V1, + XKB_COMPOSE_COMPILE_NO_FLAGS)); + fprintf(stderr, "<END bad input string>\n"); +} + +static void +test_include(struct xkb_context *ctx) +{ + char *path, *table_string; + + path = test_get_path("compose/en_US.UTF-8/Compose"); + assert(path); + + /* We don't have a mechanism to change the include paths like we + * have for keymaps. So we must include the full path. */ + table_string = asprintf_safe("<dead_tilde> <space> : \"foo\" X\n" + "include \"%s\"\n" + "<dead_tilde> <dead_tilde> : \"bar\" Y\n", path); + assert(table_string); + + assert(test_compose_seq_buffer(ctx, table_string, + /* No conflict. */ + XKB_KEY_dead_acute, XKB_COMPOSE_FEED_ACCEPTED, XKB_COMPOSE_COMPOSING, "", XKB_KEY_NoSymbol, + XKB_KEY_dead_acute, XKB_COMPOSE_FEED_ACCEPTED, XKB_COMPOSE_COMPOSED, "´", XKB_KEY_acute, + + /* Comes before - doesn't override. */ + XKB_KEY_dead_tilde, XKB_COMPOSE_FEED_ACCEPTED, XKB_COMPOSE_COMPOSING, "", XKB_KEY_NoSymbol, + XKB_KEY_space, XKB_COMPOSE_FEED_ACCEPTED, XKB_COMPOSE_COMPOSED, "~", XKB_KEY_asciitilde, + + /* Comes after - does override. */ + XKB_KEY_dead_tilde, XKB_COMPOSE_FEED_ACCEPTED, XKB_COMPOSE_COMPOSING, "", XKB_KEY_NoSymbol, + XKB_KEY_dead_tilde, XKB_COMPOSE_FEED_ACCEPTED, XKB_COMPOSE_COMPOSED, "bar", XKB_KEY_Y, + + XKB_KEY_NoSymbol)); + + free(path); + free(table_string); +} + +int +main(int argc, char *argv[]) +{ + struct xkb_context *ctx; + + ctx = test_get_context(CONTEXT_NO_FLAG); + assert(ctx); + + test_seqs(ctx); + test_conflicting(ctx); + test_XCOMPOSEFILE(ctx); + test_state(ctx); + test_modifier_syntax(ctx); + test_include(ctx); + + xkb_context_unref(ctx); + return 0; +} |