diff options
author | Sebastien Helleu <flashcode@flashtux.org> | 2011-06-26 18:15:42 +0200 |
---|---|---|
committer | Sebastien Helleu <flashcode@flashtux.org> | 2011-06-26 18:15:42 +0200 |
commit | 19bc95b96189de5a645adbe7b3487d5de1b835e7 (patch) | |
tree | b68d3d98d3d643bc02fba218db7f7ed6cd07ea2c /src/core | |
parent | 2a630031fd3c868733e3038c3e19ad4b53a8d8ce (diff) | |
download | weechat-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.c | 15 | ||||
-rw-r--r-- | src/core/wee-config-file.c | 128 | ||||
-rw-r--r-- | src/core/wee-debug.c | 96 | ||||
-rw-r--r-- | src/core/wee-hdata.c | 199 | ||||
-rw-r--r-- | src/core/wee-hdata.h | 24 | ||||
-rw-r--r-- | src/core/wee-hook.c | 552 | ||||
-rw-r--r-- | src/core/wee-infolist.c | 23 | ||||
-rw-r--r-- | src/core/wee-infolist.h | 3 | ||||
-rw-r--r-- | src/core/weechat.c | 3 |
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 */ |