X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=src%2Fxkbcomp%2Finclude.c;h=fc692fb13fe4785e423826a4af3857971b336979;hb=a83d745b62ea8ec89e939b00bb3754ad54280942;hp=8bfd6503deda265027cc38eed306e806b41a19fc;hpb=b6e0457195694b541e975c74597d4b2b24203c6d;p=platform%2Fupstream%2Flibxkbcommon.git diff --git a/src/xkbcomp/include.c b/src/xkbcomp/include.c index 8bfd650..fc692fb 100644 --- a/src/xkbcomp/include.c +++ b/src/xkbcomp/include.c @@ -24,6 +24,31 @@ * ********************************************************/ +/* + * Copyright © 2012 Ran Benita + * + * 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 #include #include @@ -149,8 +174,6 @@ ParseIncludeMap(char **str_inout, char **file_rtrn, char **map_rtrn, return true; } -/***====================================================================***/ - static const char *xkb_file_type_include_dirs[_FILE_TYPE_NUM_ENTRIES] = { [FILE_TYPE_KEYCODES] = "keycodes", [FILE_TYPE_TYPES] = "types", @@ -172,138 +195,148 @@ DirectoryForInclude(enum xkb_file_type type) return xkb_file_type_include_dirs[type]; } -/***====================================================================***/ +static void +LogIncludePaths(struct xkb_context *ctx) +{ + unsigned int i; + + if (xkb_context_num_include_paths(ctx) > 0) { + log_err_with_code(ctx, + XKB_ERROR_INCLUDED_FILE_NOT_FOUND, + "%d include paths searched:\n", + xkb_context_num_include_paths(ctx)); + for (i = 0; i < xkb_context_num_include_paths(ctx); i++) + log_err_with_code(ctx, + XKB_ERROR_INCLUDED_FILE_NOT_FOUND, + "\t%s\n", + xkb_context_include_path_get(ctx, i)); + } + else { + log_err_with_code(ctx, + XKB_ERROR_INCLUDED_FILE_NOT_FOUND, + "There are no include paths to search\n"); + } + + if (xkb_context_num_failed_include_paths(ctx) > 0) { + log_err_with_code(ctx, + XKB_ERROR_INCLUDED_FILE_NOT_FOUND, + "%d include paths could not be added:\n", + xkb_context_num_failed_include_paths(ctx)); + for (i = 0; i < xkb_context_num_failed_include_paths(ctx); i++) + log_err_with_code(ctx, + XKB_ERROR_INCLUDED_FILE_NOT_FOUND, + "\t%s\n", + xkb_context_failed_include_path_get(ctx, i)); + } +} /** - * Search for the given file name in the include directories. + * Return an open file handle to the first file (counting from offset) with the + * given name in the include paths, starting at the offset. * - * @param ctx the XKB ctx containing the include paths - * @param type one of FILE_TYPE_TYPES, FILE_TYPE_COMPAT, ..., or - * FILE_TYPE_KEYMAP or FILE_TYPE_RULES - * @param pathRtrn is set to the full path of the file if found. + * 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. * - * @return an FD to the file or NULL. If NULL is returned, the value of - * pathRtrn is undefined. + * 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) { - size_t i; - int ret; + unsigned int i; FILE *file = NULL; - char buf[PATH_MAX]; + char *buf = NULL; const char *typeDir; typeDir = DirectoryForInclude(type); - for (i = 0; i < xkb_context_num_include_paths(ctx); i++) { - ret = snprintf(buf, sizeof(buf), "%s/%s/%s", - xkb_context_include_path_get(ctx, i), typeDir, name); - if (ret >= (ssize_t) sizeof(buf)) { - log_err(ctx, "File name (%s/%s/%s) too long\n", + + 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) { + log_err_with_code(ctx, + XKB_ERROR_ALLOCATION_ERROR, + "Failed to alloc buffer for (%s/%s/%s)\n", xkb_context_include_path_get(ctx, i), typeDir, name); continue; } - file = fopen(buf, "r"); - if (file == NULL) { - log_err(ctx, "Couldn't open file (%s/%s/%s): %s\n", - xkb_context_include_path_get(ctx, i), typeDir, name, - strerror(errno)); - continue; + + file = fopen(buf, "rb"); + if (file) { + if (pathRtrn) { + *pathRtrn = buf; + buf = NULL; + } + *offset = i; + goto out; } - break; } - if ((file != NULL) && (pathRtrn != NULL)) - *pathRtrn = strdup(buf); + /* We only print warnings if we can't find the file on the first lookup */ + if (*offset == 0) { + log_err_with_code(ctx, + XKB_ERROR_INCLUDED_FILE_NOT_FOUND, + "Couldn't find file \"%s/%s\" in include paths\n", + typeDir, name); + LogIncludePaths(ctx); + } + +out: + free(buf); return file; } -/** - * Open the file given in the include statement and parse it's content. - * If the statement defines a specific map to use, this map is returned in - * file_rtrn. Otherwise, the default map is returned. - * - * @param ctx The ctx containing include paths - * @param stmt The include statement, specifying the file name to look for. - * @param file_type Type of file (FILE_TYPE_KEYCODES, etc.) - * @param file_rtrn Returns the key map to be used. - * @param merge_rtrn Always returns stmt->merge. - * - * @return true on success or false otherwise. - */ -bool -ProcessIncludeFile(struct xkb_context *ctx, - IncludeStmt * stmt, - enum xkb_file_type file_type, - XkbFile ** file_rtrn, enum merge_mode *merge_rtrn) +XkbFile * +ProcessIncludeFile(struct xkb_context *ctx, IncludeStmt *stmt, + enum xkb_file_type file_type) { FILE *file; - XkbFile *rtrn, *mapToUse, *next; + XkbFile *xkb_file = NULL; + unsigned int offset = 0; - file = FindFileInXkbPath(ctx, stmt->file, file_type, NULL); - if (file == NULL) { - log_err(ctx, "Can't find file \"%s\" for %s include\n", stmt->file, - DirectoryForInclude(file_type)); - return false; - } + file = FindFileInXkbPath(ctx, stmt->file, file_type, NULL, &offset); + if (!file) + return NULL; - if (!XkbParseFile(ctx, file, stmt->file, &rtrn)) { - log_err(ctx, "Error interpreting include file \"%s\"\n", stmt->file); + while (file) { + xkb_file = XkbParseFile(ctx, file, stmt->file, stmt->map); fclose(file); - return false; - } - fclose(file); - mapToUse = rtrn; - if (stmt->map != NULL) { - while (mapToUse) - { - next = (XkbFile *) mapToUse->common.next; - mapToUse->common.next = NULL; - if (streq(mapToUse->name, stmt->map) && - mapToUse->file_type == file_type) { - FreeXkbFile(next); + if (xkb_file) { + if (xkb_file->file_type != file_type) { + log_err_with_code(ctx, + XKB_ERROR_INVALID_INCLUDED_FILE, + "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; } - else { - FreeXkbFile(mapToUse); - } - mapToUse = next; } - if (!mapToUse) { - log_err(ctx, "No %s named \"%s\" in the include file \"%s\"\n", - xkb_file_type_to_string(file_type), stmt->map, - stmt->file); - return false; - } - } - else if (rtrn->common.next) { - for (; mapToUse; mapToUse = (XkbFile *) mapToUse->common.next) - if (mapToUse->flags & MAP_IS_DEFAULT) - break; - if (!mapToUse) { - mapToUse = rtrn; - log_vrb(ctx, 5, - "No map in include statement, but \"%s\" contains several; " - "Using first defined map, \"%s\"\n", - stmt->file, rtrn->name); - } + offset++; + file = FindFileInXkbPath(ctx, stmt->file, file_type, NULL, &offset); } - if (mapToUse->file_type != file_type) { - log_err(ctx, - "Include file wrong type (expected %s, got %s); " - "Include file \"%s\" ignored\n", - xkb_file_type_to_string(file_type), - xkb_file_type_to_string(mapToUse->file_type), stmt->file); - return false; + if (!xkb_file) { + if (stmt->map) + log_err_with_code(ctx, + XKB_ERROR_INVALID_INCLUDED_FILE, + "Couldn't process include statement for '%s(%s)'\n", + stmt->file, stmt->map); + else + log_err_with_code(ctx, + XKB_ERROR_INVALID_INCLUDED_FILE, + "Couldn't process include statement for '%s'\n", + stmt->file); } /* FIXME: we have to check recursive includes here (or somewhere) */ - *file_rtrn = mapToUse; - *merge_rtrn = stmt->merge; - return true; + return xkb_file; }