diff --git a/common/list.c b/common/list.c index feaf8abf7..16956632f 100644 --- a/common/list.c +++ b/common/list.c @@ -152,6 +152,11 @@ void *list_get(list_t *list, size_t index) { return &array[index]; } +void *list_getp(list_t *list, size_t index) { + void **elem = list_get(list, index); + return elem ? *elem : NULL; +} + void list_qsort(list_t *list, int compare(const void *, const void *)) { if (!sway_assert(list && compare, "Invalid argument")) { return; @@ -211,7 +216,7 @@ 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(key, &array[i]) == 0) { if (ret) { memcpy(ret, &array[i], size); } diff --git a/common/stringop.c b/common/stringop.c index 167562256..7a7696516 100644 --- a/common/stringop.c +++ b/common/stringop.c @@ -386,3 +386,7 @@ char *argsep(char **stringp, const char *delim) { found: return start; } + +int strcmp_ptr(const void *a, const void *b) { + return strcmp(*(char **)a, *(char **)b); +} diff --git a/include/list.h b/include/list.h index ee9143f71..5ab15c227 100644 --- a/include/list.h +++ b/include/list.h @@ -89,6 +89,15 @@ void list_swap(list_t *list, size_t i1, size_t i2); */ void *list_get(list_t *list, size_t index); +/* + * Gets an element of a list and dereferences it. + * For example, if you have a list of char *, this function + * will return a char * instead of a char **, unlike list_get. + * index must be less than the length of the list. + * list must be a list of pointers. + */ +void *list_getp(list_t *list, size_t index); + /* * Sorts the list using the stdlib qsort() function. */ diff --git a/include/stringop.h b/include/stringop.h index 7c29a745e..85659b0ad 100644 --- a/include/stringop.h +++ b/include/stringop.h @@ -14,6 +14,10 @@ char *strip_whitespace(char *str); char *strip_comments(char *str); void strip_quotes(char *str); +// strcmp that dereferences args first. +// Designed to be taken by list_lsearch and such +int strcmp_ptr(const void *a, const void *b); + // strcmp that also handles null pointers. int lenient_strcmp(char *a, char *b); diff --git a/sway/commands/assign.c b/sway/commands/assign.c index baeebc9c7..10b5e5d78 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_lsearch(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 83c7ec38c..912286faa 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_lsearch(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 2f504bc34..adfd05d75 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_lsearch(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_lsearch(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 49f2daa4a..d09490dca 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_lsearch(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 de51604c9..66452a62c 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, (int (*)(const void *, const void *))strcmp, mark, NULL); + ssize_t index = list_lsearch(container->marks, strcmp_ptr, &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, (int (*)(const void *, const void *))strcmp, mark, &item)) != -1) { + if ((index = list_lsearch(view->marks, strcmp_ptr, &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, (int (*)(const void *, const void *))strcmp, mark, NULL) != -1) { + if (toggle && list_lsearch(view->marks, strcmp_ptr, &mark, NULL) != -1) { // Delete the list list_foreach(view->marks, list_elem_free); list_free(view->marks); diff --git a/sway/commands/no_focus.c b/sway/commands/no_focus.c index dcecc3c4e..adcbbbf9d 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_lsearch(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 d9ab5d0f2..1a9353974 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_lsearch(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 35d46a744..30c001173 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, (int (*)(const void *, const void *))strcmp, mark, &item)) != -1) { + if ((index = list_lsearch(view->marks, strcmp_ptr, &mark, &item)) != -1) { free(item); list_delete(view->marks, index); diff --git a/sway/commands/workspace.c b/sway/commands/workspace.c index f79ec9443..34d14094d 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_lsearch(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 12d05dae0..d737ae65a 100644 --- a/sway/config.c +++ b/sway/config.c @@ -395,9 +395,9 @@ cleanup: sway_abort("Unable to allocate config structures"); } -static int compare_modifiers(const void *left, const void *right) { - uint32_t a = *(uint32_t *)left; - uint32_t b = *(uint32_t *)right; +static int compare_modifiers(const void *key, const void *item) { + uint32_t a = **(uint32_t **)item; + uint32_t b = *(uint32_t *)key; return a - b; } @@ -831,11 +831,11 @@ int input_identifier_cmp(const void *key, const void *item) { return strcmp((*ic)->identifier, identifier); } -int output_name_cmp(const void *item, const void *data) { - const struct output_config *output = item; - const char *name = data; +int output_name_cmp(const void *key, const void *item) { + const struct output_config *const *output = item; + const char *const *name = key; - return strcmp(output->name, name); + return strcmp((*output)->name, *name); } void merge_input_config(struct input_config *dst, struct input_config *src) { @@ -1136,7 +1136,8 @@ void apply_output_config(struct output_config *oc, swayc_t *output) { if (!oc || !oc->background) { // Look for a * config for background struct output_config *item; - if (list_lsearch(config->output_configs, output_name_cmp, "*", &item) != -1) { + const char *str = "*"; + if (list_lsearch(config->output_configs, output_name_cmp, &str, &item) != -1) { oc = item; } else { oc = NULL; @@ -1224,9 +1225,9 @@ 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 *a, const void *b) { - const struct workspace_output *wsa = a, *wsb = b; - return lenient_strcmp(wsa->workspace, wsb->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 sway_binding_cmp_keys(const void *key, const void *item) { diff --git a/sway/criteria.c b/sway/criteria.c index 83a4993ec..f8a8d5097 100644 --- a/sway/criteria.c +++ b/sway/criteria.c @@ -240,8 +240,8 @@ ect_cleanup: static int regex_cmp(const void *key, const void *item) { const pcre *regex = key; - const char *str = item; - return pcre_exec(regex, NULL, str, strlen(str), 0, 0, NULL, 0); + const char *const *str = item; + return pcre_exec(regex, NULL, *str, strlen(*str), 0, 0, NULL, 0); } // test a single view if it matches list of criteria tokens (all of them). @@ -261,14 +261,15 @@ 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(cont->class, crit->regex) == 0) { + } else if (crit->regex && regex_cmp(crit->regex, &cont->class) == 0) { matches++; } break; case CRIT_CON_MARK: if (crit->regex && cont->marks && (list_lsearch(cont->marks, regex_cmp, crit->regex, NULL) != -1)) { // Make sure it isn't matching the NUL string - if ((strcmp(crit->raw, "") == 0) == (list_lsearch(cont->marks, (int (*)(const void *, const void *))strcmp, "", NULL) != -1)) { + const char *nul = ""; + if ((strcmp(crit->raw, "") == 0) == (list_lsearch(cont->marks, strcmp_ptr, &nul, NULL) != -1)) { ++matches; } } @@ -276,7 +277,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(cont->app_id, crit->regex) == 0) { + } else if (crit->regex && regex_cmp(crit->regex, &cont->app_id) == 0) { matches++; } break; @@ -288,7 +289,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(cont->instance, crit->regex) == 0) { + } else if (crit->regex && regex_cmp(crit->regex, &cont->instance) == 0) { matches++; } break; @@ -300,7 +301,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(cont->name, crit->regex) == 0) { + } else if (crit->regex && regex_cmp(crit->regex, &cont->name) == 0) { matches++; } break; @@ -320,7 +321,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(cont_ws->name, crit->regex) == 0) { + } else if (crit->regex && regex_cmp(crit->regex, &cont_ws->name) == 0) { matches++; } break; @@ -340,7 +341,8 @@ int criteria_cmp(const void *key, const void *item) { } else if (!key) { return 1; } - const struct criteria *crit_a = item, *crit_b = key; + const struct criteria *crit_a = *(struct criteria **)item; + const struct criteria *crit_b = *(struct criteria **)key; int cmp = lenient_strcmp(crit_a->cmdlist, crit_b->cmdlist); if (cmp != 0) { return cmp;