summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSébastien Helleu <flashcode@flashtux.org>2023-09-02 11:53:56 +0200
committerSébastien Helleu <flashcode@flashtux.org>2023-10-17 18:14:53 +0200
commite34071131ec31b53c9dc4491f9eb2aa546a23ac7 (patch)
tree5d67e684f5d419026eb2c9b9697c1a706f45f893
parent9bc9df47d72af83313483c7324d3dcae9157f939 (diff)
downloadweechat-e34071131ec31b53c9dc4491f9eb2aa546a23ac7.zip
api: add function string_concat (issue #2005)
-rw-r--r--ChangeLog.adoc2
-rw-r--r--doc/en/weechat_plugin_api.en.adoc40
-rw-r--r--doc/fr/weechat_plugin_api.fr.adoc40
-rw-r--r--doc/it/weechat_plugin_api.it.adoc45
-rw-r--r--doc/ja/weechat_plugin_api.ja.adoc45
-rw-r--r--doc/sr/weechat_plugin_api.sr.adoc45
-rw-r--r--src/core/wee-string.c74
-rw-r--r--src/core/wee-string.h5
-rw-r--r--src/core/weechat.c1
-rw-r--r--src/plugins/plugin.c1
-rw-r--r--src/plugins/weechat-plugin.h9
-rw-r--r--tests/unit/core/test-core-string.cpp29
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));
+}