diff options
author | Peter Hutterer <peter.hutterer@who-t.net> | 2020-07-10 15:16:50 +1000 |
---|---|---|
committer | Ran Benita <ran@unusedvar.com> | 2020-08-30 21:49:41 +0300 |
commit | 05d6efc41723601d4d38e0c43129d2ab9d53fa48 (patch) | |
tree | 5a2ddfd43b5e36d97940dfc99896bfc58041b452 /src/xkbcomp/include.c | |
parent | bbc7005b2a6509e0723b57f54718ca4a3dc7b99b (diff) | |
download | libxkbcommon-05d6efc41723601d4d38e0c43129d2ab9d53fa48.tar.gz libxkbcommon-05d6efc41723601d4d38e0c43129d2ab9d53fa48.tar.bz2 libxkbcommon-05d6efc41723601d4d38e0c43129d2ab9d53fa48.zip |
xkbcomp: allow including kccgst files from other paths
Previously, a 'symbols/us' file in path A would shadow the same file in path B.
This is suboptimal, we rarely need to hide the system files - we care mostly
about *extending* them. By continuing to check other lookup paths, we make it
possible for a XDG_CONFIG_HOME/xkb/symbols/us file to have sections including
those from /usr/share/X11/xkb/symbols/us.
Note that this is not possible for rules files which need to be manually
controlled to get the right bits resolved.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Diffstat (limited to 'src/xkbcomp/include.c')
-rw-r--r-- | src/xkbcomp/include.c | 65 |
1 files changed, 45 insertions, 20 deletions
diff --git a/src/xkbcomp/include.c b/src/xkbcomp/include.c index 88feab3..d39be89 100644 --- a/src/xkbcomp/include.c +++ b/src/xkbcomp/include.c @@ -220,9 +220,20 @@ LogIncludePaths(struct xkb_context *ctx) } } +/** + * Return an open file handle to the first file (counting from offset) with the + * given name in the include paths, starting at the offset. + * + * offset must be zero the first time this is called and is set to the index the + * file was found. Call again with offset+1 to keep searching through the + * include paths. + * + * If this function returns NULL, no more files are available. + */ FILE * FindFileInXkbPath(struct xkb_context *ctx, const char *name, - enum xkb_file_type type, char **pathRtrn) + enum xkb_file_type type, char **pathRtrn, + unsigned int *offset) { unsigned int i; FILE *file = NULL; @@ -231,7 +242,7 @@ FindFileInXkbPath(struct xkb_context *ctx, const char *name, typeDir = DirectoryForInclude(type); - for (i = 0; i < xkb_context_num_include_paths(ctx); i++) { + for (i = *offset; i < xkb_context_num_include_paths(ctx); i++) { buf = asprintf_safe("%s/%s/%s", xkb_context_include_path_get(ctx, i), typeDir, name); if (!buf) { @@ -246,13 +257,17 @@ FindFileInXkbPath(struct xkb_context *ctx, const char *name, *pathRtrn = buf; buf = NULL; } + *offset = i; goto out; } } - log_err(ctx, "Couldn't find file \"%s/%s\" in include paths\n", - typeDir, name); - LogIncludePaths(ctx); + /* We only print warnings if we can't find the file on the first lookup */ + if (*offset == 0) { + log_err(ctx, "Couldn't find file \"%s/%s\" in include paths\n", + typeDir, name); + LogIncludePaths(ctx); + } out: free(buf); @@ -264,14 +279,35 @@ ProcessIncludeFile(struct xkb_context *ctx, IncludeStmt *stmt, enum xkb_file_type file_type) { FILE *file; - XkbFile *xkb_file; + XkbFile *xkb_file = NULL; + unsigned int offset = 0; - file = FindFileInXkbPath(ctx, stmt->file, file_type, NULL); + file = FindFileInXkbPath(ctx, stmt->file, file_type, NULL, &offset); if (!file) return NULL; - xkb_file = XkbParseFile(ctx, file, stmt->file, stmt->map); - fclose(file); + while (file) { + xkb_file = XkbParseFile(ctx, file, stmt->file, stmt->map); + fclose(file); + + if (xkb_file) { + if (xkb_file->file_type != file_type) { + log_err(ctx, + "Include file of wrong type (expected %s, got %s); " + "Include file \"%s\" ignored\n", + xkb_file_type_to_string(file_type), + xkb_file_type_to_string(xkb_file->file_type), stmt->file); + FreeXkbFile(xkb_file); + xkb_file = NULL; + } else { + break; + } + } + + offset++; + file = FindFileInXkbPath(ctx, stmt->file, file_type, NULL, &offset); + } + if (!xkb_file) { if (stmt->map) log_err(ctx, "Couldn't process include statement for '%s(%s)'\n", @@ -279,17 +315,6 @@ ProcessIncludeFile(struct xkb_context *ctx, IncludeStmt *stmt, else log_err(ctx, "Couldn't process include statement for '%s'\n", stmt->file); - return NULL; - } - - if (xkb_file->file_type != file_type) { - log_err(ctx, - "Include file of wrong type (expected %s, got %s); " - "Include file \"%s\" ignored\n", - xkb_file_type_to_string(file_type), - xkb_file_type_to_string(xkb_file->file_type), stmt->file); - FreeXkbFile(xkb_file); - return NULL; } /* FIXME: we have to check recursive includes here (or somewhere) */ |