Skip to content

Commit

Permalink
Correctly collapse multiple consecutive bindings.
Browse files Browse the repository at this point in the history
As per the specification, if several bindings (".", "*") are following
each other, they are treated as if there was only a single binding,
wherein it is treated as "." if and only if all of the consecutive bindings
were tight ("."); otherwise, it is treated as a single loose ("*") binding.

fixes #79
  • Loading branch information
Airblader committed Mar 24, 2018
1 parent a45b3d0 commit 64ee910
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 1 deletion.
14 changes: 13 additions & 1 deletion src/entry.c
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ int xcb_xrm_entry_parse(const char *_str, xcb_xrm_entry_t **_entry, bool resourc
xcb_xrm_component_t *last;
char *value;
char *value_walk;
xcb_xrm_binding_type_t binding_type;

xcb_xrm_entry_parser_state_t state = {
.chunk = CS_INITIAL,
Expand Down Expand Up @@ -166,8 +167,19 @@ int xcb_xrm_entry_parse(const char *_str, xcb_xrm_entry_t **_entry, bool resourc
goto done_error;
}

/* Subsequent bindings must be collapsed into a loose binding if at
* least one was a loose binding and a tight binding otherwise. */
binding_type = (*walk == '*') ? BT_LOOSE : BT_TIGHT;
while (*(walk + 1) == '.' || *(walk + 1) == '*') {
walk++;

if (*walk == '*') {
binding_type = BT_LOOSE;
}
}

xcb_xrm_finalize_component(entry, &state);
state.current_binding_type = (*walk == '.') ? BT_TIGHT : BT_LOOSE;
state.current_binding_type = binding_type;
break;
case '?':
state.chunk = MAX(state.chunk, CS_COMPONENTS);
Expand Down
12 changes: 12 additions & 0 deletions tests/tests_match.c
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ static int test_get_resource(void) {
err |= check_get_resource("First.?.third: 1", "First.second.third", "", "1", false);
err |= check_get_resource("First.?.?.fourth: 1", "First.second.third.fourth", "", "1", false);
err |= check_get_resource("*second: 1", "First.second", "", "1", false);
err |= check_get_resource(".second: 1", "First.second", "", NULL, false);
err |= check_get_resource("*third: 1", "First.second.third", "", "1", false);
err |= check_get_resource("First*second: 1", "First.second", "", "1", false);
err |= check_get_resource("First*third: 1", "First.second.third", "", "1", false);
Expand All @@ -110,6 +111,17 @@ static int test_get_resource(void) {
err |= check_get_resource("First:", "First", "", "", false);
err |= check_get_resource("First: ", "First", "", "", false);
err |= check_get_resource("First: \t ", "First", "", "", false);
/* Consecutive bindings */
err |= check_get_resource("*.bar: 1", "foo.foo.bar", "", "1", false);
err |= check_get_resource("...bar: 1", "foo.bar", "", NULL, false);
err |= check_get_resource("...bar: 1", "foo.foo.foo.bar", "", NULL, false);
err |= check_get_resource("***bar: 1", "foo.bar", "", "1", false);
err |= check_get_resource(".*.bar: 1", "foo.bar", "", "1", false);
err |= check_get_resource(".*.bar: 1", "foo.foo.bar", "", "1", false);
err |= check_get_resource("..*bar: 1", "foo.foo.foo.foo.bar", "", "1", false);
err |= check_get_resource("a.*.z: 1", "a.b.c.d.e.f.z", "", "1", false);
err |= check_get_resource("a...z: 1", "a.z", "", "1", false);
err |= check_get_resource("a...z: 1", "a.b.z", "", NULL, false);
/* Matching among multiple entries */
err |= check_get_resource(
"First: 1\n"
Expand Down

0 comments on commit 64ee910

Please sign in to comment.