summaryrefslogtreecommitdiff
path: root/src/core
diff options
context:
space:
mode:
authorSebastien Helleu <flashcode@flashtux.org>2011-06-26 18:15:42 +0200
committerSebastien Helleu <flashcode@flashtux.org>2011-06-26 18:15:42 +0200
commit19bc95b96189de5a645adbe7b3487d5de1b835e7 (patch)
treeb68d3d98d3d643bc02fba218db7f7ed6cd07ea2c /src/core
parent2a630031fd3c868733e3038c3e19ad4b53a8d8ce (diff)
downloadweechat-19bc95b96189de5a645adbe7b3487d5de1b835e7.zip
core: many improvements on hdata
New features: - add optional hdata name for variables in hdata - add plugin API functions: hdata_get_var_hdata - use hashtable to store hdata (created by WeeChat and plugins) - free hdata and infolists created by plugin on plugin unload - free all hdata on exit - add "free" option to command /debug hdata - remove hdata for hooks
Diffstat (limited to 'src/core')
-rw-r--r--src/core/wee-command.c15
-rw-r--r--src/core/wee-config-file.c128
-rw-r--r--src/core/wee-debug.c96
-rw-r--r--src/core/wee-hdata.c199
-rw-r--r--src/core/wee-hdata.h24
-rw-r--r--src/core/wee-hook.c552
-rw-r--r--src/core/wee-infolist.c23
-rw-r--r--src/core/wee-infolist.h3
-rw-r--r--src/core/weechat.c3
9 files changed, 338 insertions, 705 deletions
diff --git a/src/core/wee-command.c b/src/core/wee-command.c
index 85a8ec15e..a47450d84 100644
--- a/src/core/wee-command.c
+++ b/src/core/wee-command.c
@@ -40,6 +40,7 @@
#include "wee-config-file.h"
#include "wee-debug.h"
#include "wee-hashtable.h"
+#include "wee-hdata.h"
#include "wee-hook.h"
#include "wee-input.h"
#include "wee-list.h"
@@ -1154,7 +1155,10 @@ COMMAND_CALLBACK(debug)
}
else if (string_strcasecmp (argv[1], "hdata") == 0)
{
- debug_hdata ();
+ if ((argc > 2) && (string_strcasecmp (argv[2], "free") == 0))
+ hdata_free_all ();
+ else
+ debug_hdata ();
}
else if (string_strcasecmp (argv[1], "infolists") == 0)
{
@@ -4846,8 +4850,8 @@ command_init ()
N_("list"
" || set <plugin> <level>"
" || dump [<plugin>]"
- " || buffer|color|hdata|infolists|memory|tags|term"
- "|windows"),
+ " || buffer|color|infolists|memory|tags|term|windows"
+ " || hdata [free]"),
N_(" list: list plugins with debug levels\n"
" set: set debug level for plugin\n"
" plugin: name of plugin (\"core\" for WeeChat core)\n"
@@ -4857,7 +4861,8 @@ command_init ()
" buffer: dump buffer content with hexadecimal values "
"in log file\n"
" color: display infos about current color pairs\n"
- " hdata: display infos about hdata\n"
+ " hdata: display infos about hdata (with free: remove "
+ "all hdata in memory)\n"
"infolists: display infos about infolists\n"
" memory: display infos about memory usage\n"
" tags: display tags for lines\n"
@@ -4868,7 +4873,7 @@ command_init ()
" || dump %(plugins_names)|core"
" || buffer"
" || color"
- " || hdata"
+ " || hdata free"
" || infolists"
" || memory"
" || tags"
diff --git a/src/core/wee-config-file.c b/src/core/wee-config-file.c
index f9a5b4d88..966169e9d 100644
--- a/src/core/wee-config-file.c
+++ b/src/core/wee-config-file.c
@@ -53,10 +53,6 @@ char *config_option_type_string[CONFIG_NUM_OPTION_TYPES] =
char *config_boolean_true[] = { "on", "yes", "y", "true", "t", "1", NULL };
char *config_boolean_false[] = { "off", "no", "n", "false", "f", "0", NULL };
-struct t_hdata *config_file_hdata_config_file = NULL;
-struct t_hdata *config_file_hdata_config_section = NULL;
-struct t_hdata *config_file_hdata_config_option = NULL;
-
void config_file_option_free_data (struct t_config_option *option);
@@ -2561,27 +2557,23 @@ config_file_hdata_config_file_cb (void *data, const char *hdata_name)
/* make C compiler happy */
(void) data;
- if (config_file_hdata_config_file)
- return config_file_hdata_config_file;
-
- hdata = hdata_new (hdata_name, "prev_config", "next_config");
+ hdata = hdata_new (NULL, hdata_name, "prev_config", "next_config");
if (hdata)
{
- config_file_hdata_config_file = hdata;
- HDATA_VAR(struct t_config_file, plugin, POINTER);
- HDATA_VAR(struct t_config_file, name, STRING);
- HDATA_VAR(struct t_config_file, filename, STRING);
- HDATA_VAR(struct t_config_file, file, POINTER);
- HDATA_VAR(struct t_config_file, callback_reload, POINTER);
- HDATA_VAR(struct t_config_file, callback_reload_data, POINTER);
- HDATA_VAR(struct t_config_file, sections, POINTER);
- HDATA_VAR(struct t_config_file, last_section, POINTER);
- HDATA_VAR(struct t_config_file, prev_config, POINTER);
- HDATA_VAR(struct t_config_file, next_config, POINTER);
+ HDATA_VAR(struct t_config_file, plugin, POINTER, "plugin");
+ HDATA_VAR(struct t_config_file, name, STRING, NULL);
+ HDATA_VAR(struct t_config_file, filename, STRING, NULL);
+ HDATA_VAR(struct t_config_file, file, POINTER, NULL);
+ HDATA_VAR(struct t_config_file, callback_reload, POINTER, NULL);
+ HDATA_VAR(struct t_config_file, callback_reload_data, POINTER, NULL);
+ HDATA_VAR(struct t_config_file, sections, POINTER, "config_section");
+ HDATA_VAR(struct t_config_file, last_section, POINTER, "config_section");
+ HDATA_VAR(struct t_config_file, prev_config, POINTER, hdata_name);
+ HDATA_VAR(struct t_config_file, next_config, POINTER, hdata_name);
HDATA_LIST(config_files);
HDATA_LIST(last_config_file);
}
- return config_file_hdata_config_file;
+ return hdata;
}
/*
@@ -2596,33 +2588,29 @@ config_file_hdata_config_section_cb (void *data, const char *hdata_name)
/* make C compiler happy */
(void) data;
- if (config_file_hdata_config_section)
- return config_file_hdata_config_section;
-
- hdata = hdata_new (hdata_name, "prev_section", "next_section");
+ hdata = hdata_new (NULL, hdata_name, "prev_section", "next_section");
if (hdata)
{
- config_file_hdata_config_section = hdata;
- HDATA_VAR(struct t_config_section, config_file, POINTER);
- HDATA_VAR(struct t_config_section, name, STRING);
- HDATA_VAR(struct t_config_section, user_can_add_options, INTEGER);
- HDATA_VAR(struct t_config_section, user_can_delete_options, INTEGER);
- HDATA_VAR(struct t_config_section, callback_read, POINTER);
- HDATA_VAR(struct t_config_section, callback_read_data, POINTER);
- HDATA_VAR(struct t_config_section, callback_write, POINTER);
- HDATA_VAR(struct t_config_section, callback_write_data, POINTER);
- HDATA_VAR(struct t_config_section, callback_write_default, POINTER);
- HDATA_VAR(struct t_config_section, callback_write_default_data, POINTER);
- HDATA_VAR(struct t_config_section, callback_create_option, POINTER);
- HDATA_VAR(struct t_config_section, callback_create_option_data, POINTER);
- HDATA_VAR(struct t_config_section, callback_delete_option, POINTER);
- HDATA_VAR(struct t_config_section, callback_delete_option_data, POINTER);
- HDATA_VAR(struct t_config_section, options, POINTER);
- HDATA_VAR(struct t_config_section, last_option, POINTER);
- HDATA_VAR(struct t_config_section, prev_section, POINTER);
- HDATA_VAR(struct t_config_section, next_section, POINTER);
- }
- return config_file_hdata_config_section;
+ HDATA_VAR(struct t_config_section, config_file, POINTER, "config_file");
+ HDATA_VAR(struct t_config_section, name, STRING, NULL);
+ HDATA_VAR(struct t_config_section, user_can_add_options, INTEGER, NULL);
+ HDATA_VAR(struct t_config_section, user_can_delete_options, INTEGER, NULL);
+ HDATA_VAR(struct t_config_section, callback_read, POINTER, NULL);
+ HDATA_VAR(struct t_config_section, callback_read_data, POINTER, NULL);
+ HDATA_VAR(struct t_config_section, callback_write, POINTER, NULL);
+ HDATA_VAR(struct t_config_section, callback_write_data, POINTER, NULL);
+ HDATA_VAR(struct t_config_section, callback_write_default, POINTER, NULL);
+ HDATA_VAR(struct t_config_section, callback_write_default_data, POINTER, NULL);
+ HDATA_VAR(struct t_config_section, callback_create_option, POINTER, NULL);
+ HDATA_VAR(struct t_config_section, callback_create_option_data, POINTER, NULL);
+ HDATA_VAR(struct t_config_section, callback_delete_option, POINTER, NULL);
+ HDATA_VAR(struct t_config_section, callback_delete_option_data, POINTER, NULL);
+ HDATA_VAR(struct t_config_section, options, POINTER, "config_option");
+ HDATA_VAR(struct t_config_section, last_option, POINTER, "config_option");
+ HDATA_VAR(struct t_config_section, prev_section, POINTER, hdata_name);
+ HDATA_VAR(struct t_config_section, next_section, POINTER, hdata_name);
+ }
+ return hdata;
}
/*
@@ -2637,35 +2625,31 @@ config_file_hdata_config_option_cb (void *data, const char *hdata_name)
/* make C compiler happy */
(void) data;
- if (config_file_hdata_config_option)
- return config_file_hdata_config_option;
-
- hdata = hdata_new (hdata_name, "prev_option", "next_option");
+ hdata = hdata_new (NULL, hdata_name, "prev_option", "next_option");
if (hdata)
{
- config_file_hdata_config_option = hdata;
- HDATA_VAR(struct t_config_option, config_file, POINTER);
- HDATA_VAR(struct t_config_option, section, POINTER);
- HDATA_VAR(struct t_config_option, name, STRING);
- HDATA_VAR(struct t_config_option, type, INTEGER);
- HDATA_VAR(struct t_config_option, description, STRING);
- HDATA_VAR(struct t_config_option, string_values, POINTER);
- HDATA_VAR(struct t_config_option, min, INTEGER);
- HDATA_VAR(struct t_config_option, max, INTEGER);
- HDATA_VAR(struct t_config_option, default_value, POINTER);
- HDATA_VAR(struct t_config_option, value, POINTER);
- HDATA_VAR(struct t_config_option, null_value_allowed, INTEGER);
- HDATA_VAR(struct t_config_option, callback_check_value, POINTER);
- HDATA_VAR(struct t_config_option, callback_check_value_data, POINTER);
- HDATA_VAR(struct t_config_option, callback_change, POINTER);
- HDATA_VAR(struct t_config_option, callback_change_data, POINTER);
- HDATA_VAR(struct t_config_option, callback_delete, POINTER);
- HDATA_VAR(struct t_config_option, callback_delete_data, POINTER);
- HDATA_VAR(struct t_config_option, loaded, INTEGER);
- HDATA_VAR(struct t_config_option, prev_option, POINTER);
- HDATA_VAR(struct t_config_option, next_option, POINTER);
- }
- return config_file_hdata_config_option;
+ HDATA_VAR(struct t_config_option, config_file, POINTER, "config_file");
+ HDATA_VAR(struct t_config_option, section, POINTER, "config_section");
+ HDATA_VAR(struct t_config_option, name, STRING, NULL);
+ HDATA_VAR(struct t_config_option, type, INTEGER, NULL);
+ HDATA_VAR(struct t_config_option, description, STRING, NULL);
+ HDATA_VAR(struct t_config_option, string_values, POINTER, NULL);
+ HDATA_VAR(struct t_config_option, min, INTEGER, NULL);
+ HDATA_VAR(struct t_config_option, max, INTEGER, NULL);
+ HDATA_VAR(struct t_config_option, default_value, POINTER, NULL);
+ HDATA_VAR(struct t_config_option, value, POINTER, NULL);
+ HDATA_VAR(struct t_config_option, null_value_allowed, INTEGER, NULL);
+ HDATA_VAR(struct t_config_option, callback_check_value, POINTER, NULL);
+ HDATA_VAR(struct t_config_option, callback_check_value_data, POINTER, NULL);
+ HDATA_VAR(struct t_config_option, callback_change, POINTER, NULL);
+ HDATA_VAR(struct t_config_option, callback_change_data, POINTER, NULL);
+ HDATA_VAR(struct t_config_option, callback_delete, POINTER, NULL);
+ HDATA_VAR(struct t_config_option, callback_delete_data, POINTER, NULL);
+ HDATA_VAR(struct t_config_option, loaded, INTEGER, NULL);
+ HDATA_VAR(struct t_config_option, prev_option, POINTER, hdata_name);
+ HDATA_VAR(struct t_config_option, next_option, POINTER, hdata_name);
+ }
+ return hdata;
}
/*
diff --git a/src/core/wee-debug.c b/src/core/wee-debug.c
index 30f29f702..b79c4c43d 100644
--- a/src/core/wee-debug.c
+++ b/src/core/wee-debug.c
@@ -335,70 +335,78 @@ debug_hdata_hash_list_map_cb (void *data,
(void) hashtable;
gui_chat_printf (NULL,
- " list: %s -> 0x%lx",
+ " list: %s -> 0x%lx",
(char *)key,
*((void **)value));
}
/*
- * debug_hdata: display list of hdata in memory
+ * debug_hdata_map_cb: function called for each hdata in memory
*/
void
-debug_hdata ()
+debug_hdata_map_cb (void *data, struct t_hashtable *hashtable,
+ const void *key, const void *value)
{
struct t_hdata *ptr_hdata;
- int i, count;
struct t_weelist *list;
struct t_weelist_item *ptr_item;
- void *value;
+ void *ptr_value;
- count = 0;
- for (ptr_hdata = weechat_hdata; ptr_hdata;
- ptr_hdata = ptr_hdata->next_hdata)
- {
- count++;
- }
+ /* make C compiler happy */
+ (void) data;
+ (void) hashtable;
- gui_chat_printf (NULL, "");
- gui_chat_printf (NULL, "%d hdata in memory", count);
+ ptr_hdata = (struct t_hdata *)value;
- if (count > 0)
+ gui_chat_printf (NULL,
+ " hdata 0x%lx: \"%s\", %d vars, %d lists:",
+ ptr_hdata, (const char *)key,
+ hashtable_get_integer (ptr_hdata->hash_var,
+ "items_count"),
+ hashtable_get_integer (ptr_hdata->hash_list,
+ "items_count"));
+
+ /* display lists */
+ hashtable_map (ptr_hdata->hash_list,
+ &debug_hdata_hash_list_map_cb, NULL);
+
+ /* display vars */
+ list = weelist_new ();
+ hashtable_map (ptr_hdata->hash_var,
+ &debug_hdata_hash_var_map_cb, list);
+ for (ptr_item = list->items; ptr_item;
+ ptr_item = ptr_item->next_item)
{
- i = 0;
- for (ptr_hdata = weechat_hdata; ptr_hdata;
- ptr_hdata = ptr_hdata->next_hdata)
+ ptr_value = hashtable_get (ptr_hdata->hash_var, ptr_item->user_data);
+ if (ptr_value)
{
gui_chat_printf (NULL,
- "%4d: hdata 0x%lx: \"%s\", %d vars, %d lists:",
- i + 1, ptr_hdata,
- ptr_hdata->name,
- hashtable_get_integer (ptr_hdata->hash_var,
- "items_count"),
- hashtable_get_integer (ptr_hdata->hash_list,
- "items_count"));
- list = weelist_new ();
- hashtable_map (ptr_hdata->hash_var,
- &debug_hdata_hash_var_map_cb, list);
- for (ptr_item = list->items; ptr_item;
- ptr_item = ptr_item->next_item)
- {
- value = hashtable_get (ptr_hdata->hash_var, ptr_item->user_data);
- if (value)
- {
- gui_chat_printf (NULL,
- " %04d -> %s (%s)",
- (*((int *)value)) & 0xFFFF,
- (char *)ptr_item->user_data,
- hdata_type_string[(*((int *)value)) >> 16]);
- }
- }
- weelist_free (list);
- hashtable_map (ptr_hdata->hash_list,
- &debug_hdata_hash_list_map_cb, NULL);
- i++;
+ " %04d -> %s (%s)",
+ (*((int *)ptr_value)) & 0xFFFF,
+ (char *)ptr_item->user_data,
+ hdata_type_string[(*((int *)ptr_value)) >> 16]);
}
}
+ weelist_free (list);
+}
+
+/*
+ * debug_hdata: display list of hdata in memory
+ */
+
+void
+debug_hdata ()
+{
+ int count;
+
+ count = hashtable_get_integer (weechat_hdata, "items_count");
+
+ gui_chat_printf (NULL, "");
+ gui_chat_printf (NULL, "%d hdata in memory", count);
+
+ if (count > 0)
+ hashtable_map (weechat_hdata, &debug_hdata_map_cb, NULL);
}
/*
diff --git a/src/core/wee-hdata.c b/src/core/wee-hdata.c
index 15ccf643a..510c21ce6 100644
--- a/src/core/wee-hdata.c
+++ b/src/core/wee-hdata.c
@@ -36,8 +36,7 @@
#include "../plugins/plugin.h"
-struct t_hdata *weechat_hdata = NULL;
-struct t_hdata *last_weechat_hdata = NULL;
+struct t_hashtable *weechat_hdata = NULL;
char *hdata_type_string[6] =
{ "other", "integer", "long", "string", "pointer", "time" };
@@ -48,7 +47,8 @@ char *hdata_type_string[6] =
*/
struct t_hdata *
-hdata_new (const char *hdata_name, const char *var_prev, const char *var_next)
+hdata_new (struct t_weechat_plugin *plugin, const char *hdata_name,
+ const char *var_prev, const char *var_next)
{
struct t_hdata *new_hdata;
@@ -58,7 +58,7 @@ hdata_new (const char *hdata_name, const char *var_prev, const char *var_next)
new_hdata = malloc (sizeof (*new_hdata));
if (new_hdata)
{
- new_hdata->name = strdup (hdata_name);
+ new_hdata->plugin = plugin;
new_hdata->hash_var = hashtable_new (8,
WEECHAT_HASHTABLE_STRING,
WEECHAT_HASHTABLE_INTEGER,
@@ -66,19 +66,17 @@ hdata_new (const char *hdata_name, const char *var_prev, const char *var_next)
NULL);
new_hdata->var_prev = (var_prev) ? strdup (var_prev) : NULL;
new_hdata->var_next = (var_next) ? strdup (var_next) : NULL;
+ new_hdata->hash_var_hdata = hashtable_new (8,
+ WEECHAT_HASHTABLE_STRING,
+ WEECHAT_HASHTABLE_STRING,
+ NULL,
+ NULL);
new_hdata->hash_list = hashtable_new (8,
WEECHAT_HASHTABLE_STRING,
WEECHAT_HASHTABLE_POINTER,
NULL,
NULL);
-
- new_hdata->prev_hdata = last_weechat_hdata;
- new_hdata->next_hdata = NULL;
- if (weechat_hdata)
- last_weechat_hdata->next_hdata = new_hdata;
- else
- weechat_hdata = new_hdata;
- last_weechat_hdata = new_hdata;
+ hashtable_set (weechat_hdata, hdata_name, new_hdata);
}
return new_hdata;
@@ -89,7 +87,8 @@ hdata_new (const char *hdata_name, const char *var_prev, const char *var_next)
*/
void
-hdata_new_var (struct t_hdata *hdata, const char *name, int offset, int type)
+hdata_new_var (struct t_hdata *hdata, const char *name, int offset, int type,
+ const char *hdata_name)
{
int value;
@@ -97,6 +96,8 @@ hdata_new_var (struct t_hdata *hdata, const char *name, int offset, int type)
{
value = (type << 16) | (offset & 0xFFFF);
hashtable_set (hdata->hash_var, name, &value);
+ if (hdata_name && hdata_name[0])
+ hashtable_set (hdata->hash_var_hdata, name, hdata_name);
}
}
@@ -169,6 +170,20 @@ hdata_get_var_type_string (struct t_hdata *hdata, const char *name)
}
/*
+ * hdata_get_var_hdata: get hdata name for a variable (NULL if variable has
+ * no hdata)
+ */
+
+const char *
+hdata_get_var_hdata (struct t_hdata *hdata, const char *name)
+{
+ if (hdata && name)
+ return (const char *)hashtable_get (hdata->hash_var_hdata, name);
+
+ return NULL;
+}
+
+/*
* hdata_get_var: get pointer to content of variable using hdata var name
*/
@@ -360,6 +375,12 @@ hdata_get_string (struct t_hdata *hdata, const char *property)
return hdata->var_prev;
else if (string_strcasecmp (property, "var_next") == 0)
return hdata->var_next;
+ else if (string_strcasecmp (property, "var_hdata_keys") == 0)
+ return hashtable_get_string (hdata->hash_var_hdata, "keys");
+ else if (string_strcasecmp (property, "var_hdata_values") == 0)
+ return hashtable_get_string (hdata->hash_var_hdata, "values");
+ else if (string_strcasecmp (property, "var_hdata_keys_values") == 0)
+ return hashtable_get_string (hdata->hash_var_hdata, "keys_values");
else if (string_strcasecmp (property, "list_keys") == 0)
return hashtable_get_string (hdata->hash_list, "keys");
else if (string_strcasecmp (property, "list_values") == 0)
@@ -372,29 +393,147 @@ hdata_get_string (struct t_hdata *hdata, const char *property)
}
/*
- * hdata_print_log: print hdata in log (usually for crash dump)
+ * hdata_free: free a hdata
*/
void
-hdata_print_log ()
+hdata_free (struct t_hdata *hdata)
+{
+ if (hdata->hash_var)
+ hashtable_free (hdata->hash_var);
+ if (hdata->var_prev)
+ free (hdata->var_prev);
+ if (hdata->var_next)
+ free (hdata->var_next);
+ if (hdata->hash_var_hdata)
+ hashtable_free (hdata->hash_var_hdata);
+ if (hdata->hash_list)
+ hashtable_free (hdata->hash_list);
+
+ free (hdata);
+}
+
+/*
+ * hdata_free_all_plugin_map_cb: function called for each hdata in memory
+ */
+
+void
+hdata_free_all_plugin_map_cb (void *data, struct t_hashtable *hashtable,
+ const void *key, const void *value)
{
struct t_hdata *ptr_hdata;
- for (ptr_hdata = weechat_hdata; ptr_hdata;
- ptr_hdata = ptr_hdata->next_hdata)
+ ptr_hdata = (struct t_hdata *)value;
+
+ if (ptr_hdata->plugin == (struct t_weechat_plugin *)data)
{
- log_printf ("");
- log_printf ("[hdata (addr:0x%lx)]", ptr_hdata);
- log_printf (" name . . . . . . . . . : '%s'", ptr_hdata->name);
- log_printf (" hash_var . . . . . . . : 0x%lx (hashtable: '%s')",
- ptr_hdata->hash_var,
- hashtable_get_string (ptr_hdata->hash_var, "keys_values"));
- log_printf (" var_prev . . . . . . . : '%s'", ptr_hdata->var_prev);
- log_printf (" var_next . . . . . . . : '%s'", ptr_hdata->var_next);
- log_printf (" hash_list. . . . . . . : 0x%lx (hashtable: '%s')",
- ptr_hdata->hash_list,
- hashtable_get_string (ptr_hdata->hash_list, "keys_values"));
- log_printf (" prev_hdata . . . . . . : 0x%lx", ptr_hdata->prev_hdata);
- log_printf (" next_hdata . . . . . . : 0x%lx", ptr_hdata->next_hdata);
+ hdata_free (ptr_hdata);
+ hashtable_remove (hashtable, key);
}
}
+
+/*
+ * hdata_free_all_plugin: free all hdata created by a plugin
+ */
+
+void
+hdata_free_all_plugin (struct t_weechat_plugin *plugin)
+{
+ hashtable_map (weechat_hdata, &hdata_free_all_plugin_map_cb, plugin);
+}
+
+/*
+ * hdata_free_all_map_cb: function called for each hdata in memory
+ */
+
+void
+hdata_free_all_map_cb (void *data, struct t_hashtable *hashtable,
+ const void *key, const void *value)
+{
+ struct t_hdata *ptr_hdata;
+
+ /* make C compiler happy */
+ (void) data;
+
+ ptr_hdata = (struct t_hdata *)value;
+
+ hdata_free (ptr_hdata);
+ hashtable_remove (hashtable, key);
+}
+
+/*
+ * hdata_free_all: free all hdata
+ */
+
+void
+hdata_free_all ()
+{
+ hashtable_map (weechat_hdata, &hdata_free_all_map_cb, NULL);
+}
+
+/*
+ * hdata_print_log_map_cb: function called for each hdata in memory
+ */
+
+void
+hdata_print_log_map_cb (void *data, struct t_hashtable *hashtable,
+ const void *key, const void *value)
+{
+ struct t_hdata *ptr_hdata;
+
+ /* make C compiler happy */
+ (void) data;
+ (void) hashtable;
+
+ ptr_hdata = (struct t_hdata *)value;
+
+ log_printf ("");
+ log_printf ("[hdata (addr:0x%lx, name:'%s')]", ptr_hdata, (const char *)key);
+ log_printf (" plugin . . . . . . . . : 0x%lx", ptr_hdata->plugin);
+ log_printf (" hash_var . . . . . . . : 0x%lx (hashtable: '%s')",
+ ptr_hdata->hash_var,
+ hashtable_get_string (ptr_hdata->hash_var, "keys_values"));
+ log_printf (" var_prev . . . . . . . : '%s'", ptr_hdata->var_prev);
+ log_printf (" var_next . . . . . . . : '%s'", ptr_hdata->var_next);
+ log_printf (" hash_var_hdata . . . . : 0x%lx (hashtable: '%s')",
+ ptr_hdata->hash_var_hdata,
+ hashtable_get_string (ptr_hdata->hash_var_hdata, "keys_values"));
+ log_printf (" hash_list. . . . . . . : 0x%lx (hashtable: '%s')",
+ ptr_hdata->hash_list,
+ hashtable_get_string (ptr_hdata->hash_list, "keys_values"));
+}
+
+/*
+ * hdata_print_log: print hdata in log (usually for crash dump)
+ */
+
+void
+hdata_print_log ()
+{
+ hashtable_map (weechat_hdata, &hdata_print_log_map_cb, NULL);
+}
+
+/*
+ * hdata_init: create hashtable with hdata
+ */
+
+void
+hdata_init ()
+{
+ weechat_hdata = hashtable_new (16,
+ WEECHAT_HASHTABLE_STRING,
+ WEECHAT_HASHTABLE_POINTER,
+ NULL,
+ NULL);
+}
+
+/*
+ * hdata_end: free all hdata and hashtable with hdata
+ */
+
+void
+hdata_end ()
+{
+ hdata_free_all ();
+ hashtable_free (weechat_hdata);
+}
diff --git a/src/core/wee-hdata.h b/src/core/wee-hdata.h
index ce9b96f4d..bf7e9fd47 100644
--- a/src/core/wee-hdata.h
+++ b/src/core/wee-hdata.h
@@ -20,40 +20,42 @@
#ifndef __WEECHAT_HDATA_H
#define __WEECHAT_HDATA_H 1
-#define HDATA_VAR(__struct, __name, __type) \
+#define HDATA_VAR(__struct, __name, __type, __hdata_name) \
hdata_new_var (hdata, #__name, offsetof (__struct, __name), \
- WEECHAT_HDATA_##__type);
+ WEECHAT_HDATA_##__type, __hdata_name)
#define HDATA_LIST(__name) hdata_new_list (hdata, #__name, &(__name));
struct t_hdata
{
- char *name; /* name of hdata */
+ struct t_weechat_plugin *plugin; /* plugin which created this hdata */
+ /* (NULL if created by WeeChat) */
struct t_hashtable *hash_var; /* hashtable with offset of vars */
char *var_prev; /* name of var with pointer to */
/* previous element in list */
char *var_next; /* name of var with pointer to */
/* next element in list */
+ struct t_hashtable *hash_var_hdata; /* hashtable with hdata names */
struct t_hashtable *hash_list; /* hashtable with pointers on lists */
/* (used to search objects) */
- struct t_hdata *prev_hdata; /* link to previous hdata */
- struct t_hdata *next_hdata; /* link to next hdata */
};
-extern struct t_hdata *weechat_hdata;
-extern struct t_hdata *last_weechat_hdata;
+extern struct t_hashtable *weechat_hdata;
extern char *hdata_type_string[];
-extern struct t_hdata *hdata_new (const char *hdata_name, const char *var_prev,
+extern struct t_hdata *hdata_new (struct t_weechat_plugin *plugin,
+ const char *hdata_name, const char *var_prev,
const char *var_next);
extern void hdata_new_var (struct t_hdata *hdata, const char *name, int offset,
- int type);
+ int type, const char *hdata_name);
extern void hdata_new_list (struct t_hdata *hdata, const char *name,
void *pointer);
extern int hdata_get_var_offset (struct t_hdata *hdata, const char *name);
extern int hdata_get_var_type (struct t_hdata *hdata, const char *name);
extern const char *hdata_get_var_type_string (struct t_hdata *hdata,
const char *name);
+extern const char *hdata_get_var_hdata (struct t_hdata *hdata,
+ const char *name);
extern void *hdata_get_var (struct t_hdata *hdata, void *pointer,
const char *name);
extern void *hdata_get_var_at_offset (struct t_hdata *hdata, void *pointer,
@@ -72,6 +74,10 @@ extern time_t hdata_time (struct t_hdata *hdata, void *pointer,
const char *name);
extern const char *hdata_get_string (struct t_hdata *hdata,
const char *property);
+extern void hdata_free_all_plugin (struct t_weechat_plugin *plugin);
+extern void hdata_free_all ();
extern void hdata_print_log ();
+extern void hdata_init ();
+extern void hdata_end ();
#endif /* __WEECHAT_HDATA_H */
diff --git a/src/core/wee-hook.c b/src/core/wee-hook.c
index 15b2f2a6c..9cb6404a9 100644
--- a/src/core/wee-hook.c
+++ b/src/core/wee-hook.c
@@ -65,24 +65,6 @@ int hook_exec_recursion = 0; /* 1 when a hook is executed */
time_t hook_last_system_time = 0; /* used to detect system clock skew */
int real_delete_pending = 0; /* 1 if some hooks must be deleted */
-struct t_hdata *hook_hdata_hook = NULL;
-struct t_hdata *hook_hdata_hook_command = NULL;
-struct t_hdata *hook_hdata_hook_command_run = NULL;
-struct t_hdata *hook_hdata_hook_timer = NULL;
-struct t_hdata *hook_hdata_hook_fd = NULL;
-struct t_hdata *hook_hdata_hook_process = NULL;
-struct t_hdata *hook_hdata_hook_connect = NULL;
-struct t_hdata *hook_hdata_hook_print = NULL;
-struct t_hdata *hook_hdata_hook_signal = NULL;
-struct t_hdata *hook_hdata_hook_hsignal = NULL;
-struct t_hdata *hook_hdata_hook_config = NULL;
-struct t_hdata *hook_hdata_hook_completion = NULL;
-struct t_hdata *hook_hdata_hook_modifier = NULL;
-struct t_hdata *hook_hdata_hook_info = NULL;
-struct t_hdata *hook_hdata_hook_info_hashtable = NULL;
-struct t_hdata *hook_hdata_hook_infolist = NULL;
-struct t_hdata *hook_hdata_hook_hdata = NULL;
-
void hook_process_run (struct t_hook *hook_process);
@@ -2724,6 +2706,13 @@ hook_hdata_get (struct t_weechat_plugin *plugin, const char *hdata_name)
if (!hdata_name || !hdata_name[0])
return NULL;
+ if (weechat_hdata)
+ {
+ value = hashtable_get (weechat_hdata, hdata_name);
+ if (value)
+ return value;
+ }
+
hook_exec_start ();
ptr_hook = weechat_hooks[HOOK_TYPE_HDATA];
@@ -2733,8 +2722,7 @@ hook_hdata_get (struct t_weechat_plugin *plugin, const char *hdata_name)
if (!ptr_hook->deleted
&& !ptr_hook->running
- && (string_strcasecmp (HOOK_HDATA(ptr_hook, hdata_name),
- hdata_name) == 0))
+ && (strcmp (HOOK_HDATA(ptr_hook, hdata_name), hdata_name) == 0))
{
ptr_hook->running = 1;
value = (HOOK_HDATA(ptr_hook, callback))
@@ -3015,530 +3003,6 @@ unhook_all ()
}
/*
- * hook_hdata_hook_cb: return hdata for hook (variables common to all hook
- * types)
- */
-
-struct t_hdata *
-hook_hdata_hook_cb (void *data, const char *hdata_name)
-{
- struct t_hdata *hdata;
-
- /* make C compiler happy */
- (void) data;
-
- if (hook_hdata_hook)
- return hook_hdata_hook;
-
- hdata = hdata_new (hdata_name, "prev_hook", "next_hook");
- if (hdata)
- {
- hook_hdata_hook = hdata;
- HDATA_VAR(struct t_hook, plugin, POINTER);
- HDATA_VAR(struct t_hook, type, INTEGER);
- HDATA_VAR(struct t_hook, deleted, INTEGER);
- HDATA_VAR(struct t_hook, running, INTEGER);
- HDATA_VAR(struct t_hook, priority, INTEGER);
- HDATA_VAR(struct t_hook, callback_data, POINTER);
- HDATA_VAR(struct t_hook, hook_data, POINTER);
- HDATA_VAR(struct t_hook, prev_hook, POINTER);
- HDATA_VAR(struct t_hook, next_hook, POINTER);
- }
- return hook_hdata_hook;
-}
-
-/*
- * hook_hdata_hook_command_cb: return hdata for hook of type "command"
- */
-
-struct t_hdata *
-hook_hdata_hook_command_cb (void *data, const char *hdata_name)
-{
- struct t_hdata *hdata;
-
- /* make C compiler happy */
- (void) data;
-
- if (hook_hdata_hook_command)
- return hook_hdata_hook_command;
-
- hdata = hdata_new (hdata_name, NULL, NULL);
- if (hdata)
- {
- hook_hdata_hook_command = hdata;
- HDATA_VAR(struct t_hook_command, callback, POINTER);
- HDATA_VAR(struct t_hook_command, command, STRING);
- HDATA_VAR(struct t_hook_command, description, STRING);
- HDATA_VAR(struct t_hook_command, args, STRING);
- HDATA_VAR(struct t_hook_command, args_description, STRING);
- HDATA_VAR(struct t_hook_command, completion, STRING);
- HDATA_VAR(struct t_hook_command, cplt_num_templates, INTEGER);
- HDATA_VAR(struct t_hook_command, cplt_templates, POINTER);
- HDATA_VAR(struct t_hook_command, cplt_templates_static, POINTER);
- HDATA_VAR(struct t_hook_command, cplt_template_num_args, POINTER);
- HDATA_VAR(struct t_hook_command, cplt_template_args, POINTER);
- HDATA_VAR(struct t_hook_command, cplt_template_num_args_concat, INTEGER);
- HDATA_VAR(struct t_hook_command, cplt_template_args_concat, POINTER);
- hdata_new_list(hdata, "weechat_hooks_command", &weechat_hooks[HOOK_TYPE_COMMAND]);
- hdata_new_list(hdata, "last_weechat_hook_command", &last_weechat_hook[HOOK_TYPE_COMMAND]);
- }
- return hook_hdata_hook_command;
-}
-
-/*
- * hook_hdata_hook_command_run_cb: return hdata for hook of type "command_run"
- */
-
-struct t_hdata *
-hook_hdata_hook_command_run_cb (void *data, const char *hdata_name)
-{
- struct t_hdata *hdata;
-
- /* make C compiler happy */
- (void) data;
-
- if (hook_hdata_hook_command_run)
- return hook_hdata_hook_command_run;
-
- hdata = hdata_new (hdata_name, NULL, NULL);
- if (hdata)
- {
- hook_hdata_hook_command_run = hdata;
- HDATA_VAR(struct t_hook_command_run, callback, POINTER);
- HDATA_VAR(struct t_hook_command_run, command, STRING);
- hdata_new_list(hdata, "weechat_hooks_command_run", &weechat_hooks[HOOK_TYPE_COMMAND_RUN]);
- hdata_new_list(hdata, "last_weechat_hook_command_run", &last_weechat_hook[HOOK_TYPE_COMMAND_RUN]);
- }
- return hook_hdata_hook_command_run;
-}
-
-/*
- * hook_hdata_hook_timer_cb: return hdata for hook of type "timer"
- */
-
-struct t_hdata *
-hook_hdata_hook_timer_cb (void *data, const char *hdata_name)
-{
- struct t_hdata *hdata;
-
- /* make C compiler happy */
- (void) data;
-
- if (hook_hdata_hook_timer)
- return hook_hdata_hook_timer;
-
- hdata = hdata_new (hdata_name, NULL, NULL);
- if (hdata)
- {
- hook_hdata_hook_timer = hdata;
- HDATA_VAR(struct t_hook_timer, callback, POINTER);
- HDATA_VAR(struct t_hook_timer, interval, LONG);
- HDATA_VAR(struct t_hook_timer, align_second, INTEGER);
- HDATA_VAR(struct t_hook_timer, remaining_calls, INTEGER);
- HDATA_VAR(struct t_hook_timer, last_exec, OTHER);
- HDATA_VAR(struct t_hook_timer, next_exec, OTHER);
- hdata_new_list(hdata, "weechat_hooks_timer", &weechat_hooks[HOOK_TYPE_TIMER]);
- hdata_new_list(hdata, "last_weechat_hook_timer", &last_weechat_hook[HOOK_TYPE_TIMER]);
- }
- return hook_hdata_hook_timer;
-}
-
-/*
- * hook_hdata_hook_fd_cb: return hdata for hook of type "fd"
- */
-
-struct t_hdata *
-hook_hdata_hook_fd_cb (void *data, const char *hdata_name)
-{
- struct t_hdata *hdata;
-
- /* make C compiler happy */
- (void) data;
-
- if (hook_hdata_hook_fd)
- return hook_hdata_hook_fd;
-
- hdata = hdata_new (hdata_name, NULL, NULL);
- if (hdata)
- {
- hook_hdata_hook_fd = hdata;
- HDATA_VAR(struct t_hook_fd, callback, POINTER);
- HDATA_VAR(struct t_hook_fd, fd, INTEGER);
- HDATA_VAR(struct t_hook_fd, flags, INTEGER);
- HDATA_VAR(struct t_hook_fd, error, INTEGER);
- hdata_new_list(hdata, "weechat_hooks_fd", &weechat_hooks[HOOK_TYPE_FD]);
- hdata_new_list(hdata, "last_weechat_hook_fd", &last_weechat_hook[HOOK_TYPE_FD]);
- }
- return hook_hdata_hook_fd;
-}
-
-/*
- * hook_hdata_hook_process_cb: return hdata for hook of type "process"
- */
-
-struct t_hdata *
-hook_hdata_hook_process_cb (void *data, const char *hdata_name)
-{
- struct t_hdata *hdata;
-
- /* make C compiler happy */
- (void) data;
-
- if (hook_hdata_hook_process)
- return hook_hdata_hook_process;
-
- hdata = hdata_new (hdata_name, NULL, NULL);
- if (hdata)
- {
- hook_hdata_hook_process = hdata;
- HDATA_VAR(struct t_hook_process, callback, POINTER);
- HDATA_VAR(struct t_hook_process, command, STRING);
- HDATA_VAR(struct t_hook_process, timeout, LONG);
- HDATA_VAR(struct t_hook_process, child_read, POINTER);
- HDATA_VAR(struct t_hook_process, child_write, POINTER);
- HDATA_VAR(struct t_hook_process, child_pid, OTHER);
- HDATA_VAR(struct t_hook_process, hook_fd, POINTER);
- HDATA_VAR(struct t_hook_process, hook_timer, POINTER);
- HDATA_VAR(struct t_hook_process, buffer, POINTER);
- HDATA_VAR(struct t_hook_process, buffer_size, POINTER);
- hdata_new_list(hdata, "weechat_hooks_process", &weechat_hooks[HOOK_TYPE_PROCESS]);
- hdata_new_list(hdata, "last_weechat_hook_process", &last_weechat_hook[HOOK_TYPE_PROCESS]);
- }
- return hook_hdata_hook_process;
-}
-
-/*
- * hook_hdata_hook_connect_cb: return hdata for hook of type "connect"
- */
-
-struct t_hdata *
-hook_hdata_hook_connect_cb (void *data, const char *hdata_name)
-{
- struct t_hdata *hdata;
-
- /* make C compiler happy */
- (void) data;
-
- if (hook_hdata_hook_connect)
- return hook_hdata_hook_connect;
-
- hdata = hdata_new (hdata_name, NULL, NULL);
- if (hdata)
- {
- hook_hdata_hook_connect = hdata;
- HDATA_VAR(struct t_hook_connect, callback, POINTER);
- HDATA_VAR(struct t_hook_connect, proxy, STRING);
- HDATA_VAR(struct t_hook_connect, address, STRING);
- HDATA_VAR(struct t_hook_connect, port, INTEGER);
- HDATA_VAR(struct t_hook_connect, sock, INTEGER);
- HDATA_VAR(struct t_hook_connect, ipv6, INTEGER);
-#ifdef HAVE_GNUTLS
- HDATA_VAR(struct t_hook_connect, gnutls_sess, POINTER);
- HDATA_VAR(struct t_hook_connect, gnutls_cb, POINTER);
- HDATA_VAR(struct t_hook_connect, gnutls_dhkey_size, INTEGER);
- HDATA_VAR(struct t_hook_connect, gnutls_priorities, STRING);
-#endif
- HDATA_VAR(struct t_hook_connect, local_hostname, STRING);
- HDATA_VAR(struct t_hook_connect, child_read, INTEGER);
- HDATA_VAR(struct t_hook_connect, child_write, INTEGER);
- HDATA_VAR(struct t_hook_connect, child_pid, OTHER);
- HDATA_VAR(struct t_hook_connect, hook_fd, POINTER);
- HDATA_VAR(struct t_hook_connect, handshake_hook_fd, POINTER);
- HDATA_VAR(struct t_hook_connect, handshake_hook_timer, POINTER);
- HDATA_VAR(struct t_hook_connect, handshake_fd_flags, INTEGER);
- HDATA_VAR(struct t_hook_connect, handshake_ip_address, STRING);
- hdata_new_list(hdata, "weechat_hooks_connect", &weechat_hooks[HOOK_TYPE_CONNECT]);
- hdata_new_list(hdata, "last_weechat_hook_connect", &last_weechat_hook[HOOK_TYPE_CONNECT]);
- }
- return hook_hdata_hook_connect;
-}
-
-/*
- * hook_hdata_hook_print_cb: return hdata for hook of type "print"
- */
-
-struct t_hdata *
-hook_hdata_hook_print_cb (void *data, const char *hdata_name)
-{
- struct t_hdata *hdata;
-
- /* make C compiler happy */
- (void) data;
-
- if (hook_hdata_hook_print)
- return hook_hdata_hook_print;
-
- hdata = hdata_new (hdata_name, NULL, NULL);
- if (hdata)
- {
- hook_hdata_hook_print = hdata;
- HDATA_VAR(struct t_hook_print, callback, POINTER);
- HDATA_VAR(struct t_hook_print, buffer, POINTER);
- HDATA_VAR(struct t_hook_print, tags_count, INTEGER);
- HDATA_VAR(struct t_hook_print, tags_array, POINTER);
- HDATA_VAR(struct t_hook_print, message, STRING);
- HDATA_VAR(struct t_hook_print, strip_colors, INTEGER);
- hdata_new_list(hdata, "weechat_hooks_print", &weechat_hooks[HOOK_TYPE_PRINT]);
- hdata_new_list(hdata, "last_weechat_hook_print", &last_weechat_hook[HOOK_TYPE_PRINT]);
- }
- return hook_hdata_hook_print;
-}
-
-/*
- * hook_hdata_hook_signal_cb: return hdata for hook of type "signal"
- */
-
-struct t_hdata *
-hook_hdata_hook_signal_cb (void *data, const char *hdata_name)
-{
- struct t_hdata *hdata;
-
- /* make C compiler happy */
- (void) data;
-
- if (hook_hdata_hook_signal)
- return hook_hdata_hook_signal;
-
- hdata = hdata_new (hdata_name, NULL, NULL);
- if (hdata)
- {
- hook_hdata_hook_signal = hdata;
- HDATA_VAR(struct t_hook_signal, callback, POINTER);
- HDATA_VAR(struct t_hook_signal, signal, STRING);
- hdata_new_list(hdata, "weechat_hooks_signal", &weechat_hooks[HOOK_TYPE_SIGNAL]);
- hdata_new_list(hdata, "last_weechat_hook_signal", &last_weechat_hook[HOOK_TYPE_SIGNAL]);
- }
- return hook_hdata_hook_signal;
-}
-
-/*
- * hook_hdata_hook_hsignal_cb: return hdata for hook of type "hsignal"
- */
-
-struct t_hdata *
-hook_hdata_hook_hsignal_cb (void *data, const char *hdata_name)
-{
- struct t_hdata *hdata;
-
- /* make C compiler happy */
- (void) data;
-
- if (hook_hdata_hook_hsignal)
- return hook_hdata_hook_hsignal;
-
- hdata = hdata_new (hdata_name, NULL, NULL);
- if (hdata)
- {
- hook_hdata_hook_hsignal = hdata;
- HDATA_VAR(struct t_hook_hsignal, callback, POINTER);
- HDATA_VAR(struct t_hook_hsignal, signal, STRING);
- hdata_new_list(hdata, "weechat_hooks_hsignal", &weechat_hooks[HOOK_TYPE_HSIGNAL]);
- hdata_new_list(hdata, "last_weechat_hook_hsignal", &last_weechat_hook[HOOK_TYPE_HSIGNAL]);
- }
- return hook_hdata_hook_hsignal;
-}
-
-/*
- * hook_hdata_hook_config_cb: return hdata for hook of type "config"
- */
-
-struct t_hdata *
-hook_hdata_hook_config_cb (void *data, const char *hdata_name)
-{
- struct t_hdata *hdata;
-
- /* make C compiler happy */
- (void) data;
-
- if (hook_hdata_hook_config)
- return hook_hdata_hook_config;
-
- hdata = hdata_new (hdata_name, NULL, NULL);
- if (hdata)
- {
- hook_hdata_hook_config = hdata;
- HDATA_VAR(struct t_hook_config, callback, POINTER);
- HDATA_VAR(struct t_hook_config, option, STRING);
- hdata_new_list(hdata, "weechat_hooks_config", &weechat_hooks[HOOK_TYPE_CONFIG]);
- hdata_new_list(hdata, "last_weechat_hook_config", &last_weechat_hook[HOOK_TYPE_CONFIG]);
- }
- return hook_hdata_hook_config;
-}
-
-/*
- * hook_hdata_hook_completion_cb: return hdata for hook of type "completion"
- */
-
-struct t_hdata *
-hook_hdata_hook_completion_cb (void *data, const char *hdata_name)
-{
- struct t_hdata *hdata;
-
- /* make C compiler happy */
- (void) data;
-
- if (hook_hdata_hook_completion)
- return hook_hdata_hook_completion;
-
- hdata = hdata_new (hdata_name, NULL, NULL);
- if (hdata)
- {
- hook_hdata_hook_completion = hdata;
- HDATA_VAR(struct t_hook_completion, callback, POINTER);
- HDATA_VAR(struct t_hook_completion, completion_item, STRING);
- HDATA_VAR(struct t_hook_completion, description, STRING);
- hdata_new_list(hdata, "weechat_hooks_completion", &weechat_hooks[HOOK_TYPE_COMPLETION]);
- hdata_new_list(hdata, "last_weechat_hook_completion", &last_weechat_hook[HOOK_TYPE_COMPLETION]);
- }
- return hook_hdata_hook_completion;
-}
-
-/*
- * hook_hdata_hook_modifier_cb: return hdata for hook of type "modifier"
- */
-
-struct t_hdata *
-hook_hdata_hook_modifier_cb (void *data, const char *hdata_name)
-{
- struct t_hdata *hdata;
-
- /* make C compiler happy */
- (void) data;
-
- if (hook_hdata_hook_modifier)
- return hook_hdata_hook_modifier;
-
- hdata = hdata_new (hdata_name, NULL, NULL);
- if (hdata)
- {
- hook_hdata_hook_modifier = hdata;
- HDATA_VAR(struct t_hook_modifier, callback, POINTER);
- HDATA_VAR(struct t_hook_modifier, modifier, STRING);
- hdata_new_list(hdata, "weechat_hooks_modifier", &weechat_hooks[HOOK_TYPE_MODIFIER]);
- hdata_new_list(hdata, "last_weechat_hook_modifier", &last_weechat_hook[HOOK_TYPE_MODIFIER]);
- }
- return hook_hdata_hook_modifier;
-}
-
-/*
- * hook_hdata_hook_info_cb: return hdata for hook of type "info"
- */
-
-struct t_hdata *
-hook_hdata_hook_info_cb (void *data, const char *hdata_name)
-{
- struct t_hdata *hdata;
-
- /* make C compiler happy */
- (void) data;
-
- if (hook_hdata_hook_info)
- return hook_hdata_hook_info;
-
- hdata = hdata_new (hdata_name, NULL, NULL);
- if (hdata)
- {
- hook_hdata_hook_info = hdata;
- HDATA_VAR(struct t_hook_info, callback, POINTER);
- HDATA_VAR(struct t_hook_info, info_name, STRING);
- HDATA_VAR(struct t_hook_info, description, STRING);
- HDATA_VAR(struct t_hook_info, args_description, STRING);
- hdata_new_list(hdata, "weechat_hooks_info", &weechat_hooks[HOOK_TYPE_INFO]);
- hdata_new_list(hdata, "last_weechat_hook_info", &last_weechat_hook[HOOK_TYPE_INFO]);
- }
- return hook_hdata_hook_info;
-}
-
-/*
- * hook_hdata_hook_info_hashtable_cb: return hdata for hook of type
- * "info_hashtable"
- */
-
-struct t_hdata *
-hook_hdata_hook_info_hashtable_cb (void *data, const char *hdata_name)
-{
- struct t_hdata *hdata;
-
- /* make C compiler happy */
- (void) data;
-
- if (hook_hdata_hook_info_hashtable)
- return hook_hdata_hook_info_hashtable;
-
- hdata = hdata_new (hdata_name, NULL, NULL);
- if (hdata)
- {
- hook_hdata_hook_info_hashtable = hdata;
- HDATA_VAR(struct t_hook_info_hashtable, callback, POINTER);
- HDATA_VAR(struct t_hook_info_hashtable, info_name, STRING);
- HDATA_VAR(struct t_hook_info_hashtable, description, STRING);
- HDATA_VAR(struct t_hook_info_hashtable, args_description, STRING);
- HDATA_VAR(struct t_hook_info_hashtable, output_description, STRING);
- hdata_new_list(hdata, "weechat_hooks_info_hashtable", &weechat_hooks[HOOK_TYPE_INFO_HASHTABLE]);
- hdata_new_list(hdata, "last_weechat_hook_info_hashtable", &last_weechat_hook[HOOK_TYPE_INFO_HASHTABLE]);
- }
- return hook_hdata_hook_info_hashtable;
-}
-
-/*
- * hook_hdata_hook_infolist_cb: return hdata for hook of type "infolist"
- */
-
-struct t_hdata *
-hook_hdata_hook_infolist_cb (void *data, const char *hdata_name)
-{
- struct t_hdata *hdata;
-
- /* make C compiler happy */
- (void) data;
-
- if (hook_hdata_hook_infolist)
- return hook_hdata_hook_infolist;
-
- hdata = hdata_new (hdata_name, NULL, NULL);
- if (hdata)
- {
- hook_hdata_hook_infolist = hdata;
- HDATA_VAR(struct t_hook_infolist, callback, POINTER);
- HDATA_VAR(struct t_hook_infolist, infolist_name, STRING);
- HDATA_VAR(struct t_hook_infolist, description, STRING);
- HDATA_VAR(struct t_hook_infolist, pointer_description, STRING);
- HDATA_VAR(struct t_hook_infolist, args_description, STRING);
- hdata_new_list(hdata, "weechat_hooks_infolist", &weechat_hooks[HOOK_TYPE_INFOLIST]);
- hdata_new_list(hdata, "last_weechat_hook_infolist", &last_weechat_hook[HOOK_TYPE_INFOLIST]);
- }
- return hook_hdata_hook_infolist;
-}
-
-/*
- * hook_hdata_hook_hdata_cb: return hdata for hook of type "hdata"
- */
-
-struct t_hdata *
-hook_hdata_hook_hdata_cb (void *data, const char *hdata_name)
-{
- struct t_hdata *hdata;
-
- /* make C compiler happy */
- (void) data;
-
- if (hook_hdata_hook_hdata)
- return hook_hdata_hook_hdata;
-
- hdata = hdata_new (hdata_name, NULL, NULL);
- if (hdata)
- {
- hook_hdata_hook_hdata = hdata;
- HDATA_VAR(struct t_hook_hdata, callback, POINTER);
- HDATA_VAR(struct t_hook_hdata, hdata_name, STRING);
- HDATA_VAR(struct t_hook_hdata, description, STRING);
- hdata_new_list(hdata, "weechat_hooks_hdata", &weechat_hooks[HOOK_TYPE_HDATA]);
- hdata_new_list(hdata, "last_weechat_hook_hdata", &last_weechat_hook[HOOK_TYPE_HDATA]);
- }
- return hook_hdata_hook_hdata;
-}
-
-/*
* hook_add_to_infolist_type: add hooks of a type in an infolist
* return 1 if ok, 0 if error
*/
diff --git a/src/core/wee-infolist.c b/src/core/wee-infolist.c
index 3bc763e94..31f484925 100644
--- a/src/core/wee-infolist.c
+++ b/src/core/wee-infolist.c
@@ -43,13 +43,14 @@ struct t_infolist *last_weechat_infolist = NULL;
*/
struct t_infolist *
-infolist_new ()
+infolist_new (struct t_weechat_plugin *plugin)
{
struct t_infolist *new_infolist;
new_infolist = malloc (sizeof (*new_infolist));
if (new_infolist)
{
+ new_infolist->plugin = plugin;
new_infolist->items = NULL;
new_infolist->last_item = NULL;
new_infolist->ptr_item = NULL;
@@ -645,6 +646,25 @@ infolist_free (struct t_infolist *infolist)
}
/*
+ * infolist_free_all_plugin: free all infolists created by a plugin
+ */
+
+void
+infolist_free_all_plugin (struct t_weechat_plugin *plugin)
+{
+ struct t_infolist *ptr_infolist, *next_infolist;
+
+ ptr_infolist = weechat_infolists;
+ while (ptr_infolist)
+ {
+ next_infolist = ptr_infolist->next_infolist;
+ if (ptr_infolist->plugin == plugin)
+ infolist_free (ptr_infolist);
+ ptr_infolist = next_infolist;
+ }
+}
+
+/*
* infolist_print_log: print infolists infos in log (usually for crash dump)
*/
@@ -660,6 +680,7 @@ infolist_print_log ()
{
log_printf ("");
log_printf ("[infolist (addr:0x%lx)]", ptr_infolist);
+ log_printf (" plugin . . . . . . . . : 0x%lx", ptr_infolist->plugin);
log_printf (" items. . . . . . . . . : 0x%lx", ptr_infolist->items);
log_printf (" last_item. . . . . . . : 0x%lx", ptr_infolist->last_item);
log_printf (" ptr_item . . . . . . . : 0x%lx", ptr_infolist->ptr_item);
diff --git a/src/core/wee-infolist.h b/src/core/wee-infolist.h
index 4571230d8..cf97ce751 100644
--- a/src/core/wee-infolist.h
+++ b/src/core/wee-infolist.h
@@ -52,6 +52,8 @@ struct t_infolist_item
struct t_infolist
{
+ struct t_weechat_plugin *plugin; /* plugin which created this infolist*/
+ /* (NULL if created by WeeChat) */
struct t_infolist_item *items; /* link to items */
struct t_infolist_item *last_item; /* last variable */
struct t_infolist_item *ptr_item; /* pointer to current item */
@@ -100,6 +102,7 @@ extern void *infolist_buffer (struct t_infolist *infolist,
extern time_t infolist_time (struct t_infolist *infolist,
const char *var);
extern void infolist_free (struct t_infolist *infolist);
+extern void infolist_free_all_plugin (struct t_weechat_plugin *plugin);
extern void infolist_print_log ();
#endif /* __WEECHAT_INFOLIST_H */
diff --git a/src/core/weechat.c b/src/core/weechat.c
index 7812c93ba..26fe4f6d9 100644
--- a/src/core/weechat.c
+++ b/src/core/weechat.c
@@ -58,6 +58,7 @@
#include "wee-completion.h"
#include "wee-config.h"
#include "wee-debug.h"
+#include "wee-hdata.h"
#include "wee-hook.h"
#include "wee-log.h"
#include "wee-network.h"
@@ -411,6 +412,7 @@ main (int argc, char *argv[])
util_catch_signal (SIGPIPE, SIG_IGN); /* ignore SIGPIPE signal */
util_catch_signal (SIGSEGV,
&debug_sigsegv); /* crash dump for SIGSEGV signal */
+ hdata_init (); /* initialize hdata */
hook_init (); /* initialize hooks */
debug_init (); /* hook signals for debug */
gui_main_pre_init (&argc, &argv); /* pre-initiliaze interface */
@@ -451,6 +453,7 @@ main (int argc, char *argv[])
config_file_free_all (); /* free all configuration files */
gui_keyboard_end (); /* end keyboard */
unhook_all (); /* remove all hooks */
+ hdata_end (); /* end hdata */
weechat_shutdown (EXIT_SUCCESS, 0); /* quit WeeChat (oh no, why?) */
return EXIT_SUCCESS; /* make C compiler happy */