Commit e670d084a6b4431de2ef3b5395c1473ba4b73725

Ran Benita 2012-09-16T13:33:09

include: improve file-not-found error reporting Only report it once, and not only for rules. Signed-off-by: Ran Benita <ran234@gmail.com>

diff --git a/src/context.c b/src/context.c
index af9fb51..b116884 100644
--- a/src/context.c
+++ b/src/context.c
@@ -132,6 +132,12 @@ xkb_context_num_include_paths(struct xkb_context *ctx)
     return darray_size(ctx->includes);
 }
 
+unsigned int
+xkb_context_num_failed_include_paths(struct xkb_context *ctx)
+{
+    return darray_size(ctx->failed_includes);
+}
+
 /**
  * Returns the given entry in the context's include path, or NULL if an
  * invalid index is passed.
@@ -145,6 +151,16 @@ xkb_context_include_path_get(struct xkb_context *ctx, unsigned int idx)
     return darray_item(ctx->includes, idx);
 }
 
+const char *
+xkb_context_failed_include_path_get(struct xkb_context *ctx,
+                                    unsigned int idx)
+{
+    if (idx >= xkb_context_num_failed_include_paths(ctx))
+        return NULL;
+
+    return darray_item(ctx->failed_includes, idx);
+}
+
 unsigned
 xkb_context_take_file_id(struct xkb_context *ctx)
 {
diff --git a/src/xkb-priv.h b/src/xkb-priv.h
index 50e2529..dfb2645 100644
--- a/src/xkb-priv.h
+++ b/src/xkb-priv.h
@@ -506,6 +506,13 @@ xkb_key_get_syms_by_level(struct xkb_keymap *keymap,
 extern unsigned
 xkb_context_take_file_id(struct xkb_context *ctx);
 
+unsigned int
+xkb_context_num_failed_include_paths(struct xkb_context *ctx);
+
+const char *
+xkb_context_failed_include_path_get(struct xkb_context *ctx,
+                                    unsigned int idx);
+
 bool
 xkb_keysym_is_lower(xkb_keysym_t keysym);
 
diff --git a/src/xkbcomp/include.c b/src/xkbcomp/include.c
index cfb84fb..1090e83 100644
--- a/src/xkbcomp/include.c
+++ b/src/xkbcomp/include.c
@@ -212,32 +212,55 @@ FILE *
 FindFileInXkbPath(struct xkb_context *ctx, const char *name,
                   enum xkb_file_type type, char **pathRtrn)
 {
-    size_t i;
-    int ret;
+    unsigned int i;
     FILE *file = NULL;
     char buf[PATH_MAX];
     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);
+        int 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",
                     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;
+        if (file)
+            break;
+    }
+
+    if (!file) {
+        log_err(ctx, "Couldn't find file \"%s/%s\" in include paths\n",
+                typeDir, name);
+
+        if (xkb_context_num_failed_include_paths(ctx) > 0) {
+            log_err(ctx, "%d include paths searched:\n",
+                    xkb_context_num_include_paths(ctx));
+            for (i = 0; i < xkb_context_num_include_paths(ctx); i++)
+                log_err(ctx, "\t%s\n",
+                        xkb_context_include_path_get(ctx, i));
         }
-        break;
+        else {
+            log_err(ctx, "There are no include paths to search\n");
+        }
+
+        if (xkb_context_num_failed_include_paths(ctx) > 0) {
+            log_err(ctx, "%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(ctx, "\t%s\n",
+                        xkb_context_failed_include_path_get(ctx, i));
+        }
+
+        return NULL;
     }
 
-    if ((file != NULL) && (pathRtrn != NULL))
+    if (pathRtrn)
         *pathRtrn = strdup(buf);
     return file;
 }
@@ -265,11 +288,8 @@ ProcessIncludeFile(struct xkb_context *ctx,
     XkbFile *rtrn, *mapToUse, *next;
 
     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));
+    if (!file)
         return false;
-    }
 
     if (!XkbParseFile(ctx, file, stmt->file, &rtrn)) {
         log_err(ctx, "Error interpreting include file \"%s\"\n", stmt->file);
diff --git a/src/xkbcomp/rules.c b/src/xkbcomp/rules.c
index a619eee..cd4c1a3 100644
--- a/src/xkbcomp/rules.c
+++ b/src/xkbcomp/rules.c
@@ -1200,26 +1200,14 @@ xkb_components_from_rules(struct xkb_context *ctx,
     bool ret = false;
     FILE *file;
     char *path;
-    char **include;
     int fd;
     struct stat stat_buf;
     char *string;
     struct matcher *matcher;
 
     file = FindFileInXkbPath(ctx, rmlvo->rules, FILE_TYPE_RULES, &path);
-    if (!file) {
-        log_err(ctx, "Could not find \"%s\" rules in XKB path\n",
-                rmlvo->rules);
-        log_err(ctx, "%zu include paths searched:\n",
-                darray_size(ctx->includes));
-        darray_foreach(include, ctx->includes)
-            log_err(ctx, "\t%s\n", *include);
-        log_err(ctx, "%zu include paths could not be added:\n",
-                darray_size(ctx->failed_includes));
-        darray_foreach(include, ctx->failed_includes)
-            log_err(ctx, "\t%s\n", *include);
+    if (!file)
         goto err_out;
-    }
 
     fd = fileno(file);