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>master
parent
bbc7005b2a
commit
05d6efc417
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
/* 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,24 +279,18 @@ 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;
|
||||
|
||||
while (file) {
|
||||
xkb_file = XkbParseFile(ctx, file, stmt->file, stmt->map);
|
||||
fclose(file);
|
||||
if (!xkb_file) {
|
||||
if (stmt->map)
|
||||
log_err(ctx, "Couldn't process include statement for '%s(%s)'\n",
|
||||
stmt->file, stmt->map);
|
||||
else
|
||||
log_err(ctx, "Couldn't process include statement for '%s'\n",
|
||||
stmt->file);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (xkb_file) {
|
||||
if (xkb_file->file_type != file_type) {
|
||||
log_err(ctx,
|
||||
"Include file of wrong type (expected %s, got %s); "
|
||||
|
@ -289,7 +298,23 @@ ProcessIncludeFile(struct xkb_context *ctx, IncludeStmt *stmt,
|
|||
xkb_file_type_to_string(file_type),
|
||||
xkb_file_type_to_string(xkb_file->file_type), stmt->file);
|
||||
FreeXkbFile(xkb_file);
|
||||
return NULL;
|
||||
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",
|
||||
stmt->file, stmt->map);
|
||||
else
|
||||
log_err(ctx, "Couldn't process include statement for '%s'\n",
|
||||
stmt->file);
|
||||
}
|
||||
|
||||
/* FIXME: we have to check recursive includes here (or somewhere) */
|
||||
|
|
|
@ -33,7 +33,8 @@ ParseIncludeMap(char **str_inout, char **file_rtrn, char **map_rtrn,
|
|||
|
||||
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);
|
||||
|
||||
XkbFile *
|
||||
ProcessIncludeFile(struct xkb_context *ctx, IncludeStmt *stmt,
|
||||
|
|
|
@ -1104,8 +1104,9 @@ xkb_components_from_rules(struct xkb_context *ctx,
|
|||
char *path = NULL;
|
||||
struct matcher *matcher = NULL;
|
||||
struct matched_sval *mval;
|
||||
unsigned int offset = 0;
|
||||
|
||||
file = FindFileInXkbPath(ctx, rmlvo->rules, FILE_TYPE_RULES, &path);
|
||||
file = FindFileInXkbPath(ctx, rmlvo->rules, FILE_TYPE_RULES, &path, &offset);
|
||||
if (!file)
|
||||
goto err_out;
|
||||
|
||||
|
|
Loading…
Reference in New Issue