diff --git a/common/list.c b/common/list.c index 98005d9e0..4b0c3a304 100644 --- a/common/list.c +++ b/common/list.c @@ -174,24 +174,6 @@ void list_isort(list_t *list, int compare(const void *, const void *)) { } } -ssize_t list_bsearch(const list_t *list, int compare(const void *key, const void *item), - const void *key, void *ret) { - - if (!sway_assert(list && compare && key, "Invalid argument")) { - return -1; - } - - const uint8_t *ptr = bsearch(key, list->items, list->length, list->memb_size, compare); - if (!ptr) { - return -1; - } else { - if (ret) { - memcpy(ret, ptr, list->memb_size); - } - return (ptr - (uint8_t *)list->items) / list->memb_size; - } -} - ssize_t list_lsearch(const list_t *list, int compare(const void *key, const void *item), const void *key, void *ret) { @@ -203,7 +185,29 @@ ssize_t list_lsearch(const list_t *list, int compare(const void *key, const void uint8_t (*array)[size] = list->items; for (size_t i = 0; i < list->length; ++i) { - if (compare(key, &array[i]) == 0) { + if (compare(&array[i], key) == 0) { + if (ret) { + memcpy(ret, &array[i], size); + } + return i; + } + } + + return -1; +} + +ssize_t list_lsearchp(const list_t *list, int compare(const void *key, const void *item), + const void *key, void *ret) { + + if (!sway_assert(list && compare && key, "Invalid argument")) { + return -1; + } + + size_t size = list->memb_size; + uint8_t (*array)[size] = list->items; + + for (size_t i = 0; i < list->length; ++i) { + if (compare(*(void **)&array[i], key) == 0) { if (ret) { memcpy(ret, &array[i], size); } diff --git a/include/list.h b/include/list.h index b66ff72fc..09b8840ae 100644 --- a/include/list.h +++ b/include/list.h @@ -105,20 +105,22 @@ void list_qsort(list_t *list, int compare(const void *left, const void *right)); void list_isort(list_t *list, int compare(const void *left, const void *right)); /* - * Returns the index of key in the list, using the stdlib bsearch() function, + * Returns the index of the key in the list, using a linear search, * or -1 if it was not found. If ret is not null, the found element will be * copied into it. - * The list must be sorted. */ -ssize_t list_bsearch(const list_t *list, int compare(const void *key, const void *item), +ssize_t list_lsearch(const list_t *list, int compare(const void *item, const void *key), const void *key, void *ret); /* * Returns the index of the key in the list, using a linear search, * or -1 if it was not found. If ret is not null, the found element will be - * copied into it. + * copied into it. The item passed into compare will be dereferenced first. + * For example, if you have a list of char *, it will get a char * instead + * of a char **, unlike list_lsearch. + * list must be a list of pointers. */ -ssize_t list_lsearch(const list_t *list, int compare(const void *key, const void *item), +ssize_t list_lsearchp(const list_t *list, int compare(const void *item, const void *key), const void *key, void *ret); /* diff --git a/sway/commands.c b/sway/commands.c index e4ceafc81..e6c2e6242 100644 --- a/sway/commands.c +++ b/sway/commands.c @@ -103,7 +103,7 @@ void hide_view_in_scratchpad(swayc_t *sp_view) { void input_cmd_apply(struct input_config *input) { struct input_config *ic; - ssize_t i = list_lsearch(config->input_configs, input_identifier_cmp, input->identifier, &ic); + ssize_t i = list_lsearchp(config->input_configs, input_identifier_cmp, input->identifier, &ic); if (i >= 0) { // merge existing config merge_input_config(ic, input); diff --git a/sway/commands/assign.c b/sway/commands/assign.c index 10b5e5d78..d5a90296c 100644 --- a/sway/commands/assign.c +++ b/sway/commands/assign.c @@ -46,7 +46,7 @@ struct cmd_results *cmd_assign(int argc, char **argv) { } else if (crit->tokens->length == 0) { error = cmd_results_new(CMD_INVALID, "assign", "Found no name/value pairs in criteria"); free_criteria(crit); - } else if (list_lsearch(config->criteria, criteria_cmp, &crit, NULL) != -1) { + } else if (list_lsearchp(config->criteria, criteria_cmp, crit, NULL) != -1) { sway_log(L_DEBUG, "assign: Duplicate, skipping."); free_criteria(crit); } else { diff --git a/sway/commands/bar/bindsym.c b/sway/commands/bar/bindsym.c index 912286faa..212e77a50 100644 --- a/sway/commands/bar/bindsym.c +++ b/sway/commands/bar/bindsym.c @@ -34,7 +34,7 @@ struct cmd_results *bar_cmd_bindsym(int argc, char **argv) { struct bar_config *bar = config->current_bar; struct sway_mouse_binding *dup; - ssize_t i = list_lsearch(bar->bindings, sway_mouse_binding_cmp_buttons, &binding, &dup); + ssize_t i = list_lsearchp(bar->bindings, sway_mouse_binding_cmp_buttons, binding, &dup); if (i > -1) { sway_log(L_DEBUG, "bindsym - '%s' for swaybar already exists, overwriting", argv[0]); free_sway_mouse_binding(dup); diff --git a/sway/commands/bind.c b/sway/commands/bind.c index 528e47557..fdf9c1eae 100644 --- a/sway/commands/bind.c +++ b/sway/commands/bind.c @@ -81,7 +81,7 @@ struct cmd_results *cmd_bindsym(int argc, char **argv) { struct sway_mode *mode = config->current_mode; struct sway_binding *dup; - ssize_t i = list_lsearch(mode->bindings, sway_binding_cmp_keys, &binding, &dup); + ssize_t i = list_lsearchp(mode->bindings, sway_binding_cmp_keys, binding, &dup); if (i > -1) { sway_log(L_DEBUG, "bindsym - '%s' already exists, overwriting", argv[0]); free_sway_binding(dup); @@ -152,7 +152,7 @@ struct cmd_results *cmd_bindcode(int argc, char **argv) { struct sway_mode *mode = config->current_mode; struct sway_binding *dup; - ssize_t i = list_lsearch(mode->bindings, sway_binding_cmp_keys, &binding, &dup); + ssize_t i = list_lsearchp(mode->bindings, sway_binding_cmp_keys, binding, &dup); if (i > -1) { if (dup->bindcode) { sway_log(L_DEBUG, "bindcode - '%s' already exists, overwriting", argv[0]); diff --git a/sway/commands/for_window.c b/sway/commands/for_window.c index d09490dca..884421580 100644 --- a/sway/commands/for_window.c +++ b/sway/commands/for_window.c @@ -30,7 +30,7 @@ struct cmd_results *cmd_for_window(int argc, char **argv) { } else if (crit->tokens->length == 0) { error = cmd_results_new(CMD_INVALID, "for_window", "Found no name/value pairs in criteria"); free_criteria(crit); - } else if (list_lsearch(config->criteria, criteria_cmp, &crit, NULL) != -1) { + } else if (list_lsearchp(config->criteria, criteria_cmp, crit, NULL) != -1) { sway_log(L_DEBUG, "for_window: Duplicate, skipping."); free_criteria(crit); } else { diff --git a/sway/commands/mark.c b/sway/commands/mark.c index a93239a20..0bf823b7a 100644 --- a/sway/commands/mark.c +++ b/sway/commands/mark.c @@ -12,7 +12,7 @@ static void find_marks_callback(swayc_t *container, void *_mark) { return; } - ssize_t index = list_lsearch(container->marks, strcmp_ptr, &mark, NULL); + ssize_t index = list_lsearchp(container->marks, (int (*)(const void *, const void *))strcmp, mark, NULL); if (index != -1) { list_delete(container->marks, index); } @@ -51,7 +51,7 @@ struct cmd_results *cmd_mark(int argc, char **argv) { if (add) { ssize_t index; char *item; - if ((index = list_lsearch(view->marks, strcmp_ptr, &mark, &item)) != -1) { + if ((index = list_lsearchp(view->marks, (int (*)(const void *, const void *))strcmp, mark, &item)) != -1) { if (toggle) { free(item); list_delete(view->marks, index); @@ -66,7 +66,7 @@ struct cmd_results *cmd_mark(int argc, char **argv) { list_add(view->marks, &mark); } } else { - if (toggle && list_lsearch(view->marks, strcmp_ptr, &mark, NULL) != -1) { + if (toggle && list_lsearchp(view->marks, (int (*)(const void *, const void *))strcmp, mark, NULL) != -1) { // Delete the list list_free_withp(view->marks, free); view->marks = NULL; diff --git a/sway/commands/no_focus.c b/sway/commands/no_focus.c index adcbbbf9d..e38febb0b 100644 --- a/sway/commands/no_focus.c +++ b/sway/commands/no_focus.c @@ -30,7 +30,7 @@ struct cmd_results *cmd_no_focus(int argc, char **argv) { } else if (crit->tokens->length == 0) { error = cmd_results_new(CMD_INVALID, "no_focus", "Found no name/value pairs in criteria"); free_criteria(crit); - } else if (list_lsearch(config->no_focus, criteria_cmp, &crit, NULL) != -1) { + } else if (list_lsearchp(config->no_focus, criteria_cmp, crit, NULL) != -1) { sway_log(L_DEBUG, "no_focus: Duplicate, skipping."); free_criteria(crit); } else { diff --git a/sway/commands/output.c b/sway/commands/output.c index b28233e07..3b7062cfe 100644 --- a/sway/commands/output.c +++ b/sway/commands/output.c @@ -157,7 +157,7 @@ struct cmd_results *cmd_output(int argc, char **argv) { } struct output_config *oc; - ssize_t i = list_lsearch(config->output_configs, output_name_cmp, &name, &oc); + ssize_t i = list_lsearchp(config->output_configs, output_name_cmp, name, &oc); if (i >= 0) { // merge existing config merge_output_config(oc, output); diff --git a/sway/commands/unmark.c b/sway/commands/unmark.c index 938c0a84d..0ad22bbbd 100644 --- a/sway/commands/unmark.c +++ b/sway/commands/unmark.c @@ -12,7 +12,7 @@ struct cmd_results *cmd_unmark(int argc, char **argv) { char *mark = join_args(argv, argc); char *item; ssize_t index; - if ((index = list_lsearch(view->marks, strcmp_ptr, &mark, &item)) != -1) { + if ((index = list_lsearchp(view->marks, (int (*)(const void *, const void *))strcmp, mark, &item)) != -1) { free(item); list_delete(view->marks, index); diff --git a/sway/commands/workspace.c b/sway/commands/workspace.c index 34d14094d..d8817259b 100644 --- a/sway/commands/workspace.c +++ b/sway/commands/workspace.c @@ -36,7 +36,7 @@ struct cmd_results *cmd_workspace(int argc, char **argv) { wso->output = strdup(argv[output_location + 1]); ssize_t i = -1; struct workspace_output *old; - if ((i = list_lsearch(config->workspace_outputs, workspace_output_cmp_workspace, &wso, &old)) != -1) { + if ((i = list_lsearchp(config->workspace_outputs, workspace_output_cmp_workspace, wso, &old)) != -1) { free(old); // workspaces can only be assigned to a single output list_delete(config->workspace_outputs, i); } diff --git a/sway/config.c b/sway/config.c index 3b3fbf9ed..5f2115b04 100644 --- a/sway/config.c +++ b/sway/config.c @@ -351,9 +351,9 @@ cleanup: sway_abort("Unable to allocate config structures"); } -static int compare_modifiers(const void *key, const void *item) { - uint32_t a = **(uint32_t **)item; - uint32_t b = *(uint32_t *)key; +static int compare_modifiers(const void *left, const void *right) { + uint32_t a = *(uint32_t *)left; + uint32_t b = *(uint32_t *)right; return a - b; } @@ -367,7 +367,7 @@ void update_active_bar_modifiers() { for (size_t i = 0; i < config->bars->length; ++i) { struct bar_config *bar = list_getp(config->bars, i); if (strcmp(bar->mode, "hide") == 0 && strcmp(bar->hidden_state, "hide") == 0) { - if (list_lsearch(config->active_bar_modifiers, compare_modifiers, &bar->modifier, NULL) < 0) { + if (list_lsearchp(config->active_bar_modifiers, compare_modifiers, &bar->modifier, NULL) < 0) { list_add(config->active_bar_modifiers, &bar->modifier); } } @@ -781,17 +781,17 @@ bool read_config(FILE *file, struct sway_config *config) { return success; } -int input_identifier_cmp(const void *key, const void *item) { - const struct input_config *const *ic = item; - const char *identifier = key; - return strcmp((*ic)->identifier, identifier); +int input_identifier_cmp(const void *item, const void *data) { + const struct input_config *ic = item; + const char *identifier = data; + return strcmp(ic->identifier, identifier); } -int output_name_cmp(const void *key, const void *item) { - const struct output_config *const *output = item; - const char *const *name = key; +int output_name_cmp(const void *item, const void *data) { + const struct output_config *output = item; + const char *name = data; - return strcmp((*output)->name, *name); + return strcmp(output->name, name); } void merge_input_config(struct input_config *dst, struct input_config *src) { @@ -1093,7 +1093,7 @@ void apply_output_config(struct output_config *oc, swayc_t *output) { // Look for a * config for background struct output_config *item; const char *str = "*"; - if (list_lsearch(config->output_configs, output_name_cmp, &str, &item) != -1) { + if (list_lsearchp(config->output_configs, output_name_cmp, str, &item) != -1) { oc = item; } else { oc = NULL; @@ -1181,14 +1181,13 @@ char *do_var_replacement(char *str) { // the naming is intentional (albeit long): a workspace_output_cmp function // would compare two structs in full, while this method only compares the // workspace. -int workspace_output_cmp_workspace(const void *key, const void *item) { - const struct workspace_output *const *wsa = item, *const *wsb = key; - return lenient_strcmp((*wsa)->workspace, (*wsb)->workspace); +int workspace_output_cmp_workspace(const void *a, const void *b) { + const struct workspace_output *wsa = a, *wsb = b; + return lenient_strcmp(wsa->workspace, wsb->workspace); } -int sway_binding_cmp_keys(const void *key, const void *item) { - const struct sway_binding *binda = *(struct sway_binding **)item; - const struct sway_binding *bindb = *(struct sway_binding **)key; +int sway_binding_cmp_keys(const void *a, const void *b) { + const struct sway_binding *binda = a, *bindb = b; // Count keys pressed for this binding. important so we check long before // short ones. for example mod+a+b before mod+a @@ -1235,7 +1234,7 @@ int sway_binding_cmp_keys(const void *key, const void *item) { int sway_binding_cmp(const void *a, const void *b) { int cmp = 0; - if ((cmp = sway_binding_cmp_keys(&a, &b)) != 0) { + if ((cmp = sway_binding_cmp_keys(a, b)) != 0) { return cmp; } const struct sway_binding *binda = a, *bindb = b; @@ -1247,20 +1246,13 @@ int sway_binding_cmp_qsort(const void *a, const void *b) { } void free_sway_binding(struct sway_binding *binding) { - if (binding->keys) { - for (size_t i = 0; i < binding->keys->length; i++) { - free(list_getp(binding->keys, i)); - } - list_free(binding->keys); - } - if (binding->command) { - free(binding->command); - } + list_free_withp(binding->keys, free); + free(binding->command); free(binding); } -int sway_mouse_binding_cmp_buttons(const void *key, const void *item) { - const struct sway_mouse_binding *binda = item, *bindb = key; +int sway_mouse_binding_cmp_buttons(const void *a, const void *b) { + const struct sway_mouse_binding *binda = a, *bindb = b; if (binda->button > bindb->button) { return 1; } diff --git a/sway/criteria.c b/sway/criteria.c index cd87ee4f2..4aec3fd7e 100644 --- a/sway/criteria.c +++ b/sway/criteria.c @@ -238,10 +238,8 @@ ect_cleanup: return error; } -static int regex_cmp(const void *key, const void *item) { - const pcre *regex = key; - const char *const *str = item; - return pcre_exec(regex, NULL, *str, strlen(*str), 0, 0, NULL, 0); +static int regex_cmp(const char *item, const pcre *regex) { + return pcre_exec(regex, NULL, item, strlen(item), 0, 0, NULL, 0); } // test a single view if it matches list of criteria tokens (all of them). @@ -261,15 +259,14 @@ static bool criteria_test(swayc_t *cont, list_t *tokens) { if (focused->class && strcmp(cont->class, focused->class) == 0) { matches++; } - } else if (crit->regex && regex_cmp(crit->regex, &cont->class) == 0) { + } else if (crit->regex && regex_cmp(cont->class, crit->regex) == 0) { matches++; } break; case CRIT_CON_MARK: - if (crit->regex && cont->marks && (list_lsearch(cont->marks, regex_cmp, crit->regex, NULL) != -1)) { + if (crit->regex && cont->marks && (list_lsearchp(cont->marks, (int (*)(const void *, const void *))regex_cmp, crit->regex, NULL) != -1)) { // Make sure it isn't matching the NUL string - const char *nul = ""; - if ((strcmp(crit->raw, "") == 0) == (list_lsearch(cont->marks, strcmp_ptr, &nul, NULL) != -1)) { + if ((strcmp(crit->raw, "") == 0) == (list_lsearchp(cont->marks, (int (*)(const void *, const void *))strcmp, "", NULL) != -1)) { ++matches; } } @@ -277,7 +274,7 @@ static bool criteria_test(swayc_t *cont, list_t *tokens) { case CRIT_ID: if (!cont->app_id) { // ignore - } else if (crit->regex && regex_cmp(crit->regex, &cont->app_id) == 0) { + } else if (crit->regex && regex_cmp(cont->app_id, crit->regex) == 0) { matches++; } break; @@ -289,7 +286,7 @@ static bool criteria_test(swayc_t *cont, list_t *tokens) { if (focused->instance && strcmp(cont->instance, focused->instance) == 0) { matches++; } - } else if (crit->regex && regex_cmp(crit->regex, &cont->instance) == 0) { + } else if (crit->regex && regex_cmp(cont->instance, crit->regex) == 0) { matches++; } break; @@ -301,7 +298,7 @@ static bool criteria_test(swayc_t *cont, list_t *tokens) { if (focused->name && strcmp(cont->name, focused->name) == 0) { matches++; } - } else if (crit->regex && regex_cmp(crit->regex, &cont->name) == 0) { + } else if (crit->regex && regex_cmp(cont->name, crit->regex) == 0) { matches++; } break; @@ -321,7 +318,7 @@ static bool criteria_test(swayc_t *cont, list_t *tokens) { if (focused_ws->name && strcmp(cont_ws->name, focused_ws->name) == 0) { matches++; } - } else if (crit->regex && regex_cmp(crit->regex, &cont_ws->name) == 0) { + } else if (crit->regex && regex_cmp(cont_ws->name, crit->regex) == 0) { matches++; } break; @@ -333,16 +330,15 @@ static bool criteria_test(swayc_t *cont, list_t *tokens) { return matches == tokens->length; } -int criteria_cmp(const void *key, const void *item) { - if (key == item) { +int criteria_cmp(const void *a, const void *b) { + if (a == b) { return 0; - } else if (!item) { + } else if (!a) { return -1; - } else if (!key) { + } else if (!b) { return 1; } - const struct criteria *crit_a = *(struct criteria **)item; - const struct criteria *crit_b = *(struct criteria **)key; + const struct criteria *crit_a = a, *crit_b = b; int cmp = lenient_strcmp(crit_a->cmdlist, crit_b->cmdlist); if (cmp != 0) { return cmp;