From e3c47c33fa3a1fb9412198413962ac35f4483240 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C5=99emysl=20Eric=20Janouch?= Date: Mon, 14 Jun 2021 08:33:59 +0200 Subject: [PATCH] degesch: implement -=/+= for multiple values It didn't make sense to have these unimplemented, though perhaps += shouldn't enforce a set. Sadly, autocomplete is fairly difficult for -= of multiple items. --- NEWS | 2 ++ degesch.c | 80 ++++++++++++++++++++++++++----------------------------- 2 files changed, 40 insertions(+), 42 deletions(-) diff --git a/NEWS b/NEWS index 04979e7..2a8a9a1 100644 --- a/NEWS +++ b/NEWS @@ -11,6 +11,8 @@ * degesch: /deop and /devoice without arguments will use the client's user + * degesch: /set +=/-= now treats its argument as a string array + * censor.lua: now stripping colours from censored messages; their attributes are also configurable rather than always black on black diff --git a/degesch.c b/degesch.c index e96b21a..3262691 100644 --- a/degesch.c +++ b/degesch.c @@ -11053,45 +11053,38 @@ handle_command_buffer (struct handler_args *a) return result; } -static bool -replace_string_array - (struct config_item *item, struct strv *array, struct error **e) -{ - char *changed = strv_join (array, ","); - struct str tmp = { .str = changed, .len = strlen (changed) }; - bool result = config_item_set_from (item, - config_item_string_array (&tmp), e); - free (changed); - return result; -} - static bool handle_command_set_add - (struct config_item *item, const char *value, struct error **e) + (struct strv *items, const struct strv *values, struct error **e) { - struct strv items = strv_make (); - if (item->type != CONFIG_ITEM_NULL) - cstr_split (item->value.string.str, ",", false, &items); - if (items.len == 1 && !*items.vector[0]) - strv_reset (&items); - - // FIXME: handle multiple items properly - bool result = false; - if (strv_find (&items, value) != -1) - error_set (e, "already present in the array: %s", value); - else + for (size_t i = 0; i < values->len; i++) { - strv_append (&items, value); - result = replace_string_array (item, &items, e); + const char *value = values->vector[i]; + if (strv_find (items, values->vector[i]) != -1) + return error_set (e, "already present in the array: %s", value); + strv_append (items, value); } - - strv_free (&items); - return result; + return true; } static bool handle_command_set_remove - (struct config_item *item, const char *value, struct error **e) + (struct strv *items, const struct strv *values, struct error **e) +{ + for (size_t i = 0; i < values->len; i++) + { + const char *value = values->vector[i]; + ssize_t i = strv_find (items, value); + if (i == -1) + return error_set (e, "not present in the array: %s", value); + strv_remove (items, i); + } + return true; +} + +static bool +handle_command_set_modify + (struct config_item *item, const char *value, bool add, struct error **e) { struct strv items = strv_make (); if (item->type != CONFIG_ITEM_NULL) @@ -11099,18 +11092,23 @@ handle_command_set_remove if (items.len == 1 && !*items.vector[0]) strv_reset (&items); - // FIXME: handle multiple items properly - bool result = false; - ssize_t i = strv_find (&items, value); - if (i == -1) - error_set (e, "not present in the array: %s", value); - else + struct strv values = strv_make (); + cstr_split (value, ",", false, &values); + bool result = add + ? handle_command_set_add (&items, &values, e) + : handle_command_set_remove (&items, &values, e); + + if (result) { - strv_remove (&items, i); - result = replace_string_array (item, &items, e); + char *changed = strv_join (&items, ","); + struct str tmp = { .str = changed, .len = strlen (changed) }; + result = config_item_set_from (item, + config_item_string_array (&tmp), e); + free (changed); } strv_free (&items); + strv_free (&values); return result; } @@ -11129,10 +11127,8 @@ handle_command_set_assign_item (struct app_context *ctx, config_item_set_from (item, config_item_clone (new_), &e); else if (item->schema->type != CONFIG_ITEM_STRING_ARRAY) error_set (&e, "not a string array"); - else if (add) - handle_command_set_add (item, new_->value.string.str, &e); - else if (remove) - handle_command_set_remove (item, new_->value.string.str, &e); + else + handle_command_set_modify (item, new_->value.string.str, add, &e); if (e) {