api: remember insertion order in hashtables
This commit is contained in:
parent
5a59482cc8
commit
a48a615613
@ -21,6 +21,7 @@ https://weechat.org/files/releasenotes/ReleaseNotes-devel.html[release notes]
|
||||
New features::
|
||||
|
||||
* core: add option "certs" in command /debug
|
||||
* api: remember insertion order in hashtables
|
||||
* api: add keys/values with tags in output of irc_message_parse_to_hashtable (issue #1654)
|
||||
* irc: implement IRCv3.2 SASL authentication, add command /auth, reconnect by default to the server in case of SASL authentication failure (issue #413)
|
||||
* irc: add support of capability "message-tags" and TAGMSG messages (issue #1654)
|
||||
|
@ -20,6 +20,17 @@ https://weechat.org/files/changelog/ChangeLog-devel.html[ChangeLog]
|
||||
[[v3.3]]
|
||||
== Version 3.3 (under dev)
|
||||
|
||||
[[v3.3_ordered_hashtables]]
|
||||
=== Ordered hashtables
|
||||
|
||||
Hashtables entries are now ordered by creation date, the following functions
|
||||
are now returning entries sorted by insertion order:
|
||||
|
||||
* hashtable_map
|
||||
* hashtable_map_string
|
||||
* hashtable_get_string (all properties except "keys_sorted" and "keys_values_sorted")
|
||||
* hashtable_add_to_infolist
|
||||
|
||||
[[v3.3_irc_default_capabilities]]
|
||||
=== IRC default capabilities
|
||||
|
||||
|
@ -5220,7 +5220,8 @@ This function is not available in scripting API.
|
||||
|
||||
_WeeChat ≥ 0.3.3._
|
||||
|
||||
Call a function on all hashtable entries.
|
||||
Call a function on all hashtable entries, by insertion order in the hashtable
|
||||
(from oldest to newest one).
|
||||
|
||||
Prototype:
|
||||
|
||||
@ -5264,7 +5265,8 @@ This function is not available in scripting API.
|
||||
|
||||
_WeeChat ≥ 0.3.7._
|
||||
|
||||
Call a function on all hashtable entries, sending keys and values as strings.
|
||||
Call a function on all hashtable entries, by insertion order in the hashtable
|
||||
(from oldest to newest one), sending keys and values as strings.
|
||||
|
||||
Prototype:
|
||||
|
||||
@ -5478,7 +5480,8 @@ This function is not available in scripting API.
|
||||
|
||||
_WeeChat ≥ 0.3.3._
|
||||
|
||||
Add hashtable items to an infolist item.
|
||||
Add hashtable items to an infolist item, by insertion order in the hashtable
|
||||
(from oldest to newest one).
|
||||
|
||||
Prototype:
|
||||
|
||||
|
@ -5298,7 +5298,8 @@ Cette fonction n'est pas disponible dans l'API script.
|
||||
|
||||
_WeeChat ≥ 0.3.3._
|
||||
|
||||
Appeller une fonction pour chaque entrée d'une table de hachage.
|
||||
Appeller une fonction pour chaque entrée d'une table de hachage, par ordre
|
||||
d'insertion dans la table de hachage (de la plus ancienne à la plus récente).
|
||||
|
||||
Prototype :
|
||||
|
||||
@ -5343,8 +5344,9 @@ Cette fonction n'est pas disponible dans l'API script.
|
||||
|
||||
_WeeChat ≥ 0.3.7._
|
||||
|
||||
Appeller une fonction pour chaque entrée d'une table de hachage, en envoyant les
|
||||
clés et valeurs sous forme de chaînes.
|
||||
Appeller une fonction pour chaque entrée d'une table de hachage, par ordre
|
||||
d'insertion dans la table de hachage (de la plus ancienne à la plus récente),
|
||||
en envoyant les clés et valeurs sous forme de chaînes.
|
||||
|
||||
Prototype :
|
||||
|
||||
@ -5563,7 +5565,8 @@ Cette fonction n'est pas disponible dans l'API script.
|
||||
|
||||
_WeeChat ≥ 0.3.3._
|
||||
|
||||
Ajouter les éléments d'une table de hachage dans un objet infolist.
|
||||
Ajouter les éléments d'une table de hachage dans un objet infolist, par ordre
|
||||
d'insertion dans la table de hachage (de la plus ancienne à la plus récente).
|
||||
|
||||
Prototype :
|
||||
|
||||
|
@ -5410,7 +5410,9 @@ Questa funzione non è disponibile nelle API per lo scripting.
|
||||
|
||||
_WeeChat ≥ 0.3.3._
|
||||
|
||||
Chiama una funzione su tutte le voci della tabella hash.
|
||||
// TRANSLATION MISSING
|
||||
Chiama una funzione su tutte le voci della tabella hash, by insertion order
|
||||
in the hashtable (from oldest to newest one).
|
||||
|
||||
Prototipo:
|
||||
|
||||
@ -5454,8 +5456,9 @@ Questa funzione non è disponibile nelle API per lo scripting.
|
||||
|
||||
_WeeChat ≥ 0.3.7._
|
||||
|
||||
Chiama una funzione su tutte le voci della tabella hash, inviando chiavi e
|
||||
valori come stringhe.
|
||||
// TRANSLATION MISSING
|
||||
Chiama una funzione su tutte le voci della tabella hash, by insertion order
|
||||
in the hashtable (from oldest to newest one), inviando chiavi e valori come stringhe.
|
||||
|
||||
Prototipo:
|
||||
|
||||
@ -5674,7 +5677,9 @@ Questa funzione non è disponibile nelle API per lo scripting.
|
||||
|
||||
_WeeChat ≥ 0.3.3._
|
||||
|
||||
Aggiunge elementi della tabella hash ad un elemento della lista info.
|
||||
// TRANSLATION MISSING
|
||||
Aggiunge elementi della tabella hash ad un elemento della lista info, by insertion
|
||||
order in the hashtable (from oldest to newest one).
|
||||
|
||||
Prototipo:
|
||||
|
||||
|
@ -5269,7 +5269,9 @@ if (weechat_hashtable_has_key (hashtable, "my_key"))
|
||||
|
||||
_WeeChat バージョン 0.3.3 以上で利用可。_
|
||||
|
||||
ハッシュテーブルのすべてのエントリに対して関数を呼び出す。
|
||||
// TRANSLATION MISSING
|
||||
ハッシュテーブルのすべてのエントリに対して関数を呼び出す,
|
||||
by insertion order in the hashtable (from oldest to newest one).
|
||||
|
||||
プロトタイプ:
|
||||
|
||||
@ -5313,7 +5315,9 @@ weechat_hashtable_map (hashtable, &map_cb, NULL);
|
||||
|
||||
_WeeChat バージョン 0.3.7 以上で利用可。_
|
||||
|
||||
ハッシュテーブルのすべてのエントリに対して関数を呼び出す、キーと値を文字列として関数に渡す。
|
||||
// TRANSLATION MISSING
|
||||
Call a function on all hashtable entries, by insertion order in the hashtable
|
||||
(from oldest to newest one), sending keys and values as strings.
|
||||
|
||||
プロトタイプ:
|
||||
|
||||
@ -5527,7 +5531,9 @@ weechat_hashtable_set_pointer (hashtable, "callback_free_key", &my_free_key_cb);
|
||||
|
||||
_WeeChat バージョン 0.3.3 以上で利用可。_
|
||||
|
||||
ハッシュテーブルの要素をインフォリスト要素に追加
|
||||
// TRANSLATION MISSING
|
||||
ハッシュテーブルの要素をインフォリスト要素に追加, by insertion order in the hashtable
|
||||
(from oldest to newest one).
|
||||
|
||||
プロトタイプ:
|
||||
|
||||
|
@ -5057,7 +5057,9 @@ if (weechat_hashtable_has_key (hashtable, "my_key"))
|
||||
|
||||
_WeeChat ≥ 0.3.3._
|
||||
|
||||
Позива функцију над свим ставкама хеш табеле.
|
||||
// TRANSLATION MISSING
|
||||
Позива функцију над свим ставкама хеш табеле, by insertion order in the hashtable
|
||||
(from oldest to newest one).
|
||||
|
||||
Прототип:
|
||||
|
||||
@ -5101,7 +5103,9 @@ weechat_hashtable_map (hashtable, &map_cb, NULL);
|
||||
|
||||
_WeeChat ≥ 0.3.7._
|
||||
|
||||
Позива функцију над свим ставкама хеш табеле и шаље јој кључеве и вредности као стрингове.
|
||||
// TRANSLATION MISSING
|
||||
Call a function on all hashtable entries, by insertion order in the hashtable
|
||||
(from oldest to newest one), sending keys and values as strings.
|
||||
|
||||
Прототип:
|
||||
|
||||
@ -5311,7 +5315,9 @@ weechat_hashtable_set_pointer (hashtable, "callback_free_key", &my_free_key_cb);
|
||||
|
||||
_WeeChat ≥ 0.3.3._
|
||||
|
||||
Додаје ставе хеш табеле у ставку инфо листе.
|
||||
// TRANSLATION MISSING
|
||||
Додаје ставе хеш табеле у ставку инфо листе, by insertion order in the hashtable
|
||||
(from oldest to newest one).
|
||||
|
||||
Прототип:
|
||||
|
||||
|
@ -228,6 +228,8 @@ hashtable_new (int size,
|
||||
new_hashtable->htable[i] = NULL;
|
||||
}
|
||||
new_hashtable->items_count = 0;
|
||||
new_hashtable->oldest_item = NULL;
|
||||
new_hashtable->newest_item = NULL;
|
||||
|
||||
new_hashtable->callback_hash_key = (callback_hash_key) ?
|
||||
callback_hash_key : &hashtable_hash_key_default_cb;
|
||||
@ -439,6 +441,15 @@ hashtable_set_with_size (struct t_hashtable *hashtable,
|
||||
hashtable->htable[hash] = new_item;
|
||||
}
|
||||
|
||||
/* keep items ordered by date of creation */
|
||||
if (hashtable->newest_item)
|
||||
(hashtable->newest_item)->next_created_item = new_item;
|
||||
else
|
||||
hashtable->oldest_item = new_item;
|
||||
new_item->prev_created_item = hashtable->newest_item;
|
||||
new_item->next_created_item = NULL;
|
||||
hashtable->newest_item = new_item;
|
||||
|
||||
hashtable->items_count++;
|
||||
|
||||
return new_item;
|
||||
@ -574,26 +585,22 @@ hashtable_map (struct t_hashtable *hashtable,
|
||||
t_hashtable_map *callback_map,
|
||||
void *callback_map_data)
|
||||
{
|
||||
int i;
|
||||
struct t_hashtable_item *ptr_item, *ptr_next_item;
|
||||
struct t_hashtable_item *ptr_item, *ptr_next_created_item;
|
||||
|
||||
if (!hashtable)
|
||||
return;
|
||||
|
||||
for (i = 0; i < hashtable->size; i++)
|
||||
ptr_item = hashtable->oldest_item;
|
||||
while (ptr_item)
|
||||
{
|
||||
ptr_item = hashtable->htable[i];
|
||||
while (ptr_item)
|
||||
{
|
||||
ptr_next_item = ptr_item->next_item;
|
||||
ptr_next_created_item = ptr_item->next_created_item;
|
||||
|
||||
(void) (callback_map) (callback_map_data,
|
||||
hashtable,
|
||||
ptr_item->key,
|
||||
ptr_item->value);
|
||||
(void) (callback_map) (callback_map_data,
|
||||
hashtable,
|
||||
ptr_item->key,
|
||||
ptr_item->value);
|
||||
|
||||
ptr_item = ptr_next_item;
|
||||
}
|
||||
ptr_item = ptr_next_created_item;
|
||||
}
|
||||
}
|
||||
|
||||
@ -606,41 +613,37 @@ hashtable_map_string (struct t_hashtable *hashtable,
|
||||
t_hashtable_map_string *callback_map,
|
||||
void *callback_map_data)
|
||||
{
|
||||
int i;
|
||||
struct t_hashtable_item *ptr_item, *ptr_next_item;
|
||||
struct t_hashtable_item *ptr_item, *ptr_next_created_item;
|
||||
const char *str_key, *str_value;
|
||||
char *key, *value;
|
||||
|
||||
if (!hashtable)
|
||||
return;
|
||||
|
||||
for (i = 0; i < hashtable->size; i++)
|
||||
ptr_item = hashtable->oldest_item;
|
||||
while (ptr_item)
|
||||
{
|
||||
ptr_item = hashtable->htable[i];
|
||||
while (ptr_item)
|
||||
{
|
||||
ptr_next_item = ptr_item->next_item;
|
||||
ptr_next_created_item = ptr_item->next_created_item;
|
||||
|
||||
str_key = hashtable_to_string (hashtable->type_keys,
|
||||
ptr_item->key);
|
||||
key = (str_key) ? strdup (str_key) : NULL;
|
||||
str_key = hashtable_to_string (hashtable->type_keys,
|
||||
ptr_item->key);
|
||||
key = (str_key) ? strdup (str_key) : NULL;
|
||||
|
||||
str_value = hashtable_to_string (hashtable->type_values,
|
||||
ptr_item->value);
|
||||
value = (str_value) ? strdup (str_value) : NULL;
|
||||
str_value = hashtable_to_string (hashtable->type_values,
|
||||
ptr_item->value);
|
||||
value = (str_value) ? strdup (str_value) : NULL;
|
||||
|
||||
(void) (callback_map) (callback_map_data,
|
||||
hashtable,
|
||||
key,
|
||||
value);
|
||||
(void) (callback_map) (callback_map_data,
|
||||
hashtable,
|
||||
key,
|
||||
value);
|
||||
|
||||
if (key)
|
||||
free (key);
|
||||
if (value)
|
||||
free (value);
|
||||
if (key)
|
||||
free (key);
|
||||
if (value)
|
||||
free (value);
|
||||
|
||||
ptr_item = ptr_next_item;
|
||||
}
|
||||
ptr_item = ptr_next_created_item;
|
||||
}
|
||||
}
|
||||
|
||||
@ -675,6 +678,9 @@ hashtable_dup (struct t_hashtable *hashtable)
|
||||
{
|
||||
struct t_hashtable *new_hashtable;
|
||||
|
||||
if (!hashtable)
|
||||
return NULL;
|
||||
|
||||
new_hashtable = hashtable_new (hashtable->size,
|
||||
hashtable_type_string[hashtable->type_keys],
|
||||
hashtable_type_string[hashtable->type_values],
|
||||
@ -724,6 +730,9 @@ hashtable_get_list_keys (struct t_hashtable *hashtable)
|
||||
{
|
||||
struct t_weelist *weelist;
|
||||
|
||||
if (!hashtable)
|
||||
return NULL;
|
||||
|
||||
weelist = weelist_new ();
|
||||
if (weelist)
|
||||
hashtable_map (hashtable, &hashtable_get_list_keys_map_cb, weelist);
|
||||
@ -1044,7 +1053,7 @@ hashtable_add_to_infolist (struct t_hashtable *hashtable,
|
||||
struct t_infolist_item *infolist_item,
|
||||
const char *prefix)
|
||||
{
|
||||
int i, item_number;
|
||||
int item_number;
|
||||
struct t_hashtable_item *ptr_item;
|
||||
char option_name[128];
|
||||
|
||||
@ -1052,52 +1061,50 @@ hashtable_add_to_infolist (struct t_hashtable *hashtable,
|
||||
return 0;
|
||||
|
||||
item_number = 0;
|
||||
for (i = 0; i < hashtable->size; i++)
|
||||
ptr_item = hashtable->oldest_item;
|
||||
while (ptr_item)
|
||||
{
|
||||
for (ptr_item = hashtable->htable[i]; ptr_item;
|
||||
ptr_item = ptr_item->next_item)
|
||||
snprintf (option_name, sizeof (option_name),
|
||||
"%s_name_%05d", prefix, item_number);
|
||||
if (!infolist_new_var_string (infolist_item, option_name,
|
||||
hashtable_to_string (hashtable->type_keys,
|
||||
ptr_item->key)))
|
||||
return 0;
|
||||
snprintf (option_name, sizeof (option_name),
|
||||
"%s_value_%05d", prefix, item_number);
|
||||
switch (hashtable->type_values)
|
||||
{
|
||||
snprintf (option_name, sizeof (option_name),
|
||||
"%s_name_%05d", prefix, item_number);
|
||||
if (!infolist_new_var_string (infolist_item, option_name,
|
||||
hashtable_to_string (hashtable->type_keys,
|
||||
ptr_item->key)))
|
||||
return 0;
|
||||
snprintf (option_name, sizeof (option_name),
|
||||
"%s_value_%05d", prefix, item_number);
|
||||
switch (hashtable->type_values)
|
||||
{
|
||||
case HASHTABLE_INTEGER:
|
||||
if (!infolist_new_var_integer (infolist_item, option_name,
|
||||
*((int *)ptr_item->value)))
|
||||
return 0;
|
||||
break;
|
||||
case HASHTABLE_STRING:
|
||||
if (!infolist_new_var_string (infolist_item, option_name,
|
||||
(const char *)ptr_item->value))
|
||||
return 0;
|
||||
break;
|
||||
case HASHTABLE_POINTER:
|
||||
if (!infolist_new_var_pointer (infolist_item, option_name,
|
||||
ptr_item->value))
|
||||
return 0;
|
||||
break;
|
||||
case HASHTABLE_BUFFER:
|
||||
if (!infolist_new_var_buffer (infolist_item, option_name,
|
||||
ptr_item->value,
|
||||
ptr_item->value_size))
|
||||
return 0;
|
||||
break;
|
||||
case HASHTABLE_TIME:
|
||||
if (!infolist_new_var_time (infolist_item, option_name,
|
||||
*((time_t *)ptr_item->value)))
|
||||
return 0;
|
||||
break;
|
||||
case HASHTABLE_NUM_TYPES:
|
||||
break;
|
||||
}
|
||||
item_number++;
|
||||
case HASHTABLE_INTEGER:
|
||||
if (!infolist_new_var_integer (infolist_item, option_name,
|
||||
*((int *)ptr_item->value)))
|
||||
return 0;
|
||||
break;
|
||||
case HASHTABLE_STRING:
|
||||
if (!infolist_new_var_string (infolist_item, option_name,
|
||||
(const char *)ptr_item->value))
|
||||
return 0;
|
||||
break;
|
||||
case HASHTABLE_POINTER:
|
||||
if (!infolist_new_var_pointer (infolist_item, option_name,
|
||||
ptr_item->value))
|
||||
return 0;
|
||||
break;
|
||||
case HASHTABLE_BUFFER:
|
||||
if (!infolist_new_var_buffer (infolist_item, option_name,
|
||||
ptr_item->value,
|
||||
ptr_item->value_size))
|
||||
return 0;
|
||||
break;
|
||||
case HASHTABLE_TIME:
|
||||
if (!infolist_new_var_time (infolist_item, option_name,
|
||||
*((time_t *)ptr_item->value)))
|
||||
return 0;
|
||||
break;
|
||||
case HASHTABLE_NUM_TYPES:
|
||||
break;
|
||||
}
|
||||
item_number++;
|
||||
ptr_item = ptr_item->next_created_item;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
@ -1203,6 +1210,16 @@ hashtable_remove_item (struct t_hashtable *hashtable,
|
||||
hashtable_free_value (hashtable, item);
|
||||
hashtable_free_key (hashtable, item);
|
||||
|
||||
/* remove item from ordered list (by date of creation) */
|
||||
if (item->prev_created_item)
|
||||
(item->prev_created_item)->next_created_item = item->next_created_item;
|
||||
if (item->next_created_item)
|
||||
(item->next_created_item)->prev_created_item = item->prev_created_item;
|
||||
if (hashtable->oldest_item == item)
|
||||
hashtable->oldest_item = item->next_created_item;
|
||||
if (hashtable->newest_item == item)
|
||||
hashtable->newest_item = item->prev_created_item;
|
||||
|
||||
/* remove item from list */
|
||||
if (item->prev_item)
|
||||
(item->prev_item)->next_item = item->next_item;
|
||||
@ -1287,6 +1304,8 @@ hashtable_print_log (struct t_hashtable *hashtable, const char *name)
|
||||
log_printf (" size . . . . . . . . . : %d", hashtable->size);
|
||||
log_printf (" htable . . . . . . . . : 0x%lx", hashtable->htable);
|
||||
log_printf (" items_count. . . . . . : %d", hashtable->items_count);
|
||||
log_printf (" oldest_item. . . . . . : 0x%lx", hashtable->oldest_item);
|
||||
log_printf (" newest_item. . . . . . : 0x%lx", hashtable->newest_item);
|
||||
log_printf (" type_keys. . . . . . . : %d (%s)",
|
||||
hashtable->type_keys,
|
||||
hashtable_type_string[hashtable->type_keys]);
|
||||
@ -1350,6 +1369,8 @@ hashtable_print_log (struct t_hashtable *hashtable, const char *name)
|
||||
log_printf (" value_size . . . . : %d", ptr_item->value_size);
|
||||
log_printf (" prev_item. . . . . : 0x%lx", ptr_item->prev_item);
|
||||
log_printf (" next_item. . . . . : 0x%lx", ptr_item->next_item);
|
||||
log_printf (" prev_created_item. : 0x%lx", ptr_item->prev_created_item);
|
||||
log_printf (" next_created_item. : 0x%lx", ptr_item->next_created_item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -117,6 +117,10 @@ struct t_hashtable_item
|
||||
int value_size; /* size of value (in bytes) */
|
||||
struct t_hashtable_item *prev_item; /* link to previous item */
|
||||
struct t_hashtable_item *next_item; /* link to next item */
|
||||
/* previous/next item by order of creation in the hashtable */
|
||||
struct t_hashtable_item *prev_created_item;
|
||||
struct t_hashtable_item *next_created_item;
|
||||
|
||||
};
|
||||
|
||||
struct t_hashtable
|
||||
@ -125,6 +129,8 @@ struct t_hashtable
|
||||
struct t_hashtable_item **htable; /* table to map hashes with linked */
|
||||
/* lists */
|
||||
int items_count; /* number of items in hashtable */
|
||||
struct t_hashtable_item *oldest_item; /* oldest item in hashtable */
|
||||
struct t_hashtable_item *newest_item; /* newest item in hashtable */
|
||||
|
||||
/* type for keys and values */
|
||||
enum t_hashtable_type type_keys; /* type for keys: int/str/pointer */
|
||||
|
@ -25,6 +25,8 @@ extern "C"
|
||||
{
|
||||
#include <string.h>
|
||||
#include "src/core/wee-hashtable.h"
|
||||
#include "src/core/wee-infolist.h"
|
||||
#include "src/core/wee-list.h"
|
||||
#include "src/plugins/plugin.h"
|
||||
}
|
||||
|
||||
@ -34,8 +36,27 @@ extern "C"
|
||||
#define HASHTABLE_TEST_KEY_LONG_HASH 11232856562070989738ULL
|
||||
#define HASHTABLE_TEST_VALUE "this is a value"
|
||||
|
||||
char *test_map_string = NULL;
|
||||
|
||||
TEST_GROUP(CoreHashtable)
|
||||
{
|
||||
struct t_hashtable *get_weechat_hashtable ()
|
||||
{
|
||||
struct t_hashtable *hashtable;
|
||||
|
||||
hashtable = hashtable_new (8,
|
||||
WEECHAT_HASHTABLE_STRING,
|
||||
WEECHAT_HASHTABLE_STRING,
|
||||
NULL,
|
||||
NULL);
|
||||
hashtable_set (hashtable, "weechat", "the first item");
|
||||
hashtable_set (hashtable, "light", "item2");
|
||||
hashtable_set (hashtable, "fast", "item3");
|
||||
hashtable_set (hashtable, "extensible", "item4");
|
||||
hashtable_set (hashtable, "chat", "item5");
|
||||
hashtable_set (hashtable, "client", "last item");
|
||||
return hashtable;
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
@ -121,6 +142,8 @@ TEST(CoreHashtable, New)
|
||||
LONGS_EQUAL(32, hashtable->size);
|
||||
CHECK(hashtable->htable);
|
||||
LONGS_EQUAL(0, hashtable->items_count);
|
||||
POINTERS_EQUAL(NULL, hashtable->oldest_item);
|
||||
POINTERS_EQUAL(NULL, hashtable->newest_item);
|
||||
LONGS_EQUAL(HASHTABLE_STRING, hashtable->type_keys);
|
||||
LONGS_EQUAL(HASHTABLE_INTEGER, hashtable->type_values);
|
||||
POINTERS_EQUAL(&test_hashtable_hash_key_cb, hashtable->callback_hash_key);
|
||||
@ -169,23 +192,31 @@ TEST(CoreHashtable, SetGetRemove)
|
||||
item = hashtable_set (hashtable, str_key, NULL);
|
||||
CHECK(item);
|
||||
LONGS_EQUAL(1, hashtable->items_count);
|
||||
CHECK(hashtable->oldest_item);
|
||||
CHECK(hashtable->newest_item);
|
||||
STRCMP_EQUAL(str_key, (const char *)item->key);
|
||||
LONGS_EQUAL(strlen (str_key) + 1, item->key_size);
|
||||
POINTERS_EQUAL(NULL, item->value);
|
||||
LONGS_EQUAL(0, item->value_size);
|
||||
POINTERS_EQUAL(NULL, item->prev_item);
|
||||
POINTERS_EQUAL(NULL, item->next_item);
|
||||
POINTERS_EQUAL(NULL, item->prev_created_item);
|
||||
POINTERS_EQUAL(NULL, item->next_created_item);
|
||||
|
||||
/* set a string value for the same key */
|
||||
item = hashtable_set (hashtable, str_key, str_value);
|
||||
CHECK(item);
|
||||
LONGS_EQUAL(1, hashtable->items_count);
|
||||
CHECK(hashtable->oldest_item);
|
||||
CHECK(hashtable->newest_item);
|
||||
STRCMP_EQUAL(str_key, (const char *)item->key);
|
||||
LONGS_EQUAL(strlen (str_key) + 1, item->key_size);
|
||||
STRCMP_EQUAL(str_value, (const char *)item->value);
|
||||
LONGS_EQUAL(strlen (str_value) + 1, item->value_size);
|
||||
POINTERS_EQUAL(NULL, item->prev_item);
|
||||
POINTERS_EQUAL(NULL, item->next_item);
|
||||
POINTERS_EQUAL(NULL, item->prev_created_item);
|
||||
POINTERS_EQUAL(NULL, item->next_created_item);
|
||||
|
||||
/* get item */
|
||||
item = hashtable_get_item (hashtable, str_key, &hash);
|
||||
@ -208,6 +239,8 @@ TEST(CoreHashtable, SetGetRemove)
|
||||
/* delete an item */
|
||||
hashtable_remove (hashtable, str_key);
|
||||
LONGS_EQUAL(0, hashtable->items_count);
|
||||
POINTERS_EQUAL(NULL, hashtable->oldest_item);
|
||||
POINTERS_EQUAL(NULL, hashtable->newest_item);
|
||||
|
||||
/* add an item with size in hashtable */
|
||||
item = hashtable_set_with_size (hashtable,
|
||||
@ -215,6 +248,8 @@ TEST(CoreHashtable, SetGetRemove)
|
||||
str_value, strlen (str_value) + 1);
|
||||
CHECK(item);
|
||||
LONGS_EQUAL(1, hashtable->items_count);
|
||||
CHECK(hashtable->oldest_item);
|
||||
CHECK(hashtable->newest_item);
|
||||
STRCMP_EQUAL(str_key, (const char *)item->key);
|
||||
LONGS_EQUAL(strlen (str_key) + 1, item->key_size);
|
||||
STRCMP_EQUAL(str_value, (const char *)item->value);
|
||||
@ -223,6 +258,15 @@ TEST(CoreHashtable, SetGetRemove)
|
||||
/* add another item */
|
||||
hashtable_set (hashtable, "xxx", "zzz");
|
||||
LONGS_EQUAL(2, hashtable->items_count);
|
||||
CHECK(hashtable->oldest_item);
|
||||
CHECK(hashtable->newest_item);
|
||||
CHECK(hashtable->oldest_item != hashtable->newest_item);
|
||||
CHECK(hashtable->oldest_item->next_created_item == hashtable->newest_item);
|
||||
STRCMP_EQUAL(str_key, (const char *)hashtable->oldest_item->key);
|
||||
STRCMP_EQUAL("xxx",
|
||||
(const char *)hashtable->oldest_item->next_created_item->key);
|
||||
STRCMP_EQUAL("xxx",
|
||||
(const char *)hashtable->newest_item->key);
|
||||
|
||||
/*
|
||||
* test duplication of hashtable and check that duplicated content is
|
||||
@ -273,7 +317,17 @@ TEST(CoreHashtable, SetGetRemove)
|
||||
|
||||
/* remove all items */
|
||||
hashtable_remove_all (hashtable);
|
||||
POINTERS_EQUAL(NULL, hashtable->htable[0]);
|
||||
POINTERS_EQUAL(NULL, hashtable->htable[1]);
|
||||
POINTERS_EQUAL(NULL, hashtable->htable[2]);
|
||||
POINTERS_EQUAL(NULL, hashtable->htable[3]);
|
||||
POINTERS_EQUAL(NULL, hashtable->htable[4]);
|
||||
POINTERS_EQUAL(NULL, hashtable->htable[5]);
|
||||
POINTERS_EQUAL(NULL, hashtable->htable[6]);
|
||||
POINTERS_EQUAL(NULL, hashtable->htable[7]);
|
||||
LONGS_EQUAL(0, hashtable->items_count);
|
||||
POINTERS_EQUAL(NULL, hashtable->oldest_item);
|
||||
POINTERS_EQUAL(NULL, hashtable->newest_item);
|
||||
|
||||
/* free hashtables */
|
||||
hashtable_free (hashtable);
|
||||
@ -313,13 +367,13 @@ TEST(CoreHashtable, SetGetRemove)
|
||||
CHECK(item);
|
||||
POINTERS_EQUAL(item, hashtable->htable[7]);
|
||||
|
||||
item = hashtable_set (hashtable, "fast", NULL);
|
||||
item = hashtable_set (hashtable, "light", NULL);
|
||||
CHECK(item);
|
||||
POINTERS_EQUAL(item, hashtable->htable[3]);
|
||||
|
||||
item = hashtable_set (hashtable, "light", NULL);
|
||||
item = hashtable_set (hashtable, "fast", NULL);
|
||||
CHECK(item);
|
||||
POINTERS_EQUAL(item, hashtable->htable[3]->next_item);
|
||||
POINTERS_EQUAL(item, hashtable->htable[3]);
|
||||
|
||||
item = hashtable_set (hashtable, "extensible", NULL);
|
||||
CHECK(item);
|
||||
@ -333,32 +387,335 @@ TEST(CoreHashtable, SetGetRemove)
|
||||
CHECK(item);
|
||||
POINTERS_EQUAL(item, hashtable->htable[6]);
|
||||
|
||||
/* check items by order of creation */
|
||||
ptr_item = hashtable->oldest_item;
|
||||
STRCMP_EQUAL("weechat", (const char *)ptr_item->key);
|
||||
ptr_item = ptr_item->next_created_item;
|
||||
STRCMP_EQUAL("light", (const char *)ptr_item->key);
|
||||
ptr_item = ptr_item->next_created_item;
|
||||
STRCMP_EQUAL("fast", (const char *)ptr_item->key);
|
||||
ptr_item = ptr_item->next_created_item;
|
||||
STRCMP_EQUAL("extensible", (const char *)ptr_item->key);
|
||||
ptr_item = ptr_item->next_created_item;
|
||||
STRCMP_EQUAL("chat", (const char *)ptr_item->key);
|
||||
ptr_item = ptr_item->next_created_item;
|
||||
STRCMP_EQUAL("client", (const char *)ptr_item->key);
|
||||
STRCMP_EQUAL("client", (const char *)hashtable->newest_item->key);
|
||||
ptr_item = ptr_item->next_created_item;
|
||||
POINTERS_EQUAL(NULL, ptr_item);
|
||||
|
||||
/* remove items and check again by order of creation */
|
||||
hashtable_remove (hashtable, "fast");
|
||||
LONGS_EQUAL(5, hashtable->items_count);
|
||||
ptr_item = hashtable->oldest_item;
|
||||
STRCMP_EQUAL("weechat", (const char *)ptr_item->key);
|
||||
ptr_item = ptr_item->next_created_item;
|
||||
STRCMP_EQUAL("light", (const char *)ptr_item->key);
|
||||
ptr_item = ptr_item->next_created_item;
|
||||
STRCMP_EQUAL("extensible", (const char *)ptr_item->key);
|
||||
ptr_item = ptr_item->next_created_item;
|
||||
STRCMP_EQUAL("chat", (const char *)ptr_item->key);
|
||||
ptr_item = ptr_item->next_created_item;
|
||||
STRCMP_EQUAL("client", (const char *)ptr_item->key);
|
||||
STRCMP_EQUAL("client", (const char *)hashtable->newest_item->key);
|
||||
ptr_item = ptr_item->next_created_item;
|
||||
POINTERS_EQUAL(NULL, ptr_item);
|
||||
|
||||
hashtable_remove (hashtable, "light");
|
||||
LONGS_EQUAL(4, hashtable->items_count);
|
||||
ptr_item = hashtable->oldest_item;
|
||||
STRCMP_EQUAL("weechat", (const char *)ptr_item->key);
|
||||
ptr_item = ptr_item->next_created_item;
|
||||
STRCMP_EQUAL("extensible", (const char *)ptr_item->key);
|
||||
ptr_item = ptr_item->next_created_item;
|
||||
STRCMP_EQUAL("chat", (const char *)ptr_item->key);
|
||||
ptr_item = ptr_item->next_created_item;
|
||||
STRCMP_EQUAL("client", (const char *)ptr_item->key);
|
||||
STRCMP_EQUAL("client", (const char *)hashtable->newest_item->key);
|
||||
ptr_item = ptr_item->next_created_item;
|
||||
POINTERS_EQUAL(NULL, ptr_item);
|
||||
|
||||
hashtable_remove (hashtable, "weechat");
|
||||
LONGS_EQUAL(3, hashtable->items_count);
|
||||
ptr_item = hashtable->oldest_item;
|
||||
STRCMP_EQUAL("extensible", (const char *)ptr_item->key);
|
||||
ptr_item = ptr_item->next_created_item;
|
||||
STRCMP_EQUAL("chat", (const char *)ptr_item->key);
|
||||
ptr_item = ptr_item->next_created_item;
|
||||
STRCMP_EQUAL("client", (const char *)ptr_item->key);
|
||||
STRCMP_EQUAL("client", (const char *)hashtable->newest_item->key);
|
||||
ptr_item = ptr_item->next_created_item;
|
||||
POINTERS_EQUAL(NULL, ptr_item);
|
||||
|
||||
hashtable_remove (hashtable, "client");
|
||||
LONGS_EQUAL(2, hashtable->items_count);
|
||||
ptr_item = hashtable->oldest_item;
|
||||
STRCMP_EQUAL("extensible", (const char *)ptr_item->key);
|
||||
ptr_item = ptr_item->next_created_item;
|
||||
STRCMP_EQUAL("chat", (const char *)ptr_item->key);
|
||||
STRCMP_EQUAL("chat", (const char *)hashtable->newest_item->key);
|
||||
ptr_item = ptr_item->next_created_item;
|
||||
POINTERS_EQUAL(NULL, ptr_item);
|
||||
|
||||
/* check current content of hashtable */
|
||||
POINTERS_EQUAL(NULL, hashtable->htable[0]);
|
||||
POINTERS_EQUAL(NULL, hashtable->htable[1]);
|
||||
STRCMP_EQUAL("extensible", (const char *)hashtable->htable[2]->key);
|
||||
POINTERS_EQUAL(NULL, hashtable->htable[3]);
|
||||
POINTERS_EQUAL(NULL, hashtable->htable[4]);
|
||||
STRCMP_EQUAL("chat", (const char *)hashtable->htable[5]->key);
|
||||
POINTERS_EQUAL(NULL, hashtable->htable[6]);
|
||||
POINTERS_EQUAL(NULL, hashtable->htable[7]);
|
||||
|
||||
/* free hashtable */
|
||||
hashtable_free (hashtable);
|
||||
}
|
||||
|
||||
void
|
||||
test_hashtable_map_string_cb (void *data,
|
||||
struct t_hashtable *hashtable,
|
||||
const char *key, const char *value)
|
||||
{
|
||||
/* make C++ compiler happy */
|
||||
(void) hashtable;
|
||||
(void) data;
|
||||
|
||||
if (test_map_string[0])
|
||||
strcat (test_map_string, ";");
|
||||
strcat (test_map_string, key);
|
||||
strcat (test_map_string, ":");
|
||||
strcat (test_map_string, value);
|
||||
}
|
||||
|
||||
/*
|
||||
* Tests functions:
|
||||
* hashtable_map_string
|
||||
*/
|
||||
|
||||
TEST(CoreHashtable, MapString)
|
||||
{
|
||||
struct t_hashtable *hashtable;
|
||||
int value_int;
|
||||
void *value_ptr;
|
||||
time_t value_time;
|
||||
char result[1024], value_buffer[3] = { 0x01, 0x05, 0x09 };
|
||||
|
||||
test_map_string = (char *)malloc (1024);
|
||||
|
||||
/* string -> string */
|
||||
test_map_string[0] = '\0';
|
||||
hashtable = get_weechat_hashtable ();
|
||||
hashtable_map_string (hashtable, &test_hashtable_map_string_cb, NULL);
|
||||
STRCMP_EQUAL("weechat:the first item;light:item2;fast:item3;"
|
||||
"extensible:item4;chat:item5;client:last item",
|
||||
test_map_string);
|
||||
|
||||
/* integer -> pointer */
|
||||
test_map_string[0] = '\0';
|
||||
hashtable = hashtable_new (8,
|
||||
WEECHAT_HASHTABLE_INTEGER,
|
||||
WEECHAT_HASHTABLE_POINTER,
|
||||
NULL,
|
||||
NULL);
|
||||
value_int = 123;
|
||||
value_ptr = (void *)0x123abc;
|
||||
hashtable_set (hashtable, &value_int, value_ptr);
|
||||
value_int = 45678;
|
||||
value_ptr = (void *)0xdef789;
|
||||
hashtable_set (hashtable, &value_int, value_ptr);
|
||||
hashtable_map_string (hashtable, &test_hashtable_map_string_cb, NULL);
|
||||
STRCMP_EQUAL("123:0x123abc;45678:0xdef789", test_map_string);
|
||||
|
||||
/* time -> buffer */
|
||||
test_map_string[0] = '\0';
|
||||
hashtable = hashtable_new (8,
|
||||
WEECHAT_HASHTABLE_TIME,
|
||||
WEECHAT_HASHTABLE_BUFFER,
|
||||
NULL,
|
||||
NULL);
|
||||
value_time = 1624693124;
|
||||
hashtable_set_with_size (hashtable,
|
||||
&value_time, 0,
|
||||
value_buffer, sizeof (value_buffer));
|
||||
hashtable_map_string (hashtable, &test_hashtable_map_string_cb, NULL);
|
||||
snprintf (result, sizeof (result),
|
||||
"1624693124:0x%lx",
|
||||
(unsigned long)(hashtable->newest_item->value));
|
||||
STRCMP_EQUAL(result, test_map_string);
|
||||
|
||||
free (test_map_string);
|
||||
}
|
||||
|
||||
/*
|
||||
* Tests functions:
|
||||
* hashtable_map
|
||||
* hashtable_map_string
|
||||
* hashtable_dup
|
||||
*/
|
||||
|
||||
TEST(CoreHashtable, Map)
|
||||
TEST(CoreHashtable, Dup)
|
||||
{
|
||||
/* TODO: write tests */
|
||||
struct t_hashtable *hashtable, *hashtable2;
|
||||
struct t_hashtable_item *ptr_item;
|
||||
|
||||
hashtable = get_weechat_hashtable ();
|
||||
|
||||
POINTERS_EQUAL(NULL, hashtable_dup (NULL));
|
||||
|
||||
hashtable2 = hashtable_dup (hashtable);
|
||||
|
||||
LONGS_EQUAL(6, hashtable2->items_count);
|
||||
ptr_item = hashtable2->oldest_item;
|
||||
STRCMP_EQUAL("weechat", (const char *)ptr_item->key);
|
||||
ptr_item = ptr_item->next_created_item;
|
||||
STRCMP_EQUAL("light", (const char *)ptr_item->key);
|
||||
ptr_item = ptr_item->next_created_item;
|
||||
STRCMP_EQUAL("fast", (const char *)ptr_item->key);
|
||||
ptr_item = ptr_item->next_created_item;
|
||||
STRCMP_EQUAL("extensible", (const char *)ptr_item->key);
|
||||
ptr_item = ptr_item->next_created_item;
|
||||
STRCMP_EQUAL("chat", (const char *)ptr_item->key);
|
||||
ptr_item = ptr_item->next_created_item;
|
||||
STRCMP_EQUAL("client", (const char *)ptr_item->key);
|
||||
STRCMP_EQUAL("client", (const char *)hashtable2->newest_item->key);
|
||||
ptr_item = ptr_item->next_created_item;
|
||||
POINTERS_EQUAL(NULL, ptr_item);
|
||||
|
||||
hashtable_free (hashtable);
|
||||
hashtable_free (hashtable2);
|
||||
}
|
||||
|
||||
/*
|
||||
* Tests functions:
|
||||
* hashtable_get_list_keys
|
||||
*/
|
||||
|
||||
TEST(CoreHashtable, GetListKeys)
|
||||
{
|
||||
struct t_hashtable *hashtable;
|
||||
struct t_weelist *list_keys;
|
||||
|
||||
hashtable = get_weechat_hashtable ();
|
||||
|
||||
POINTERS_EQUAL(NULL, hashtable_get_list_keys (NULL));
|
||||
|
||||
list_keys = hashtable_get_list_keys (hashtable);
|
||||
CHECK(list_keys);
|
||||
STRCMP_EQUAL("chat", weelist_string (weelist_get (list_keys, 0)));
|
||||
STRCMP_EQUAL("client", weelist_string (weelist_get (list_keys, 1)));
|
||||
STRCMP_EQUAL("extensible", weelist_string (weelist_get (list_keys, 2)));
|
||||
STRCMP_EQUAL("fast", weelist_string (weelist_get (list_keys, 3)));
|
||||
STRCMP_EQUAL("light", weelist_string (weelist_get (list_keys, 4)));
|
||||
STRCMP_EQUAL("weechat", weelist_string (weelist_get (list_keys, 5)));
|
||||
|
||||
hashtable_free (hashtable);
|
||||
}
|
||||
|
||||
/*
|
||||
* Tests functions:
|
||||
* hashtable_get_integer
|
||||
*/
|
||||
|
||||
TEST(CoreHashtable, GetInteger)
|
||||
{
|
||||
struct t_hashtable *hashtable;
|
||||
|
||||
hashtable = get_weechat_hashtable ();
|
||||
|
||||
LONGS_EQUAL(0, hashtable_get_integer (NULL, NULL));
|
||||
LONGS_EQUAL(0, hashtable_get_integer (hashtable, NULL));
|
||||
LONGS_EQUAL(0, hashtable_get_integer (hashtable, ""));
|
||||
LONGS_EQUAL(0, hashtable_get_integer (hashtable, "unknown"));
|
||||
|
||||
LONGS_EQUAL(8, hashtable_get_integer (hashtable, "size"));
|
||||
LONGS_EQUAL(6, hashtable_get_integer (hashtable, "items_count"));
|
||||
|
||||
hashtable_free (hashtable);
|
||||
}
|
||||
|
||||
/*
|
||||
* Tests functions:
|
||||
* hashtable_get_string
|
||||
*/
|
||||
|
||||
TEST(CoreHashtable, GetString)
|
||||
{
|
||||
struct t_hashtable *hashtable;
|
||||
|
||||
hashtable = get_weechat_hashtable ();
|
||||
|
||||
POINTERS_EQUAL(NULL, hashtable_get_string (NULL, NULL));
|
||||
POINTERS_EQUAL(NULL, hashtable_get_string (hashtable, NULL));
|
||||
POINTERS_EQUAL(NULL, hashtable_get_string (hashtable, ""));
|
||||
POINTERS_EQUAL(NULL, hashtable_get_string (hashtable, "unknown"));
|
||||
|
||||
STRCMP_EQUAL("string", hashtable_get_string (hashtable, "type_keys"));
|
||||
STRCMP_EQUAL("string", hashtable_get_string (hashtable, "type_values"));
|
||||
STRCMP_EQUAL("weechat,light,fast,extensible,chat,client",
|
||||
hashtable_get_string (hashtable, "keys"));
|
||||
STRCMP_EQUAL("chat,client,extensible,fast,light,weechat",
|
||||
hashtable_get_string (hashtable, "keys_sorted"));
|
||||
STRCMP_EQUAL("the first item,item2,item3,item4,item5,last item",
|
||||
hashtable_get_string (hashtable, "values"));
|
||||
STRCMP_EQUAL("weechat:the first item,light:item2,fast:item3,"
|
||||
"extensible:item4,chat:item5,client:last item",
|
||||
hashtable_get_string (hashtable, "keys_values"));
|
||||
STRCMP_EQUAL("chat:item5,client:last item,extensible:item4,fast:item3,"
|
||||
"light:item2,weechat:the first item",
|
||||
hashtable_get_string (hashtable, "keys_values_sorted"));
|
||||
|
||||
hashtable_free (hashtable);
|
||||
}
|
||||
|
||||
/*
|
||||
* Test callback freeing key (it does nothing).
|
||||
*/
|
||||
|
||||
void
|
||||
test_hashtable_free_key (struct t_hashtable *hashtable, void *key)
|
||||
{
|
||||
/* make C++ compiler happy */
|
||||
(void) hashtable;
|
||||
(void) key;
|
||||
}
|
||||
|
||||
/*
|
||||
* Test callback freeing value (it does nothing).
|
||||
*/
|
||||
|
||||
void
|
||||
test_hashtable_free_value (struct t_hashtable *hashtable,
|
||||
const void *key, void *value)
|
||||
{
|
||||
/* make C++ compiler happy */
|
||||
(void) hashtable;
|
||||
(void) key;
|
||||
(void) value;
|
||||
}
|
||||
|
||||
/*
|
||||
* Tests functions:
|
||||
* hashtable_set_pointer
|
||||
*/
|
||||
|
||||
TEST(CoreHashtable, Properties)
|
||||
TEST(CoreHashtable, SetPointer)
|
||||
{
|
||||
/* TODO: write tests */
|
||||
struct t_hashtable *hashtable;
|
||||
|
||||
hashtable = get_weechat_hashtable ();
|
||||
|
||||
hashtable_set_pointer (NULL, NULL, NULL);
|
||||
hashtable_set_pointer (hashtable, NULL, NULL);
|
||||
hashtable_set_pointer (hashtable, "", NULL);
|
||||
hashtable_set_pointer (hashtable, "unknown", NULL);
|
||||
|
||||
hashtable_set_pointer (hashtable,
|
||||
"callback_free_key", (void *)&test_hashtable_free_key);
|
||||
POINTERS_EQUAL(&test_hashtable_free_key, hashtable->callback_free_key);
|
||||
hashtable_set_pointer (hashtable,
|
||||
"callback_free_value", (void *)&test_hashtable_free_value);
|
||||
POINTERS_EQUAL(&test_hashtable_free_value, hashtable->callback_free_value);
|
||||
|
||||
hashtable_free (hashtable);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -369,7 +726,36 @@ TEST(CoreHashtable, Properties)
|
||||
|
||||
TEST(CoreHashtable, Infolist)
|
||||
{
|
||||
/* TODO: write tests */
|
||||
struct t_hashtable *hashtable;
|
||||
struct t_infolist *infolist;
|
||||
struct t_infolist_item *infolist_item;
|
||||
|
||||
hashtable = get_weechat_hashtable ();
|
||||
|
||||
infolist = infolist_new (NULL);
|
||||
infolist_item = infolist_new_item (infolist);
|
||||
|
||||
LONGS_EQUAL(0, hashtable_add_to_infolist (NULL, NULL, NULL));
|
||||
LONGS_EQUAL(0, hashtable_add_to_infolist (hashtable, NULL, NULL));
|
||||
LONGS_EQUAL(0, hashtable_add_to_infolist (hashtable, infolist_item, NULL));
|
||||
|
||||
LONGS_EQUAL(1, hashtable_add_to_infolist (hashtable, infolist_item, "test"));
|
||||
|
||||
infolist_reset_item_cursor (infolist);
|
||||
infolist_next (infolist);
|
||||
|
||||
STRCMP_EQUAL("weechat", infolist_string (infolist, "test_name_00000"));
|
||||
STRCMP_EQUAL("the first item", infolist_string (infolist, "test_value_00000"));
|
||||
STRCMP_EQUAL("light", infolist_string (infolist, "test_name_00001"));
|
||||
STRCMP_EQUAL("item2", infolist_string (infolist, "test_value_00001"));
|
||||
STRCMP_EQUAL("fast", infolist_string (infolist, "test_name_00002"));
|
||||
STRCMP_EQUAL("item3", infolist_string (infolist, "test_value_00002"));
|
||||
STRCMP_EQUAL("extensible", infolist_string (infolist, "test_name_00003"));
|
||||
STRCMP_EQUAL("item4", infolist_string (infolist, "test_value_00003"));
|
||||
STRCMP_EQUAL("chat", infolist_string (infolist, "test_name_00004"));
|
||||
STRCMP_EQUAL("item5", infolist_string (infolist, "test_value_00004"));
|
||||
STRCMP_EQUAL("client", infolist_string (infolist, "test_name_00005"));
|
||||
STRCMP_EQUAL("last item", infolist_string (infolist, "test_value_00005"));
|
||||
}
|
||||
|
||||
/*
|
||||
|
Loading…
x
Reference in New Issue
Block a user