Commit d8a4f52cb95d989b48f39ce13c18fe85cda4e9e1

Ran Benita 2014-09-20T16:13:24

rules: warn when an RMLVO component isn't used Due to wildcard matches in the rules file, this is only really useful for misspelled or missing options, e.g. $ ./test/rmlvo-to-kccgst -o comprose:ralt > /dev/null xkbcommon: ERROR: Unrecognized RMLVO option "comprose:ralt" was ignored Although it is more of a warning, it indicates a misconfiguration which the user probably wants to see. Therefore the log level is ERROR. Signed-off-by: Ran Benita <ran234@gmail.com>

diff --git a/src/xkbcomp/rules.c b/src/xkbcomp/rules.c
index 94ceee6..2d6792a 100644
--- a/src/xkbcomp/rules.c
+++ b/src/xkbcomp/rules.c
@@ -182,15 +182,23 @@ static const struct sval rules_kccgst_svals[_KCCGST_NUM_ENTRIES] = {
     [KCCGST_GEOMETRY] = SVAL_LIT("geometry"),
 };
 
+/* We use this to keep score whether an mlvo was matched or not; if not,
+ * we warn the user that his preference was ignored. */
+struct matched_sval {
+    struct sval sval;
+    bool matched;
+};
+typedef darray(struct matched_sval) darray_matched_sval;
+
 /*
  * A broken-down version of xkb_rule_names (without the rules,
  * obviously).
  */
 struct rule_names {
-    struct sval model;
-    darray_sval layouts;
-    darray_sval variants;
-    darray_sval options;
+    struct matched_sval model;
+    darray_matched_sval layouts;
+    darray_matched_sval variants;
+    darray_matched_sval options;
 };
 
 struct group {
@@ -253,10 +261,10 @@ strip_spaces(struct sval v)
     return v;
 }
 
-static darray_sval
-split_comma_separated_string(const char *s)
+static darray_matched_sval
+split_comma_separated_mlvo(const char *s)
 {
-    darray_sval arr = darray_new();
+    darray_matched_sval arr = darray_new();
 
     /*
      * Make sure the array returned by this function always includes at
@@ -264,15 +272,16 @@ split_comma_separated_string(const char *s)
      */
 
     if (!s) {
-        struct sval val = { NULL, 0 };
+        struct matched_sval val = { .sval = { NULL, 0 } };
         darray_append(arr, val);
         return arr;
     }
 
     while (true) {
-        struct sval val = { s, 0 };
-        while (*s != '\0' && *s != ',') { s++; val.len++; }
-        darray_append(arr, strip_spaces(val));
+        struct matched_sval val = { .sval = { s, 0 } };
+        while (*s != '\0' && *s != ',') { s++; val.sval.len++; }
+        val.sval = strip_spaces(val.sval);
+        darray_append(arr, val);
         if (*s == '\0') break;
         if (*s == ',') s++;
     }
@@ -289,11 +298,11 @@ matcher_new(struct xkb_context *ctx,
         return NULL;
 
     m->ctx = ctx;
-    m->rmlvo.model.start = rmlvo->model;
-    m->rmlvo.model.len = strlen_safe(rmlvo->model);
-    m->rmlvo.layouts = split_comma_separated_string(rmlvo->layout);
-    m->rmlvo.variants = split_comma_separated_string(rmlvo->variant);
-    m->rmlvo.options = split_comma_separated_string(rmlvo->options);
+    m->rmlvo.model.sval.start = rmlvo->model;
+    m->rmlvo.model.sval.len = strlen_safe(rmlvo->model);
+    m->rmlvo.layouts = split_comma_separated_mlvo(rmlvo->layout);
+    m->rmlvo.variants = split_comma_separated_mlvo(rmlvo->variant);
+    m->rmlvo.options = split_comma_separated_mlvo(rmlvo->options);
 
     return m;
 }
@@ -586,7 +595,7 @@ match_group(struct matcher *m, struct sval group_name, struct sval to)
 
 static bool
 match_value(struct matcher *m, struct sval val, struct sval to,
-          enum mlvo_match_type match_type)
+            enum mlvo_match_type match_type)
 {
     if (match_type == MLVO_MATCH_WILDCARD)
         return true;
@@ -595,6 +604,16 @@ match_value(struct matcher *m, struct sval val, struct sval to,
     return svaleq(val, to);
 }
 
+static bool
+match_value_and_mark(struct matcher *m, struct sval val,
+                     struct matched_sval *to, enum mlvo_match_type match_type)
+{
+    bool matched = match_value(m, val, to->sval, match_type);
+    if (matched)
+        to->matched = true;
+    return matched;
+}
+
 /*
  * This function performs %-expansion on @value (see overview above),
  * and appends the result to @to.
@@ -672,22 +691,22 @@ append_expanded_kccgst_value(struct matcher *m, darray_char *to,
             if (idx != XKB_LAYOUT_INVALID &&
                 idx < darray_size(m->rmlvo.layouts) &&
                 darray_size(m->rmlvo.layouts) > 1)
-                expanded_value = darray_item(m->rmlvo.layouts, idx);
+                expanded_value = darray_item(m->rmlvo.layouts, idx).sval;
             else if (idx == XKB_LAYOUT_INVALID &&
                      darray_size(m->rmlvo.layouts) == 1)
-                expanded_value = darray_item(m->rmlvo.layouts, 0);
+                expanded_value = darray_item(m->rmlvo.layouts, 0).sval;
         }
         else if (mlv == MLVO_VARIANT) {
             if (idx != XKB_LAYOUT_INVALID &&
                 idx < darray_size(m->rmlvo.variants) &&
                 darray_size(m->rmlvo.variants) > 1)
-                expanded_value = darray_item(m->rmlvo.variants, idx);
+                expanded_value = darray_item(m->rmlvo.variants, idx).sval;
             else if (idx == XKB_LAYOUT_INVALID &&
                      darray_size(m->rmlvo.variants) == 1)
-                expanded_value = darray_item(m->rmlvo.variants, 0);
+                expanded_value = darray_item(m->rmlvo.variants, 0).sval;
         }
         else if (mlv == MLVO_MODEL) {
-            expanded_value = m->rmlvo.model;
+            expanded_value = m->rmlvo.model.sval;
         }
 
         /* If we didn't get one, skip silently. */
@@ -745,29 +764,28 @@ matcher_rule_apply_if_matches(struct matcher *m)
         enum rules_mlvo mlvo = m->mapping.mlvo_at_pos[i];
         struct sval value = m->rule.mlvo_value_at_pos[i];
         enum mlvo_match_type match_type = m->rule.match_type_at_pos[i];
+        struct matched_sval *to;
         bool matched = false;
 
         if (mlvo == MLVO_MODEL) {
-            matched = match_value(m, value, m->rmlvo.model, match_type);
+            to = &m->rmlvo.model;
+            matched = match_value_and_mark(m, value, to, match_type);
         }
         else if (mlvo == MLVO_LAYOUT) {
             xkb_layout_index_t idx = m->mapping.layout_idx;
             idx = (idx == XKB_LAYOUT_INVALID ? 0 : idx);
-            matched = match_value(m, value,
-                                  darray_item(m->rmlvo.layouts, idx),
-                                  match_type);
+            to = &darray_item(m->rmlvo.layouts, idx);
+            matched = match_value_and_mark(m, value, to, match_type);
         }
         else if (mlvo == MLVO_VARIANT) {
             xkb_layout_index_t idx = m->mapping.layout_idx;
             idx = (idx == XKB_LAYOUT_INVALID ? 0 : idx);
-            matched = match_value(m, value,
-                                  darray_item(m->rmlvo.variants, idx),
-                                  match_type);
+            to = &darray_item(m->rmlvo.variants, idx);
+            matched = match_value_and_mark(m, value, to, match_type);
         }
         else if (mlvo == MLVO_OPTION) {
-            struct sval *option;
-            darray_foreach(option, m->rmlvo.options) {
-                matched = match_value(m, value, *option, match_type);
+            darray_foreach(to, m->rmlvo.options) {
+                matched = match_value_and_mark(m, value, to, match_type);
                 if (matched)
                     break;
             }
@@ -803,6 +821,7 @@ matcher_match(struct matcher *m, const char *string, size_t len,
               const char *file_name, struct xkb_component_names *out)
 {
     enum rules_token tok;
+    struct matched_sval *mval;
 
     if (!m)
         return false;
@@ -952,6 +971,24 @@ finish:
     darray_steal(m->kccgst[KCCGST_SYMBOLS], &out->symbols, NULL);
     darray_free(m->kccgst[KCCGST_GEOMETRY]);
 
+
+    mval = &m->rmlvo.model;
+    if (!mval->matched && mval->sval.len > 0)
+        log_err(m->ctx, "Unrecognized RMLVO model \"%.*s\" was ignored\n",
+                mval->sval.len, mval->sval.start);
+    darray_foreach(mval, m->rmlvo.layouts)
+        if (!mval->matched && mval->sval.len > 0)
+            log_err(m->ctx, "Unrecognized RMLVO layout \"%.*s\" was ignored\n",
+                    mval->sval.len, mval->sval.start);
+    darray_foreach(mval, m->rmlvo.variants)
+        if (!mval->matched && mval->sval.len > 0)
+            log_err(m->ctx, "Unrecognized RMLVO variant \"%.*s\" was ignored\n",
+                    mval->sval.len, mval->sval.start);
+    darray_foreach(mval, m->rmlvo.options)
+        if (!mval->matched && mval->sval.len > 0)
+            log_err(m->ctx, "Unrecognized RMLVO option \"%.*s\" was ignored\n",
+                    mval->sval.len, mval->sval.start);
+
     return true;
 
 state_error: