api: add dynamic string functions (string_dyn_*)
New functions: - string_dyn_alloc - string_dyn_copy - string_dyn_concat - string_dyn_freev2.8-utf8proc
parent
a5b00ec979
commit
07d16903f3
|
@ -2169,6 +2169,166 @@ options = {
|
|||
str5 = weechat.string_eval_expression("password=abc password=def", {}, {}, options) # "password=*** password=***"
|
||||
----
|
||||
|
||||
==== string_dyn_alloc
|
||||
|
||||
_WeeChat ≥ 1.8._
|
||||
|
||||
Allocate a dynamic string, with a variable length. +
|
||||
Internally, a structure is allocated with the string pointer, the allocated size
|
||||
and current length of string.
|
||||
|
||||
Only the pointer to string pointer (_**string_) is used in all the
|
||||
_pass:[string_dyn_*]_ functions.
|
||||
|
||||
Prototype:
|
||||
|
||||
[source,C]
|
||||
----
|
||||
char **weechat_dyn_alloc (int size_alloc);
|
||||
----
|
||||
|
||||
Arguments:
|
||||
|
||||
* _size_alloc_: the initial allocated size (must be greater than zero)
|
||||
|
||||
Return value:
|
||||
|
||||
* pointer to the dynamic string
|
||||
|
||||
C example:
|
||||
|
||||
[source,C]
|
||||
----
|
||||
char **string = weechat_dyn_alloc (256);
|
||||
----
|
||||
|
||||
[NOTE]
|
||||
This function is not available in scripting API.
|
||||
|
||||
==== string_dyn_copy
|
||||
|
||||
_WeeChat ≥ 1.8._
|
||||
|
||||
Copy a string in a dynamic string.
|
||||
|
||||
The pointer _*string_ can change if the string is reallocated (if there is
|
||||
not enough space to copy the string).
|
||||
|
||||
Prototype:
|
||||
|
||||
[source,C]
|
||||
----
|
||||
int weechat_dyn_copy (char **string, const char *new_string);
|
||||
----
|
||||
|
||||
Arguments:
|
||||
|
||||
* _string_: pointer to dynamic string
|
||||
* _new_string_: the string to copy
|
||||
|
||||
Return value:
|
||||
|
||||
* 1 if OK, 0 if error
|
||||
|
||||
C example:
|
||||
|
||||
[source,C]
|
||||
----
|
||||
char **string = weechat_dyn_alloc (256);
|
||||
if (weechat_dyn_copy (string, "test"))
|
||||
{
|
||||
/* OK */
|
||||
}
|
||||
else
|
||||
{
|
||||
/* error */
|
||||
}
|
||||
----
|
||||
|
||||
[NOTE]
|
||||
This function is not available in scripting API.
|
||||
|
||||
==== string_dyn_concat
|
||||
|
||||
_WeeChat ≥ 1.8._
|
||||
|
||||
Concatenate a string to a dynamic string.
|
||||
|
||||
The pointer _*string_ can change if the string is reallocated (if there is
|
||||
not enough space to concatenate the string).
|
||||
|
||||
Prototype:
|
||||
|
||||
[source,C]
|
||||
----
|
||||
int weechat_dyn_concat (char **string, const char *add);
|
||||
----
|
||||
|
||||
Arguments:
|
||||
|
||||
* _string_: pointer to dynamic string
|
||||
* _add_: the string to add
|
||||
|
||||
Return value:
|
||||
|
||||
* 1 if OK, 0 if error
|
||||
|
||||
C example:
|
||||
|
||||
[source,C]
|
||||
----
|
||||
char **string = weechat_dyn_alloc (256);
|
||||
if (weechat_dyn_copy (string, "test"))
|
||||
{
|
||||
if (weechat_dyn_concat (string, "abc"))
|
||||
{
|
||||
/* ... */
|
||||
}
|
||||
}
|
||||
----
|
||||
|
||||
[NOTE]
|
||||
This function is not available in scripting API.
|
||||
|
||||
==== string_dyn_free
|
||||
|
||||
_WeeChat ≥ 1.8._
|
||||
|
||||
Free a dynamic string.
|
||||
|
||||
Prototype:
|
||||
|
||||
[source,C]
|
||||
----
|
||||
void weechat_dyn_free (char **string, int free_string);
|
||||
----
|
||||
|
||||
Arguments:
|
||||
|
||||
* _string_: pointer to dynamic string
|
||||
* _free_string_: free the string itself; if 0, the content of _*string_ remains
|
||||
valid after the call to this function
|
||||
|
||||
C example:
|
||||
|
||||
[source,C]
|
||||
----
|
||||
char **string = weechat_dyn_alloc (256);
|
||||
if (weechat_dyn_concat (string, "test"))
|
||||
{
|
||||
/* OK */
|
||||
}
|
||||
else
|
||||
{
|
||||
/* error */
|
||||
}
|
||||
/* ... */
|
||||
weechat_dyn_free (string, 1);
|
||||
----
|
||||
|
||||
[NOTE]
|
||||
This function is not available in scripting API.
|
||||
|
||||
[[utf-8]]
|
||||
=== UTF-8
|
||||
|
||||
|
|
|
@ -2211,6 +2211,166 @@ options = {
|
|||
str5 = weechat.string_eval_expression("password=abc password=def", {}, {}, options) # "password=*** password=***"
|
||||
----
|
||||
|
||||
==== string_dyn_alloc
|
||||
|
||||
_WeeChat ≥ 1.8._
|
||||
|
||||
Allouer une chaîne dynamique, avec une longueur variable. +
|
||||
De manière interne, une structure est allouée avec le pointeur vers la chaîne,
|
||||
la taille allouée et la longueur courante de la chaîne.
|
||||
|
||||
Seul le pointeur de pointeur de chaîne (_**string_) est utilisé dans toutes les fonctions
|
||||
_pass:[string_dyn_*]_.
|
||||
|
||||
Prototype :
|
||||
|
||||
[source,C]
|
||||
----
|
||||
char **weechat_dyn_alloc (int size_alloc);
|
||||
----
|
||||
|
||||
Paramètres :
|
||||
|
||||
* _size_alloc_ : la taille initialement allouée (doit être supérieure à zéro)
|
||||
|
||||
Valeur de retour :
|
||||
|
||||
* pointeur vers la chaîne dynamique
|
||||
|
||||
Exemple en C :
|
||||
|
||||
[source,C]
|
||||
----
|
||||
char **string = weechat_dyn_alloc (256);
|
||||
----
|
||||
|
||||
[NOTE]
|
||||
Cette fonction n'est pas disponible dans l'API script.
|
||||
|
||||
==== string_dyn_copy
|
||||
|
||||
_WeeChat ≥ 1.8._
|
||||
|
||||
Copier une chaîne dans une chaîne dynamique.
|
||||
|
||||
Le pointeur _*string_ peut changer si la chaîne est réallouée (s'il n'y a pas
|
||||
assez de place pour copier la chaîne).
|
||||
|
||||
Prototype :
|
||||
|
||||
[source,C]
|
||||
----
|
||||
int weechat_dyn_copy (char **string, const char *new_string);
|
||||
----
|
||||
|
||||
Paramètres :
|
||||
|
||||
* _string_ : pointeur vers la chaîne dynamique
|
||||
* _new_string_ : la chaîne à copier
|
||||
|
||||
Valeur de retour :
|
||||
|
||||
* 1 si OK, 0 si erreur
|
||||
|
||||
Exemple en C :
|
||||
|
||||
[source,C]
|
||||
----
|
||||
char **string = weechat_dyn_alloc (256);
|
||||
if (weechat_dyn_copy (string, "test"))
|
||||
{
|
||||
/* OK */
|
||||
}
|
||||
else
|
||||
{
|
||||
/* erreur */
|
||||
}
|
||||
----
|
||||
|
||||
[NOTE]
|
||||
Cette fonction n'est pas disponible dans l'API script.
|
||||
|
||||
==== string_dyn_concat
|
||||
|
||||
_WeeChat ≥ 1.8._
|
||||
|
||||
Concaténer une chaîne dans une chaîne dynamique.
|
||||
|
||||
Le pointeur _*string_ peut changer si la chaîne est réallouée (s'il n'y a pas
|
||||
assez de place pour concaténer la chaîne).
|
||||
|
||||
Prototype :
|
||||
|
||||
[source,C]
|
||||
----
|
||||
int weechat_dyn_concat (char **string, const char *add);
|
||||
----
|
||||
|
||||
Paramètres :
|
||||
|
||||
* _string_ : pointeur vers la chaîne dynamique
|
||||
* _add_ : la chaîne à ajouter
|
||||
|
||||
Valeur de retour :
|
||||
|
||||
* 1 si OK, 0 si erreur
|
||||
|
||||
Exemple en C :
|
||||
|
||||
[source,C]
|
||||
----
|
||||
char **string = weechat_dyn_alloc (256);
|
||||
if (weechat_dyn_copy (string, "test"))
|
||||
{
|
||||
if (weechat_dyn_concat (string, "abc"))
|
||||
{
|
||||
/* ... */
|
||||
}
|
||||
}
|
||||
----
|
||||
|
||||
[NOTE]
|
||||
Cette fonction n'est pas disponible dans l'API script.
|
||||
|
||||
==== string_dyn_free
|
||||
|
||||
_WeeChat ≥ 1.8._
|
||||
|
||||
Libérer une chaîne dynamique.
|
||||
|
||||
Prototype :
|
||||
|
||||
[source,C]
|
||||
----
|
||||
void weechat_dyn_free (char **string, int free_string);
|
||||
----
|
||||
|
||||
Paramètres :
|
||||
|
||||
* _string_ : pointeur vers la chaîne dynamique
|
||||
* _free_string_ : libérer la chaîne elle-même ; si 0, le contenu de _*string_
|
||||
reste valide après l'appel à cette fonction
|
||||
|
||||
Exemple en C :
|
||||
|
||||
[source,C]
|
||||
----
|
||||
char **string = weechat_dyn_alloc (256);
|
||||
if (weechat_dyn_concat (string, "test"))
|
||||
{
|
||||
/* OK */
|
||||
}
|
||||
else
|
||||
{
|
||||
/* erreur */
|
||||
}
|
||||
/* ... */
|
||||
weechat_dyn_free (string, 1);
|
||||
----
|
||||
|
||||
[NOTE]
|
||||
Cette fonction n'est pas disponible dans l'API script.
|
||||
|
||||
[[utf-8]]
|
||||
=== UTF-8
|
||||
|
||||
|
|
|
@ -2248,6 +2248,180 @@ options = {
|
|||
str5 = weechat.string_eval_expression("password=abc password=def", {}, {}, options) # "password=*** password=***"
|
||||
----
|
||||
|
||||
==== string_dyn_alloc
|
||||
|
||||
_WeeChat ≥ 1.8._
|
||||
|
||||
// TRANSLATION MISSING
|
||||
Allocate a dynamic string, with a variable length. +
|
||||
Internally, a structure is allocated with the string pointer, the allocated size
|
||||
and current length of string.
|
||||
|
||||
// TRANSLATION MISSING
|
||||
Only the pointer to string pointer (_**string_) is used in all the
|
||||
_pass:[string_dyn_*]_ functions.
|
||||
|
||||
Prototipo:
|
||||
|
||||
[source,C]
|
||||
----
|
||||
char **weechat_dyn_alloc (int size_alloc);
|
||||
----
|
||||
|
||||
Argomenti:
|
||||
|
||||
// TRANSLATION MISSING
|
||||
* _size_alloc_: the initial allocated size (must be greater than zero)
|
||||
|
||||
Valore restituito:
|
||||
|
||||
// TRANSLATION MISSING
|
||||
* pointer to the dynamic string
|
||||
|
||||
Esempio in C:
|
||||
|
||||
[source,C]
|
||||
----
|
||||
char **string = weechat_dyn_alloc (256);
|
||||
----
|
||||
|
||||
[NOTE]
|
||||
Questa funzione non è disponibile nelle API per lo scripting.
|
||||
|
||||
==== string_dyn_copy
|
||||
|
||||
_WeeChat ≥ 1.8._
|
||||
|
||||
// TRANSLATION MISSING
|
||||
Copy a string in a dynamic string.
|
||||
|
||||
// TRANSLATION MISSING
|
||||
The pointer _*string_ can change if the string is reallocated (if there is
|
||||
not enough space to copy the string).
|
||||
|
||||
Prototipo:
|
||||
|
||||
[source,C]
|
||||
----
|
||||
int weechat_dyn_copy (char **string, const char *new_string);
|
||||
----
|
||||
|
||||
Argomenti:
|
||||
|
||||
// TRANSLATION MISSING
|
||||
* _string_: pointer to dynamic string
|
||||
* _new_string_: the string to copy
|
||||
|
||||
Valore restituito:
|
||||
|
||||
// TRANSLATION MISSING
|
||||
* 1 if OK, 0 if error
|
||||
|
||||
Esempio in C:
|
||||
|
||||
[source,C]
|
||||
----
|
||||
char **string = weechat_dyn_alloc (256);
|
||||
if (weechat_dyn_copy (string, "test"))
|
||||
{
|
||||
/* OK */
|
||||
}
|
||||
else
|
||||
{
|
||||
/* error */
|
||||
}
|
||||
----
|
||||
|
||||
[NOTE]
|
||||
Questa funzione non è disponibile nelle API per lo scripting.
|
||||
|
||||
==== string_dyn_concat
|
||||
|
||||
_WeeChat ≥ 1.8._
|
||||
|
||||
// TRANSLATION MISSING
|
||||
Concatenate a string to a dynamic string.
|
||||
|
||||
// TRANSLATION MISSING
|
||||
The pointer _*string_ can change if the string is reallocated (if there is
|
||||
not enough space to concatenate the string).
|
||||
|
||||
Prototipo:
|
||||
|
||||
[source,C]
|
||||
----
|
||||
int weechat_dyn_concat (char **string, const char *add);
|
||||
----
|
||||
|
||||
Argomenti:
|
||||
|
||||
// TRANSLATION MISSING
|
||||
* _string_: pointer to dynamic string
|
||||
* _add_: the string to add
|
||||
|
||||
Valore restituito:
|
||||
|
||||
// TRANSLATION MISSING
|
||||
* 1 if OK, 0 if error
|
||||
|
||||
Esempio in C:
|
||||
|
||||
[source,C]
|
||||
----
|
||||
char **string = weechat_dyn_alloc (256);
|
||||
if (weechat_dyn_copy (string, "test"))
|
||||
{
|
||||
if (weechat_dyn_concat (string, "abc"))
|
||||
{
|
||||
/* ... */
|
||||
}
|
||||
}
|
||||
----
|
||||
|
||||
[NOTE]
|
||||
Questa funzione non è disponibile nelle API per lo scripting.
|
||||
|
||||
==== string_dyn_free
|
||||
|
||||
_WeeChat ≥ 1.8._
|
||||
|
||||
// TRANSLATION MISSING
|
||||
Free a dynamic string.
|
||||
|
||||
Prototipo:
|
||||
|
||||
[source,C]
|
||||
----
|
||||
void weechat_dyn_free (char **string, int free_string);
|
||||
----
|
||||
|
||||
Argomenti:
|
||||
|
||||
// TRANSLATION MISSING
|
||||
* _string_: pointer to dynamic string
|
||||
* _free_string_: free the string itself; if 0, the content of _*string_ remains
|
||||
valid after the call to this function
|
||||
|
||||
Esempio in C:
|
||||
|
||||
[source,C]
|
||||
----
|
||||
char **string = weechat_dyn_alloc (256);
|
||||
if (weechat_dyn_concat (string, "test"))
|
||||
{
|
||||
/* OK */
|
||||
}
|
||||
else
|
||||
{
|
||||
/* error */
|
||||
}
|
||||
/* ... */
|
||||
weechat_dyn_free (string, 1);
|
||||
----
|
||||
|
||||
[NOTE]
|
||||
Questa funzione non è disponibile nelle API per lo scripting.
|
||||
|
||||
[[utf-8]]
|
||||
=== UTF-8
|
||||
|
||||
|
|
|
@ -2175,6 +2175,180 @@ options = {
|
|||
str5 = weechat.string_eval_expression("password=abc password=def", {}, {}, options) # "password=*** password=***"
|
||||
----
|
||||
|
||||
==== string_dyn_alloc
|
||||
|
||||
_WeeChat ≥ 1.8._
|
||||
|
||||
// TRANSLATION MISSING
|
||||
Allocate a dynamic string, with a variable length. +
|
||||
Internally, a structure is allocated with the string pointer, the allocated size
|
||||
and current length of string.
|
||||
|
||||
// TRANSLATION MISSING
|
||||
Only the pointer to string pointer (_**string_) is used in all the
|
||||
_pass:[string_dyn_*]_ functions.
|
||||
|
||||
プロトタイプ:
|
||||
|
||||
[source,C]
|
||||
----
|
||||
char **weechat_dyn_alloc (int size_alloc);
|
||||
----
|
||||
|
||||
引数:
|
||||
|
||||
// TRANSLATION MISSING
|
||||
* _size_alloc_: the initial allocated size (must be greater than zero)
|
||||
|
||||
戻り値:
|
||||
|
||||
// TRANSLATION MISSING
|
||||
* pointer to the dynamic string
|
||||
|
||||
C 言語での使用例:
|
||||
|
||||
[source,C]
|
||||
----
|
||||
char **string = weechat_dyn_alloc (256);
|
||||
----
|
||||
|
||||
[NOTE]
|
||||
スクリプト API ではこの関数を利用できません。
|
||||
|
||||
==== string_dyn_copy
|
||||
|
||||
_WeeChat ≥ 1.8._
|
||||
|
||||
// TRANSLATION MISSING
|
||||
Copy a string in a dynamic string.
|
||||
|
||||
// TRANSLATION MISSING
|
||||
The pointer _*string_ can change if the string is reallocated (if there is
|
||||
not enough space to copy the string).
|
||||
|
||||
プロトタイプ:
|
||||
|
||||
[source,C]
|
||||
----
|
||||
int weechat_dyn_copy (char **string, const char *new_string);
|
||||
----
|
||||
|
||||
引数:
|
||||
|
||||
// TRANSLATION MISSING
|
||||
* _string_: pointer to dynamic string
|
||||
* _new_string_: the string to copy
|
||||
|
||||
戻り値:
|
||||
|
||||
// TRANSLATION MISSING
|
||||
* 1 if OK, 0 if error
|
||||
|
||||
C 言語での使用例:
|
||||
|
||||
[source,C]
|
||||
----
|
||||
char **string = weechat_dyn_alloc (256);
|
||||
if (weechat_dyn_copy (string, "test"))
|
||||
{
|
||||
/* OK */
|
||||
}
|
||||
else
|
||||
{
|
||||
/* error */
|
||||
}
|
||||
----
|
||||
|
||||
[NOTE]
|
||||
スクリプト API ではこの関数を利用できません。
|
||||
|
||||
==== string_dyn_concat
|
||||
|
||||
_WeeChat ≥ 1.8._
|
||||
|
||||
// TRANSLATION MISSING
|
||||
Concatenate a string to a dynamic string.
|
||||
|
||||
// TRANSLATION MISSING
|
||||
The pointer _*string_ can change if the string is reallocated (if there is
|
||||
not enough space to concatenate the string).
|
||||
|
||||
プロトタイプ:
|
||||
|
||||
[source,C]
|
||||
----
|
||||
int weechat_dyn_concat (char **string, const char *add);
|
||||
----
|
||||
|
||||
引数:
|
||||
|
||||
// TRANSLATION MISSING
|
||||
* _string_: pointer to dynamic string
|
||||
* _add_: the string to add
|
||||
|
||||
戻り値:
|
||||
|
||||
// TRANSLATION MISSING
|
||||
* 1 if OK, 0 if error
|
||||
|
||||
C 言語での使用例:
|
||||
|
||||
[source,C]
|
||||
----
|
||||
char **string = weechat_dyn_alloc (256);
|
||||
if (weechat_dyn_copy (string, "test"))
|
||||
{
|
||||
if (weechat_dyn_concat (string, "abc"))
|
||||
{
|
||||
/* ... */
|
||||
}
|
||||
}
|
||||
----
|
||||
|
||||
[NOTE]
|
||||
スクリプト API ではこの関数を利用できません。
|
||||
|
||||
==== string_dyn_free
|
||||
|
||||
_WeeChat ≥ 1.8._
|
||||
|
||||
// TRANSLATION MISSING
|
||||
Free a dynamic string.
|
||||
|
||||
プロトタイプ:
|
||||
|
||||
[source,C]
|
||||
----
|
||||
void weechat_dyn_free (char **string, int free_string);
|
||||
----
|
||||
|
||||
引数:
|
||||
|
||||
// TRANSLATION MISSING
|
||||
* _string_: pointer to dynamic string
|
||||
* _free_string_: free the string itself; if 0, the content of _*string_ remains
|
||||
valid after the call to this function
|
||||
|
||||
C 言語での使用例:
|
||||
|
||||
[source,C]
|
||||
----
|
||||
char **string = weechat_dyn_alloc (256);
|
||||
if (weechat_dyn_concat (string, "test"))
|
||||
{
|
||||
/* OK */
|
||||
}
|
||||
else
|
||||
{
|
||||
/* error */
|
||||
}
|
||||
/* ... */
|
||||
weechat_dyn_free (string, 1);
|
||||
----
|
||||
|
||||
[NOTE]
|
||||
スクリプト API ではこの関数を利用できません。
|
||||
|
||||
[[utf-8]]
|
||||
=== UTF-8
|
||||
|
||||
|
|
|
@ -60,8 +60,6 @@
|
|||
((c >= 'A') && (c <= 'F')) ? c - 'A' + 10 : \
|
||||
c - '0')
|
||||
|
||||
typedef uint32_t string_shared_count_t;
|
||||
|
||||
struct t_hashtable *string_hashtable_shared = NULL;
|
||||
|
||||
|
||||
|
@ -3195,6 +3193,190 @@ string_shared_free (const char *string)
|
|||
hashtable_remove (string_hashtable_shared, ptr_count);
|
||||
}
|
||||
|
||||
/*
|
||||
* Allocates a dynamic string (with a variable length).
|
||||
*
|
||||
* The parameter size_alloc is the initial allocated size, which must be
|
||||
* greater than zero.
|
||||
*
|
||||
* Returns the pointer to the allocated string, which is initialized as empty
|
||||
* string.
|
||||
*
|
||||
* The string returned can be used with following restrictions:
|
||||
* - changes are allowed in the string, between the first char and the final
|
||||
* '\0', which must not be removed nor moved,
|
||||
* - no other '\0' must be added in the string,
|
||||
* - content can be added in the string with function string_dyn_concat(),
|
||||
* - string can be freed with function string_dyn_free() (do NEVER call
|
||||
* directly free() on the string).
|
||||
*
|
||||
* Note: result must be freed after use with function string_dyn_free().
|
||||
*/
|
||||
|
||||
char **
|
||||
string_dyn_alloc (int size_alloc)
|
||||
{
|
||||
struct t_string_dyn *string_dyn;
|
||||
|
||||
if (size_alloc <= 0)
|
||||
return NULL;
|
||||
|
||||
string_dyn = malloc (sizeof (*string_dyn));
|
||||
if (!string_dyn)
|
||||
return NULL;
|
||||
|
||||
string_dyn->string = malloc (size_alloc);
|
||||
if (!string_dyn->string)
|
||||
{
|
||||
free (string_dyn);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
string_dyn->string[0] = '\0';
|
||||
string_dyn->size_alloc = size_alloc;
|
||||
string_dyn->size = 1;
|
||||
|
||||
return &(string_dyn->string);
|
||||
}
|
||||
|
||||
/*
|
||||
* Copies "new_string" into a dynamic string and replaces its current content
|
||||
* (adjusts its size accordingly).
|
||||
*
|
||||
* The string pointer (*string) is updated with the new allocated string
|
||||
* if the string had to be extended, or the same pointer if there was enough
|
||||
* size to copy the new string.
|
||||
*
|
||||
* Returns:
|
||||
* 1: OK
|
||||
* 0: error
|
||||
*/
|
||||
|
||||
int
|
||||
string_dyn_copy (char **string, const char *new_string)
|
||||
{
|
||||
struct t_string_dyn *ptr_string_dyn;
|
||||
char *string_realloc;
|
||||
string_dyn_size_t length_new, new_size_alloc;
|
||||
|
||||
if (!string || !*string)
|
||||
return 0;
|
||||
|
||||
ptr_string_dyn = (struct t_string_dyn *)string;
|
||||
|
||||
length_new = (new_string) ? strlen (new_string) : 0;
|
||||
|
||||
if (length_new + 1 > ptr_string_dyn->size_alloc)
|
||||
{
|
||||
/* compute new size_alloc for the string + add */
|
||||
new_size_alloc = (ptr_string_dyn->size_alloc < 2) ?
|
||||
2 : ptr_string_dyn->size_alloc + (ptr_string_dyn->size_alloc / 2);
|
||||
if (new_size_alloc < length_new + 1)
|
||||
new_size_alloc = length_new + 1;
|
||||
string_realloc = realloc (ptr_string_dyn->string, new_size_alloc);
|
||||
if (!string_realloc)
|
||||
return 0;
|
||||
ptr_string_dyn->string = string_realloc;
|
||||
*string = string_realloc;
|
||||
ptr_string_dyn->size_alloc = new_size_alloc;
|
||||
}
|
||||
|
||||
/* copy "new_string" in "string" */
|
||||
if (new_string)
|
||||
memmove (ptr_string_dyn->string, new_string, length_new + 1);
|
||||
else
|
||||
ptr_string_dyn->string[0] = '\0';
|
||||
ptr_string_dyn->size = length_new + 1;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Concatenates a string to a dynamic string and adjusts its size accordingly.
|
||||
*
|
||||
* The string pointer (*string) is updated with the new allocated string
|
||||
* if the string had to be extended, or the same pointer if there was enough
|
||||
* size to concatenate the new string.
|
||||
*
|
||||
* Returns:
|
||||
* 1: OK
|
||||
* 0: error
|
||||
*/
|
||||
|
||||
int
|
||||
string_dyn_concat (char **string, const char *add)
|
||||
{
|
||||
struct t_string_dyn *ptr_string_dyn;
|
||||
char *string_realloc;
|
||||
string_dyn_size_t length_add, new_size_alloc, new_size;
|
||||
|
||||
if (!string || !*string)
|
||||
return 0;
|
||||
|
||||
if (!add || !add[0])
|
||||
return 1;
|
||||
|
||||
ptr_string_dyn = (struct t_string_dyn *)string;
|
||||
|
||||
length_add = strlen (add);
|
||||
new_size = ptr_string_dyn->size + length_add;
|
||||
|
||||
if (new_size > ptr_string_dyn->size_alloc)
|
||||
{
|
||||
/* compute new size_alloc for the string + add */
|
||||
new_size_alloc = (ptr_string_dyn->size_alloc < 2) ?
|
||||
2 : ptr_string_dyn->size_alloc + (ptr_string_dyn->size_alloc / 2);
|
||||
if (new_size_alloc < new_size)
|
||||
new_size_alloc = new_size;
|
||||
string_realloc = realloc (ptr_string_dyn->string, new_size_alloc);
|
||||
if (!string_realloc)
|
||||
{
|
||||
free (ptr_string_dyn->string);
|
||||
free (ptr_string_dyn);
|
||||
*string = NULL;
|
||||
return 0;
|
||||
}
|
||||
ptr_string_dyn->string = string_realloc;
|
||||
*string = string_realloc;
|
||||
ptr_string_dyn->size_alloc = new_size_alloc;
|
||||
}
|
||||
|
||||
/* concatenate "add" after "string" */
|
||||
memmove (ptr_string_dyn->string + ptr_string_dyn->size - 1,
|
||||
add,
|
||||
length_add + 1);
|
||||
ptr_string_dyn->size = new_size;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Frees a dynamic string.
|
||||
*
|
||||
* The argument "string" is a pointer on a string returned by function
|
||||
* string_dyn_alloc or a string pointer modified by string_dyn_concat.
|
||||
*
|
||||
* If free_string == 1, the string itself is freed in the structure.
|
||||
* Otherwise the pointer (*string) remains valid after this call, and
|
||||
* the caller must manually free the string with a call to free().
|
||||
*/
|
||||
|
||||
void
|
||||
string_dyn_free (char **string, int free_string)
|
||||
{
|
||||
struct t_string_dyn *ptr_string_dyn;
|
||||
|
||||
if (!string || !*string)
|
||||
return;
|
||||
|
||||
ptr_string_dyn = (struct t_string_dyn *)string;
|
||||
|
||||
if (free_string)
|
||||
free (ptr_string_dyn->string);
|
||||
|
||||
free (ptr_string_dyn);
|
||||
}
|
||||
|
||||
/*
|
||||
* Frees all allocated data.
|
||||
*/
|
||||
|
|
|
@ -20,8 +20,19 @@
|
|||
#ifndef WEECHAT_STRING_H
|
||||
#define WEECHAT_STRING_H 1
|
||||
|
||||
#include <stdint.h>
|
||||
#include <regex.h>
|
||||
|
||||
typedef uint32_t string_shared_count_t;
|
||||
|
||||
typedef uint32_t string_dyn_size_t;
|
||||
struct t_string_dyn
|
||||
{
|
||||
char *string; /* the string */
|
||||
string_dyn_size_t size_alloc; /* allocated size */
|
||||
string_dyn_size_t size; /* size of string (including '\0') */
|
||||
};
|
||||
|
||||
struct t_hashtable;
|
||||
|
||||
extern char *string_strndup (const char *string, int length);
|
||||
|
@ -104,6 +115,10 @@ extern char *string_replace_with_callback (const char *string,
|
|||
int *errors);
|
||||
extern const char *string_shared_get (const char *string);
|
||||
extern void string_shared_free (const char *string);
|
||||
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);
|
||||
extern void string_dyn_free (char **string, int free_string);
|
||||
extern void string_end ();
|
||||
|
||||
#endif /* WEECHAT_STRING_H */
|
||||
|
|
|
@ -638,6 +638,10 @@ plugin_load (const char *filename, int init_plugin, int argc, char **argv)
|
|||
new_plugin->string_is_command_char = &string_is_command_char;
|
||||
new_plugin->string_input_for_buffer = &string_input_for_buffer;
|
||||
new_plugin->string_eval_expression = &eval_expression;
|
||||
new_plugin->string_dyn_alloc = &string_dyn_alloc;
|
||||
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->utf8_has_8bits = &utf8_has_8bits;
|
||||
new_plugin->utf8_is_valid = &utf8_is_valid;
|
||||
|
|
|
@ -58,7 +58,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 "20160618-01"
|
||||
#define WEECHAT_PLUGIN_API_VERSION "20170303-01"
|
||||
|
||||
/* macros for defining plugin infos */
|
||||
#define WEECHAT_PLUGIN_NAME(__name) \
|
||||
|
@ -324,6 +324,10 @@ struct t_weechat_plugin
|
|||
struct t_hashtable *pointers,
|
||||
struct t_hashtable *extra_vars,
|
||||
struct t_hashtable *options);
|
||||
char **(*string_dyn_alloc) (int size_alloc);
|
||||
int (*string_dyn_copy) (char **string, const char *new_string);
|
||||
int (*string_dyn_concat) (char **string, const char *add);
|
||||
void (*string_dyn_free) (char **string, int free_string);
|
||||
|
||||
/* UTF-8 strings */
|
||||
int (*utf8_has_8bits) (const char *string);
|
||||
|
@ -1185,6 +1189,14 @@ extern int weechat_plugin_end (struct t_weechat_plugin *plugin);
|
|||
__extra_vars, __options) \
|
||||
(weechat_plugin->string_eval_expression)(__expr, __pointers, \
|
||||
__extra_vars, __options)
|
||||
#define weechat_string_dyn_alloc(__size_alloc) \
|
||||
(weechat_plugin->string_dyn_alloc)(__size_alloc)
|
||||
#define weechat_string_dyn_copy(__string, __new_string) \
|
||||
(weechat_plugin->string_dyn_copy)(__string, __new_string)
|
||||
#define weechat_string_dyn_concat(__string, __add) \
|
||||
(weechat_plugin->string_dyn_concat)(__string, __add)
|
||||
#define weechat_string_dyn_free(__string, __free_string) \
|
||||
(weechat_plugin->string_dyn_free)(__string, __free_string)
|
||||
|
||||
/* UTF-8 strings */
|
||||
#define weechat_utf8_has_8bits(__string) \
|
||||
|
|
|
@ -1345,3 +1345,118 @@ TEST(String, Shared)
|
|||
string_shared_free (str3);
|
||||
LONGS_EQUAL(count + 0, string_hashtable_shared->items_count);
|
||||
}
|
||||
|
||||
/*
|
||||
* Tests functions:
|
||||
* string_dyn_alloc
|
||||
* string_dyn_copy
|
||||
* string_dyn_concat
|
||||
* string_dyn_free
|
||||
*/
|
||||
|
||||
TEST(String, Dyn)
|
||||
{
|
||||
char **str, *str_ptr;
|
||||
struct t_string_dyn *ptr_string_dyn;
|
||||
|
||||
POINTERS_EQUAL(NULL, string_dyn_alloc (-1));
|
||||
POINTERS_EQUAL(NULL, string_dyn_alloc (0));
|
||||
|
||||
str = string_dyn_alloc (1);
|
||||
CHECK(str);
|
||||
CHECK(*str);
|
||||
STRCMP_EQUAL("", *str);
|
||||
|
||||
/* check internal structure content */
|
||||
ptr_string_dyn = (struct t_string_dyn *)str;
|
||||
LONGS_EQUAL(1, ptr_string_dyn->size_alloc);
|
||||
LONGS_EQUAL(1, ptr_string_dyn->size);
|
||||
STRCMP_EQUAL("", ptr_string_dyn->string);
|
||||
|
||||
/* check copy with NULL */
|
||||
LONGS_EQUAL(1, string_dyn_copy (str, NULL));
|
||||
LONGS_EQUAL(1, ptr_string_dyn->size_alloc);
|
||||
LONGS_EQUAL(1, ptr_string_dyn->size);
|
||||
POINTERS_EQUAL(ptr_string_dyn->string, *str);
|
||||
STRCMP_EQUAL("", ptr_string_dyn->string);
|
||||
STRCMP_EQUAL("", *str);
|
||||
|
||||
/* check copy with an empty string */
|
||||
LONGS_EQUAL(1, string_dyn_copy (str, ""));
|
||||
LONGS_EQUAL(1, ptr_string_dyn->size_alloc);
|
||||
LONGS_EQUAL(1, ptr_string_dyn->size);
|
||||
POINTERS_EQUAL(ptr_string_dyn->string, *str);
|
||||
STRCMP_EQUAL("", ptr_string_dyn->string);
|
||||
STRCMP_EQUAL("", *str);
|
||||
|
||||
/* check copy with some strings */
|
||||
LONGS_EQUAL(1, string_dyn_copy (str, "a"));
|
||||
LONGS_EQUAL(2, ptr_string_dyn->size_alloc);
|
||||
LONGS_EQUAL(2, ptr_string_dyn->size);
|
||||
POINTERS_EQUAL(ptr_string_dyn->string, *str);
|
||||
STRCMP_EQUAL("a", ptr_string_dyn->string);
|
||||
STRCMP_EQUAL("a", *str);
|
||||
|
||||
LONGS_EQUAL(1, string_dyn_copy (str, "abcd"));
|
||||
LONGS_EQUAL(5, ptr_string_dyn->size_alloc);
|
||||
LONGS_EQUAL(5, ptr_string_dyn->size);
|
||||
POINTERS_EQUAL(ptr_string_dyn->string, *str);
|
||||
STRCMP_EQUAL("abcd", ptr_string_dyn->string);
|
||||
STRCMP_EQUAL("abcd", *str);
|
||||
|
||||
string_dyn_free (str, 1);
|
||||
|
||||
str = string_dyn_alloc (1);
|
||||
|
||||
/* check concat with NULL */
|
||||
LONGS_EQUAL(1, string_dyn_concat (str, NULL));
|
||||
LONGS_EQUAL(1, ptr_string_dyn->size_alloc);
|
||||
LONGS_EQUAL(1, ptr_string_dyn->size);
|
||||
POINTERS_EQUAL(ptr_string_dyn->string, *str);
|
||||
STRCMP_EQUAL("", ptr_string_dyn->string);
|
||||
STRCMP_EQUAL("", *str);
|
||||
|
||||
/* check concat with an empty string */
|
||||
LONGS_EQUAL(1, string_dyn_concat (str, ""));
|
||||
LONGS_EQUAL(1, ptr_string_dyn->size_alloc);
|
||||
LONGS_EQUAL(1, ptr_string_dyn->size);
|
||||
POINTERS_EQUAL(ptr_string_dyn->string, *str);
|
||||
STRCMP_EQUAL("", ptr_string_dyn->string);
|
||||
STRCMP_EQUAL("", *str);
|
||||
|
||||
/* check concat with some strings */
|
||||
LONGS_EQUAL(1, string_dyn_concat (str, "a"));
|
||||
LONGS_EQUAL(2, ptr_string_dyn->size_alloc);
|
||||
LONGS_EQUAL(2, ptr_string_dyn->size);
|
||||
POINTERS_EQUAL(ptr_string_dyn->string, *str);
|
||||
STRCMP_EQUAL("a", ptr_string_dyn->string);
|
||||
STRCMP_EQUAL("a", *str);
|
||||
|
||||
LONGS_EQUAL(1, string_dyn_concat (str, "bcd"));
|
||||
LONGS_EQUAL(5, ptr_string_dyn->size_alloc);
|
||||
LONGS_EQUAL(5, ptr_string_dyn->size);
|
||||
POINTERS_EQUAL(ptr_string_dyn->string, *str);
|
||||
STRCMP_EQUAL("abcd", ptr_string_dyn->string);
|
||||
STRCMP_EQUAL("abcd", *str);
|
||||
|
||||
LONGS_EQUAL(1, string_dyn_concat (str, "e"));
|
||||
LONGS_EQUAL(7, ptr_string_dyn->size_alloc);
|
||||
LONGS_EQUAL(6, ptr_string_dyn->size);
|
||||
POINTERS_EQUAL(ptr_string_dyn->string, *str);
|
||||
STRCMP_EQUAL("abcde", ptr_string_dyn->string);
|
||||
STRCMP_EQUAL("abcde", *str);
|
||||
|
||||
LONGS_EQUAL(1, string_dyn_concat (str, "fg"));
|
||||
LONGS_EQUAL(10, ptr_string_dyn->size_alloc);
|
||||
LONGS_EQUAL(8, ptr_string_dyn->size);
|
||||
POINTERS_EQUAL(ptr_string_dyn->string, *str);
|
||||
STRCMP_EQUAL("abcdefg", ptr_string_dyn->string);
|
||||
STRCMP_EQUAL("abcdefg", *str);
|
||||
|
||||
str_ptr = *str;
|
||||
string_dyn_free (str, 0);
|
||||
|
||||
STRCMP_EQUAL("abcdefg", str_ptr);
|
||||
|
||||
free (str_ptr);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue