Skip to content

Commit

Permalink
Implement ":all" modifier for rules & include
Browse files Browse the repository at this point in the history
  • Loading branch information
wismill committed May 13, 2023
1 parent c8efb70 commit 5409b36
Show file tree
Hide file tree
Showing 10 changed files with 82 additions and 33 deletions.
3 changes: 2 additions & 1 deletion bench/rules.c
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,8 @@ main(int argc, char *argv[])
for (i = 0; i < BENCHMARK_ITERATIONS; i++) {
struct xkb_component_names kccgst;

assert(xkb_components_from_rules(ctx, &rmlvo, &kccgst));
// [FIXME] num_explicit_groups
assert(xkb_components_from_rules(ctx, &rmlvo, &kccgst, NULL));
free(kccgst.keycodes);
free(kccgst.types);
free(kccgst.compat);
Expand Down
1 change: 1 addition & 0 deletions src/keymap-priv.c
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ xkb_keymap_new(struct xkb_context *ctx,

keymap->format = format;
keymap->flags = flags;
keymap->num_explicit_groups = 0;

update_builtin_keymap_fields(keymap);

Expand Down
2 changes: 2 additions & 0 deletions src/keymap.h
Original file line number Diff line number Diff line change
Expand Up @@ -389,6 +389,8 @@ struct xkb_keymap {

/* Number of groups in the key with the most groups. */
xkb_layout_index_t num_groups;
/* Number of groups that were explicitly declared at section level. */
xkb_layout_index_t num_explicit_groups;
/* Not all groups must have names. */
xkb_layout_index_t num_group_names;
xkb_atom_t *group_names;
Expand Down
7 changes: 6 additions & 1 deletion src/xkbcomp/rules.c
Original file line number Diff line number Diff line change
Expand Up @@ -1104,7 +1104,8 @@ read_rules_file(struct xkb_context *ctx,
bool
xkb_components_from_rules(struct xkb_context *ctx,
const struct xkb_rule_names *rmlvo,
struct xkb_component_names *out)
struct xkb_component_names *out,
xkb_layout_index_t *layout_count)
{
bool ret = false;
FILE *file;
Expand All @@ -1118,6 +1119,10 @@ xkb_components_from_rules(struct xkb_context *ctx,
goto err_out;

matcher = matcher_new(ctx, rmlvo);
// Set the number of explicit layouts
if (layout_count != NULL) {
*layout_count = matcher->rmlvo.layouts.size;
}

ret = read_rules_file(ctx, matcher, 0, file, path);
if (!ret ||
Expand Down
3 changes: 2 additions & 1 deletion src/xkbcomp/rules.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
bool
xkb_components_from_rules(struct xkb_context *ctx,
const struct xkb_rule_names *rmlvo,
struct xkb_component_names *out);
struct xkb_component_names *out,
xkb_layout_index_t *layout_count);

#endif
54 changes: 38 additions & 16 deletions src/xkbcomp/symbols.c
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@
#include "vmod.h"
#include "include.h"
#include "keysym.h"
#include "utils.h"

enum key_repeat {
KEY_REPEAT_UNDEFINED = 0,
Expand Down Expand Up @@ -565,35 +566,56 @@ HandleIncludeSymbols(SymbolsInfo *info, IncludeStmt *include)
for (IncludeStmt *stmt = include; stmt; stmt = stmt->next_incl) {
SymbolsInfo next_incl;
XkbFile *file;
xkb_layout_index_t min_layout;
xkb_layout_index_t max_layout;

// Parse the file
file = ProcessIncludeFile(info->ctx, stmt, FILE_TYPE_SYMBOLS);
if (!file) {
info->errorCount += 10;
ClearSymbolsInfo(&included);
return false;
}

InitSymbolsInfo(&next_incl, info->keymap, info->actions,
&included.mods);
if (stmt->modifier) {
next_incl.explicit_group = atoi(stmt->modifier) - 1;
if (next_incl.explicit_group >= XKB_MAX_GROUPS) {
log_err(info->ctx,
"Cannot set explicit group to %d - must be between 1..%d; "
"Ignoring group number\n",
next_incl.explicit_group + 1, XKB_MAX_GROUPS);
next_incl.explicit_group = info->explicit_group;
// Try to interpret the modifier as a layout index
min_layout = atoi(stmt->modifier) - 1;
if (min_layout >= XKB_MAX_GROUPS) {
// Could not parse as a layout index, could it be “all”?
if (istreq(stmt->modifier, "all")) {
min_layout = 0;
// [FIXME] check this
max_layout = info->keymap->num_explicit_groups
? info->keymap->num_explicit_groups - 1
: 0;
} else {
log_err(info->ctx,
"Cannot set explicit group to %d - must be between 1..%d; "
"Ignoring group number\n",
next_incl.explicit_group + 1, XKB_MAX_GROUPS);
min_layout = max_layout = info->explicit_group;
}
} else {
// Explicit group
max_layout = min_layout;
}
}
else {
next_incl.explicit_group = info->explicit_group;
} else {
// No modifier
min_layout = max_layout = info->explicit_group;
}

HandleSymbolsFile(&next_incl, file, MERGE_OVERRIDE);

MergeIncludedSymbols(&included, &next_incl, stmt->merge);
// Loop over the layouts to include
// NOTE: the check "min_layout <= layout" is necessary to handle
// min_layout == XKB_LAYOUT_INVALID
for (xkb_layout_index_t layout=min_layout;
min_layout <= layout && layout <= max_layout; layout++) {
InitSymbolsInfo(&next_incl, info->keymap, info->actions, &included.mods);
next_incl.explicit_group = layout;
HandleSymbolsFile(&next_incl, file, MERGE_OVERRIDE);
MergeIncludedSymbols(&included, &next_incl, stmt->merge);
ClearSymbolsInfo(&next_incl);
}

ClearSymbolsInfo(&next_incl);
FreeXkbFile(file);
}

Expand Down
2 changes: 1 addition & 1 deletion src/xkbcomp/xkbcomp.c
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ text_v1_keymap_new_from_names(struct xkb_keymap *keymap,
rmlvo->rules, rmlvo->model, rmlvo->layout, rmlvo->variant,
rmlvo->options);

ok = xkb_components_from_rules(keymap->ctx, rmlvo, &kccgst);
ok = xkb_components_from_rules(keymap->ctx, rmlvo, &kccgst, &keymap->num_explicit_groups);
if (!ok) {
log_err(keymap->ctx,
"Couldn't look up rules '%s', model '%s', layout '%s', "
Expand Down
20 changes: 14 additions & 6 deletions test/rules-file-includes.c
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ struct test_data {
const char *types;
const char *compat;
const char *symbols;
const xkb_layout_index_t groups;

/* Or set this if xkb_components_from_rules() should fail. */
bool should_fail;
Expand All @@ -57,28 +58,30 @@ test_rules(struct xkb_context *ctx, struct test_data *data)
data->rules, data->model, data->layout, data->variant, data->options
};
struct xkb_component_names kccgst;
xkb_layout_index_t groups;

fprintf(stderr, "\n\nChecking : %s\t%s\t%s\t%s\t%s\n", data->rules,
data->model, data->layout, data->variant, data->options);

if (data->should_fail)
fprintf(stderr, "Expecting: FAILURE\n");
else
fprintf(stderr, "Expecting: %s\t%s\t%s\t%s\n",
data->keycodes, data->types, data->compat, data->symbols);
fprintf(stderr, "Expecting: %s\t%s\t%s\t%s\t%u\n",
data->keycodes, data->types, data->compat, data->symbols, data->groups);

if (!xkb_components_from_rules(ctx, &rmlvo, &kccgst)) {
if (!xkb_components_from_rules(ctx, &rmlvo, &kccgst, &groups)) {
fprintf(stderr, "Received : FAILURE\n");
return data->should_fail;
}

fprintf(stderr, "Received : %s\t%s\t%s\t%s\n",
kccgst.keycodes, kccgst.types, kccgst.compat, kccgst.symbols);
fprintf(stderr, "Received : %s\t%s\t%s\t%s\t%u\n",
kccgst.keycodes, kccgst.types, kccgst.compat, kccgst.symbols, groups);

passed = streq(kccgst.keycodes, data->keycodes) &&
streq(kccgst.types, data->types) &&
streq(kccgst.compat, data->compat) &&
streq(kccgst.symbols, data->symbols);
streq(kccgst.symbols, data->symbols) &&
groups == data->groups;

free(kccgst.keycodes);
free(kccgst.types);
Expand All @@ -105,6 +108,7 @@ main(int argc, char *argv[])

.keycodes = "my_keycodes", .types = "default_types",
.compat = "default_compat", .symbols = "my_symbols",
.groups = 1,
};
assert(test_rules(ctx, &test1));

Expand All @@ -115,6 +119,7 @@ main(int argc, char *argv[])

.keycodes = "my_keycodes", .types = "default_types",
.compat = "default_compat", .symbols = "my_symbols",
.groups = 1,
};
assert(test_rules(ctx, &test2));

Expand All @@ -134,6 +139,7 @@ main(int argc, char *argv[])

.keycodes = "my_keycodes", .types = "default_types",
.compat = "default_compat", .symbols = "default_symbols",
.groups = 1,
};
assert(test_rules(ctx, &test4));

Expand All @@ -146,6 +152,7 @@ main(int argc, char *argv[])
.keycodes = "my_keycodes", .types = "default_types",
.compat = "default_compat+substring+group(bla)|some:compat",
.symbols = "my_symbols+extra_variant+altwin(menu)",
.groups = 1,
};
assert(test_rules(ctx, &test5));

Expand All @@ -156,6 +163,7 @@ main(int argc, char *argv[])

.keycodes = "my_keycodes", .types = "default_types",
.compat = "default_compat", .symbols = "my_symbols",
.groups = 1,
};
assert(test_rules(ctx, &test6));

Expand Down
21 changes: 15 additions & 6 deletions test/rules-file.c
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ struct test_data {
const char *types;
const char *compat;
const char *symbols;
const xkb_layout_index_t groups;

/* Or set this if xkb_components_from_rules() should fail. */
bool should_fail;
Expand All @@ -55,28 +56,30 @@ test_rules(struct xkb_context *ctx, struct test_data *data)
data->rules, data->model, data->layout, data->variant, data->options
};
struct xkb_component_names kccgst;
xkb_layout_index_t groups;

fprintf(stderr, "\n\nChecking : %s\t%s\t%s\t%s\t%s\n", data->rules,
data->model, data->layout, data->variant, data->options);

if (data->should_fail)
fprintf(stderr, "Expecting: FAILURE\n");
else
fprintf(stderr, "Expecting: %s\t%s\t%s\t%s\n",
data->keycodes, data->types, data->compat, data->symbols);
fprintf(stderr, "Expecting: %s\t%s\t%s\t%s\t%u\n",
data->keycodes, data->types, data->compat, data->symbols, data->groups);

if (!xkb_components_from_rules(ctx, &rmlvo, &kccgst)) {
if (!xkb_components_from_rules(ctx, &rmlvo, &kccgst, &groups)) {
fprintf(stderr, "Received : FAILURE\n");
return data->should_fail;
}

fprintf(stderr, "Received : %s\t%s\t%s\t%s\n",
kccgst.keycodes, kccgst.types, kccgst.compat, kccgst.symbols);
fprintf(stderr, "Received : %s\t%s\t%s\t%s\t%u\n",
kccgst.keycodes, kccgst.types, kccgst.compat, kccgst.symbols, groups);

passed = streq(kccgst.keycodes, data->keycodes) &&
streq(kccgst.types, data->types) &&
streq(kccgst.compat, data->compat) &&
streq(kccgst.symbols, data->symbols);
streq(kccgst.symbols, data->symbols) &&
groups == data->groups;

free(kccgst.keycodes);
free(kccgst.types);
Expand All @@ -103,6 +106,7 @@ main(int argc, char *argv[])
.keycodes = "my_keycodes", .types = "my_types",
.compat = "my_compat|some:compat",
.symbols = "my_symbols+extra_variant",
.groups = 1,
};
assert(test_rules(ctx, &test1));

Expand All @@ -113,6 +117,7 @@ main(int argc, char *argv[])

.keycodes = "default_keycodes", .types = "default_types",
.compat = "default_compat", .symbols = "default_symbols",
.groups = 1,
};
assert(test_rules(ctx, &test2));

Expand All @@ -123,6 +128,7 @@ main(int argc, char *argv[])

.keycodes = "something(pc104)", .types = "default_types",
.compat = "default_compat", .symbols = "default_symbols",
.groups = 1,
};
assert(test_rules(ctx, &test3));

Expand All @@ -133,6 +139,7 @@ main(int argc, char *argv[])

.keycodes = "default_keycodes", .types = "default_types",
.compat = "default_compat", .symbols = "my_symbols+(bar)",
.groups = 1,
};
assert(test_rules(ctx, &test4));

Expand All @@ -155,6 +162,7 @@ main(int argc, char *argv[])
.keycodes = "default_keycodes", .types = "default_types",
.compat = "default_compat",
.symbols = "default_symbols+extra:1+extra:2+extra:3+extra:4",
.groups = 4,
};
assert(test_rules(ctx, &test6));

Expand All @@ -167,6 +175,7 @@ main(int argc, char *argv[])
.keycodes = "my_keycodes", .types = "my_types",
.compat = "my_compat+some:compat+group(bla)",
.symbols = "my_symbols+extra_variant+compose(foo)+keypad(bar)+altwin(menu)",
.groups = 1,
};
assert(test_rules(ctx, &test7));

Expand Down
2 changes: 1 addition & 1 deletion tools/compile-keymap.c
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@ print_kccgst(struct xkb_context *ctx, const struct xkb_rule_names *rmlvo)
#if ENABLE_PRIVATE_APIS
struct xkb_component_names kccgst;

if (!xkb_components_from_rules(ctx, rmlvo, &kccgst))
if (!xkb_components_from_rules(ctx, rmlvo, &kccgst, NULL))
return false;

printf("xkb_keymap {\n"
Expand Down

0 comments on commit 5409b36

Please sign in to comment.