Commit 19f814f95e30675606dc5ac7c72e1f9434b3020c

Ran Benita 2012-07-11T14:08:28

rules: fix parsing of multiple options This was broken by commit 18d331b86b4942ba54fe087ca07e47c9383d768b (where only the first option out of a comma-separated string was matched). Do it correctly this time and add a test. Signed-off-by: Ran Benita <ran234@gmail.com>

diff --git a/src/xkbcomp/rules.c b/src/xkbcomp/rules.c
index 6c7f4fd..5cd4e31 100644
--- a/src/xkbcomp/rules.c
+++ b/src/xkbcomp/rules.c
@@ -680,19 +680,16 @@ match_group_member(struct rules *rules, const char *group_name,
 static bool
 match_one_of(const char *haystack, const char *needle, char sep)
 {
-    const char *s = strstr(haystack, needle);
+    const char *s = haystack;
+    const size_t len = strlen(needle);
 
-    if (s == NULL)
-        return false;
-
-    if (s != haystack && *s != sep)
-        return false;
+    do {
+        if (strncmp(s, needle, len) == 0 && (s[len] == '\0' || s[len] == sep))
+            return true;
+        s = strchr(s, sep);
+    } while (s++);
 
-    s += strlen(needle);
-    if (*s != '\0' && *s != sep)
-        return false;
-
-    return true;
+    return false;
 }
 
 static int
diff --git a/test/data/rules/multiple-options b/test/data/rules/multiple-options
new file mode 100644
index 0000000..afbdc9f
--- /dev/null
+++ b/test/data/rules/multiple-options
@@ -0,0 +1,27 @@
+! model         = keycodes
+  my_model      = my_keycodes
+  *             = default_keycodes
+
+! layout        variant    = symbols
+  my_layout     my_variant = my_symbols+extra_variant
+
+! layout        = symbols
+  my_layout     = my_symbols
+  *             = default_symbols
+
+! model         = types
+  my_model      = my_types
+  *             = default_types
+
+! model         = compat
+  my_model      = my_compat
+  *             = default_compat
+
+! option        = compat
+  option111     = +substring
+  option1       = +some:compat
+  option11      = +group(bla)
+
+! option        = symbols
+  option3       = +compose(foo)+keypad(bar)
+  colon:opt     = +altwin(menu)
diff --git a/test/rules-file.c b/test/rules-file.c
index 8e301b2..6d4c508 100644
--- a/test/rules-file.c
+++ b/test/rules-file.c
@@ -176,6 +176,18 @@ main(void)
     };
     assert(test_rules(ctx, &test6));
 
+    struct test_data test7 = {
+        .rules = "multiple-options",
+
+        .model = "my_model", .layout = "my_layout", .variant = "my_variant",
+        .options = "option3,option1,colon:opt,option11",
+
+        .keycodes = "my_keycodes", .types = "my_types",
+        .compat = "my_compat+some:compat+group(bla)",
+        .symbols = "my_symbols+extra_variant+compose(foo)+keypad(bar)+altwin(menu)",
+    };
+    assert(test_rules(ctx, &test7));
+
     xkb_context_unref(ctx);
     return 0;
 }