diff options
Diffstat (limited to 'src/plugins/plugin-script.c')
-rw-r--r-- | src/plugins/plugin-script.c | 395 |
1 files changed, 255 insertions, 140 deletions
diff --git a/src/plugins/plugin-script.c b/src/plugins/plugin-script.c index 7a33b10e5..620ddba6d 100644 --- a/src/plugins/plugin-script.c +++ b/src/plugins/plugin-script.c @@ -33,7 +33,6 @@ #include "weechat-plugin.h" #include "plugin-script.h" -#include "plugin-script-callback.h" #define SCRIPT_OPTION_CHECK_LICENSE "check_license" @@ -67,13 +66,19 @@ plugin_script_config_read (struct t_weechat_plugin *weechat_plugin) */ int -plugin_script_config_cb (void *data, const char *option, const char *value) +plugin_script_config_cb (const void *pointer, void *data, + const char *option, const char *value) { + struct t_weechat_plugin *plugin; + /* make C compiler happy */ + (void) data; (void) option; (void) value; - plugin_script_config_read (data); + plugin = (struct t_weechat_plugin *)pointer; + + plugin_script_config_read (plugin); return WEECHAT_RC_OK; } @@ -130,7 +135,8 @@ plugin_script_init (struct t_weechat_plugin *weechat_plugin, { snprintf (string, length, "plugins.var.%s.%s", weechat_plugin->name, SCRIPT_OPTION_CHECK_LICENSE); - weechat_hook_config (string, &plugin_script_config_cb, weechat_plugin); + weechat_hook_config (string, + &plugin_script_config_cb, weechat_plugin, NULL); free (string); } @@ -175,7 +181,7 @@ plugin_script_init (struct t_weechat_plugin *weechat_plugin, "\n" "Without argument, this command lists all loaded scripts."), completion, - init->callback_command, NULL); + init->callback_command, NULL, NULL); if (string) free (string); if (completion) @@ -188,29 +194,24 @@ plugin_script_init (struct t_weechat_plugin *weechat_plugin, { snprintf (string, length, "%s_script", weechat_plugin->name); weechat_hook_completion (string, N_("list of scripts"), - init->callback_completion, NULL); + init->callback_completion, NULL, NULL); weechat_hook_hdata (string, N_("list of scripts"), - init->callback_hdata, weechat_plugin); + init->callback_hdata, weechat_plugin, NULL); weechat_hook_infolist (string, N_("list of scripts"), N_("script pointer (optional)"), - N_("script name (wildcard \"*\" is allowed) (optional)"), - init->callback_infolist, NULL); - snprintf (string, length, "%s_callback", weechat_plugin->name); - weechat_hook_hdata (string, N_("callback of a script"), - &plugin_script_callback_hdata_callback_cb, - weechat_plugin); + N_("script name (wildcard \"*\" is allowed) " + "(optional)"), + init->callback_infolist, NULL, NULL); free (string); } /* add signal for "debug_dump" */ - weechat_hook_signal ("debug_dump", init->callback_signal_debug_dump, NULL); + weechat_hook_signal ("debug_dump", + init->callback_signal_debug_dump, NULL, NULL); /* add signal for "debug_libs" */ - weechat_hook_signal ("debug_libs", init->callback_signal_debug_libs, NULL); - - /* add signal for "buffer_closed" */ - weechat_hook_signal ("buffer_closed", - init->callback_signal_buffer_closed, NULL); + weechat_hook_signal ("debug_libs", + init->callback_signal_debug_libs, NULL, NULL); /* add signals for script actions (install/remove/autoload) */ for (i = 0; action_signals[i]; i++) @@ -219,7 +220,7 @@ plugin_script_init (struct t_weechat_plugin *weechat_plugin, weechat_plugin->name, action_signals[i]); weechat_hook_signal (signal_name, - init->callback_signal_script_action, NULL); + init->callback_signal_script_action, NULL, NULL); } /* parse arguments */ @@ -334,12 +335,74 @@ invalid: } /* + * Builds concatenated function name and data (both are strings). + * The result will be sent to callbacks. + */ + +char * +plugin_script_build_function_and_data (const char *function, const char *data) +{ + int length_function, length_data, length; + char *result; + + if (!function || !function[0]) + return NULL; + + length_function = (function) ? strlen (function) : 0; + length_data = (data) ? strlen (data) : 0; + length = length_function + 1 + length_data + 1; + + result = malloc (length); + if (!result) + return NULL; + + if (function) + memcpy (result, function, length_function + 1); + else + result[0] = '\0'; + + if (data) + memcpy (result + length_function + 1, data, length_data + 1); + else + result[length_function + 1] = '\0'; + + return result; +} + +/* + * Gets pointer on function name and data from a callback data pointer + * (which contains 2 strings separated by '\0'). + */ + +void +plugin_script_get_function_and_data (void *callback_data, + const char **function, const char **data) +{ + const char *string, *ptr_data; + + string = (const char *)callback_data; + + if (string) + { + *function = string; + ptr_data = string + strlen (string) + 1; + *data = (ptr_data[0]) ? ptr_data : NULL; + } + else + { + *function = NULL; + *data = NULL; + } +} + +/* * Auto-loads all scripts in a directory. */ void plugin_script_auto_load (struct t_weechat_plugin *weechat_plugin, - void (*callback)(void *data, const char *filename)) + void (*callback)(void *data, + const char *filename)) { const char *dir_home; char *dir_name; @@ -356,7 +419,7 @@ plugin_script_auto_load (struct t_weechat_plugin *weechat_plugin, snprintf (dir_name, dir_length, "%s/%s/autoload", dir_home, weechat_plugin->name); - weechat_exec_on_files (dir_name, 0, NULL, callback); + weechat_exec_on_files (dir_name, 0, callback, NULL); free (dir_name); } @@ -605,7 +668,6 @@ plugin_script_add (struct t_weechat_plugin *weechat_plugin, new_script->shutdown_func = (shutdown_func) ? strdup (shutdown_func) : NULL; new_script->charset = (charset) ? strdup (charset) : NULL; - new_script->callbacks = NULL; new_script->unloading = 0; plugin_script_insert_sorted (weechat_plugin, scripts, last_script, @@ -630,19 +692,21 @@ void plugin_script_set_buffer_callbacks (struct t_weechat_plugin *weechat_plugin, struct t_plugin_script *scripts, struct t_plugin_script *script, - int (*callback_buffer_input) (void *data, + int (*callback_buffer_input) (const void *pointer, + void *data, struct t_gui_buffer *buffer, const char *input_data), - int (*callback_buffer_close) (void *data, + int (*callback_buffer_close) (const void *pointer, + void *data, struct t_gui_buffer *buffer)) { struct t_infolist *infolist; struct t_gui_buffer *ptr_buffer; - const char *script_name, *str_script_input_cb, *str_script_input_cb_data; + const char *script_name; + const char *str_script_input_cb, *str_script_input_cb_data; const char *str_script_close_cb, *str_script_close_cb_data; + char *function_and_data; struct t_plugin_script *ptr_script; - struct t_plugin_script_cb *script_cb_input; - struct t_plugin_script_cb *script_cb_close; infolist = weechat_infolist_get ("buffer", NULL, NULL); if (infolist) @@ -659,46 +723,49 @@ plugin_script_set_buffer_callbacks (struct t_weechat_plugin *weechat_plugin, script_name); if (ptr_script && (ptr_script == script)) { - str_script_input_cb = weechat_buffer_get_string (ptr_buffer, - "localvar_script_input_cb"); - str_script_input_cb_data = weechat_buffer_get_string (ptr_buffer, - "localvar_script_input_cb_data"); - str_script_close_cb = weechat_buffer_get_string (ptr_buffer, - "localvar_script_close_cb"); - str_script_close_cb_data = weechat_buffer_get_string (ptr_buffer, - "localvar_script_close_cb_data"); - - if (str_script_input_cb && str_script_input_cb[0]) + str_script_input_cb = weechat_buffer_get_string ( + ptr_buffer, "localvar_script_input_cb"); + str_script_input_cb_data = weechat_buffer_get_string ( + ptr_buffer, "localvar_script_input_cb_data"); + str_script_close_cb = weechat_buffer_get_string ( + ptr_buffer, "localvar_script_close_cb"); + str_script_close_cb_data = weechat_buffer_get_string ( + ptr_buffer, "localvar_script_close_cb_data"); + + function_and_data = plugin_script_build_function_and_data ( + str_script_input_cb, str_script_input_cb_data); + if (function_and_data) { - script_cb_input = plugin_script_callback_add (ptr_script, - str_script_input_cb, - str_script_input_cb_data); - if (script_cb_input) - { - script_cb_input->buffer = ptr_buffer; - weechat_buffer_set_pointer (ptr_buffer, - "input_callback", - callback_buffer_input); - weechat_buffer_set_pointer (ptr_buffer, - "input_callback_data", - script_cb_input); - } + weechat_buffer_set_pointer ( + ptr_buffer, + "input_callback", + callback_buffer_input); + weechat_buffer_set_pointer ( + ptr_buffer, + "input_callback_pointer", + ptr_script); + weechat_buffer_set_pointer ( + ptr_buffer, + "input_callback_data", + function_and_data); } - if (str_script_close_cb && str_script_close_cb[0]) + + function_and_data = plugin_script_build_function_and_data ( + str_script_close_cb, str_script_close_cb_data); + if (function_and_data) { - script_cb_close = plugin_script_callback_add (ptr_script, - str_script_close_cb, - str_script_close_cb_data); - if (script_cb_close) - { - script_cb_close->buffer = ptr_buffer; - weechat_buffer_set_pointer (ptr_buffer, - "close_callback", - callback_buffer_close); - weechat_buffer_set_pointer (ptr_buffer, - "close_callback_data", - script_cb_close); - } + weechat_buffer_set_pointer ( + ptr_buffer, + "close_callback", + callback_buffer_close); + weechat_buffer_set_pointer ( + ptr_buffer, + "close_callback_pointer", + ptr_script); + weechat_buffer_set_pointer ( + ptr_buffer, + "close_callback_data", + function_and_data); } } } @@ -709,36 +776,136 @@ plugin_script_set_buffer_callbacks (struct t_weechat_plugin *weechat_plugin, } /* - * Removes callbacks for a buffer (called when a buffer is closed by user). + * Closes all buffers created by the script. */ void -plugin_script_remove_buffer_callbacks (struct t_plugin_script *scripts, - struct t_gui_buffer *buffer) +plugin_script_close_buffers (struct t_weechat_plugin *weechat_plugin, + struct t_plugin_script *script) { - struct t_plugin_script *ptr_script; - struct t_plugin_script_cb *ptr_script_cb, *next_script_cb; + struct t_hdata *hdata; + struct t_gui_buffer *ptr_buffer, *ptr_buffer_to_close; + const char *ptr_script_name; - for (ptr_script = scripts; ptr_script; - ptr_script = ptr_script->next_script) + hdata = weechat_hdata_get ("buffer"); + while (1) { - /* - * do not remove buffer callbacks if script is being unloaded - * (because all callbacks will be removed anyway) - */ - if (!ptr_script->unloading) + ptr_buffer = weechat_hdata_get_list (hdata, "gui_buffers"); + ptr_buffer_to_close = NULL; + while (ptr_buffer) { - ptr_script_cb = ptr_script->callbacks; - while (ptr_script_cb) + ptr_script_name = weechat_buffer_get_string ( + ptr_buffer, "localvar_script_name"); + if (ptr_script_name + && (strcmp (ptr_script_name, script->name) == 0)) { - next_script_cb = ptr_script_cb->next_callback; + ptr_buffer_to_close = ptr_buffer; + break; + } + ptr_buffer = weechat_hdata_move (hdata, ptr_buffer, 1); + } + if (ptr_buffer_to_close) + { + weechat_buffer_close (ptr_buffer_to_close); + } + else + break; + } +} - if (ptr_script_cb->buffer == buffer) - plugin_script_callback_remove (ptr_script, ptr_script_cb); +/* + * Removes all bar items created by the script. + */ + +void +plugin_script_remove_bar_items (struct t_weechat_plugin *weechat_plugin, + struct t_plugin_script *script) +{ + struct t_hdata *hdata; + struct t_gui_bar_item *ptr_bar_item, *ptr_next_item; + void *callback_pointer; - ptr_script_cb = next_script_cb; + hdata = weechat_hdata_get ("bar_item"); + ptr_bar_item = weechat_hdata_get_list (hdata, "gui_bar_items"); + while (ptr_bar_item) + { + ptr_next_item = weechat_hdata_pointer (hdata, ptr_bar_item, + "next_item"); + callback_pointer = weechat_hdata_pointer (hdata, ptr_bar_item, + "build_callback_pointer"); + if (callback_pointer == script) + weechat_bar_item_remove (ptr_bar_item); + ptr_bar_item = ptr_next_item; + } +} + +/* + * Removes all configuration files/sections/options created by the script. + */ + +void +plugin_script_remove_configs (struct t_weechat_plugin *weechat_plugin, + struct t_plugin_script *script) +{ + struct t_hdata *hdata_config, *hdata_section, *hdata_option; + struct t_config_file *ptr_config, *ptr_next_config; + struct t_config_section *ptr_section, *ptr_next_section; + struct t_config_option *ptr_option, *ptr_next_option; + void *callback_pointer; + + hdata_config = weechat_hdata_get ("config_file"); + hdata_section = weechat_hdata_get ("config_section"); + hdata_option = weechat_hdata_get ("config_option"); + ptr_config = weechat_hdata_get_list (hdata_config, "config_files"); + while (ptr_config) + { + ptr_next_config = weechat_hdata_pointer (hdata_config, ptr_config, + "next_config"); + callback_pointer = weechat_hdata_pointer ( + hdata_config, ptr_config, "callback_reload_pointer"); + if (callback_pointer == script) + { + if (weechat_config_boolean (weechat_config_get ("weechat.plugin.save_config_on_unload"))) + weechat_config_write (ptr_config); + weechat_config_free (ptr_config); + } + else + { + ptr_section = weechat_hdata_pointer (hdata_config, ptr_config, + "sections"); + while (ptr_section) + { + ptr_next_section = weechat_hdata_pointer (hdata_section, + ptr_section, + "next_section"); + callback_pointer = weechat_hdata_pointer ( + hdata_section, ptr_section, "callback_read_pointer"); + if (callback_pointer == script) + { + weechat_config_section_free (ptr_section); + } + else + { + ptr_option = weechat_hdata_pointer (hdata_section, + ptr_section, + "options"); + while (ptr_option) + { + ptr_next_option = weechat_hdata_pointer (hdata_option, + ptr_option, + "next_option"); + callback_pointer = weechat_hdata_pointer ( + hdata_option, ptr_option, + "callback_check_value_pointer"); + if (callback_pointer == script) + weechat_config_option_free (ptr_option); + ptr_option = ptr_next_option; + } + } + ptr_section = ptr_next_section; } } + ptr_config = ptr_next_config; } } @@ -752,59 +919,16 @@ plugin_script_remove (struct t_weechat_plugin *weechat_plugin, struct t_plugin_script **last_script, struct t_plugin_script *script) { - struct t_plugin_script_cb *ptr_script_cb, *ptr_script_cb2; - script->unloading = 1; - for (ptr_script_cb = script->callbacks; ptr_script_cb; - ptr_script_cb = ptr_script_cb->next_callback) - { - /* free configuration file */ - if (ptr_script_cb->config_file) - { - if (weechat_config_boolean (weechat_config_get ("weechat.plugin.save_config_on_unload"))) - weechat_config_write (ptr_script_cb->config_file); - weechat_config_free (ptr_script_cb->config_file); - } - - /* unhook */ - if (ptr_script_cb->hook) - weechat_unhook (ptr_script_cb->hook); + plugin_script_close_buffers (weechat_plugin, script); - /* close buffer */ - if (ptr_script_cb->buffer) - weechat_buffer_close (ptr_script_cb->buffer); + plugin_script_remove_bar_items (weechat_plugin, script); - /* remove bar item */ - if (ptr_script_cb->bar_item) - weechat_bar_item_remove (ptr_script_cb->bar_item); - - /* - * remove same pointers in other callbacks - * (to not free two times the same pointer!) - */ - for (ptr_script_cb2 = ptr_script_cb->next_callback; ptr_script_cb2; - ptr_script_cb2 = ptr_script_cb2->next_callback) - { - if (ptr_script_cb2->config_file == ptr_script_cb->config_file) - ptr_script_cb2->config_file = NULL; - if (ptr_script_cb2->config_section == ptr_script_cb->config_section) - ptr_script_cb2->config_section = NULL; - if (ptr_script_cb2->config_option == ptr_script_cb->config_option) - ptr_script_cb2->config_option = NULL; - if (ptr_script_cb2->hook == ptr_script_cb->hook) - ptr_script_cb2->hook = NULL; - if (ptr_script_cb2->buffer == ptr_script_cb->buffer) - ptr_script_cb2->buffer = NULL; - if (ptr_script_cb2->bar_item == ptr_script_cb->bar_item) - ptr_script_cb2->bar_item = NULL; - if (ptr_script_cb2->upgrade_file == ptr_script_cb->upgrade_file) - ptr_script_cb2->upgrade_file = NULL; - } - } + plugin_script_remove_configs (weechat_plugin, script); - /* remove all callbacks created by this script */ - plugin_script_callback_remove_all (script); + /* remove all hooks created by this script */ + weechat_unhook_all_plugin (script->name); /* free data */ if (script->filename) @@ -1385,7 +1509,6 @@ plugin_script_hdata_script (struct t_weechat_plugin *weechat_plugin, WEECHAT_HDATA_VAR(struct t_plugin_script, description, STRING, 0, NULL, NULL); WEECHAT_HDATA_VAR(struct t_plugin_script, shutdown_func, STRING, 0, NULL, NULL); WEECHAT_HDATA_VAR(struct t_plugin_script, charset, STRING, 0, NULL, NULL); - WEECHAT_HDATA_VAR(struct t_plugin_script, callbacks, POINTER, 0, NULL, str_hdata_callback); WEECHAT_HDATA_VAR(struct t_plugin_script, unloading, INTEGER, 0, NULL, NULL); WEECHAT_HDATA_VAR(struct t_plugin_script, prev_script, POINTER, 0, NULL, hdata_name); WEECHAT_HDATA_VAR(struct t_plugin_script, next_script, POINTER, 0, NULL, hdata_name); @@ -1529,7 +1652,6 @@ plugin_script_print_log (struct t_weechat_plugin *weechat_plugin, struct t_plugin_script *scripts) { struct t_plugin_script *ptr_script; - struct t_plugin_script_cb *ptr_script_cb; weechat_log_printf (""); weechat_log_printf ("***** \"%s\" plugin dump *****", @@ -1549,16 +1671,9 @@ plugin_script_print_log (struct t_weechat_plugin *weechat_plugin, weechat_log_printf (" description . . . . : '%s'", ptr_script->description); weechat_log_printf (" shutdown_func . . . : '%s'", ptr_script->shutdown_func); weechat_log_printf (" charset . . . . . . : '%s'", ptr_script->charset); - weechat_log_printf (" callbacks . . . . . : 0x%lx", ptr_script->callbacks); weechat_log_printf (" unloading . . . . . : %d", ptr_script->unloading); weechat_log_printf (" prev_script . . . . : 0x%lx", ptr_script->prev_script); weechat_log_printf (" next_script . . . . : 0x%lx", ptr_script->next_script); - - for (ptr_script_cb = ptr_script->callbacks; ptr_script_cb; - ptr_script_cb = ptr_script_cb->next_callback) - { - plugin_script_callback_print_log (weechat_plugin, ptr_script_cb); - } } weechat_log_printf (""); |