diff options
Diffstat (limited to 'src/3rdparty/xkbcommon/src/compose')
-rw-r--r-- | src/3rdparty/xkbcommon/src/compose/compose-state.c | 196 | ||||
-rw-r--r-- | src/3rdparty/xkbcommon/src/compose/parser.c | 737 | ||||
-rw-r--r-- | src/3rdparty/xkbcommon/src/compose/parser.h | 36 | ||||
-rw-r--r-- | src/3rdparty/xkbcommon/src/compose/paths.c | 203 | ||||
-rw-r--r-- | src/3rdparty/xkbcommon/src/compose/paths.h | 42 | ||||
-rw-r--r-- | src/3rdparty/xkbcommon/src/compose/table.c | 219 | ||||
-rw-r--r-- | src/3rdparty/xkbcommon/src/compose/table.h | 100 |
7 files changed, 0 insertions, 1533 deletions
diff --git a/src/3rdparty/xkbcommon/src/compose/compose-state.c b/src/3rdparty/xkbcommon/src/compose/compose-state.c deleted file mode 100644 index 8657ff7e17..0000000000 --- a/src/3rdparty/xkbcommon/src/compose/compose-state.c +++ /dev/null @@ -1,196 +0,0 @@ -/* - * Copyright © 2013 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 "table.h" -#include "utils.h" -#include "keysym.h" - -struct xkb_compose_state { - int refcnt; - enum xkb_compose_state_flags flags; - struct xkb_compose_table *table; - - /* - * Offsets into xkb_compose_table::nodes. - * - * They maintain the current and previous position in the trie; see - * xkb_compose_state_feed(). - * - * This is also sufficient for inferring the current status; see - * xkb_compose_state_get_status(). - */ - uint32_t prev_context; - uint32_t context; -}; - -XKB_EXPORT struct xkb_compose_state * -xkb_compose_state_new(struct xkb_compose_table *table, - enum xkb_compose_state_flags flags) -{ - struct xkb_compose_state *state; - - state = calloc(1, sizeof(*state)); - if (!state) - return NULL; - - state->refcnt = 1; - state->table = xkb_compose_table_ref(table); - - state->flags = flags; - state->prev_context = 0; - state->context = 0; - - return state; -} - -XKB_EXPORT struct xkb_compose_state * -xkb_compose_state_ref(struct xkb_compose_state *state) -{ - state->refcnt++; - return state; -} - -XKB_EXPORT void -xkb_compose_state_unref(struct xkb_compose_state *state) -{ - if (!state || --state->refcnt > 0) - return; - - xkb_compose_table_unref(state->table); - free(state); -} - -XKB_EXPORT struct xkb_compose_table * -xkb_compose_state_get_compose_table(struct xkb_compose_state *state) -{ - return state->table; -} - -XKB_EXPORT enum xkb_compose_feed_result -xkb_compose_state_feed(struct xkb_compose_state *state, xkb_keysym_t keysym) -{ - uint32_t context; - const struct compose_node *node; - - /* - * Modifiers do not affect the sequence directly. In particular, - * they do not cancel a sequence; otherwise it'd be impossible to - * have a sequence like <dead_acute><A> (needs Shift in the middle). - * - * The following test is not really accurate - in order to test if - * a key is "modifier key", we really need the keymap, but we don't - * have it here. However, this is (approximately) what libX11 does - * as well. - */ - if (xkb_keysym_is_modifier(keysym)) - return XKB_COMPOSE_FEED_IGNORED; - - node = &darray_item(state->table->nodes, state->context); - - context = (node->is_leaf ? 0 : node->u.successor); - node = &darray_item(state->table->nodes, context); - - while (node->keysym != keysym && node->next != 0) { - context = node->next; - node = &darray_item(state->table->nodes, context); - } - - if (node->keysym != keysym) - context = 0; - - state->prev_context = state->context; - state->context = context; - return XKB_COMPOSE_FEED_ACCEPTED; -} - -XKB_EXPORT void -xkb_compose_state_reset(struct xkb_compose_state *state) -{ - state->prev_context = 0; - state->context = 0; -} - -XKB_EXPORT enum xkb_compose_status -xkb_compose_state_get_status(struct xkb_compose_state *state) -{ - const struct compose_node *prev_node, *node; - - prev_node = &darray_item(state->table->nodes, state->prev_context); - node = &darray_item(state->table->nodes, state->context); - - if (state->context == 0 && !prev_node->is_leaf) - return XKB_COMPOSE_CANCELLED; - - if (state->context == 0) - return XKB_COMPOSE_NOTHING; - - if (!node->is_leaf) - return XKB_COMPOSE_COMPOSING; - - return XKB_COMPOSE_COMPOSED; -} - -XKB_EXPORT int -xkb_compose_state_get_utf8(struct xkb_compose_state *state, - char *buffer, size_t size) -{ - const struct compose_node *node = - &darray_item(state->table->nodes, state->context); - - if (!node->is_leaf) - goto fail; - - /* If there's no string specified, but only a keysym, try to do the - * most helpful thing. */ - if (node->u.leaf.utf8 == 0 && node->u.leaf.keysym != XKB_KEY_NoSymbol) { - char name[64]; - int ret; - - ret = xkb_keysym_to_utf8(node->u.leaf.keysym, name, sizeof(name)); - if (ret < 0 || ret == 0) { - /* ret < 0 is impossible. - * ret == 0 means the keysym has no string representation. */ - goto fail; - } - - return snprintf(buffer, size, "%s", name); - } - - return snprintf(buffer, size, "%s", - &darray_item(state->table->utf8, node->u.leaf.utf8)); - -fail: - if (size > 0) - buffer[0] = '\0'; - return 0; -} - -XKB_EXPORT xkb_keysym_t -xkb_compose_state_get_one_sym(struct xkb_compose_state *state) -{ - const struct compose_node *node = - &darray_item(state->table->nodes, state->context); - if (!node->is_leaf) - return XKB_KEY_NoSymbol; - return node->u.leaf.keysym; -} diff --git a/src/3rdparty/xkbcommon/src/compose/parser.c b/src/3rdparty/xkbcommon/src/compose/parser.c deleted file mode 100644 index 439d404f06..0000000000 --- a/src/3rdparty/xkbcommon/src/compose/parser.c +++ /dev/null @@ -1,737 +0,0 @@ -/* - * Copyright © 2013 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. - */ - -/****************************************************************** - - Copyright 1992 by Oki Technosystems Laboratory, Inc. - Copyright 1992 by Fuji Xerox Co., Ltd. - -Permission to use, copy, modify, distribute, and sell this software -and its documentation for any purpose is hereby granted without fee, -provided that the above copyright notice appear in all copies and -that both that copyright notice and this permission notice appear -in supporting documentation, and that the name of Oki Technosystems -Laboratory and Fuji Xerox not be used in advertising or publicity -pertaining to distribution of the software without specific, written -prior permission. -Oki Technosystems Laboratory and Fuji Xerox make no representations -about the suitability of this software for any purpose. It is provided -"as is" without express or implied warranty. - -OKI TECHNOSYSTEMS LABORATORY AND FUJI XEROX DISCLAIM ALL WARRANTIES -WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL OKI TECHNOSYSTEMS -LABORATORY AND FUJI XEROX BE LIABLE FOR ANY SPECIAL, INDIRECT OR -CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS -OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE -OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE -OR PERFORMANCE OF THIS SOFTWARE. - - Author: Yasuhiro Kawai Oki Technosystems Laboratory - Author: Kazunori Nishihara Fuji Xerox - -******************************************************************/ - -#include <errno.h> - -#include "utils.h" -#include "scanner-utils.h" -#include "table.h" -#include "paths.h" -#include "utf8.h" -#include "parser.h" - -#define MAX_LHS_LEN 10 -#define MAX_INCLUDE_DEPTH 5 - -/* - * Grammar adapted from libX11/modules/im/ximcp/imLcPrs.c. - * See also the XCompose(5) manpage. - * - * FILE ::= { [PRODUCTION] [COMMENT] "\n" | INCLUDE } - * INCLUDE ::= "include" '"' INCLUDE_STRING '"' - * PRODUCTION ::= LHS ":" RHS [ COMMENT ] - * COMMENT ::= "#" {<any character except null or newline>} - * LHS ::= EVENT { EVENT } - * EVENT ::= [MODIFIER_LIST] "<" keysym ">" - * MODIFIER_LIST ::= (["!"] {MODIFIER} ) | "None" - * MODIFIER ::= ["~"] MODIFIER_NAME - * MODIFIER_NAME ::= ("Ctrl"|"Lock"|"Caps"|"Shift"|"Alt"|"Meta") - * RHS ::= ( STRING | keysym | STRING keysym ) - * STRING ::= '"' { CHAR } '"' - * CHAR ::= GRAPHIC_CHAR | ESCAPED_CHAR - * GRAPHIC_CHAR ::= locale (codeset) dependent code - * ESCAPED_CHAR ::= ('\\' | '\"' | OCTAL | HEX ) - * OCTAL ::= '\' OCTAL_CHAR [OCTAL_CHAR [OCTAL_CHAR]] - * OCTAL_CHAR ::= (0|1|2|3|4|5|6|7) - * HEX ::= '\' (x|X) HEX_CHAR [HEX_CHAR]] - * HEX_CHAR ::= (0|1|2|3|4|5|6|7|8|9|A|B|C|D|E|F|a|b|c|d|e|f) - * - * INCLUDE_STRING is a filesystem path, with the following %-expansions: - * %% - '%'. - * %H - The user's home directory (the $HOME environment variable). - * %L - The name of the locale specific Compose file (e.g., - * "/usr/share/X11/locale/<localename>/Compose"). - * %S - The name of the system directory for Compose files (e.g., - * "/usr/share/X11/locale"). - */ - -enum rules_token { - TOK_END_OF_FILE = 0, - TOK_END_OF_LINE, - TOK_INCLUDE, - TOK_INCLUDE_STRING, - TOK_LHS_KEYSYM, - TOK_COLON, - TOK_BANG, - TOK_TILDE, - TOK_STRING, - TOK_IDENT, - TOK_ERROR -}; - -/* Values returned with some tokens, like yylval. */ -union lvalue { - struct { - /* Still \0-terminated. */ - const char *str; - size_t len; - } string; -}; - -static enum rules_token -lex(struct scanner *s, union lvalue *val) -{ -skip_more_whitespace_and_comments: - /* Skip spaces. */ - while (is_space(peek(s))) - if (next(s) == '\n') - return TOK_END_OF_LINE; - - /* Skip comments. */ - if (chr(s, '#')) { - skip_to_eol(s); - goto skip_more_whitespace_and_comments; - } - - /* See if we're done. */ - if (eof(s)) return TOK_END_OF_FILE; - - /* New token. */ - s->token_line = s->line; - s->token_column = s->column; - s->buf_pos = 0; - - /* LHS Keysym. */ - if (chr(s, '<')) { - while (peek(s) != '>' && !eol(s) && !eof(s)) - buf_append(s, next(s)); - if (!chr(s, '>')) { - scanner_err(s, "unterminated keysym literal"); - return TOK_ERROR; - } - if (!buf_append(s, '\0')) { - scanner_err(s, "keysym literal is too long"); - return TOK_ERROR; - } - val->string.str = s->buf; - val->string.len = s->buf_pos; - return TOK_LHS_KEYSYM; - } - - /* Colon. */ - if (chr(s, ':')) - return TOK_COLON; - if (chr(s, '!')) - return TOK_BANG; - if (chr(s, '~')) - return TOK_TILDE; - - /* String literal. */ - if (chr(s, '\"')) { - while (!eof(s) && !eol(s) && peek(s) != '\"') { - if (chr(s, '\\')) { - uint8_t o; - if (chr(s, '\\')) { - buf_append(s, '\\'); - } - else if (chr(s, '"')) { - buf_append(s, '"'); - } - else if (chr(s, 'x') || chr(s, 'X')) { - if (hex(s, &o)) - buf_append(s, (char) o); - else - scanner_warn(s, "illegal hexadecimal escape sequence in string literal"); - } - else if (oct(s, &o)) { - buf_append(s, (char) o); - } - else { - scanner_warn(s, "unknown escape sequence (%c) in string literal", peek(s)); - /* Ignore. */ - } - } else { - buf_append(s, next(s)); - } - } - if (!chr(s, '\"')) { - scanner_err(s, "unterminated string literal"); - return TOK_ERROR; - } - if (!buf_append(s, '\0')) { - scanner_err(s, "string literal is too long"); - return TOK_ERROR; - } - if (!is_valid_utf8(s->buf, s->buf_pos - 1)) { - scanner_err(s, "string literal is not a valid UTF-8 string"); - return TOK_ERROR; - } - val->string.str = s->buf; - val->string.len = s->buf_pos; - return TOK_STRING; - } - - /* Identifier or include. */ - if (is_alpha(peek(s)) || peek(s) == '_') { - s->buf_pos = 0; - while (is_alnum(peek(s)) || peek(s) == '_') - buf_append(s, next(s)); - if (!buf_append(s, '\0')) { - scanner_err(s, "identifier is too long"); - return TOK_ERROR; - } - - if (streq(s->buf, "include")) - return TOK_INCLUDE; - - val->string.str = s->buf; - val->string.len = s->buf_pos; - return TOK_IDENT; - } - - /* Discard rest of line. */ - skip_to_eol(s); - - scanner_err(s, "unrecognized token"); - return TOK_ERROR; -} - -static enum rules_token -lex_include_string(struct scanner *s, struct xkb_compose_table *table, - union lvalue *val_out) -{ - while (is_space(peek(s))) - if (next(s) == '\n') - return TOK_END_OF_LINE; - - s->token_line = s->line; - s->token_column = s->column; - s->buf_pos = 0; - - if (!chr(s, '\"')) { - scanner_err(s, "include statement must be followed by a path"); - return TOK_ERROR; - } - - while (!eof(s) && !eol(s) && peek(s) != '\"') { - if (chr(s, '%')) { - if (chr(s, '%')) { - buf_append(s, '%'); - } - else if (chr(s, 'H')) { - const char *home = secure_getenv("HOME"); - if (!home) { - scanner_err(s, "%%H was used in an include statement, but the HOME environment variable is not set"); - return TOK_ERROR; - } - if (!buf_appends(s, home)) { - scanner_err(s, "include path after expanding %%H is too long"); - return TOK_ERROR; - } - } - else if (chr(s, 'L')) { - char *path = get_locale_compose_file_path(table->locale); - if (!path) { - scanner_err(s, "failed to expand %%L to the locale Compose file"); - return TOK_ERROR; - } - if (!buf_appends(s, path)) { - free(path); - scanner_err(s, "include path after expanding %%L is too long"); - return TOK_ERROR; - } - free(path); - } - else if (chr(s, 'S')) { - const char *xlocaledir = get_xlocaledir_path(); - if (!buf_appends(s, xlocaledir)) { - scanner_err(s, "include path after expanding %%S is too long"); - return TOK_ERROR; - } - } - else { - scanner_err(s, "unknown %% format (%c) in include statement", peek(s)); - return TOK_ERROR; - } - } else { - buf_append(s, next(s)); - } - } - if (!chr(s, '\"')) { - scanner_err(s, "unterminated include statement"); - return TOK_ERROR; - } - if (!buf_append(s, '\0')) { - scanner_err(s, "include path is too long"); - return TOK_ERROR; - } - val_out->string.str = s->buf; - val_out->string.len = s->buf_pos; - return TOK_INCLUDE_STRING; -} - -struct production { - xkb_keysym_t lhs[MAX_LHS_LEN]; - unsigned int len; - xkb_keysym_t keysym; - char string[256]; - /* At least one of these is true. */ - bool has_keysym; - bool has_string; - - /* The matching is as follows: (active_mods & modmask) == mods. */ - xkb_mod_mask_t modmask; - xkb_mod_mask_t mods; -}; - -static uint32_t -add_node(struct xkb_compose_table *table, xkb_keysym_t keysym) -{ - struct compose_node new = { - .keysym = keysym, - .next = 0, - .is_leaf = true, - }; - darray_append(table->nodes, new); - return darray_size(table->nodes) - 1; -} - -static void -add_production(struct xkb_compose_table *table, struct scanner *s, - const struct production *production) -{ - unsigned lhs_pos; - uint32_t curr; - struct compose_node *node; - - curr = 0; - node = &darray_item(table->nodes, curr); - - /* - * Insert the sequence to the trie, creating new nodes as needed. - * - * TODO: This can be sped up a bit by first trying the path that the - * previous production took, and only then doing the linear search - * through the trie levels. This will work because sequences in the - * Compose files are often clustered by a common prefix; especially - * in the 1st and 2nd keysyms, which is where the largest variation - * (thus, longest search) is. - */ - for (lhs_pos = 0; lhs_pos < production->len; lhs_pos++) { - while (production->lhs[lhs_pos] != node->keysym) { - if (node->next == 0) { - uint32_t next = add_node(table, production->lhs[lhs_pos]); - /* Refetch since add_node could have realloc()ed. */ - node = &darray_item(table->nodes, curr); - node->next = next; - } - - curr = node->next; - node = &darray_item(table->nodes, curr); - } - - if (lhs_pos + 1 == production->len) - break; - - if (node->is_leaf) { - if (node->u.leaf.utf8 != 0 || - node->u.leaf.keysym != XKB_KEY_NoSymbol) { - scanner_warn(s, "a sequence already exists which is a prefix of this sequence; overriding"); - node->u.leaf.utf8 = 0; - node->u.leaf.keysym = XKB_KEY_NoSymbol; - } - - { - uint32_t successor = add_node(table, production->lhs[lhs_pos + 1]); - /* Refetch since add_node could have realloc()ed. */ - node = &darray_item(table->nodes, curr); - node->is_leaf = false; - node->u.successor = successor; - } - } - - curr = node->u.successor; - node = &darray_item(table->nodes, curr); - } - - if (!node->is_leaf) { - scanner_warn(s, "this compose sequence is a prefix of another; skipping line"); - return; - } - - if (node->u.leaf.utf8 != 0 || node->u.leaf.keysym != XKB_KEY_NoSymbol) { - bool same_string = - (node->u.leaf.utf8 == 0 && !production->has_string) || - ( - node->u.leaf.utf8 != 0 && production->has_string && - streq(&darray_item(table->utf8, node->u.leaf.utf8), - production->string) - ); - bool same_keysym = - (node->u.leaf.keysym == XKB_KEY_NoSymbol && !production->has_keysym) || - ( - node->u.leaf.keysym != XKB_KEY_NoSymbol && production->has_keysym && - node->u.leaf.keysym == production->keysym - ); - if (same_string && same_keysym) { - scanner_warn(s, "this compose sequence is a duplicate of another; skipping line"); - return; - } - scanner_warn(s, "this compose sequence already exists; overriding"); - } - - if (production->has_string) { - node->u.leaf.utf8 = darray_size(table->utf8); - darray_append_items(table->utf8, production->string, - strlen(production->string) + 1); - } - if (production->has_keysym) { - node->u.leaf.keysym = production->keysym; - } -} - -/* Should match resolve_modifier(). */ -#define ALL_MODS_MASK ((1 << 0) | (1 << 1) | (1 << 2) | (1 << 3)) - -static xkb_mod_index_t -resolve_modifier(const char *name) -{ - static const struct { - const char *name; - xkb_mod_index_t mod; - } mods[] = { - { "Shift", 0 }, - { "Ctrl", 2 }, - { "Alt", 3 }, - { "Meta", 3 }, - { "Lock", 1 }, - { "Caps", 1 }, - }; - - for (unsigned i = 0; i < ARRAY_SIZE(mods); i++) - if (streq(name, mods[i].name)) - return mods[i].mod; - - return XKB_MOD_INVALID; -} - -static bool -parse(struct xkb_compose_table *table, struct scanner *s, - unsigned include_depth); - -static bool -do_include(struct xkb_compose_table *table, struct scanner *s, - const char *path, unsigned include_depth) -{ - FILE *file; - bool ok; - char *string; - size_t size; - struct scanner new_s; - - if (include_depth >= MAX_INCLUDE_DEPTH) { - scanner_err(s, "maximum include depth (%d) exceeded; maybe there is an include loop?", - MAX_INCLUDE_DEPTH); - return false; - } - - file = fopen(path, "r"); - if (!file) { - scanner_err(s, "failed to open included Compose file \"%s\": %s", - path, strerror(errno)); - return false; - } - - ok = map_file(file, &string, &size); - if (!ok) { - scanner_err(s, "failed to read included Compose file \"%s\": %s", - path, strerror(errno)); - goto err_file; - } - - scanner_init(&new_s, table->ctx, string, size, path, s->priv); - - ok = parse(table, &new_s, include_depth + 1); - if (!ok) - goto err_unmap; - -err_unmap: - unmap_file(string, size); -err_file: - fclose(file); - return ok; -} - -static bool -parse(struct xkb_compose_table *table, struct scanner *s, - unsigned include_depth) -{ - enum rules_token tok; - union lvalue val; - xkb_keysym_t keysym; - struct production production; - enum { MAX_ERRORS = 10 }; - int num_errors = 0; - -initial: - production.len = 0; - production.has_keysym = false; - production.has_string = false; - production.mods = 0; - production.modmask = 0; - - /* fallthrough */ - -initial_eol: - switch (tok = lex(s, &val)) { - case TOK_END_OF_LINE: - goto initial_eol; - case TOK_END_OF_FILE: - goto finished; - case TOK_INCLUDE: - goto include; - default: - goto lhs_tok; - } - -include: - switch (tok = lex_include_string(s, table, &val)) { - case TOK_INCLUDE_STRING: - goto include_eol; - default: - goto unexpected; - } - -include_eol: - switch (tok = lex(s, &val)) { - case TOK_END_OF_LINE: - if (!do_include(table, s, val.string.str, include_depth)) - goto fail; - goto initial; - default: - goto unexpected; - } - -lhs: - tok = lex(s, &val); -lhs_tok: - switch (tok) { - case TOK_COLON: - if (production.len <= 0) { - scanner_warn(s, "expected at least one keysym on left-hand side; skipping line"); - goto skip; - } - goto rhs; - case TOK_IDENT: - if (streq(val.string.str, "None")) { - production.mods = 0; - production.modmask = ALL_MODS_MASK; - goto lhs_keysym; - } - goto lhs_mod_list_tok; - case TOK_TILDE: - goto lhs_mod_list_tok; - case TOK_BANG: - production.modmask = ALL_MODS_MASK; - goto lhs_mod_list; - default: - goto lhs_keysym_tok; - } - -lhs_keysym: - tok = lex(s, &val); -lhs_keysym_tok: - switch (tok) { - case TOK_LHS_KEYSYM: - keysym = xkb_keysym_from_name(val.string.str, XKB_KEYSYM_NO_FLAGS); - if (keysym == XKB_KEY_NoSymbol) { - scanner_err(s, "unrecognized keysym \"%s\" on left-hand side", - val.string.str); - goto error; - } - if (production.len + 1 > MAX_LHS_LEN) { - scanner_warn(s, "too many keysyms (%d) on left-hand side; skipping line", - MAX_LHS_LEN + 1); - goto skip; - } - production.lhs[production.len++] = keysym; - production.mods = 0; - production.modmask = 0; - goto lhs; - default: - goto unexpected; - } - -lhs_mod_list: - tok = lex(s, &val); -lhs_mod_list_tok: { - bool tilde = false; - xkb_mod_index_t mod; - - if (tok != TOK_TILDE && tok != TOK_IDENT) - goto lhs_keysym_tok; - - if (tok == TOK_TILDE) { - tilde = true; - tok = lex(s, &val); - } - - if (tok != TOK_IDENT) - goto unexpected; - - mod = resolve_modifier(val.string.str); - if (mod == XKB_MOD_INVALID) { - scanner_err(s, "unrecognized modifier \"%s\"", - val.string.str); - goto error; - } - - production.modmask |= 1 << mod; - if (tilde) - production.mods &= ~(1 << mod); - else - production.mods |= 1 << mod; - - goto lhs_mod_list; - } - -rhs: - switch (tok = lex(s, &val)) { - case TOK_STRING: - if (production.has_string) { - scanner_warn(s, "right-hand side can have at most one string; skipping line"); - goto skip; - } - if (val.string.len <= 0) { - scanner_warn(s, "right-hand side string must not be empty; skipping line"); - goto skip; - } - if (val.string.len >= sizeof(production.string)) { - scanner_warn(s, "right-hand side string is too long; skipping line"); - goto skip; - } - strcpy(production.string, val.string.str); - production.has_string = true; - goto rhs; - case TOK_IDENT: - keysym = xkb_keysym_from_name(val.string.str, XKB_KEYSYM_NO_FLAGS); - if (keysym == XKB_KEY_NoSymbol) { - scanner_err(s, "unrecognized keysym \"%s\" on right-hand side", - val.string.str); - goto error; - } - if (production.has_keysym) { - scanner_warn(s, "right-hand side can have at most one keysym; skipping line"); - goto skip; - } - production.keysym = keysym; - production.has_keysym = true; - /* fallthrough */ - case TOK_END_OF_LINE: - if (!production.has_string && !production.has_keysym) { - scanner_warn(s, "right-hand side must have at least one of string or keysym; skipping line"); - goto skip; - } - add_production(table, s, &production); - goto initial; - default: - goto unexpected; - } - -unexpected: - if (tok != TOK_ERROR) - scanner_err(s, "unexpected token"); -error: - num_errors++; - if (num_errors <= MAX_ERRORS) - goto skip; - - scanner_err(s, "too many errors"); - goto fail; - -fail: - scanner_err(s, "failed to parse file"); - return false; - -skip: - while (tok != TOK_END_OF_LINE && tok != TOK_END_OF_FILE) - tok = lex(s, &val); - goto initial; - -finished: - return true; -} - -bool -parse_string(struct xkb_compose_table *table, const char *string, size_t len, - const char *file_name) -{ - struct scanner s; - scanner_init(&s, table->ctx, string, len, file_name, NULL); - if (!parse(table, &s, 0)) - return false; - /* Maybe the allocator can use the excess space. */ - darray_shrink(table->nodes); - darray_shrink(table->utf8); - return true; -} - -bool -parse_file(struct xkb_compose_table *table, FILE *file, const char *file_name) -{ - bool ok; - char *string; - size_t size; - - ok = map_file(file, &string, &size); - if (!ok) { - log_err(table->ctx, "Couldn't read Compose file %s: %s\n", - file_name, strerror(errno)); - return false; - } - - ok = parse_string(table, string, size, file_name); - unmap_file(string, size); - return ok; -} diff --git a/src/3rdparty/xkbcommon/src/compose/parser.h b/src/3rdparty/xkbcommon/src/compose/parser.h deleted file mode 100644 index 3f64a07402..0000000000 --- a/src/3rdparty/xkbcommon/src/compose/parser.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright © 2013 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. - */ - -#ifndef COMPOSE_PARSER_H -#define COMPOSE_PARSER_H - -bool -parse_string(struct xkb_compose_table *table, - const char *string, size_t len, - const char *file_name); - -bool -parse_file(struct xkb_compose_table *table, - FILE *file, const char *file_name); - -#endif diff --git a/src/3rdparty/xkbcommon/src/compose/paths.c b/src/3rdparty/xkbcommon/src/compose/paths.c deleted file mode 100644 index e9d43d7e44..0000000000 --- a/src/3rdparty/xkbcommon/src/compose/paths.c +++ /dev/null @@ -1,203 +0,0 @@ -/* - * 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 "utils.h" -#include "paths.h" - -enum resolve_name_direction { - LEFT_TO_RIGHT, - RIGHT_TO_LEFT, -}; - -const char * -get_xlocaledir_path(void) -{ - const char *dir = secure_getenv("XLOCALEDIR"); - if (!dir) - dir = XLOCALEDIR; - return dir; -} - -/* - * Files like compose.dir have the format LEFT: RIGHT. Lookup @name in - * such a file and return its matching value, according to @direction. - * @filename is relative to the xlocaledir. - */ -static char * -resolve_name(const char *filename, enum resolve_name_direction direction, - const char *name) -{ - int ret; - bool ok; - const char *xlocaledir; - char path[512]; - FILE *file; - char *string; - size_t string_size; - const char *end; - const char *s, *left, *right; - char *match; - size_t left_len, right_len, name_len; - - xlocaledir = get_xlocaledir_path(); - - ret = snprintf(path, sizeof(path), "%s/%s", xlocaledir, filename); - if (ret < 0 || (size_t) ret >= sizeof(path)) - return false; - - file = fopen(path, "r"); - if (!file) - return false; - - ok = map_file(file, &string, &string_size); - fclose(file); - if (!ok) - return false; - - s = string; - end = string + string_size; - name_len = strlen(name); - match = NULL; - - while (s < end) { - /* Skip spaces. */ - while (s < end && is_space(*s)) - s++; - - /* Skip comments. */ - if (s < end && *s == '#') { - while (s < end && *s != '\n') - s++; - continue; - } - - /* Get the left value. */ - left = s; - while (s < end && !is_space(*s) && *s != ':') - s++; - left_len = s - left; - - /* There's an optional colon between left and right. */ - if (s < end && *s == ':') - s++; - - /* Skip spaces. */ - while (s < end && is_space(*s)) - s++; - - /* Get the right value. */ - right = s; - while (s < end && !is_space(*s)) - s++; - right_len = s - right; - - /* Discard rest of line. */ - while (s < end && *s != '\n') - s++; - - if (direction == LEFT_TO_RIGHT) { - if (left_len == name_len && memcmp(left, name, left_len) == 0) { - match = strndup(right, right_len); - break; - } - } - else if (direction == RIGHT_TO_LEFT) { - if (right_len == name_len && memcmp(right, name, right_len) == 0) { - match = strndup(left, left_len); - break; - } - } - } - - unmap_file(string, string_size); - return match; -} - -char * -resolve_locale(const char *locale) -{ - char *alias = resolve_name("locale.alias", LEFT_TO_RIGHT, locale); - return alias ? alias : strdup(locale); -} - -const char * -get_xcomposefile_path(void) -{ - return secure_getenv("XCOMPOSEFILE"); -} - -char * -get_home_xcompose_file_path(void) -{ - int ret; - const char *home; - char *path; - - home = secure_getenv("HOME"); - if (!home) - return NULL; - - ret = asprintf(&path, "%s/.XCompose", home); - if (ret <0) - return NULL; - - return path; -} - -char * -get_locale_compose_file_path(const char *locale) -{ - char *resolved; - char *path; - - /* - * WARNING: Random workaround ahead. - * - * We currently do not support non-UTF-8 Compose files. The C/POSIX - * locale is specified to be the default fallback locale with an - * ASCII charset. But for some reason the compose.dir points the C - * locale to the iso8859-1/Compose file, which is not ASCII but - * ISO8859-1. Since this is bound to happen a lot, and since our API - * is UTF-8 based, and since 99% of the time a C locale is really just - * a misconfiguration for UTF-8, let's do the most helpful thing. - */ - if (streq(locale, "C")) - locale = "en_US.UTF-8"; - - resolved = resolve_name("compose.dir", RIGHT_TO_LEFT, locale); - if (!resolved) - return NULL; - - if (resolved[0] == '/') { - path = resolved; - } - else { - const char *xlocaledir = get_xlocaledir_path(); - int ret = asprintf(&path, "%s/%s", xlocaledir, resolved); - free(resolved); - if (ret < 0) - return NULL; - } - - return path; -} diff --git a/src/3rdparty/xkbcommon/src/compose/paths.h b/src/3rdparty/xkbcommon/src/compose/paths.h deleted file mode 100644 index 1d719af1b9..0000000000 --- a/src/3rdparty/xkbcommon/src/compose/paths.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * 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. - */ - -#ifndef COMPOSE_RESOLVE_H -#define COMPOSE_RESOLVE_H - -char * -resolve_locale(const char *locale); - -const char * -get_xlocaledir_path(void); - -const char * -get_xcomposefile_path(void); - -char * -get_home_xcompose_file_path(void); - -char * -get_locale_compose_file_path(const char *locale); - -#endif diff --git a/src/3rdparty/xkbcommon/src/compose/table.c b/src/3rdparty/xkbcommon/src/compose/table.c deleted file mode 100644 index 5cd8415850..0000000000 --- a/src/3rdparty/xkbcommon/src/compose/table.c +++ /dev/null @@ -1,219 +0,0 @@ -/* - * Copyright © 2013 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 "utils.h" -#include "table.h" -#include "parser.h" -#include "paths.h" - -static struct xkb_compose_table * -xkb_compose_table_new(struct xkb_context *ctx, - const char *locale, - enum xkb_compose_format format, - enum xkb_compose_compile_flags flags) -{ - char *resolved_locale; - struct xkb_compose_table *table; - struct compose_node root; - - resolved_locale = resolve_locale(locale); - if (!resolved_locale) - return NULL; - - table = calloc(1, sizeof(*table)); - if (!table) { - free(resolved_locale); - return NULL; - } - - table->refcnt = 1; - table->ctx = xkb_context_ref(ctx); - - table->locale = resolved_locale; - table->format = format; - table->flags = flags; - - darray_init(table->nodes); - darray_init(table->utf8); - - root.keysym = XKB_KEY_NoSymbol; - root.next = 0; - root.is_leaf = true; - root.u.leaf.utf8 = 0; - root.u.leaf.keysym = XKB_KEY_NoSymbol; - darray_append(table->nodes, root); - - darray_append(table->utf8, '\0'); - - return table; -} - -XKB_EXPORT struct xkb_compose_table * -xkb_compose_table_ref(struct xkb_compose_table *table) -{ - table->refcnt++; - return table; -} - -XKB_EXPORT void -xkb_compose_table_unref(struct xkb_compose_table *table) -{ - if (!table || --table->refcnt > 0) - return; - free(table->locale); - darray_free(table->nodes); - darray_free(table->utf8); - xkb_context_unref(table->ctx); - free(table); -} - -XKB_EXPORT struct xkb_compose_table * -xkb_compose_table_new_from_file(struct xkb_context *ctx, - FILE *file, - const char *locale, - enum xkb_compose_format format, - enum xkb_compose_compile_flags flags) -{ - struct xkb_compose_table *table; - bool ok; - - if (flags & ~(XKB_COMPOSE_COMPILE_NO_FLAGS)) { - log_err_func(ctx, "unrecognized flags: %#x\n", flags); - return NULL; - } - - if (format != XKB_COMPOSE_FORMAT_TEXT_V1) { - log_err_func(ctx, "unsupported compose format: %d\n", format); - return NULL; - } - - table = xkb_compose_table_new(ctx, locale, format, flags); - if (!table) - return NULL; - - ok = parse_file(table, file, "(unknown file)"); - if (!ok) { - xkb_compose_table_unref(table); - return NULL; - } - - return table; -} - -XKB_EXPORT struct xkb_compose_table * -xkb_compose_table_new_from_buffer(struct xkb_context *ctx, - const char *buffer, size_t length, - const char *locale, - enum xkb_compose_format format, - enum xkb_compose_compile_flags flags) -{ - struct xkb_compose_table *table; - bool ok; - - if (flags & ~(XKB_COMPOSE_COMPILE_NO_FLAGS)) { - log_err_func(ctx, "unrecognized flags: %#x\n", flags); - return NULL; - } - - if (format != XKB_COMPOSE_FORMAT_TEXT_V1) { - log_err_func(ctx, "unsupported compose format: %d\n", format); - return NULL; - } - - table = xkb_compose_table_new(ctx, locale, format, flags); - if (!table) - return NULL; - - ok = parse_string(table, buffer, length, "(input string)"); - if (!ok) { - xkb_compose_table_unref(table); - return NULL; - } - - return table; -} - -XKB_EXPORT struct xkb_compose_table * -xkb_compose_table_new_from_locale(struct xkb_context *ctx, - const char *locale, - enum xkb_compose_compile_flags flags) -{ - struct xkb_compose_table *table; - char *path = NULL; - const char *cpath; - FILE *file; - bool ok; - - if (flags & ~(XKB_COMPOSE_COMPILE_NO_FLAGS)) { - log_err_func(ctx, "unrecognized flags: %#x\n", flags); - return NULL; - } - - table = xkb_compose_table_new(ctx, locale, XKB_COMPOSE_FORMAT_TEXT_V1, - flags); - if (!table) - return NULL; - - cpath = get_xcomposefile_path(); - if (cpath) { - file = fopen(cpath, "r"); - if (file) - goto found_path; - } - - cpath = path = get_home_xcompose_file_path(); - if (path) { - file = fopen(path, "r"); - if (file) - goto found_path; - } - free(path); - path = NULL; - - cpath = path = get_locale_compose_file_path(table->locale); - if (path) { - file = fopen(path, "r"); - if (file) - goto found_path; - } - free(path); - path = NULL; - - log_err(ctx, "couldn't find a Compose file for locale \"%s\"\n", locale); - xkb_compose_table_unref(table); - return NULL; - -found_path: - ok = parse_file(table, file, cpath); - fclose(file); - if (!ok) { - xkb_compose_table_unref(table); - return NULL; - } - - log_dbg(ctx, "created compose table from locale %s with path %s\n", - table->locale, path); - - free(path); - return table; -} diff --git a/src/3rdparty/xkbcommon/src/compose/table.h b/src/3rdparty/xkbcommon/src/compose/table.h deleted file mode 100644 index 05a415ffa3..0000000000 --- a/src/3rdparty/xkbcommon/src/compose/table.h +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright © 2013 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. - */ - -#ifndef COMPOSE_COMPOSE_H -#define COMPOSE_COMPOSE_H - -#include "xkbcommon/xkbcommon-compose.h" -#include "utils.h" -#include "context.h" - -/* - * The compose table data structure is a simple trie. An example will - * help. Given these sequences: - * - * <A> <B> : "first" dead_a - * <A> <C> <D> : "second" dead_b - * <E> <F> : "third" dead_c - * - * the trie would look like: - * - * [root] ---> [<A>] -----------------> [<E>] -# - * | | | - * # v v - * [<B>] ---> [<C>] -# [<F>] -# - * | | - - * # v # - * [<D>] -# - * | - * # - * where: - * - [root] is a special empty root node. - * - [<X>] is a node for a sequence keysym <X>. - * - right arrows are `next` pointers. - * - down arrows are `successor` pointers. - * - # is a nil pointer. - * - * The nodes are all kept in a contiguous array. Pointers are represented - * as integer offsets into this array. A nil pointer is represented as 0 - * (which, helpfully, is the offset of the empty root node). - * - * Nodes without a successor are leaf nodes. Since a sequence cannot be a - * prefix of another, these are exactly the nodes which terminate the - * sequences (in a bijective manner). - * - * A leaf contains the result data of its sequence. The result keysym is - * contained in the node struct itself; the result UTF-8 string is a byte - * offset into an array of the form "\0first\0second\0third" (the initial - * \0 is so offset 0 points to an empty string). - */ - -struct compose_node { - xkb_keysym_t keysym; - /* Offset into xkb_compose_table::nodes. */ - unsigned int next:31; - bool is_leaf:1; - - union { - /* Offset into xkb_compose_table::nodes. */ - uint32_t successor; - struct { - /* Offset into xkb_compose_table::utf8. */ - uint32_t utf8; - xkb_keysym_t keysym; - } leaf; - } u; -}; - -struct xkb_compose_table { - int refcnt; - enum xkb_compose_format format; - enum xkb_compose_compile_flags flags; - struct xkb_context *ctx; - - char *locale; - - darray_char utf8; - darray(struct compose_node) nodes; -}; - -#endif |