diff options
author | Sébastien Helleu <flashcode@flashtux.org> | 2023-09-02 11:53:56 +0200 |
---|---|---|
committer | Sébastien Helleu <flashcode@flashtux.org> | 2023-10-17 18:14:53 +0200 |
commit | e34071131ec31b53c9dc4491f9eb2aa546a23ac7 (patch) | |
tree | 5d67e684f5d419026eb2c9b9697c1a706f45f893 | |
parent | 9bc9df47d72af83313483c7324d3dcae9157f939 (diff) | |
download | weechat-e34071131ec31b53c9dc4491f9eb2aa546a23ac7.zip |
api: add function string_concat (issue #2005)
-rw-r--r-- | ChangeLog.adoc | 2 | ||||
-rw-r--r-- | doc/en/weechat_plugin_api.en.adoc | 40 | ||||
-rw-r--r-- | doc/fr/weechat_plugin_api.fr.adoc | 40 | ||||
-rw-r--r-- | doc/it/weechat_plugin_api.it.adoc | 45 | ||||
-rw-r--r-- | doc/ja/weechat_plugin_api.ja.adoc | 45 | ||||
-rw-r--r-- | doc/sr/weechat_plugin_api.sr.adoc | 45 | ||||
-rw-r--r-- | src/core/wee-string.c | 74 | ||||
-rw-r--r-- | src/core/wee-string.h | 5 | ||||
-rw-r--r-- | src/core/weechat.c | 1 | ||||
-rw-r--r-- | src/plugins/plugin.c | 1 | ||||
-rw-r--r-- | src/plugins/weechat-plugin.h | 9 | ||||
-rw-r--r-- | tests/unit/core/test-core-string.cpp | 29 |
12 files changed, 334 insertions, 2 deletions
diff --git a/ChangeLog.adoc b/ChangeLog.adoc index 646872337..7f3268697 100644 --- a/ChangeLog.adoc +++ b/ChangeLog.adoc @@ -37,7 +37,7 @@ New features:: * core: add options weechat.buffer.* to save buffer properties set by user, add option `setauto` in command `/buffer` (issue #352) * core: add parameters and key bindings to move to edges of current area with commands `/cursor go` and `/cursor move` (issue #1282) * core: add variables "_chat_focused_line_bol" and "_chat_focused_line_eol" in focus data (issue #1955) - * api: add function hook_url, add option `url` in command `/debug` (issue #1723) + * api: add function string_concat (issue #2005) * api: add support of path to variable and hashtable comparison in function hdata_compare (issue #1066) * api: add infos "nick_color_ignore_case" and "nick_color_name_ignore_case" (issue #194) * api: add info "buffer" (issue #1962) diff --git a/doc/en/weechat_plugin_api.en.adoc b/doc/en/weechat_plugin_api.en.adoc index 2be3f7237..bbd2ec40a 100644 --- a/doc/en/weechat_plugin_api.en.adoc +++ b/doc/en/weechat_plugin_api.en.adoc @@ -3476,6 +3476,46 @@ weechat_string_dyn_free (string, 1); [NOTE] This function is not available in scripting API. +==== string_concat + +_WeeChat ≥ 4.2.0._ + +Concatenate multiple strings using a separator. + +Prototype: + +[source,c] +---- +const char *weechat_string_concat (const char *separator, ...); +---- + +Arguments: + +* _separator_: the separator string which is inserted between concatenated + strings (can be NULL or empty string) + +[NOTE] +Last argument *MUST* always be NULL. + +A macro called `WEECHAT_STR_CONCAT` can be used, where the final NULL value is +not needed (usage of this macro is recommended). + +Return value: + +* concatenated string + +C example: + +[source,c] +---- +const char *result = weechat_string_concat (" / ", "abc", "def", "ghi", NULL); /* result == "abc / def / ghi" */ + +/* with macro */ +const char *result = WEECHAT_STR_CONCAT(" / ", "abc", "def", "ghi"); /* result == "abc / def / ghi" */ +---- + +[NOTE] +This function is not available in scripting API. + [[utf-8]] === UTF-8 diff --git a/doc/fr/weechat_plugin_api.fr.adoc b/doc/fr/weechat_plugin_api.fr.adoc index 42b1ff747..c9432f18a 100644 --- a/doc/fr/weechat_plugin_api.fr.adoc +++ b/doc/fr/weechat_plugin_api.fr.adoc @@ -3533,6 +3533,46 @@ weechat_string_dyn_free (string, 1); [NOTE] Cette fonction n'est pas disponible dans l'API script. +==== string_concat + +_WeeChat ≥ 4.2.0._ + +Concaténer plusieurs chaînes de caractères en utilisant un séparateur. + +Prototype : + +[source,c] +---- +const char *weechat_string_concat (const char *separator, ...); +---- + +Paramètres : + +* _separator_ : la chaîne de séparation qui est insérée entre les chaînes + concaténées (peut être NULL ou une chaîne vide) + +[NOTE] +Le dernier paramètre *DOIT* toujours être NULL. + +Une macro nommée `WEECHAT_STR_CONCAT` peut être utilisée, où la valeur finale +NULL n'est pas nécessaire (l'utilisation de cette macro est recommandée). + +Valeur de retour : + +* chaîne concaténée + +Exemple en C : + +[source,c] +---- +const char *result = weechat_string_concat (" / ", "abc", "def", "ghi", NULL); /* result == "abc / def / ghi" */ + +/* with macro */ +const char *result = WEECHAT_STR_CONCAT(" / ", "abc", "def", "ghi"); /* result == "abc / def / ghi" */ +---- + +[NOTE] +Cette fonction n'est pas disponible dans l'API script. + [[utf-8]] === UTF-8 diff --git a/doc/it/weechat_plugin_api.it.adoc b/doc/it/weechat_plugin_api.it.adoc index 6efd0c6e9..c8330e7fc 100644 --- a/doc/it/weechat_plugin_api.it.adoc +++ b/doc/it/weechat_plugin_api.it.adoc @@ -3641,6 +3641,51 @@ weechat_string_dyn_free (string, 1); [NOTE] Questa funzione non è disponibile nelle API per lo scripting. +==== string_concat + +_WeeChat ≥ 4.2.0._ + +// TRANSLATION MISSING +Concatenate multiple strings using a separator. + +Prototipo: + +[source,c] +---- +const char *weechat_string_concat (const char *separator, ...); +---- + +Argomenti: + +// TRANSLATION MISSING +* _separator_: the separator string which is inserted between concatenated + strings (can be NULL or empty string) + +// TRANSLATION MISSING +[NOTE] +Last argument *MUST* always be NULL. + +A macro called `WEECHAT_STR_CONCAT` can be used, where the final NULL value is +not needed (usage of this macro is recommended). + +Valore restituito: + +// TRANSLATION MISSING +* concatenated string + +Esempio in C: + +// TRANSLATION MISSING +[source,c] +---- +const char *result = weechat_string_concat (" / ", "abc", "def", "ghi", NULL); /* result == "abc / def / ghi" */ + +/* with macro */ +const char *result = WEECHAT_STR_CONCAT(" / ", "abc", "def", "ghi"); /* result == "abc / def / ghi" */ +---- + +[NOTE] +Questa funzione non è disponibile nelle API per lo scripting. + [[utf-8]] === UTF-8 diff --git a/doc/ja/weechat_plugin_api.ja.adoc b/doc/ja/weechat_plugin_api.ja.adoc index f651d640d..406a5560a 100644 --- a/doc/ja/weechat_plugin_api.ja.adoc +++ b/doc/ja/weechat_plugin_api.ja.adoc @@ -3579,6 +3579,51 @@ weechat_string_dyn_free (string, 1); [NOTE] スクリプト API ではこの関数を利用できません。 +==== string_concat + +_WeeChat ≥ 4.2.0._ + +// TRANSLATION MISSING +Concatenate multiple strings using a separator. + +プロトタイプ: + +[source,c] +---- +const char *weechat_string_concat (const char *separator, ...); +---- + +引数: + +// TRANSLATION MISSING +* _separator_: the separator string which is inserted between concatenated + strings (can be NULL or empty string) + +// TRANSLATION MISSING +[NOTE] +Last argument *MUST* always be NULL. + +A macro called `WEECHAT_STR_CONCAT` can be used, where the final NULL value is +not needed (usage of this macro is recommended). + +戻り値: + +// TRANSLATION MISSING +* concatenated string + +C 言語での使用例: + +// TRANSLATION MISSING +[source,c] +---- +const char *result = weechat_string_concat (" / ", "abc", "def", "ghi", NULL); /* result == "abc / def / ghi" */ + +/* with macro */ +const char *result = WEECHAT_STR_CONCAT(" / ", "abc", "def", "ghi"); /* result == "abc / def / ghi" */ +---- + +[NOTE] +スクリプト API ではこの関数を利用できません。 + [[utf-8]] === UTF-8 diff --git a/doc/sr/weechat_plugin_api.sr.adoc b/doc/sr/weechat_plugin_api.sr.adoc index dc9e538b8..393ffe570 100644 --- a/doc/sr/weechat_plugin_api.sr.adoc +++ b/doc/sr/weechat_plugin_api.sr.adoc @@ -3357,6 +3357,51 @@ weechat_string_dyn_free (string, 1); [NOTE] Ова функција није доступна у API скриптовања. +==== string_concat + +_WeeChat ≥ 4.2.0._ + +// TRANSLATION MISSING +Concatenate multiple strings using a separator. + +Прототип: + +[source,c] +---- +const char *weechat_string_concat (const char *separator, ...); +---- + +Аргументи: + +// TRANSLATION MISSING +* _separator_: the separator string which is inserted between concatenated + strings (can be NULL or empty string) + +// TRANSLATION MISSING +[NOTE] +Last argument *MUST* always be NULL. + +A macro called `WEECHAT_STR_CONCAT` can be used, where the final NULL value is +not needed (usage of this macro is recommended). + +Повратна вредност: + +// TRANSLATION MISSING +* concatenated string + +C пример: + +// TRANSLATION MISSING +[source,c] +---- +const char *result = weechat_string_concat (" / ", "abc", "def", "ghi", NULL); /* result == "abc / def / ghi" */ + +/* with macro */ +const char *result = WEECHAT_STR_CONCAT(" / ", "abc", "def", "ghi"); /* result == "abc / def / ghi" */ +---- + +[NOTE] +Ова функција није доступна у API скриптовања. + [[utf-8]] === UTF-8 diff --git a/src/core/wee-string.c b/src/core/wee-string.c index ab0bee82e..7374f9fe9 100644 --- a/src/core/wee-string.c +++ b/src/core/wee-string.c @@ -66,6 +66,8 @@ #define MIN3(a, b, c) ((a) < (b) ? ((a) < (c) ? (a) : (c)) : ((b) < (c) ? (b) : (c))) struct t_hashtable *string_hashtable_shared = NULL; +int string_concat_index = 0; +char **string_concat_buffer[STRING_NUM_CONCAT_BUFFERS]; /* @@ -4694,15 +4696,87 @@ string_dyn_free (char **string, int free_string) } /* + * Concatenates strings, using a separator (which can be NULL or empty string + * to not use any separator). + * + * Last argument must be NULL to terminate the variable list of arguments. + */ + +const char * +string_concat (const char *separator, ...) +{ + va_list args; + const char *str; + int index; + + string_concat_index = (string_concat_index + 1) % 8; + + if (string_concat_buffer[string_concat_index]) + { + string_dyn_copy (string_concat_buffer[string_concat_index], NULL); + } + else + { + string_concat_buffer[string_concat_index] = string_dyn_alloc (128); + if (!string_concat_buffer[string_concat_index]) + return NULL; + } + + index = 0; + va_start (args, separator); + while (1) + { + str = va_arg (args, const char *); + if (!str) + break; + if ((index > 0) && separator && separator[0]) + { + string_dyn_concat (string_concat_buffer[string_concat_index], + separator, -1); + } + string_dyn_concat (string_concat_buffer[string_concat_index], str, -1); + index++; + } + va_end (args); + + return (const char *)(*string_concat_buffer[string_concat_index]); +} + +/* + * Initializes string. + */ + +void +string_init () +{ + int i; + + for (i = 0; i < STRING_NUM_CONCAT_BUFFERS; i++) + { + string_concat_buffer[i] = NULL; + } +} + +/* * Frees all allocated data. */ void string_end () { + int i; + if (string_hashtable_shared) { hashtable_free (string_hashtable_shared); string_hashtable_shared = NULL; } + for (i = 0; i < STRING_NUM_CONCAT_BUFFERS; i++) + { + if (string_concat_buffer[i]) + { + string_dyn_free (string_concat_buffer[i], 1); + string_concat_buffer[i] = NULL; + } + } } diff --git a/src/core/wee-string.h b/src/core/wee-string.h index 522d3e440..716335e9a 100644 --- a/src/core/wee-string.h +++ b/src/core/wee-string.h @@ -24,6 +24,9 @@ #include <stdint.h> #include <regex.h> +#define STRING_NUM_CONCAT_BUFFERS 8 +#define STR_CONCAT(separator, argz...) string_concat (separator, ##argz, NULL) + typedef uint32_t string_shared_count_t; typedef uint32_t string_dyn_size_t; @@ -157,6 +160,8 @@ extern char **string_dyn_alloc (int size_alloc); extern int string_dyn_copy (char **string, const char *new_string); extern int string_dyn_concat (char **string, const char *add, int bytes); extern char *string_dyn_free (char **string, int free_string); +extern const char *string_concat (const char *separator, ...); +extern void string_init (); extern void string_end (); #endif /* WEECHAT_STRING_H */ diff --git a/src/core/weechat.c b/src/core/weechat.c index 9c11dd16b..4eb80c8b2 100644 --- a/src/core/weechat.c +++ b/src/core/weechat.c @@ -642,6 +642,7 @@ weechat_init (int argc, char *argv[], void (*gui_init_cb)()) ^ getpid ()); weeurl_init (); /* initialize URL */ + string_init (); /* initialize string */ signal_init (); /* initialize signals */ hdata_init (); /* initialize hdata */ hook_init (); /* initialize hooks */ diff --git a/src/plugins/plugin.c b/src/plugins/plugin.c index 91836e3e2..e496d547a 100644 --- a/src/plugins/plugin.c +++ b/src/plugins/plugin.c @@ -658,6 +658,7 @@ plugin_load (const char *filename, int init_plugin, int argc, char **argv) new_plugin->string_dyn_copy = &string_dyn_copy; new_plugin->string_dyn_concat = &string_dyn_concat; new_plugin->string_dyn_free = &string_dyn_free; + new_plugin->string_concat = &string_concat; new_plugin->utf8_has_8bits = &utf8_has_8bits; new_plugin->utf8_is_valid = &utf8_is_valid; diff --git a/src/plugins/weechat-plugin.h b/src/plugins/weechat-plugin.h index ae27b9bdd..e976760bf 100644 --- a/src/plugins/weechat-plugin.h +++ b/src/plugins/weechat-plugin.h @@ -68,7 +68,7 @@ struct timeval; * please change the date with current one; for a second change at same * date, increment the 01, otherwise please keep 01. */ -#define WEECHAT_PLUGIN_API_VERSION "20230908-01" +#define WEECHAT_PLUGIN_API_VERSION "20231017-01" /* macros for defining plugin infos */ #define WEECHAT_PLUGIN_NAME(__name) \ @@ -216,6 +216,10 @@ struct timeval; } \ } +/* macro to concatenate strings */ +#define WEECHAT_STR_CONCAT(separator, argz...) \ + weechat_string_concat (separator, ##argz, NULL) + /* * macro to return error in case of missing arguments in callback of * hook_command @@ -367,6 +371,7 @@ struct t_weechat_plugin int (*string_dyn_copy) (char **string, const char *new_string); int (*string_dyn_concat) (char **string, const char *add, int bytes); char *(*string_dyn_free) (char **string, int free_string); + const char *(*string_concat) (const char *separator, ...); /* UTF-8 strings */ int (*utf8_has_8bits) (const char *string); @@ -1379,6 +1384,8 @@ extern int weechat_plugin_end (struct t_weechat_plugin *plugin); (weechat_plugin->string_dyn_concat)(__string, __add, __bytes) #define weechat_string_dyn_free(__string, __free_string) \ (weechat_plugin->string_dyn_free)(__string, __free_string) +#define weechat_string_concat(__separator, __argz...) \ + (weechat_plugin->string_concat)(__separator, ##__argz) /* UTF-8 strings */ #define weechat_utf8_has_8bits(__string) \ diff --git a/tests/unit/core/test-core-string.cpp b/tests/unit/core/test-core-string.cpp index 11a742161..ea4722e38 100644 --- a/tests/unit/core/test-core-string.cpp +++ b/tests/unit/core/test-core-string.cpp @@ -2969,3 +2969,32 @@ TEST(CoreString, Dyn) string_dyn_free (NULL, 0); string_dyn_free (str, 0); } + +/* + * Tests functions: + * string_concat + */ + +TEST(CoreString, Concat) +{ + STRCMP_EQUAL("", string_concat (NULL, NULL)); + STRCMP_EQUAL("", string_concat (NULL, "", NULL)); + STRCMP_EQUAL("", string_concat ("", "", NULL)); + STRCMP_EQUAL("", string_concat (",", "", NULL)); + + STRCMP_EQUAL("abc", string_concat (NULL, "abc", NULL)); + STRCMP_EQUAL("abcdef", string_concat (NULL, "abc", "def", NULL)); + STRCMP_EQUAL("abcdefghi", string_concat (NULL, "abc", "def", "ghi", NULL)); + + STRCMP_EQUAL("abc", string_concat ("", "abc", NULL)); + STRCMP_EQUAL("abcdef", string_concat ("", "abc", "def", NULL)); + STRCMP_EQUAL("abcdefghi", string_concat ("", "abc", "def", "ghi", NULL)); + + STRCMP_EQUAL("abc", string_concat (",", "abc", NULL)); + STRCMP_EQUAL("abc,def", string_concat (",", "abc", "def", NULL)); + STRCMP_EQUAL("abc,def,ghi", string_concat (",", "abc", "def", "ghi", NULL)); + + STRCMP_EQUAL("abc", string_concat (" / ", "abc", NULL)); + STRCMP_EQUAL("abc / def", string_concat (" / ", "abc", "def", NULL)); + STRCMP_EQUAL("abc / def / ghi", string_concat (" / ", "abc", "def", "ghi", NULL)); +} |