api: add dynamic string functions (string_dyn_*)

New functions:
- string_dyn_alloc
- string_dyn_copy
- string_dyn_concat
- string_dyn_free
v2.8-utf8proc
Sébastien Helleu 2017-03-03 22:35:09 +01:00
parent a5b00ec979
commit 07d16903f3
9 changed files with 999 additions and 3 deletions

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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.
*/

View File

@ -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 */

View File

@ -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;

View File

@ -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) \

View File

@ -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);
}