From 0a4be02dc368218f729eb118521885f30fa23a6d Mon Sep 17 00:00:00 2001 From: Simmo Saan Date: Sun, 13 Dec 2015 16:55:59 +0200 Subject: [PATCH] core: add hashtable_add_from_infolist to API --- doc/en/weechat_plugin_api.en.adoc | 45 +++++++++++++++ src/core/wee-hashtable.c | 92 ++++++++++++++++++++++++++++++ src/core/wee-hashtable.h | 4 ++ src/plugins/plugin.c | 1 + src/plugins/weechat-plugin.h | 10 +++- tests/unit/core/test-hashtable.cpp | 1 + 6 files changed, 152 insertions(+), 1 deletion(-) diff --git a/doc/en/weechat_plugin_api.en.adoc b/doc/en/weechat_plugin_api.en.adoc index 4fb28a02c..bce4692bd 100644 --- a/doc/en/weechat_plugin_api.en.adoc +++ b/doc/en/weechat_plugin_api.en.adoc @@ -4846,6 +4846,51 @@ weechat_hashtable_add_to_infolist (hashtable, infolist_item, "testhash"); [NOTE] This function is not available in scripting API. +==== hashtable_add_from_infolist + +_WeeChat ≥ x.y.z._ + +Add hashtable items from an infolist. + +Prototype: + +[source,C] +---- +int weechat_hashtable_add_from_infolist (struct t_hashtable *hashtable, + struct t_infolist *infolist, + const char *prefix); +---- + +Arguments: + +* 'hashtable': hashtable pointer +* 'infolist': infolist pointer +* 'prefix': string used as prefix for names in infolist + +Return value: + +* 1 if OK, 0 if error + +C example: + +[source,C] +---- +weechat_hashtable_add_from_infolist (hashtable, infolist, "testhash"); + +/* if infolist contains: + "testhash_name_00000" = "key1" + "testhash_value_00000" = "value 1" + "testhash_name_00001" = "key2" + "testhash_value_00001" = "value 2" + then following variables will be added to hashtable: + "key1" => "value 1" + "key2" => "value 2" +*/ +---- + +[NOTE] +This function is not available in scripting API. + ==== hashtable_remove _WeeChat ≥ 0.3.3._ diff --git a/src/core/wee-hashtable.c b/src/core/wee-hashtable.c index 15ebd14c4..d9f480c42 100644 --- a/src/core/wee-hashtable.c +++ b/src/core/wee-hashtable.c @@ -1062,6 +1062,8 @@ hashtable_add_to_infolist (struct t_hashtable *hashtable, hashtable_to_string (hashtable->type_keys, ptr_item->key))) return 0; + /* TODO: implement other key types */ + snprintf (option_name, sizeof (option_name), "%s_value_%05d", prefix, item_number); switch (hashtable->type_values) @@ -1101,6 +1103,96 @@ hashtable_add_to_infolist (struct t_hashtable *hashtable, return 1; } +/* + * Adds hashtable keys and values from an infolist. + * + * Returns: + * 1: OK + * 0: error + */ + +int +hashtable_add_from_infolist (struct t_hashtable *hashtable, + struct t_infolist *infolist, + const char *prefix) +{ + struct t_infolist_item *infolist_item; + struct t_infolist_var *ptr_name, *ptr_value; + void *value; + char prefix_name[128], option_value[128]; + int prefix_length; + + if (!hashtable || !infolist || !prefix) + return 0; + + infolist_item = infolist->ptr_item; + if (!infolist_item) + return 0; + + if (hashtable->type_keys != HASHTABLE_STRING) + return 0; + /* TODO: implement other key types */ + + snprintf (prefix_name, sizeof (prefix_name), + "%s_name_", prefix); + prefix_length = strlen (prefix_name); + + for (ptr_name = infolist_item->vars; ptr_name; ptr_name = ptr_name->next_var) + { + if (string_strncasecmp (ptr_name->name, prefix_name, prefix_length) == 0) + { + snprintf (option_value, sizeof (option_value), + "%s_value_%s", prefix, ptr_name->name + prefix_length); + + for (ptr_value = infolist_item->vars; ptr_value; ptr_value = ptr_value->next_var) + { + if (string_strcasecmp (ptr_value->name, option_value) == 0) + { + switch (hashtable->type_values) + { + case HASHTABLE_INTEGER: + if (ptr_value->type != INFOLIST_INTEGER) + return 0; + + value = ptr_value->value; + break; + case HASHTABLE_STRING: + if (ptr_value->type != INFOLIST_STRING) + return 0; + + value = ptr_value->value; + break; + case HASHTABLE_POINTER: + if (ptr_value->type != INFOLIST_POINTER) + return 0; + + value = ptr_value->value; + break; + case HASHTABLE_BUFFER: + if (ptr_value->type != INFOLIST_BUFFER) + return 0; + + value = ptr_value->value; /* TODO: implement size */ + break; + case HASHTABLE_TIME: + if (ptr_value->type != INFOLIST_TIME) + return 0; + + value = ptr_value->value; + break; + case HASHTABLE_NUM_TYPES: + break; + } + hashtable_set (hashtable, ptr_name->value, value); + break; + } + } + } + } + + return 1; +} + /* * Removes an item from hashtable. */ diff --git a/src/core/wee-hashtable.h b/src/core/wee-hashtable.h index 38706d7cb..2ea414574 100644 --- a/src/core/wee-hashtable.h +++ b/src/core/wee-hashtable.h @@ -22,6 +22,7 @@ struct t_hashtable; struct t_infolist_item; +struct t_infolist; typedef unsigned long long (t_hashtable_hash_key)(struct t_hashtable *hashtable, const void *key); @@ -149,6 +150,9 @@ extern void hashtable_set_pointer (struct t_hashtable *hashtable, extern int hashtable_add_to_infolist (struct t_hashtable *hashtable, struct t_infolist_item *infolist_item, const char *prefix); +extern int hashtable_add_from_infolist (struct t_hashtable *hashtable, + struct t_infolist *infolist, + const char *prefix); extern void hashtable_remove (struct t_hashtable *hashtable, const void *key); extern void hashtable_remove_all (struct t_hashtable *hashtable); extern void hashtable_free (struct t_hashtable *hashtable); diff --git a/src/plugins/plugin.c b/src/plugins/plugin.c index 6d9d6583a..1d4e104ee 100644 --- a/src/plugins/plugin.c +++ b/src/plugins/plugin.c @@ -711,6 +711,7 @@ plugin_load (const char *filename, int init_plugin, int argc, char **argv) new_plugin->hashtable_get_string = &hashtable_get_string; new_plugin->hashtable_set_pointer = &hashtable_set_pointer; new_plugin->hashtable_add_to_infolist = &hashtable_add_to_infolist; + new_plugin->hashtable_add_from_infolist = &hashtable_add_from_infolist; new_plugin->hashtable_remove = &hashtable_remove; new_plugin->hashtable_remove_all = &hashtable_remove_all; new_plugin->hashtable_free = &hashtable_free; diff --git a/src/plugins/weechat-plugin.h b/src/plugins/weechat-plugin.h index a78db2cd6..4ac49d11e 100644 --- a/src/plugins/weechat-plugin.h +++ b/src/plugins/weechat-plugin.h @@ -66,7 +66,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 "20170530-02" +#define WEECHAT_PLUGIN_API_VERSION "20170617-01" /* macros for defining plugin infos */ #define WEECHAT_PLUGIN_NAME(__name) \ @@ -465,6 +465,9 @@ struct t_weechat_plugin int (*hashtable_add_to_infolist) (struct t_hashtable *hashtable, struct t_infolist_item *infolist_item, const char *prefix); + int (*hashtable_add_from_infolist) (struct t_hashtable *hashtable, + struct t_infolist *infolist, + const char *prefix); void (*hashtable_remove) (struct t_hashtable *hashtable, const void *key); void (*hashtable_remove_all) (struct t_hashtable *hashtable); void (*hashtable_free) (struct t_hashtable *hashtable); @@ -1396,6 +1399,11 @@ extern int weechat_plugin_end (struct t_weechat_plugin *plugin); (weechat_plugin->hashtable_add_to_infolist)(__hashtable, \ __infolist_item, \ __prefix) +#define weechat_hashtable_add_from_infolist(__hashtable, __infolist, \ + __prefix) \ + (weechat_plugin->hashtable_add_from_infolist)(__hashtable, \ + __infolist, \ + __prefix) #define weechat_hashtable_remove(__hashtable, __key) \ (weechat_plugin->hashtable_remove)(__hashtable, __key) #define weechat_hashtable_remove_all(__hashtable) \ diff --git a/tests/unit/core/test-hashtable.cpp b/tests/unit/core/test-hashtable.cpp index dd33d9a40..1201d7996 100644 --- a/tests/unit/core/test-hashtable.cpp +++ b/tests/unit/core/test-hashtable.cpp @@ -359,6 +359,7 @@ TEST(Hashtable, Properties) /* * Tests functions: * hashtable_add_to_infolist + * hashtable_add_from_infolist */ TEST(Hashtable, Infolist)