mirror of
https://codeberg.org/dnkl/foot.git
synced 2026-03-26 07:57:59 -04:00
config: argv_compare(): change parameters to ‘struct argv *’
Instead of passing raw char** pointers to argv_compare(), pass pointers to ‘struct argv’. This lets argv_compare() handle both argv’s being NULL, or one of them being NULL. That is, the caller no longer needs to check that both argv’s are non-NULL before calling argv_compare(). Furthermore, update has_key_binding_collisions() to require the pipe argv to match, in addition to matching the ‘action’, when allowing a key collision.
This commit is contained in:
parent
9174e6d79a
commit
cdb2d90b89
1 changed files with 46 additions and 40 deletions
86
config.c
86
config.c
|
|
@ -1557,11 +1557,40 @@ err:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
argv_compare(const struct argv *argv1, const struct argv *argv2)
|
||||||
|
{
|
||||||
|
if (argv1->args == NULL && argv2->args == NULL)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (argv1->args == NULL)
|
||||||
|
return -1;
|
||||||
|
if (argv2->args == NULL)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
for (size_t i = 0; ; i++) {
|
||||||
|
if (argv1->args[i] == NULL && argv2->args[i] == NULL)
|
||||||
|
return 0;
|
||||||
|
if (argv1->args[i] == NULL)
|
||||||
|
return -1;
|
||||||
|
if (argv2->args[i] == NULL)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
int ret = strcmp(argv1->args[i], argv2->args[i]);
|
||||||
|
if (ret != 0)
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
BUG("unexpected loop break");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
has_key_binding_collisions(struct context *ctx,
|
has_key_binding_collisions(struct context *ctx,
|
||||||
int action, const char *const action_map[],
|
int action, const char *const action_map[],
|
||||||
const struct config_key_binding_list *bindings,
|
const struct config_key_binding_list *bindings,
|
||||||
const struct key_combo_list *key_combos)
|
const struct key_combo_list *key_combos,
|
||||||
|
const struct argv *pipe_argv)
|
||||||
{
|
{
|
||||||
for (size_t j = 0; j < bindings->count; j++) {
|
for (size_t j = 0; j < bindings->count; j++) {
|
||||||
const struct config_key_binding *combo1 = &bindings->arr[j];
|
const struct config_key_binding *combo1 = &bindings->arr[j];
|
||||||
|
|
@ -1569,8 +1598,10 @@ has_key_binding_collisions(struct context *ctx,
|
||||||
if (combo1->action == BIND_ACTION_NONE)
|
if (combo1->action == BIND_ACTION_NONE)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (combo1->action == action)
|
if (combo1->action == action) {
|
||||||
continue;
|
if (argv_compare(&combo1->pipe.argv, pipe_argv) == 0)
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
for (size_t i = 0; i < key_combos->count; i++) {
|
for (size_t i = 0; i < key_combos->count; i++) {
|
||||||
const struct key_combo *combo2 = &key_combos->combos[i];
|
const struct key_combo *combo2 = &key_combos->combos[i];
|
||||||
|
|
@ -1600,29 +1631,6 @@ has_key_binding_collisions(struct context *ctx,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
|
||||||
argv_compare(char *const *argv1, char *const *argv2)
|
|
||||||
{
|
|
||||||
xassert(argv1 != NULL);
|
|
||||||
xassert(argv2 != NULL);
|
|
||||||
|
|
||||||
for (size_t i = 0; ; i++) {
|
|
||||||
if (argv1[i] == NULL && argv2[i] == NULL)
|
|
||||||
return 0;
|
|
||||||
if (argv1[i] == NULL)
|
|
||||||
return -1;
|
|
||||||
if (argv2[i] == NULL)
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
int ret = strcmp(argv1[i], argv2[i]);
|
|
||||||
if (ret != 0)
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
BUG("unexpected loop break");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Parses a key binding value on the form
|
* Parses a key binding value on the form
|
||||||
* "[cmd-to-exec arg1 arg2] Mods+Key"
|
* "[cmd-to-exec arg1 arg2] Mods+Key"
|
||||||
|
|
@ -1680,7 +1688,7 @@ pipe_argv_from_value(struct context *ctx, struct argv *argv)
|
||||||
|
|
||||||
static void NOINLINE
|
static void NOINLINE
|
||||||
remove_action_from_key_bindings_list(struct config_key_binding_list *bindings,
|
remove_action_from_key_bindings_list(struct config_key_binding_list *bindings,
|
||||||
int action, char **pipe_argv)
|
int action, const struct argv *pipe_argv)
|
||||||
{
|
{
|
||||||
size_t remove_first_idx = 0;
|
size_t remove_first_idx = 0;
|
||||||
size_t remove_count = 0;
|
size_t remove_count = 0;
|
||||||
|
|
@ -1688,11 +1696,10 @@ remove_action_from_key_bindings_list(struct config_key_binding_list *bindings,
|
||||||
for (size_t i = 0; i < bindings->count; i++) {
|
for (size_t i = 0; i < bindings->count; i++) {
|
||||||
struct config_key_binding *binding = &bindings->arr[i];
|
struct config_key_binding *binding = &bindings->arr[i];
|
||||||
|
|
||||||
if (binding->action == action &&
|
if (binding->action != action)
|
||||||
((binding->pipe.argv.args == NULL && pipe_argv == NULL) ||
|
continue;
|
||||||
(binding->pipe.argv.args != NULL && pipe_argv != NULL &&
|
|
||||||
argv_compare(binding->pipe.argv.args, pipe_argv) == 0)))
|
if (argv_compare(&binding->pipe.argv, pipe_argv) == 0) {
|
||||||
{
|
|
||||||
if (remove_count++ == 0)
|
if (remove_count++ == 0)
|
||||||
remove_first_idx = i;
|
remove_first_idx = i;
|
||||||
|
|
||||||
|
|
@ -1736,7 +1743,7 @@ parse_key_binding_section(struct context *ctx,
|
||||||
|
|
||||||
/* Unset binding */
|
/* Unset binding */
|
||||||
if (strcasecmp(ctx->value, "none") == 0) {
|
if (strcasecmp(ctx->value, "none") == 0) {
|
||||||
remove_action_from_key_bindings_list(bindings, action, pipe_argv.args);
|
remove_action_from_key_bindings_list(bindings, action, &pipe_argv);
|
||||||
free_argv(&pipe_argv);
|
free_argv(&pipe_argv);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
@ -1744,14 +1751,14 @@ parse_key_binding_section(struct context *ctx,
|
||||||
struct key_combo_list key_combos = {0};
|
struct key_combo_list key_combos = {0};
|
||||||
if (!value_to_key_combos(ctx, &key_combos) ||
|
if (!value_to_key_combos(ctx, &key_combos) ||
|
||||||
has_key_binding_collisions(
|
has_key_binding_collisions(
|
||||||
ctx, action, action_map, bindings, &key_combos))
|
ctx, action, action_map, bindings, &key_combos, &pipe_argv))
|
||||||
{
|
{
|
||||||
free_argv(&pipe_argv);
|
free_argv(&pipe_argv);
|
||||||
free_key_combo_list(&key_combos);
|
free_key_combo_list(&key_combos);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
remove_action_from_key_bindings_list(bindings, action, pipe_argv.args);
|
remove_action_from_key_bindings_list(bindings, action, &pipe_argv);
|
||||||
|
|
||||||
/* Emit key bindings */
|
/* Emit key bindings */
|
||||||
size_t ofs = bindings->count;
|
size_t ofs = bindings->count;
|
||||||
|
|
@ -2140,11 +2147,10 @@ parse_section_mouse_bindings(struct context *ctx)
|
||||||
for (size_t i = 0; i < conf->bindings.mouse.count; i++) {
|
for (size_t i = 0; i < conf->bindings.mouse.count; i++) {
|
||||||
struct config_mouse_binding *binding = &conf->bindings.mouse.arr[i];
|
struct config_mouse_binding *binding = &conf->bindings.mouse.arr[i];
|
||||||
|
|
||||||
if (binding->action == action &&
|
if (binding->action != action)
|
||||||
((binding->pipe.argv.args == NULL && pipe_argv.args == NULL) ||
|
continue;
|
||||||
(binding->pipe.argv.args != NULL && pipe_argv.args != NULL &&
|
|
||||||
argv_compare(binding->pipe.argv.args, pipe_argv.args) == 0)))
|
if (argv_compare(&binding->pipe.argv, &pipe_argv) == 0) {
|
||||||
{
|
|
||||||
if (binding->pipe.master_copy)
|
if (binding->pipe.master_copy)
|
||||||
free_argv(&binding->pipe.argv);
|
free_argv(&binding->pipe.argv);
|
||||||
binding->action = BIND_ACTION_NONE;
|
binding->action = BIND_ACTION_NONE;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue