From ed26a0389c06250f02329fa477d2cffe7df59b5e Mon Sep 17 00:00:00 2001 From: Sebastien Helleu Date: Thu, 24 Jan 2008 16:50:20 +0100 Subject: Add of "modifier" hook, migration of charset plugin to new API, SIGHUP signal catched (reload all config files), better config files reloading --- src/core/wee-command.c | 108 +-- src/core/wee-command.h | 4 + src/core/wee-config-file.c | 4 +- src/core/wee-config-file.h | 8 +- src/core/wee-config.c | 42 +- src/core/wee-hook.c | 196 ++++-- src/core/wee-hook.h | 20 +- src/core/wee-string.c | 9 +- src/core/wee-string.h | 4 +- src/gui/curses/gui-curses-color.c | 2 +- src/gui/curses/gui-curses-main.c | 17 +- src/gui/curses/gui-curses-window.c | 4 - src/gui/gui-completion.c | 4 +- src/gui/gui-keyboard.c | 4 +- src/plugins/alias/alias.c | 66 +- src/plugins/charset/Makefile.am | 2 +- src/plugins/charset/charset.c | 900 ++++++++++++------------ src/plugins/charset/charset.h | 33 + src/plugins/demo/demo.c | 5 +- src/plugins/fifo/fifo.c | 5 +- src/plugins/irc/irc-config.c | 129 ++-- src/plugins/irc/irc-config.h | 1 - src/plugins/irc/irc-protocol.c | 2 +- src/plugins/irc/irc-protocol.h | 4 +- src/plugins/irc/irc-server.c | 112 ++- src/plugins/irc/irc-server.h | 5 +- src/plugins/irc/irc.c | 8 +- src/plugins/logger/logger.c | 5 +- src/plugins/plugin-config.c | 40 +- src/plugins/plugin.c | 5 +- src/plugins/scripts/lua/weechat-lua-api.c | 112 ++- src/plugins/scripts/perl/weechat-perl-api.c | 104 ++- src/plugins/scripts/perl/weechat-perl.c | 9 +- src/plugins/scripts/python/weechat-python-api.c | 95 +++ src/plugins/scripts/ruby/weechat-ruby-api.c | 110 +++ src/plugins/scripts/script-api.c | 36 + src/plugins/scripts/script-api.h | 8 + src/plugins/weechat-plugin.h | 28 +- 38 files changed, 1506 insertions(+), 744 deletions(-) create mode 100644 src/plugins/charset/charset.h (limited to 'src') diff --git a/src/core/wee-command.c b/src/core/wee-command.c index 52991c7b3..98bf6697f 100644 --- a/src/core/wee-command.c +++ b/src/core/wee-command.c @@ -31,6 +31,7 @@ #include "weechat.h" #include "wee-command.h" #include "wee-config.h" +#include "wee-config-file.h" #include "wee-hook.h" #include "wee-input.h" #include "wee-log.h" @@ -818,7 +819,7 @@ command_key (void *data, struct t_gui_buffer *buffer, else { gui_chat_printf (NULL, - _("No key found.")); + _("No key found")); } if (internal_code) free (internal_code); @@ -1034,13 +1035,30 @@ command_plugin_list (char *name, int full) HOOK_COMPLETION(ptr_hook, completion)); } } + + /* modifier hooked */ + hook_found = 0; + for (ptr_hook = weechat_hooks[HOOK_TYPE_MODIFIER]; ptr_hook; + ptr_hook = ptr_hook->next_hook) + { + if (!ptr_hook->deleted && (ptr_hook->plugin == ptr_plugin)) + { + if (!hook_found) + gui_chat_printf (NULL, + _(" modifiers hooked:")); + hook_found = 1; + gui_chat_printf (NULL, + " %s", + HOOK_MODIFIER(ptr_hook, modifier)); + } + } } } } if (plugins_found == 0) { if (name) - gui_chat_printf (NULL, _("No plugin found.")); + gui_chat_printf (NULL, _("No plugin found")); else gui_chat_printf (NULL, _(" (no plugin)")); } @@ -1142,6 +1160,8 @@ int command_reload (void *data, struct t_gui_buffer *buffer, int argc, char **argv, char **argv_eol) { + struct t_config_file *ptr_config_file; + /* make C compiler happy */ (void) data; (void) buffer; @@ -1149,28 +1169,26 @@ command_reload (void *data, struct t_gui_buffer *buffer, (void) argv; (void) argv_eol; - /* reload WeeChat configuration */ - if (config_weechat_reload () == 0) - gui_chat_printf (NULL, - _("%sWeeChat configuration file reloaded"), - gui_chat_prefix[GUI_CHAT_PREFIX_INFO]); - else - gui_chat_printf (NULL, - _("%sError: failed to reload WeeChat configuration " - "file"), - gui_chat_prefix[GUI_CHAT_PREFIX_ERROR]); - - /* reload plugins configuration */ - if (plugin_config_reload () == 0) - gui_chat_printf (NULL, _("%sPlugins options reloaded"), - gui_chat_prefix[GUI_CHAT_PREFIX_INFO]); - else - gui_chat_printf (NULL, - _("%sError: failed to reload plugins options"), - gui_chat_prefix[GUI_CHAT_PREFIX_ERROR]); - - /* tell to plugins to reload their configuration */ - hook_signal_send ("config_reload", WEECHAT_HOOK_SIGNAL_STRING, NULL); + for (ptr_config_file = config_files; ptr_config_file; + ptr_config_file = ptr_config_file->next_config) + { + if (ptr_config_file->callback_reload) + { + if ((int) (ptr_config_file->callback_reload) (ptr_config_file) == 0) + { + gui_chat_printf (NULL, _("%sOptions reloaded from %s"), + gui_chat_prefix[GUI_CHAT_PREFIX_INFO], + ptr_config_file->filename); + } + else + { + gui_chat_printf (NULL, + _("%sError: failed to reload options from %s"), + gui_chat_prefix[GUI_CHAT_PREFIX_ERROR], + ptr_config_file->filename); + } + } + } return WEECHAT_RC_OK; } @@ -1183,32 +1201,32 @@ int command_save (void *data, struct t_gui_buffer *buffer, int argc, char **argv, char **argv_eol) { + struct t_config_file *ptr_config_file; + /* make C compiler happy */ (void) data; (void) buffer; (void) argc; (void) argv; (void) argv_eol; - - /* save WeeChat configuration */ - if (config_weechat_write () == 0) - gui_chat_printf (NULL, - _("%sWeeChat configuration file saved"), - gui_chat_prefix[GUI_CHAT_PREFIX_INFO]); - else - gui_chat_printf (NULL, - _("%sError: failed to save WeeChat configuration " - "file"), - gui_chat_prefix[GUI_CHAT_PREFIX_ERROR]); - /* save plugins configuration */ - if (plugin_config_write () == 0) - gui_chat_printf (NULL, _("%sPlugins options saved"), - gui_chat_prefix[GUI_CHAT_PREFIX_INFO]); - else - gui_chat_printf (NULL, - _("%sError: failed to save plugins options"), - gui_chat_prefix[GUI_CHAT_PREFIX_ERROR]); + for (ptr_config_file = config_files; ptr_config_file; + ptr_config_file = ptr_config_file->next_config) + { + if (config_file_write (ptr_config_file) == 0) + { + gui_chat_printf (NULL, _("%sOptions saved to %s"), + gui_chat_prefix[GUI_CHAT_PREFIX_INFO], + ptr_config_file->filename); + } + else + { + gui_chat_printf (NULL, + _("%sError: failed to save options to %s"), + gui_chat_prefix[GUI_CHAT_PREFIX_ERROR], + ptr_config_file->filename); + } + } return WEECHAT_RC_OK; } @@ -1826,7 +1844,7 @@ command_window (void *data, struct t_gui_buffer *buffer, gui_chat_printf (NULL, _("%sError: can not merge windows, " "there's no other window with same " - "size near current one."), + "size near current one"), gui_chat_prefix[GUI_CHAT_PREFIX_ERROR]); return WEECHAT_RC_ERROR; } @@ -1972,7 +1990,7 @@ command_init () "all plugins, then autoload plugins)\n" " unload: unload one or all plugins\n\n" "Without argument, /plugin command lists loaded plugins."), - "list|listfull|load|autoload|reload|unload %p", + "list|listfull|load|autoload|reload|unload %f|%p", command_plugin, NULL); hook_command (NULL, "quit", N_("quit WeeChat"), diff --git a/src/core/wee-command.h b/src/core/wee-command.h index adffc3c8c..f73e06fc7 100644 --- a/src/core/wee-command.h +++ b/src/core/wee-command.h @@ -20,6 +20,10 @@ #ifndef __WEECHAT_COMMAND_H #define __WEECHAT_COMMAND_H 1 +struct t_gui_buffer; + +extern int command_reload (void *data, struct t_gui_buffer *buffer, + int argc, char **argv, char **argv_eol); extern void command_init (); extern void command_print_stdout (); diff --git a/src/core/wee-config-file.c b/src/core/wee-config-file.c index ec7b5ce8f..7cc16fe4b 100644 --- a/src/core/wee-config-file.c +++ b/src/core/wee-config-file.c @@ -69,7 +69,8 @@ config_file_search (char *filename) */ struct t_config_file * -config_file_new (struct t_weechat_plugin *plugin, char *filename) +config_file_new (struct t_weechat_plugin *plugin, char *filename, + int (*callback_reload)(struct t_config_file *config_file)) { struct t_config_file *new_config_file; @@ -86,6 +87,7 @@ config_file_new (struct t_weechat_plugin *plugin, char *filename) new_config_file->plugin = plugin; new_config_file->filename = strdup (filename); new_config_file->file = NULL; + new_config_file->callback_reload = callback_reload; new_config_file->sections = NULL; new_config_file->last_section = NULL; diff --git a/src/core/wee-config-file.h b/src/core/wee-config-file.h index 4468c406f..87e4743f2 100644 --- a/src/core/wee-config-file.h +++ b/src/core/wee-config-file.h @@ -40,6 +40,8 @@ struct t_config_file struct t_weechat_plugin *plugin; /* plugin which created this cfg */ char *filename; /* config filename (without path)*/ FILE *file; /* file pointer */ + int (*callback_reload) /* callback for reloading file */ + (struct t_config_file *config_file); struct t_config_section *sections; /* config sections */ struct t_config_section *last_section; /* last config section */ struct t_config_file *prev_config; /* link to previous config file */ @@ -87,8 +89,12 @@ struct t_config_option struct t_config_option *next_option; /* link to next option */ }; +extern struct t_config_file *config_files; +extern struct t_config_file *last_config_file; + extern struct t_config_file *config_file_new (struct t_weechat_plugin *plugin, - char *filename); + char *filename, + int (*callback_reload)(struct t_config_file *config_file)); extern int config_file_valid_for_plugin (struct t_weechat_plugin *plugin, struct t_config_file *config_file); extern struct t_config_section *config_file_new_section (struct t_config_file *config_file, diff --git a/src/core/wee-config.c b/src/core/wee-config.c index 1643c2187..9058774b6 100644 --- a/src/core/wee-config.c +++ b/src/core/wee-config.c @@ -414,6 +414,25 @@ config_change_day_change () } } +/* + * config_weechat_reload: reload WeeChat configuration file + * return: 0 = successful + * -1 = config file file not found + * -2 = error in config file + */ + +int +config_weechat_reload (struct t_config_file *config_file) +{ + /* make C compiler happy */ + (void) config_file; + + /* remove all keys */ + gui_keyboard_free_all (); + + return config_file_reload (weechat_config_file); +} + /* * config_weechat_read_key: read a key in configuration file */ @@ -495,7 +514,8 @@ config_weechat_init () { struct t_config_section *ptr_section; - weechat_config_file = config_file_new (NULL, WEECHAT_CONFIG_FILENAME); + weechat_config_file = config_file_new (NULL, WEECHAT_CONFIG_FILENAME, + &config_weechat_reload); if (!weechat_config_file) return 0; @@ -1159,23 +1179,6 @@ config_weechat_read () return rc; } -/* - * config_weechat_reload: reload WeeChat configuration file - * return: 0 = successful - * -1 = configuration file file not found - * -2 = error in configuration file - */ - -int -config_weechat_reload () -{ - /* remove all keys */ - gui_keyboard_free_all (); - - /* reload configuration file */ - return config_file_reload (weechat_config_file); -} - /* * config_weechat_write: write WeeChat configuration file * return: 0 if ok @@ -1185,6 +1188,7 @@ config_weechat_reload () int config_weechat_write () { - log_printf (_("Saving WeeChat configuration to disk")); + log_printf (_("Saving WeeChat configuration to disk (%s)"), + weechat_config_file->filename); return config_file_write (weechat_config_file); } diff --git a/src/core/wee-hook.c b/src/core/wee-hook.c index 02e92de78..fe57e98c2 100644 --- a/src/core/wee-hook.c +++ b/src/core/wee-hook.c @@ -256,6 +256,30 @@ hook_valid_for_plugin (struct t_weechat_plugin *plugin, struct t_hook *hook) return 0; } +/* + * hook_exec_start: code executed before a hook exec + */ + +void +hook_exec_start () +{ + hook_exec_recursion++; +} + +/* + * hook_exec_end: code executed after a hook exec + */ + +void +hook_exec_end () +{ + if (hook_exec_recursion > 0) + hook_exec_recursion--; + + if (hook_exec_recursion == 0) + hook_remove_deleted (); +} + /* * hook_search_command: search command hook in list */ @@ -362,7 +386,7 @@ hook_command_exec (struct t_gui_buffer *buffer, char *string, int only_builtin) } argv_eol = string_explode (string, " ", 1, 0, NULL); - hook_exec_recursion++; + hook_exec_start (); ptr_hook = weechat_hooks[HOOK_TYPE_COMMAND]; while (ptr_hook) @@ -383,10 +407,9 @@ hook_command_exec (struct t_gui_buffer *buffer, char *string, int only_builtin) rc = (int) (HOOK_COMMAND(ptr_hook, callback)) (ptr_hook->callback_data, buffer, argc, argv, argv_eol); ptr_hook->running = 0; - if (hook_exec_recursion > 0) - hook_exec_recursion--; - if (hook_exec_recursion == 0) - hook_remove_deleted (); + string_free_exploded (argv); + string_free_exploded (argv_eol); + hook_exec_end (); if (rc == WEECHAT_RC_ERROR) return 0; else @@ -399,11 +422,7 @@ hook_command_exec (struct t_gui_buffer *buffer, char *string, int only_builtin) string_free_exploded (argv); string_free_exploded (argv_eol); - if (hook_exec_recursion > 0) - hook_exec_recursion--; - - if (hook_exec_recursion == 0) - hook_remove_deleted (); + hook_exec_end (); /* no hook found */ return -1; @@ -530,7 +549,7 @@ hook_timer_exec () gettimeofday (&tv_time, NULL); - hook_exec_recursion++; + hook_exec_start (); ptr_hook = weechat_hooks[HOOK_TYPE_TIMER]; while (ptr_hook) @@ -566,11 +585,7 @@ hook_timer_exec () ptr_hook = next_hook; } - if (hook_exec_recursion > 0) - hook_exec_recursion--; - - if (hook_exec_recursion == 0) - hook_remove_deleted (); + hook_exec_end (); } /* @@ -686,7 +701,7 @@ hook_fd_exec (fd_set *read_fds, fd_set *write_fds, fd_set *exception_fds) { struct t_hook *ptr_hook, *next_hook; - hook_exec_recursion++; + hook_exec_start (); ptr_hook = weechat_hooks[HOOK_TYPE_FD]; while (ptr_hook) @@ -710,11 +725,7 @@ hook_fd_exec (fd_set *read_fds, fd_set *write_fds, fd_set *exception_fds) ptr_hook = next_hook; } - if (hook_exec_recursion > 0) - hook_exec_recursion--; - - if (hook_exec_recursion == 0) - hook_remove_deleted (); + hook_exec_end (); } /* @@ -776,7 +787,7 @@ hook_print_exec (struct t_gui_buffer *buffer, time_t date, char *prefix, return; } - hook_exec_recursion++; + hook_exec_start (); ptr_hook = weechat_hooks[HOOK_TYPE_PRINT]; while (ptr_hook) @@ -802,11 +813,7 @@ hook_print_exec (struct t_gui_buffer *buffer, time_t date, char *prefix, ptr_hook = next_hook; } - if (hook_exec_recursion > 0) - hook_exec_recursion--; - - if (hook_exec_recursion == 0) - hook_remove_deleted (); + hook_exec_end (); } /* @@ -853,7 +860,7 @@ hook_signal_send (char *signal, char *type_data, void *signal_data) { struct t_hook *ptr_hook, *next_hook; - hook_exec_recursion++; + hook_exec_start (); ptr_hook = weechat_hooks[HOOK_TYPE_SIGNAL]; while (ptr_hook) @@ -874,11 +881,7 @@ hook_signal_send (char *signal, char *type_data, void *signal_data) ptr_hook = next_hook; } - if (hook_exec_recursion > 0) - hook_exec_recursion--; - - if (hook_exec_recursion == 0) - hook_remove_deleted (); + hook_exec_end (); } /* @@ -923,7 +926,7 @@ hook_config_exec (char *type, char *option, char *value) { struct t_hook *ptr_hook, *next_hook; - hook_exec_recursion++; + hook_exec_start (); ptr_hook = weechat_hooks[HOOK_TYPE_CONFIG]; while (ptr_hook) @@ -948,11 +951,7 @@ hook_config_exec (char *type, char *option, char *value) ptr_hook = next_hook; } - if (hook_exec_recursion > 0) - hook_exec_recursion--; - - if (hook_exec_recursion == 0) - hook_remove_deleted (); + hook_exec_end (); } /* @@ -1003,7 +1002,7 @@ hook_completion_exec (struct t_weechat_plugin *plugin, char *completion, /* make C compiler happy */ (void) plugin; - hook_exec_recursion++; + hook_exec_start (); ptr_hook = weechat_hooks[HOOK_TYPE_COMPLETION]; while (ptr_hook) @@ -1024,11 +1023,103 @@ hook_completion_exec (struct t_weechat_plugin *plugin, char *completion, ptr_hook = next_hook; } - if (hook_exec_recursion > 0) - hook_exec_recursion--; + hook_exec_end (); +} + +/* + * hook_modifier: hook a modifier + */ + +struct t_hook * +hook_modifier (struct t_weechat_plugin *plugin, char *modifier, + t_hook_callback_modifier *callback, void *callback_data) +{ + struct t_hook *new_hook; + struct t_hook_modifier *new_hook_modifier; - if (hook_exec_recursion == 0) - hook_remove_deleted (); + if (!modifier || !modifier[0]) + return NULL; + + new_hook = (struct t_hook *)malloc (sizeof (struct t_hook)); + if (!new_hook) + return NULL; + new_hook_modifier = (struct t_hook_modifier *)malloc (sizeof (struct t_hook_modifier)); + if (!new_hook_modifier) + { + free (new_hook); + return NULL; + } + + hook_init_data (new_hook, plugin, HOOK_TYPE_MODIFIER, callback_data); + + new_hook->hook_data = new_hook_modifier; + new_hook_modifier->callback = callback; + new_hook_modifier->modifier = strdup (modifier); + + hook_add_to_list (new_hook); + + return new_hook; +} + +/* + * hook_modifier_exec: execute modifier hook + */ + +char * +hook_modifier_exec (struct t_weechat_plugin *plugin, char *modifier, + char *modifier_data, char *string) +{ + struct t_hook *ptr_hook, *next_hook; + char *new_msg, *message_modified; + + /* make C compiler happy */ + (void) plugin; + + new_msg = NULL; + message_modified = strdup (string); + if (!message_modified) + return NULL; + + hook_exec_start (); + + ptr_hook = weechat_hooks[HOOK_TYPE_MODIFIER]; + while (ptr_hook) + { + next_hook = ptr_hook->next_hook; + + if (!ptr_hook->deleted + && !ptr_hook->running + && (string_strcasecmp (HOOK_MODIFIER(ptr_hook, modifier), + modifier) == 0)) + { + ptr_hook->running = 1; + new_msg = (HOOK_MODIFIER(ptr_hook, callback)) + (ptr_hook->callback_data, modifier, modifier_data, + message_modified); + ptr_hook->running = 0; + + /* empty string returned => message dropped */ + if (new_msg && !new_msg[0]) + { + free (message_modified); + hook_exec_end (); + return new_msg; + } + + /* new message => keep it as base for next modifier */ + if (new_msg) + { + free (message_modified); + message_modified = new_msg; + } + } + + ptr_hook = next_hook; + } + + hook_exec_end (); + + return message_modified; } /* @@ -1104,6 +1195,11 @@ unhook (struct t_hook *hook) free (HOOK_COMPLETION(hook, completion)); free ((struct t_hook_completion *)hook->hook_data); break; + case HOOK_TYPE_MODIFIER: + if (HOOK_MODIFIER(hook, modifier)) + free (HOOK_MODIFIER(hook, modifier)); + free ((struct t_hook_modifier *)hook->hook_data); + break; case HOOK_NUM_TYPES: /* this constant is used to count types only, it is never used as type */ @@ -1288,6 +1384,16 @@ hook_print_log () log_printf (" completion . . . . . : '%s'", HOOK_COMPLETION(ptr_hook, completion)); } break; + case HOOK_TYPE_MODIFIER: + log_printf (" type . . . . . . . . . : %d (modifier)", ptr_hook->type); + log_printf (" callback_data. . . . . : 0x%x", ptr_hook->callback_data); + if (!ptr_hook->deleted) + { + log_printf (" modifier data:"); + log_printf (" callback . . . . . . : 0x%x", HOOK_MODIFIER(ptr_hook, callback)); + log_printf (" modifier . . . . . . : '%s'", HOOK_MODIFIER(ptr_hook, modifier)); + } + break; case HOOK_NUM_TYPES: /* this constant is used to count types only, it is never used as type */ diff --git a/src/core/wee-hook.h b/src/core/wee-hook.h index 0975aef37..26f684b06 100644 --- a/src/core/wee-hook.h +++ b/src/core/wee-hook.h @@ -34,6 +34,7 @@ enum t_hook_type HOOK_TYPE_SIGNAL, /* signal */ HOOK_TYPE_CONFIG, /* config option */ HOOK_TYPE_COMPLETION, /* custom completions */ + HOOK_TYPE_MODIFIER, /* stirng modifier */ /* number of hook types */ HOOK_NUM_TYPES, }; @@ -49,6 +50,7 @@ enum t_hook_type #define HOOK_SIGNAL(hook, var) (((struct t_hook_signal *)hook->hook_data)->var) #define HOOK_CONFIG(hook, var) (((struct t_hook_config *)hook->hook_data)->var) #define HOOK_COMPLETION(hook, var) (((struct t_hook_completion *)hook->hook_data)->var) +#define HOOK_MODIFIER(hook, var) (((struct t_hook_modifier *)hook->hook_data)->var) struct t_hook { @@ -139,7 +141,16 @@ typedef int (t_hook_callback_completion)(void *data, char *completion, struct t_hook_completion { t_hook_callback_completion *callback; /* completion callback */ - char *completion; /* name of completion */ + char *completion; /* name of completion */ +}; + +typedef char *(t_hook_callback_modifier)(void *data, char *modifier, + char *modifier_data, char *string); + +struct t_hook_modifier +{ + t_hook_callback_modifier *callback; /* modifier callback */ + char *modifier; /* name of modifier */ }; /* hook variables */ @@ -203,6 +214,13 @@ extern void hook_completion_exec (struct t_weechat_plugin *plugin, char *completion, struct t_gui_buffer *buffer, struct t_weelist *list); +extern struct t_hook *hook_modifier (struct t_weechat_plugin *plugin, + char *modifier, + t_hook_callback_modifier *callback, + void *callback_data); +extern char *hook_modifier_exec (struct t_weechat_plugin *plugin, + char *modifier, char *modifier_data, + char *string); extern void unhook (struct t_hook *hook); extern void unhook_all_plugin (struct t_weechat_plugin *plugin); extern void unhook_all (); diff --git a/src/core/wee-string.c b/src/core/wee-string.c index 61aacd5ec..b1728d578 100644 --- a/src/core/wee-string.c +++ b/src/core/wee-string.c @@ -47,12 +47,12 @@ /* - * strndup: define strndup function if not existing (FreeBSD and maybe other) + * string_strndup: define strndup function for systems where this function does + * not exist (FreeBSD and maybe other) */ -#ifndef HAVE_STRNDUP char * -strndup (char *string, int length) +string_strndup (char *string, int length) { char *result; @@ -68,7 +68,6 @@ strndup (char *string, int length) return result; } -#endif /* * string_tolower: locale independant string conversion to lower case @@ -337,7 +336,7 @@ string_remove_quotes (char *string, char *quotes) { if (pos_end == (pos_start + 1)) return strdup (""); - return strndup (pos_start + 1, pos_end - pos_start - 1); + return string_strndup (pos_start + 1, pos_end - pos_start - 1); } return strdup (string); diff --git a/src/core/wee-string.h b/src/core/wee-string.h index bcf0efa96..66729f1d2 100644 --- a/src/core/wee-string.h +++ b/src/core/wee-string.h @@ -20,9 +20,7 @@ #ifndef __WEECHAT_STRING_H #define __WEECHAT_STRING_H 1 -#ifndef HAVE_STRNDUP -extern char *strndup (char *string, int length); -#endif +extern char *string_strndup (char *string, int length); extern void string_tolower (char *string); extern void string_toupper (char *string); extern int string_strcasecmp (char *string1, char *string2); diff --git a/src/gui/curses/gui-curses-color.c b/src/gui/curses/gui-curses-color.c index 073fcd74d..cacb8ec46 100644 --- a/src/gui/curses/gui-curses-color.c +++ b/src/gui/curses/gui-curses-color.c @@ -98,7 +98,7 @@ gui_color_get_fg_bg (char *string, char **fg, char **bg) { pos_end_fg--; } - *fg = strndup (string, pos_end_fg - string + 1); + *fg = string_strndup (string, pos_end_fg - string + 1); } else *fg = strudp ("default"); diff --git a/src/gui/curses/gui-curses-main.c b/src/gui/curses/gui-curses-main.c index 793ad9e78..e0f9e2547 100644 --- a/src/gui/curses/gui-curses-main.c +++ b/src/gui/curses/gui-curses-main.c @@ -30,6 +30,7 @@ #include #include "../../core/weechat.h" +#include "../../core/wee-command.h" #include "../../core/wee-config.h" #include "../../core/wee-hook.h" #include "../../core/wee-string.h" @@ -119,7 +120,7 @@ gui_main_init () } /* - * gui_main_quit: quit weechat (signal received) + * gui_main_quit: quit WeeChat */ void @@ -128,6 +129,16 @@ gui_main_quit () quit_weechat = 1; } +/* + * gui_main_reload: reload WeeChat configuration + */ + +void +gui_main_reload () +{ + command_reload (NULL, NULL, 0, NULL, NULL); +} + /* * gui_main_loop: main loop for WeeChat with ncurses GUI */ @@ -147,8 +158,8 @@ gui_main_loop () /* catch SIGTERM signal: quit program */ util_catch_signal (SIGTERM, &gui_main_quit); - /* cach SIGHUP signal: reload configuration */ - util_catch_signal (SIGHUP, &gui_main_quit); + /* catch SIGHUP signal: reload configuration */ + util_catch_signal (SIGHUP, &gui_main_reload); /* catch SIGWINCH signal: redraw screen */ util_catch_signal (SIGWINCH, &gui_window_refresh_screen_sigwinch); diff --git a/src/gui/curses/gui-curses-window.c b/src/gui/curses/gui-curses-window.c index 3742a857f..69af89496 100644 --- a/src/gui/curses/gui-curses-window.c +++ b/src/gui/curses/gui-curses-window.c @@ -24,10 +24,7 @@ #endif #include -#include #include -#include -#include #include "../../core/weechat.h" #include "../../core/wee-config.h" @@ -1334,7 +1331,6 @@ gui_window_refresh_screen_sigwinch () { gui_window_refresh_needed = 1; //gui_window_refresh_screen (0); - signal (SIGWINCH, &gui_window_refresh_screen_sigwinch); } /* diff --git a/src/gui/gui-completion.c b/src/gui/gui-completion.c index fde152aef..20bec9132 100644 --- a/src/gui/gui-completion.c +++ b/src/gui/gui-completion.c @@ -710,8 +710,8 @@ gui_completion_build_list_template (struct t_gui_completion *completion, { if (pos_end > pos) { - custom_completion = strndup (pos, - pos_end - pos); + custom_completion = string_strndup (pos, + pos_end - pos); if (custom_completion) { gui_completion_custom (completion, diff --git a/src/gui/gui-keyboard.c b/src/gui/gui-keyboard.c index 195d12b38..47aec611c 100644 --- a/src/gui/gui-keyboard.c +++ b/src/gui/gui-keyboard.c @@ -405,7 +405,7 @@ gui_keyboard_new (char *key, char *command, t_gui_key_func *function, char *args { length = strlen (args); if ((length > 1) && (args[length - 1] == '"')) - new_key->args = strndup (args + 1, length - 2); + new_key->args = string_strndup (args + 1, length - 2); else new_key->args = strdup (args); } @@ -544,7 +544,7 @@ gui_keyboard_bind (char *key, char *command) { ptr_args = strchr (command, ' '); if (ptr_args) - command2 = strndup (command, ptr_args - command); + command2 = string_strndup (command, ptr_args - command); else command2 = strdup (command); if (command2) diff --git a/src/plugins/alias/alias.c b/src/plugins/alias/alias.c index 7485a04ca..9267f5d7a 100644 --- a/src/plugins/alias/alias.c +++ b/src/plugins/alias/alias.c @@ -309,7 +309,8 @@ alias_new (char *name, char *command) return ptr_alias; } - if ((new_alias = ((struct t_alias *)malloc (sizeof (struct t_alias))))) + new_alias = (struct t_alias *)malloc (sizeof (struct t_alias)); + if (new_alias) { new_hook = weechat_hook_command (name, "[alias]", NULL, NULL, NULL, alias_cb, new_alias); @@ -331,11 +332,9 @@ alias_new (char *name, char *command) else alias_list = new_alias; last_alias = new_alias; - - return new_alias; } - return NULL; + return new_alias; } /* @@ -372,7 +371,7 @@ alias_get_final_command (struct t_alias *alias) } /* - * alias_free: free an alias and reomve it from list + * alias_free: free an alias and remove it from list */ void @@ -390,7 +389,6 @@ alias_free (struct t_alias *alias) } else new_alias_list = alias->next_alias; - if (alias->next_alias) (alias->next_alias)->prev_alias = alias->prev_alias; @@ -402,6 +400,7 @@ alias_free (struct t_alias *alias) if (alias->command) free (alias->command); free (alias); + alias_list = new_alias_list; } @@ -416,6 +415,20 @@ alias_free_all () alias_free (alias_list); } +/* + * alias_config_reaload: reload alias configuration file + */ + +int +alias_config_reload (struct t_config_file *config_file) +{ + /* make C compiler happy */ + (void) config_file; + + alias_free_all (); + return weechat_config_reload (alias_config_file); +} + /* * alias_config_read_line: read an alias in configuration file */ @@ -510,7 +523,8 @@ alias_config_init () { struct t_config_section *ptr_section; - alias_config_file = weechat_config_new (ALIAS_CONFIG_FILENAME); + alias_config_file = weechat_config_new (ALIAS_CONFIG_FILENAME, + &alias_config_reload); if (!alias_config_file) return 0; @@ -537,34 +551,6 @@ alias_config_read () return weechat_config_read (alias_config_file); } -/* - * alias_config_reaload_signal_cb: reload alias configuration file - */ - -int -alias_config_reload_signal_cb (void *data, char *signal, char *type_data, - void *signal_data) -{ - /* make C compiler happy */ - (void) data; - (void) signal; - (void) type_data; - (void) signal_data; - - alias_free_all (); - if (weechat_config_reload (alias_config_file) == 0) - { - weechat_printf (NULL, - _("%s%s: configuration file reloaded"), - weechat_prefix ("info"), "alias"); - return WEECHAT_RC_OK; - } - weechat_printf (NULL, - _("%s%s: failed to reload configuration file"), - weechat_prefix ("error"), "alias"); - return WEECHAT_RC_ERROR; -} - /* * alias_config_write: write alias configuration file */ @@ -651,7 +637,8 @@ alias_command_cb (void *data, struct t_gui_buffer *buffer, int argc, else weechat_printf (NULL, _("No alias defined")); } - return 0; + + return WEECHAT_RC_OK; } /* @@ -755,8 +742,6 @@ weechat_plugin_init (struct t_weechat_plugin *plugin) "%(alias)", &unalias_command_cb, NULL); - weechat_hook_signal ("config_reload", &alias_config_reload_signal_cb, NULL); - weechat_hook_completion ("alias", &alias_completion_cb, NULL); return WEECHAT_RC_OK; @@ -767,8 +752,11 @@ weechat_plugin_init (struct t_weechat_plugin *plugin) */ int -weechat_plugin_end () +weechat_plugin_end (struct t_weechat_plugin *plugin) { + /* make C compiler happy */ + (void) plugin; + alias_config_write (); alias_free_all (); weechat_config_free (alias_config_file); diff --git a/src/plugins/charset/Makefile.am b/src/plugins/charset/Makefile.am index 0f5a770bb..0c73d8057 100644 --- a/src/plugins/charset/Makefile.am +++ b/src/plugins/charset/Makefile.am @@ -20,6 +20,6 @@ libdir = ${weechat_libdir}/plugins lib_LTLIBRARIES = charset.la -charset_la_SOURCES = charset.c +charset_la_SOURCES = charset.c charset.h charset_la_LDFLAGS = -module charset_la_LIBADD = $(CHARSET_LFLAGS) diff --git a/src/plugins/charset/charset.c b/src/plugins/charset/charset.c index 45125307d..10a71af87 100644 --- a/src/plugins/charset/charset.c +++ b/src/plugins/charset/charset.c @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -/* weechat-charset.c: Charset plugin for WeeChat */ +/* charset.c: Charset plugin for WeeChat */ #include @@ -26,6 +26,7 @@ #include #include "../weechat-plugin.h" +#include "charset.h" WEECHAT_PLUGIN_NAME("charset"); @@ -37,176 +38,292 @@ WEECHAT_PLUGIN_LICENSE("GPL"); struct t_weechat_plugin *weechat_charset_plugin = NULL; #define weechat_plugin weechat_charset_plugin -char *weechat_charset_terminal = NULL; -char *weechat_charset_internal = NULL; +struct t_config_file *charset_config_file = NULL; +struct t_charset *charset_list = NULL; +struct t_charset *last_charset = NULL; -/* set to 1 by /charset debug (hidden option) */ -int weechat_charset_debug = 0; +char *charset_terminal = NULL; +char *charset_internal = NULL; + +int charset_debug = 0; /* - * weechat_charset_strndup: define strndup function if not existing - * (FreeBSD and maybe other) + * charset_debug_cb: callback for "debug" signal */ -char * -weechat_charset_strndup (char *string, int length) +int +charset_debug_cb (void *data, char *signal, char *type_data, void *signal_data) +{ + /* make C compiler happy */ + (void) data; + (void) signal; + + if (strcmp (type_data, WEECHAT_HOOK_SIGNAL_STRING) == 0) + { + if (weechat_strcasecmp ((char *)signal_data, "charset") == 0) + charset_debug ^= 1; + } + + return WEECHAT_RC_OK; +} + +/* + * charset_search: search a charset + */ + +struct t_charset * +charset_search (char *name) { - char *result; + struct t_charset *ptr_charset; - if ((int)strlen (string) < length) - return strdup (string); + for (ptr_charset = charset_list; ptr_charset; + ptr_charset = ptr_charset->next_charset) + { + if (strcmp (name, ptr_charset->name) == 0) + return ptr_charset; + } + return NULL; +} + +/* + * charset_new: create new charset and add it to charset list + */ + +struct t_charset * +charset_new (char *name, char *charset) +{ + struct t_charset *new_charset, *ptr_charset; - result = (char *)malloc (length + 1); - if (!result) + if (!name || !name[0] || !charset || !charset[0]) return NULL; - memcpy (result, string, length); - result[length] = '\0'; + ptr_charset = charset_search (name); + if (ptr_charset) + { + if (ptr_charset->charset) + free (ptr_charset->charset); + ptr_charset->charset = strdup (charset); + return ptr_charset; + } + + new_charset = (struct t_charset *)malloc (sizeof (struct t_charset)); + { + new_charset->name = strdup (name); + new_charset->charset = strdup (charset); + + new_charset->prev_charset = last_charset; + new_charset->next_charset = NULL; + if (charset_list) + last_charset->next_charset = new_charset; + else + charset_list = new_charset; + last_charset = new_charset; + } - return result; + return new_charset; } /* - * weechat_charset_default_decode: set "global.decode" option if needed + * charset_free: free a charset and remove it from list */ void -weechat_charset_default_decode (t_weechat_plugin *plugin) +charset_free (struct t_charset *charset) { - char *global_decode; - int rc; - - global_decode = plugin->get_plugin_config (plugin, "global.decode"); - - /* if global decode is not set, we may set it, depending on terminal - charset */ - if (!global_decode || !global_decode[0]) + struct t_charset *new_charset_list; + + /* remove charset from list */ + if (last_charset == charset) + last_charset = charset->prev_charset; + if (charset->prev_charset) { - /* set global decode charset to terminal if different from internal */ - /* otherwise use ISO-8859-1 */ - if (weechat_charset_terminal && weechat_charset_internal - && (strcasecmp (weechat_charset_terminal, - weechat_charset_internal) != 0)) - rc = plugin->set_plugin_config (plugin, - "global.decode", - weechat_charset_terminal); - else - rc = plugin->set_plugin_config (plugin, - "global.decode", - "ISO-8859-1"); - if (rc) - plugin->print_server (plugin, - "Charset: setting \"charset.global.decode\" " - "to %s", - weechat_charset_terminal); - else - plugin->print_server (plugin, - "Charset: failed to set " - "\"charset.global.decode\" option."); + (charset->prev_charset)->next_charset = charset->next_charset; + new_charset_list = charset_list; } - if (global_decode) - free (global_decode); + else + new_charset_list = charset->next_charset; + if (charset->next_charset) + (charset->next_charset)->prev_charset = charset->prev_charset; + + /* free data */ + if (charset->name) + free (charset->name); + if (charset->charset) + free (charset->charset); + free (charset); + + charset_list = new_charset_list; } /* - * weechat_charset_check: check if a charset is valid - * if a charset is NULL, internal charset is used + * charset_free_all: free all charsets */ -int -weechat_charset_check (char *charset) +void +charset_free_all () { - iconv_t cd; + while (charset_list) + charset_free (charset_list); +} - if (!charset || !charset[0]) - return 0; - - cd = iconv_open (charset, weechat_charset_internal); - if (cd == (iconv_t)(-1)) - return 0; +/* + * charset_config_reaload: reload charset configuration file + */ + +int +charset_config_reload (struct t_config_file *config_file) +{ + /* make C compiler happy */ + (void) config_file; - iconv_close (cd); - return 1; + charset_free_all (); + return weechat_config_reload (charset_config_file); } /* - * weechat_charset_get_config: read a charset in config file - * we first in this order: channel, server, global + * charset_config_read_line: read a charset in configuration file */ -char * -weechat_charset_get_config (t_weechat_plugin *plugin, - char *type, char *server, char *channel) +void +charset_config_read_line (struct t_config_file *config_file, char *option_name, + char *value) { - static char option[1024]; - char *value; - - /* we try channel first */ - if (server && channel) - { - snprintf (option, sizeof (option) - 1, "%s.%s.%s", type, - server, channel); - value = plugin->get_plugin_config (plugin, option); - if (value && value[0]) - return value; - if (value) - free (value); - } + /* make C compiler happy */ + (void) config_file; - /* channel not found, we try server only */ - if (server) + if (option_name && value) { - snprintf (option, sizeof (option) - 1, "%s.%s", type, server); - value = plugin->get_plugin_config (plugin, option); - if (value && value[0]) - return value; - if (value) - free (value); + /* create new charset */ + if (!charset_new (option_name, value)) + { + weechat_printf (NULL, + _("%s%s: error creating charset \"%s\" => \"%s\""), + weechat_prefix ("error"), "charset", + option_name, value); + } } +} + +/* + * charseet_config_write_section: write charset section in configuration file + * Return: 0 = successful + * -1 = write error + */ + +void +charset_config_write_section (struct t_config_file *config_file, + char *section_name) +{ + struct t_charset *ptr_charset; - /* nothing found, we try global charset */ - snprintf (option, sizeof (option) - 1, "global.%s", type); - value = plugin->get_plugin_config (plugin, option); - if (value && value[0]) - return value; - if (value) - free (value); + weechat_config_write_line (config_file, section_name, NULL); - /* nothing found => no decode/encode for this message! */ - return NULL; + for (ptr_charset = charset_list; ptr_charset; + ptr_charset = ptr_charset->next_charset) + { + weechat_config_write_line (config_file, + ptr_charset->name, + "\"%s\"", + ptr_charset->charset); + } } /* - * weechat_charset_set_config: set a charset in config file + * charset_config_write_default_aliases: write default charsets in configuration file */ void -weechat_charset_set_config (t_weechat_plugin *plugin, - char *type, char *server, char *channel, - char *value) +charset_config_write_default_charsets (struct t_config_file *config_file, + char *section_name) { - static char option[1024]; - - if (server && channel) - snprintf (option, sizeof (option) - 1, "%s.%s.%s", type, - server, channel); - else if (server) - snprintf (option, sizeof (option) - 1, "%s.%s", type, server); + weechat_config_write_line (config_file, section_name, NULL); + + if (charset_terminal && charset_internal + && (strcasecmp (charset_terminal, + charset_internal) != 0)) + weechat_config_write_line (config_file, "decode", "%s", charset_terminal); else - return; + weechat_config_write_line (config_file, "decode", "%s", "iso-8859-1"); +} + +/* + * charset_config_init: init charset configuration file + * return: 1 if ok, 0 if error + */ + +int +charset_config_init () +{ + struct t_config_section *ptr_section; + + charset_config_file = weechat_config_new (CHARSET_CONFIG_FILENAME, + &charset_config_reload); + if (!charset_config_file) + return 0; + + ptr_section = weechat_config_new_section (charset_config_file, "charset", + charset_config_read_line, + charset_config_write_section, + charset_config_write_default_charsets); + if (!ptr_section) + { + weechat_config_free (charset_config_file); + return 0; + } + + return 1; +} + +/* + * charset_config_read: read charset configuration file + */ + +int +charset_config_read () +{ + return weechat_config_read (charset_config_file); +} + +/* + * charset_config_write: write charset configuration file + */ - plugin->set_plugin_config (plugin, option, value); +int +charset_config_write () +{ + return weechat_config_write (charset_config_file); } /* - * weechat_charset_parse_irc_msg: return nick, command, channel and position - * of arguments in IRC message + * charset_check: check if a charset is valid + * return 1 if charset is valid, 0 if not valid + */ + +int +charset_check (char *charset) +{ + iconv_t cd; + + if (!charset || !charset[0]) + return 0; + + cd = iconv_open (charset, charset_internal); + if (cd == (iconv_t)(-1)) + return 0; + + iconv_close (cd); + return 1; +} + +/* + * charset_parse_irc_msg: return nick, command, channel and position + * of arguments in IRC message */ void -weechat_charset_parse_irc_msg (char *message, char **nick, char **command, - char **channel, char **pos_args) +charset_parse_irc_msg (char *message, char **nick, char **command, + char **channel, char **pos_args) { char *pos, *pos2, *pos3, *pos4, *pos_tmp; @@ -223,12 +340,12 @@ weechat_charset_parse_irc_msg (char *message, char **nick, char **command, pos_tmp[0] = '\0'; pos2 = strchr (pos, '!'); if (pos2) - *nick = weechat_charset_strndup (pos, pos2 - pos); + *nick = weechat_strndup (pos, pos2 - pos); else { pos2 = strchr (pos, ' '); if (pos2) - *nick = weechat_charset_strndup (pos, pos2 - pos); + *nick = weechat_strndup (pos, pos2 - pos); } if (pos_tmp) pos_tmp[0] = ' '; @@ -246,7 +363,7 @@ weechat_charset_parse_irc_msg (char *message, char **nick, char **command, pos2 = strchr (pos, ' '); if (pos2) { - *command = weechat_charset_strndup (pos, pos2 - pos); + *command = weechat_strndup (pos, pos2 - pos); pos2++; while (pos2[0] == ' ') pos2++; @@ -258,7 +375,7 @@ weechat_charset_parse_irc_msg (char *message, char **nick, char **command, { pos3 = strchr (pos2, ' '); if (pos3) - *channel = weechat_charset_strndup (pos2, pos3 - pos2); + *channel = weechat_strndup (pos2, pos3 - pos2); else *channel = strdup (pos2); } @@ -268,8 +385,7 @@ weechat_charset_parse_irc_msg (char *message, char **nick, char **command, if (!*nick) { if (pos3) - *nick = weechat_charset_strndup (pos2, - pos3 - pos2); + *nick = weechat_strndup (pos2, pos3 - pos2); else *nick = strdup (pos2); } @@ -283,8 +399,7 @@ weechat_charset_parse_irc_msg (char *message, char **nick, char **command, { pos4 = strchr (pos3, ' '); if (pos4) - *channel = weechat_charset_strndup (pos3, - pos4 - pos3); + *channel = weechat_strndup (pos3, pos4 - pos3); else *channel = strdup (pos3); } @@ -296,390 +411,297 @@ weechat_charset_parse_irc_msg (char *message, char **nick, char **command, } /* - * weechat_charset_irc_in: transform charset for incoming messages - * convert from any charset to WeeChat internal + * charset_set: set a charset + * return 1 if ok, 0 if error */ -char * -weechat_charset_irc_in (t_weechat_plugin *plugin, int argc, char **argv, - char *handler_args, void *handler_pointer) +int +charset_set (char *name, char *charset) { - char *nick, *command, *channel, *charset, *ptr_args; - char *output; - - /* make C compiler happy */ - (void) argc; - (void) handler_args; - (void) handler_pointer; - - output = NULL; - - weechat_charset_parse_irc_msg (argv[1], &nick, &command, &channel, - &ptr_args); - - charset = weechat_charset_get_config (plugin, - "decode", argv[0], - (channel) ? channel : nick); - - if (weechat_charset_debug) - plugin->print(plugin, NULL, NULL, - "Charset IN: srv='%s', nick='%s', chan='%s', " - "msg='%s', ptr_args='%s' => charset: %s", - argv[0], nick, channel, argv[1], ptr_args, charset); + struct t_charset *ptr_charset; - if (charset) + if (charset && charset[0]) { - output = plugin->iconv_to_internal (plugin, charset, argv[1]); - if (charset) - free (charset); + if (charset_new (name, charset)) + { + weechat_printf (NULL, + _("%sCharset \"%s\" => \"%s\""), + weechat_prefix ("info"), name, charset); + } + else + { + weechat_printf (NULL, + _("%s%s: error creating charset \"%s\" " + "=> \"%s\""), + weechat_prefix ("error"), "charset", name, charset); + return 0; + } + } + else + { + ptr_charset = charset_search (name); + if (!ptr_charset) + { + weechat_printf (NULL, + _("%s%s: charset \"%s\" not found"), + weechat_prefix ("error"), "charset", name); + return 0; + } + charset_free (ptr_charset); + weechat_printf (NULL, + _("%sCharset \"%s\" removed"), + weechat_prefix ("info"), name); } - if (nick) - free (nick); - if (command) - free (command); - if (channel) - free (channel); - - return output; + return 1; } /* - * weechat_charset_irc_out: transform charset for outgoing messages - * convert from WeeChat internal charset to other + * charset_get: read a charset in config file + * type is "decode" or "encode" + * we first try with all arguments, then remove one by one + * to find charset (from specific to general charset) */ char * -weechat_charset_irc_out (t_weechat_plugin *plugin, int argc, char **argv, - char *handler_args, void *handler_pointer) +charset_get (char *type, char *name) { - char *nick, *command, *channel, *charset, *ptr_args; - char *output; - - /* make C compiler happy */ - (void) argc; - (void) handler_args; - (void) handler_pointer; - - output = NULL; - - weechat_charset_parse_irc_msg (argv[1], &nick, &command, &channel, - &ptr_args); - - charset = weechat_charset_get_config (plugin, - "encode", argv[0], - (channel) ? channel : nick); - - if (weechat_charset_debug) - plugin->print(plugin, NULL, NULL, - "Charset OUT: srv='%s', nick='%s', chan='%s', " - "msg='%s', ptr_args='%s' => charset: %s", - argv[0], nick, channel, argv[1], ptr_args, charset); + char *option_name, *ptr_end; + struct t_charset *ptr_charset; + int length; - if (charset) + length = strlen (type) + 1 + strlen (name) + 1; + option_name = (char *)malloc (length); + if (option_name) { - output = plugin->iconv_from_internal (plugin, charset, argv[1]); - if (charset) - free (charset); + snprintf (option_name, length, "%s.%s", + type, name); + ptr_end = option_name + strlen (option_name); + while (ptr_end >= option_name) + { + ptr_charset = charset_search (option_name); + if (ptr_charset) + { + free (option_name); + return ptr_charset->charset; + } + ptr_end--; + while ((ptr_end >= option_name) && (ptr_end[0] != '.')) + { + ptr_end--; + } + if ((ptr_end >= option_name) && (ptr_end[0] == '.')) + ptr_end[0] = '\0'; + } + ptr_charset = charset_search (option_name); + + free (option_name); + + if (ptr_charset) + return ptr_charset->charset; } - if (nick) - free (nick); - if (command) - free (command); - if (channel) - free (channel); - - return output; + /* nothing found => no decode/encode for this message! */ + return NULL; } /* - * weechat_charset_display: display charsets (global/server/channel) + * charset_decode: decode a string with a charset to internal charset */ -void -weechat_charset_display (t_weechat_plugin *plugin, - int display_on_server, char *server, char *channel) +char * +charset_decode (void *data, char *modifier, char *modifier_data, + char *string) { - char *decode, *encode; - static char option[1024]; - - decode = NULL; - encode = NULL; + char *charset; - /* display global settings */ - if (!server && !channel) - { - decode = plugin->get_plugin_config (plugin, "global.decode"); - encode = plugin->get_plugin_config (plugin, "global.encode"); - - if (display_on_server) - plugin->print_server (plugin, - "Charset: global charsets: decode = %s, " - "encode = %s", - (decode) ? decode : "(none)", - (encode) ? encode : "(none)"); - else - plugin->print (plugin, NULL, NULL, - "Charset: global charsets: decode = %s, " - "encode = %s", - (decode) ? decode : "(none)", - (encode) ? encode : "(none)"); - } - - /* display server settings */ - if (server && !channel) - { - snprintf (option, sizeof (option) - 1, "decode.%s", server); - decode = plugin->get_plugin_config (plugin, option); - snprintf (option, sizeof (option) - 1, "encode.%s", server); - encode = plugin->get_plugin_config (plugin, option); - - if (display_on_server) - plugin->print_server (plugin, - "Charset: decode / encode charset for " - "server %s: %s / %s", - server, - (decode) ? decode : "(none)", - (encode) ? encode : "(none)"); - else - plugin->print (plugin, NULL, NULL, - "Charset: decode / encode charset for server %s: " - "%s / %s", - server, - (decode) ? decode : "(none)", - (encode) ? encode : "(none)"); - } + /* make C compiler happy */ + (void) data; + (void) modifier; - /* display chan/nick settings */ - if (server && channel) - { - snprintf (option, sizeof (option) - 1, - "decode.%s.%s", server, channel); - decode = plugin->get_plugin_config (plugin, option); - snprintf (option, sizeof (option) - 1, - "encode.%s.%s", server, channel); - encode = plugin->get_plugin_config (plugin, option); - - if (display_on_server) - plugin->print_server (plugin, - "Charset: decode / encode charset for " - "%s/%s: %s / %s", - server, channel, - (decode) ? decode : "(none)", - (encode) ? encode : "(none)"); - else - plugin->print (plugin, NULL, NULL, - "Charset: decode / encode charset for %s/%s: " - "%s / %s", - server, channel, - (decode) ? decode : "(none)", - (encode) ? encode : "(none)"); - } + charset = charset_get ("decode", modifier_data); + if (charset && charset[0]) + return weechat_iconv_to_internal (charset, string); - if (decode) - free (decode); - if (encode) - free (encode); + return NULL; } /* - * weechat_charset_cmd: /charset command + * charset_encode: encode a string from internal charset to another one */ -int -weechat_charset_cmd (t_weechat_plugin *plugin, - int cmd_argc, char **cmd_argv, - char *handler_args, void *handler_pointer) +char * +charset_encode (void *data, char *modifier, char *modifier_data, + char *string) { - int argc; - char **argv, *server, *channel; - - if (cmd_argc < 3) - return PLUGIN_RC_KO; + char *charset; /* make C compiler happy */ - (void) handler_args; - (void) handler_pointer; + (void) data; + (void) modifier; - if (cmd_argv[2]) - argv = plugin->explode_string (plugin, cmd_argv[2], " ", 0, &argc); - else - { - argv = NULL; - argc = 0; - } + charset = charset_get ("encode", modifier_data); + if (charset && charset[0]) + return weechat_iconv_from_internal (charset, string); - /* get command context */ - server = plugin->get_info (plugin, "server", NULL); - channel = plugin->get_info (plugin, "channel", NULL); + return NULL; +} + +/* + * charset_command_cb: callback for /charset command + */ + +int +charset_command_cb (void *data, struct t_gui_buffer *buffer, int argc, + char **argv, char **argv_eol) +{ + int charset_found, length, rc; + struct t_charset *ptr_charset; + char *option_name, *ptr_value; - switch (argc) + /* make C compiler happy */ + (void) data; + (void) buffer; + + if ((argc > 2) && (strcmp (argv[2], "=") == 0)) { - case 0: - plugin->print_server (plugin, ""); - weechat_charset_display (plugin, 1, NULL, NULL); - weechat_charset_display (plugin, 1, server, NULL); - if (channel) - weechat_charset_display (plugin, 1, server, channel); - break; - case 1: - if (strcasecmp (argv[0], "decode") == 0) - { - weechat_charset_set_config (plugin, "decode", - server, channel, NULL); - weechat_charset_display (plugin, 0, server, channel); - } - else if (strcasecmp (argv[0], "encode") == 0) - { - weechat_charset_set_config (plugin, "encode", - server, channel, NULL); - weechat_charset_display (plugin, 0, server, channel); - } - else if (strcasecmp (argv[0], "debug") == 0) - { - weechat_charset_debug ^= 1; - plugin->print (plugin, NULL, NULL, - "Charset: debug [%s].", - (weechat_charset_debug) ? "ON" : "off"); - } - else if (strcasecmp (argv[0], "reset") == 0) + ptr_value = (argc > 3) ? argv_eol[3] : NULL; + if ((weechat_strncasecmp (argv[1], "decode.", 7) != 0) + && (weechat_strncasecmp (argv[1], "encode.", 7) != 0)) + { + length = strlen (argv[1]) + strlen ("decode.") + 1; + option_name = (char *)malloc (length); + if (option_name) { - weechat_charset_set_config (plugin, "decode", - server, channel, NULL); - weechat_charset_set_config (plugin, "encode", - server, channel, NULL); - weechat_charset_display (plugin, 0, server, channel); + rc = 1; + snprintf (option_name, length, "decode.%s", argv[1]); + if (!charset_set (option_name, ptr_value)) + rc = 0; + snprintf (option_name, length, "encode.%s", argv[1]); + if (!charset_set (option_name, ptr_value)) + rc = 0; + if (!rc) + return WEECHAT_RC_ERROR; } + } + else + { + if (!charset_set (argv[1], ptr_value)) + return WEECHAT_RC_ERROR; + } + } + else + { + /* list all charsets */ + if (charset_list) + { + weechat_printf (NULL, ""); + if (argc == 1) + weechat_printf (NULL, _("List of charsets:")); else + weechat_printf (NULL, _("List of charsets with \"%s\":"), + argv_eol[1]); + charset_found = 0; + for (ptr_charset = charset_list; ptr_charset; + ptr_charset = ptr_charset->next_charset) { - if (!weechat_charset_check (argv[0])) - plugin->print_server (plugin, - "Charset error: invalid charset " - "\"%s\"", - argv[0]); - else - { - weechat_charset_set_config (plugin, "decode", - server, channel, argv[0]); - weechat_charset_set_config (plugin, "encode", - server, channel, argv[0]); - weechat_charset_display (plugin, 0, server, channel); - } - } - break; - case 2: - if (!weechat_charset_check (argv[1])) - plugin->print_server (plugin, - "Charset error: invalid charset \"%s\"", - argv[1]); - else - { - if (strcasecmp (argv[0], "decode") == 0) - { - weechat_charset_set_config (plugin, "decode", - server, channel, argv[1]); - weechat_charset_display (plugin, 0, server, channel); - } - else if (strcasecmp (argv[0], "encode") == 0) + if ((argc < 2) + || (weechat_strcasestr (ptr_charset->name, argv_eol[1]))) { - weechat_charset_set_config (plugin, "encode", - server, channel, argv[1]); - weechat_charset_display (plugin, 0, server, channel); + charset_found = 1; + weechat_printf (NULL, + " %s %s=>%s %s", + ptr_charset->name, + weechat_color ("color_chat_delimiters"), + weechat_color ("color_chat"), + ptr_charset->charset); } - else - plugin->print_server (plugin, - "Charset error: unknown option " - "\"%s\"", - argv[0]); } - break; + if (!charset_found) + weechat_printf (NULL, _("No charset found")); + } + else + weechat_printf (NULL, _("No charset defined")); } - - if (argv) - plugin->free_exploded_string (plugin, argv); - if (server) - free (server); - if (channel) - free (channel); - return PLUGIN_RC_OK; + return WEECHAT_RC_OK; } - + /* * weechat_plugin_init: init charset plugin */ int -weechat_plugin_init (t_weechat_plugin *plugin) +weechat_plugin_init (struct t_weechat_plugin *plugin) { - t_plugin_modifier *msg_irc_in, *msg_irc_out; - t_plugin_handler *cmd_handler; - weechat_plugin = plugin; - + /* get terminal & internal charsets */ - weechat_charset_terminal = plugin->get_info (plugin, "charset_terminal", - NULL); - weechat_charset_internal = plugin->get_info (plugin, "charset_internal", - NULL); - + charset_terminal = weechat_info_get ("charset_terminal"); + charset_internal = weechat_info_get ("charset_internal"); + /* display message */ - plugin->print_server (plugin, - "Charset plugin starting, terminal charset: " - "%s (WeeChat internal: %s)", - weechat_charset_terminal, weechat_charset_internal); + weechat_printf (NULL, + _("%s%s: terminal: %s, internal: %s"), + weechat_prefix ("info"), "charset", + charset_terminal, charset_internal); - /* set global default decode charset */ - weechat_charset_default_decode (plugin); + if (!charset_config_init ()) + { + weechat_printf (NULL, + _("%s%s: error creating configuration file \"%s\""), + weechat_prefix("error"), "charset", + CHARSET_CONFIG_FILENAME); + return WEECHAT_RC_ERROR; + } + charset_config_read (); /* add command handler */ - cmd_handler = plugin->cmd_handler_add (plugin, "charset", - "Charset management by server or " - "channel", - "[[decode | encode] charset] | " - "[reset]", - " decode: set a decoding charset " - "for server/channel\n" - " encode: set an encofing charset " - "for server/channel\n" - "charset: the charset for decoding " - "or encoding messages\n" - " reset: reset charsets for " - "server/channel\n\n" - "To set global decode/encode " - "charset (for all servers), use " - "/setp charset.global.decode " - "or /setp charset.global.encode\n" - "To see all charsets for all " - "servers, use /setp charset", - "decode|encode|reset", - &weechat_charset_cmd, - NULL, NULL); - - /* add messge modifier */ - msg_irc_in = plugin->modifier_add (plugin, "irc_in", "*", - &weechat_charset_irc_in, - NULL, NULL); - msg_irc_out = plugin->modifier_add (plugin, "irc_out", "*", - &weechat_charset_irc_out, - NULL, NULL); - - return PLUGIN_RC_OK; + weechat_hook_command ("charset", + _("manage charsets"), + _("[[type.]plugin.string [= charset]]"), + _(" type: \"decode\" or \"encode\" (if type is " + "omitted, then both \"decode\" and \"encode\" are " + "set)\n" + " plugin: plugin name\n" + " string: string specific to plugin (for example " + "a server name or server.channel for IRC plugin)\n" + "charset: charset to use (if empty, then charset " + "is removed)\n\n" + "Examples :\n" + "/charset decode iso-8859-15 => set global " + "decode charset to iso-8859-15\n" + "/charset encode iso-8859-15 => set global " + "encode charset to iso-8859-15\n" + "/charset decode.irc.freenode => set decode " + "charset to iso-8859-15 for IRC server " + "\"freenode\" (all channels)\n" + "/charset decode.irc.freenode.#weechat => set " + "decode charset to iso-8859-15 for IRC channel " + "\"#weechat\" on server \"freenode\""), + "%(charset_name) %(charset)", + &charset_command_cb, NULL); + + /* add messge modifiers */ + weechat_hook_modifier ("charset_decode", &charset_decode, NULL); + weechat_hook_modifier ("charset_encode", &charset_encode, NULL); + + return WEECHAT_RC_OK; } /* * weechat_plugin_end: end charset plugin */ -void -weechat_plugin_end (t_weechat_plugin *plugin) +int +weechat_plugin_end (struct t_weechat_plugin *plugin) { /* make C compiler happy */ (void) plugin; - if (weechat_charset_terminal) - free (weechat_charset_terminal); - if (weechat_charset_internal) - free (weechat_charset_internal); + charset_config_write (); + charset_free_all (); + weechat_config_free (charset_config_file); + + return WEECHAT_RC_OK; } diff --git a/src/plugins/charset/charset.h b/src/plugins/charset/charset.h new file mode 100644 index 000000000..248972587 --- /dev/null +++ b/src/plugins/charset/charset.h @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2003-2008 by FlashCode + * See README for License detail, AUTHORS for developers list. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + + +#ifndef __WEECHAT_CHARSET_H +#define __WEECHAT_CHARSET_H 1 + +#define CHARSET_CONFIG_FILENAME "charset.rc" + +struct t_charset +{ + char *name; /* charset name (identifier) */ + char *charset; /* charset value for name */ + struct t_charset *prev_charset; /* link to previous charset */ + struct t_charset *next_charset; /* link to next charset */ +}; + +#endif /* charset.h */ diff --git a/src/plugins/demo/demo.c b/src/plugins/demo/demo.c index 8535963b6..16c991553 100644 --- a/src/plugins/demo/demo.c +++ b/src/plugins/demo/demo.c @@ -387,7 +387,10 @@ weechat_plugin_init (struct t_weechat_plugin *plugin) */ int -weechat_plugin_end () +weechat_plugin_end (struct t_weechat_plugin *plugin) { + /* make C compiler happy */ + (void) plugin; + return WEECHAT_RC_OK; } diff --git a/src/plugins/fifo/fifo.c b/src/plugins/fifo/fifo.c index 5cd3187cb..5dae603a6 100644 --- a/src/plugins/fifo/fifo.c +++ b/src/plugins/fifo/fifo.c @@ -368,8 +368,11 @@ weechat_plugin_init (struct t_weechat_plugin *plugin) */ int -weechat_plugin_end () +weechat_plugin_end (struct t_weechat_plugin *plugin) { + /* make C compiler happy */ + (void) plugin; + fifo_remove (); return WEECHAT_RC_OK; diff --git a/src/plugins/irc/irc-config.c b/src/plugins/irc/irc-config.c index f163e84a9..ff56751be 100644 --- a/src/plugins/irc/irc-config.c +++ b/src/plugins/irc/irc-config.c @@ -207,6 +207,64 @@ irc_config_change_notify_levels () { } +/* + * irc_config_reload: reload IRC configuration file + */ + +int +irc_config_reload (struct t_config_file *config_file) +{ + struct t_irc_server *ptr_server, *next_server; + int rc; + + /* make C compiler happy */ + (void) config_file; + + irc_config_server = NULL; + irc_config_reload_flag = 1; + for (ptr_server = irc_servers; ptr_server; + ptr_server = ptr_server->next_server) + { + ptr_server->reloaded_from_config = 0; + } + + rc = weechat_config_reload (irc_config_file); + + if (rc == 0) + { + + if (irc_config_server) + irc_server_init_with_config_options (irc_config_server, + irc_config_section_server, + irc_config_reload_flag); + + ptr_server = irc_servers; + while (ptr_server) + { + next_server = ptr_server->next_server; + + if (!ptr_server->reloaded_from_config) + { + if (ptr_server->is_connected) + { + weechat_printf (NULL, + _("%s%s: warning: server \"%s\" not found " + "in configuration file, not deleted in " + "memory because it's currently used"), + weechat_prefix ("error"), "irc", + ptr_server->name); + } + else + irc_server_free (ptr_server); + } + + ptr_server = next_server; + } + } + + return rc; +} + /* * irc_config_read_server_line: read a server line in configuration file */ @@ -410,7 +468,8 @@ irc_config_init () { struct t_config_section *ptr_section; - irc_config_file = weechat_config_new (IRC_CONFIG_FILENAME); + irc_config_file = weechat_config_new (IRC_CONFIG_FILENAME, + &irc_config_reload); if (!irc_config_file) return 0; @@ -726,74 +785,6 @@ irc_config_read () return rc; } -/* - * irc_config_reload_cb: read IRC configuration file - */ - -int -irc_config_reload_cb (void *data, char *event, void *pointer) -{ - struct t_irc_server *ptr_server, *next_server; - int rc; - - /* make C compiler happy */ - (void) data; - (void) event; - (void) pointer; - - irc_config_server = NULL; - irc_config_reload_flag = 1; - for (ptr_server = irc_servers; ptr_server; - ptr_server = ptr_server->next_server) - { - ptr_server->reloaded_from_config = 0; - } - - rc = weechat_config_reload (irc_config_file); - - if (rc == 0) - { - - if (irc_config_server) - irc_server_init_with_config_options (irc_config_server, - irc_config_section_server, - irc_config_reload_flag); - - ptr_server = irc_servers; - while (ptr_server) - { - next_server = ptr_server->next_server; - - if (!ptr_server->reloaded_from_config) - { - if (ptr_server->is_connected) - { - weechat_printf (NULL, - _("%s%s: warning: server \"%s\" not found " - "in configuration file. It has not been " - "deleted because it's used now."), - weechat_prefix ("info"), "irc", - ptr_server->name); - } - else - irc_server_free (ptr_server); - } - - ptr_server = next_server; - } - - weechat_printf (NULL, - _("%s%s: configuration file reloaded"), - weechat_prefix ("info"), "irc"); - return WEECHAT_RC_OK; - } - - weechat_printf (NULL, - _("%s%s: failed to reload configuration file"), - weechat_prefix ("error"), "irc"); - return WEECHAT_RC_ERROR; -} - /* * irc_config_write: write IRC configuration file * return: 0 if ok diff --git a/src/plugins/irc/irc-config.h b/src/plugins/irc/irc-config.h index d44968587..8127bd6d2 100644 --- a/src/plugins/irc/irc-config.h +++ b/src/plugins/irc/irc-config.h @@ -69,7 +69,6 @@ struct t_config_option *irc_config_log_hide_nickserv_pwd; int irc_config_init (); int irc_config_read (); -int irc_config_reload_cb (); int irc_config_write (); #endif /* irc-config.h */ diff --git a/src/plugins/irc/irc-protocol.c b/src/plugins/irc/irc-protocol.c index 07c3f0f46..1b63781d9 100644 --- a/src/plugins/irc/irc-protocol.c +++ b/src/plugins/irc/irc-protocol.c @@ -499,7 +499,7 @@ irc_protocol_recv_command (struct t_irc_server *server, char *entire_line, if (!command) return -2; - + /* look for IRC command */ cmd_found = -1; for (i = 0; irc_protocol_messages[i].name; i++) diff --git a/src/plugins/irc/irc-protocol.h b/src/plugins/irc/irc-protocol.h index 64c725ede..84fe84f08 100644 --- a/src/plugins/irc/irc-protocol.h +++ b/src/plugins/irc/irc-protocol.h @@ -37,8 +37,8 @@ struct t_irc_protocol_msg t_irc_recv_func2 *recv_function2; /* function called when msg is received */ }; -extern int irc_protocol_is_highlight (char *, char *); -extern int irc_protocol_recv_command (struct t_irc_server *, char *, char *, char *, char *); +extern int irc_protocol_is_highlight (char *message, char *nick); +extern int irc_protocol_recv_command (struct t_irc_server *server, char *entire_line, char *host, char *command, char *arguments); extern int irc_protocol_cmd_error (struct t_irc_server *server, int argc, char **argv, char **argv_eol, int ignore, int highlight); extern int irc_protocol_cmd_invite (struct t_irc_server *server, int argc, char **argv, char **argv_eol, int ignore, int highlight); extern int irc_protocol_cmd_join (struct t_irc_server *server, int argc, char **argv, char **argv_eol, int ignore, int highlight); diff --git a/src/plugins/irc/irc-server.c b/src/plugins/irc/irc-server.c index 3c8c9297c..2d22f6cf9 100644 --- a/src/plugins/irc/irc-server.c +++ b/src/plugins/irc/irc-server.c @@ -986,24 +986,33 @@ irc_server_sendf (struct t_irc_server *server, char *format, ...) /* * irc_server_parse_message: parse IRC message and return pointer to - * host, command and arguments (if any) + * host, command, channel, target nick and arguments + * (if any) */ void -irc_server_parse_message (char *message, char **host, char **command, char **args) +irc_server_parse_message (char *message, char **nick, char **host, + char **command, char **channel, char **arguments) { - char *pos, *pos2; + char *pos, *pos2, *pos3, *pos4; + *nick = NULL; *host = NULL; *command = NULL; - *args = NULL; + *channel = NULL; + *arguments = NULL; if (message[0] == ':') { + pos2 = strchr (message, '!'); pos = strchr (message, ' '); + if (pos2) + *nick = weechat_strndup (message + 1, pos2 - (message + 1)); + else if (pos) + *nick = weechat_strndup (message + 1, pos - (message + 1)); if (pos) { - *host = strndup (message + 1, pos - (message + 1)); + *host = weechat_strndup (message + 1, pos - (message + 1)); pos++; } else @@ -1019,11 +1028,47 @@ irc_server_parse_message (char *message, char **host, char **command, char **arg pos2 = strchr (pos, ' '); if (pos2) { - *command = strndup (pos, pos2 - pos); + *command = weechat_strndup (pos, pos2 - pos); pos2++; while (pos2[0] == ' ') pos2++; - *args = strdup (pos2); + *arguments = strdup (pos2); + if (pos2[0] != ':') + { + if (irc_channel_is_channel (pos2)) + { + pos3 = strchr (pos2, ' '); + if (pos3) + *channel = weechat_strndup (pos2, pos3 - pos2); + else + *channel = strdup (pos2); + } + else + { + pos3 = strchr (pos2, ' '); + if (!*nick) + { + if (pos3) + *nick = weechat_strndup (pos2, pos3 - pos2); + else + *nick = strdup (pos2); + } + if (pos3) + { + pos3++; + while (pos3[0] == ' ') + pos3++; + if (irc_channel_is_channel (pos3)) + { + pos4 = strchr (pos3, ' '); + if (pos4) + *channel = weechat_strndup (pos3, pos4 - pos3); + else + *channel = strdup (pos3); + } + } + } + } } } } @@ -1171,7 +1216,9 @@ irc_server_msgq_flush () { struct t_irc_message *next; char *ptr_data, *new_msg, *ptr_msg, *pos; - char *host, *command, *args; + char *nick, *host, *command, *channel, *arguments, *msg_decoded; + char *modifier_data, *ptr_chan_nick; + int length; while (irc_recv_msgq) { @@ -1220,17 +1267,48 @@ irc_server_msgq_flush () pos = strchr (ptr_msg, '\n'); if (pos) pos[0] = '\0'; - + //if (new_msg) // gui_chat_printf_raw_data (irc_recv_msgq->server, // 0, 1, ptr_msg); - irc_server_parse_message (ptr_msg, &host, - &command, &args); + irc_server_parse_message (ptr_msg, &nick, &host, + &command, &channel, + &arguments); + /* convert charset for message */ + msg_decoded = NULL; + ptr_chan_nick = (channel) ? channel : nick; + length = strlen (weechat_plugin->name) + 1 + + strlen (irc_recv_msgq->server->name) + 1 + + ((ptr_chan_nick) ? strlen (ptr_chan_nick) : 0) + 1; + modifier_data = (char *)malloc (length); + if (modifier_data) + { + if (ptr_chan_nick) + { + snprintf (modifier_data, length, "%s.%s.%s", + weechat_plugin->name, + irc_recv_msgq->server->name, + ptr_chan_nick); + } + else + { + snprintf (modifier_data, length, "%s.%s.%s", + weechat_plugin->name, + irc_recv_msgq->server->name, + ptr_chan_nick); + } + msg_decoded = weechat_hook_modifier_exec ("charset_decode", + modifier_data, + ptr_msg); + free (modifier_data); + } switch (irc_protocol_recv_command (irc_recv_msgq->server, - ptr_msg, - host, command, args)) + (msg_decoded) ? + msg_decoded : ptr_msg, + host, command, + arguments)) { case -1: weechat_printf (irc_recv_msgq->server->buffer, @@ -1251,9 +1329,9 @@ irc_server_msgq_flush () _("%s%s: unknown command: " "cmd=\"%s\", " "host=\"%s\", " - "args=\"%s\""), + "arguments=\"%s\""), weechat_prefix ("error"), - "irc", command, host, args); + "irc", command, host, arguments); break; } @@ -1261,8 +1339,8 @@ irc_server_msgq_flush () free (host); if (command) free (command); - if (args) - free (args); + if (arguments) + free (arguments); if (pos) { diff --git a/src/plugins/irc/irc-server.h b/src/plugins/irc/irc-server.h index 63f539dea..c893dbcd7 100644 --- a/src/plugins/irc/irc-server.h +++ b/src/plugins/irc/irc-server.h @@ -161,8 +161,9 @@ extern int irc_server_send (struct t_irc_server *server, char *buffer, int size_buf); extern void irc_server_outqueue_send (struct t_irc_server *server); extern void irc_server_sendf (struct t_irc_server *server, char *format, ...); -extern void irc_server_parse_message (char *message, char **host, - char **command, char **args); +extern void irc_server_parse_message (char *message, char **nick, + char **host, char **command, + char **channel, char **arguments); extern int irc_server_recv_cb (void *arg_server); extern void irc_server_timer_cb (void *empty); extern void irc_server_timer_check_away (void *empty); diff --git a/src/plugins/irc/irc.c b/src/plugins/irc/irc.c index 34d6da91c..990475113 100644 --- a/src/plugins/irc/irc.c +++ b/src/plugins/irc/irc.c @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -/* irc-core.c: main IRC functions */ +/* irc.c: IRC plugin for WeeChat */ #ifdef HAVE_CONFIG_H @@ -185,7 +185,6 @@ weechat_plugin_init (struct t_weechat_plugin *plugin) /* hook signals */ weechat_hook_signal ("dump_data", &irc_dump_data_cb, NULL); - weechat_hook_signal ("config_reload", &irc_config_reload_cb, NULL); weechat_hook_signal ("quit", &irc_quit_cb, NULL); weechat_hook_signal ("debug", &irc_debug_cb, NULL); @@ -213,8 +212,11 @@ weechat_plugin_init (struct t_weechat_plugin *plugin) */ int -weechat_plugin_end () +weechat_plugin_end (struct t_weechat_plugin *plugin) { + /* make C compiler happy */ + (void) plugin; + irc_config_write (); irc_server_disconnect_all (); diff --git a/src/plugins/logger/logger.c b/src/plugins/logger/logger.c index 3472efb97..bfcfd858a 100644 --- a/src/plugins/logger/logger.c +++ b/src/plugins/logger/logger.c @@ -659,8 +659,11 @@ weechat_plugin_init (struct t_weechat_plugin *plugin) */ int -weechat_plugin_end () +weechat_plugin_end (struct t_weechat_plugin *plugin) { + /* make C compiler happy */ + (void) plugin; + logger_stop_all (); return WEECHAT_RC_OK; diff --git a/src/plugins/plugin-config.c b/src/plugins/plugin-config.c index 731fb2b54..1cd131223 100644 --- a/src/plugins/plugin-config.c +++ b/src/plugins/plugin-config.c @@ -281,6 +281,26 @@ plugin_config_free_all () plugin_config_free (plugin_options); } +/* + * plugin_config_reload: reload plugins configuration file + * return: 0 = successful + * -1 = config file file not found + * -2 = error in config file + */ + +int +plugin_config_reload (struct t_config_file *config_file) +{ + /* make C compiler happy */ + (void) config_file; + + /* remove all plugin options */ + plugin_config_free_all (); + + /* reload plugins config file */ + return config_file_reload (plugin_config); +} + /* * plugin_config_read_option: read an option in config file * Return: 0 = successful @@ -335,7 +355,8 @@ plugin_config_write_options (struct t_config_file *config_file, void plugin_config_init () { - plugin_config = config_file_new (NULL, PLUGIN_CONFIG_FILENAME); + plugin_config = config_file_new (NULL, PLUGIN_CONFIG_FILENAME, + &plugin_config_reload); if (plugin_config) { config_file_new_section (plugin_config, "plugins", @@ -358,23 +379,6 @@ plugin_config_read () return config_file_read (plugin_config); } -/* - * plugin_config_reload: read plugins configuration file - * return: 0 = successful - * -1 = config file file not found - * -2 = error in config file - */ - -int -plugin_config_reload () -{ - /* remove all plugin options */ - plugin_config_free_all (); - - /* reload plugins config file */ - return config_file_reload (plugin_config); -} - /* * plugin_config_write: write plugins configuration file * return: 0 if ok diff --git a/src/plugins/plugin.c b/src/plugins/plugin.c index f5cb53d31..ce621a63d 100644 --- a/src/plugins/plugin.c +++ b/src/plugins/plugin.c @@ -233,6 +233,7 @@ plugin_load (char *filename) new_plugin->iconv_from_internal = &string_iconv_from_internal; new_plugin->gettext = &plugin_api_gettext; new_plugin->ngettext = &plugin_api_ngettext; + new_plugin->strndup = &string_strndup; new_plugin->strcasecmp = &string_strcasecmp; new_plugin->strncasecmp = &string_strncasecmp; new_plugin->strcmp_ignore_chars = &string_strcmp_ignore_chars; @@ -315,6 +316,8 @@ plugin_load (char *filename) new_plugin->hook_signal_send = &hook_signal_send; new_plugin->hook_config = &hook_config; new_plugin->hook_completion = &hook_completion; + new_plugin->hook_modifier = &hook_modifier; + new_plugin->hook_modifier_exec = &hook_modifier_exec; new_plugin->unhook = &unhook; new_plugin->unhook_all = &unhook_all_plugin; @@ -517,7 +520,7 @@ plugin_remove (struct t_weechat_plugin *plugin) /* remove all hooks */ unhook_all_plugin (plugin); - + /* remove pointer to this plugin on buffers */ for (ptr_buffer = gui_buffers; ptr_buffer; ptr_buffer = ptr_buffer->next_buffer) diff --git a/src/plugins/scripts/lua/weechat-lua-api.c b/src/plugins/scripts/lua/weechat-lua-api.c index e72f0a88a..a5ad609f0 100644 --- a/src/plugins/scripts/lua/weechat-lua-api.c +++ b/src/plugins/scripts/lua/weechat-lua-api.c @@ -1671,7 +1671,7 @@ weechat_lua_api_hook_config (lua_State *L) } /* - * weechat_lua_api_hook_completion_cb: callback for completion option hooked + * weechat_lua_api_hook_completion_cb: callback for completion hooked */ int @@ -1752,6 +1752,114 @@ weechat_lua_api_hook_completion (lua_State *L) LUA_RETURN_STRING_FREE(result); } +/* + * weechat_lua_api_hook_modifier_cb: callback for modifier hooked + */ + +char * +weechat_lua_api_hook_modifier_cb (void *data, char *modifier, + char *modifier_data, char *string) +{ + struct t_script_callback *script_callback; + char *lua_argv[4]; + + script_callback = (struct t_script_callback *)data; + + lua_argv[0] = modifier; + lua_argv[1] = modifier_data; + lua_argv[2] = string; + lua_argv[3] = NULL; + + return (char *)weechat_lua_exec (script_callback->script, + WEECHAT_SCRIPT_EXEC_STRING, + script_callback->function, + lua_argv); +} + +/* + * weechat_lua_api_hook_modifier: hook a modifier + */ + +static int +weechat_lua_api_hook_modifier (lua_State *L) +{ + const char *modifier, *function; + char *result; + int n; + + /* make C compiler happy */ + (void) L; + + if (!lua_current_script) + { + WEECHAT_SCRIPT_MSG_NOT_INITIALIZED("hook_modifier"); + LUA_RETURN_EMPTY; + } + + modifier = NULL; + function = NULL; + + n = lua_gettop (lua_current_interpreter); + + if (n < 2) + { + WEECHAT_SCRIPT_MSG_WRONG_ARGUMENTS("hook_modifier"); + LUA_RETURN_EMPTY; + } + + modifier = lua_tostring (lua_current_interpreter, -2); + function = lua_tostring (lua_current_interpreter, -1); + + result = script_ptr2str (script_api_hook_modifier (weechat_lua_plugin, + lua_current_script, + (char *)modifier, + &weechat_lua_api_hook_modifier_cb, + (char *)function)); + LUA_RETURN_STRING_FREE(result); +} + +/* + * weechat_lua_api_hook_modifier_exec: execute a modifier hook + */ + +static int +weechat_lua_api_hook_modifier_exec (lua_State *L) +{ + const char *modifier, *modifier_data, *string; + char *result; + int n; + + /* make C compiler happy */ + (void) L; + + if (!lua_current_script) + { + WEECHAT_SCRIPT_MSG_NOT_INITIALIZED("hook_modifier_exec"); + LUA_RETURN_EMPTY; + } + + modifier = NULL; + modifier_data = NULL; + string = NULL; + + n = lua_gettop (lua_current_interpreter); + + if (n < 3) + { + WEECHAT_SCRIPT_MSG_WRONG_ARGUMENTS("hook_modifier_exec"); + LUA_RETURN_ERROR; + } + + modifier = lua_tostring (lua_current_interpreter, -3); + modifier_data = lua_tostring (lua_current_interpreter, -2); + string = lua_tostring (lua_current_interpreter, -1); + + result = weechat_hook_modifier_exec ((char *)modifier, + (char *)modifier_data, + (char *)string); + LUA_RETURN_STRING_FREE(result); +} + /* * weechat_lua_api_unhook: unhook something */ @@ -3539,6 +3647,8 @@ const struct luaL_reg weechat_lua_api_funcs[] = { { "hook_signal_send", &weechat_lua_api_hook_signal_send }, { "hook_config", &weechat_lua_api_hook_config }, { "hook_completion", &weechat_lua_api_hook_completion }, + { "hook_modifier", &weechat_lua_api_hook_modifier }, + { "hook_modifier_exec", &weechat_lua_api_hook_modifier_exec }, { "unhook", &weechat_lua_api_unhook }, { "unhook_all", &weechat_lua_api_unhook_all }, { "buffer_new", &weechat_lua_api_buffer_new }, diff --git a/src/plugins/scripts/perl/weechat-perl-api.c b/src/plugins/scripts/perl/weechat-perl-api.c index f300719b7..23b5a56cc 100644 --- a/src/plugins/scripts/perl/weechat-perl-api.c +++ b/src/plugins/scripts/perl/weechat-perl-api.c @@ -1422,6 +1422,92 @@ static XS (XS_weechat_hook_completion) PERL_RETURN_STRING_FREE(result); } +/* + * weechat_perl_api_hook_modifier_cb: callback for modifier hooked + */ + +char * +weechat_perl_api_hook_modifier_cb (void *data, char *modifier, + char *modifier_data, char *string) +{ + struct t_script_callback *script_callback; + char *perl_argv[4]; + + script_callback = (struct t_script_callback *)data; + + perl_argv[0] = modifier; + perl_argv[1] = modifier_data; + perl_argv[2] = string; + perl_argv[3] = NULL; + + return (char *)weechat_perl_exec (script_callback->script, + WEECHAT_SCRIPT_EXEC_STRING, + script_callback->function, + perl_argv); +} + +/* + * weechat::hook_modifier: hook a modifier + */ + +static XS (XS_weechat_hook_modifier) +{ + char *result; + dXSARGS; + + /* make C compiler happy */ + (void) cv; + + if (!perl_current_script) + { + WEECHAT_SCRIPT_MSG_NOT_INITIALIZED("hook_modifier"); + PERL_RETURN_EMPTY; + } + + if (items < 2) + { + WEECHAT_SCRIPT_MSG_WRONG_ARGUMENTS("hook_modifier"); + PERL_RETURN_EMPTY; + } + + result = script_ptr2str (script_api_hook_modifier (weechat_perl_plugin, + perl_current_script, + SvPV (ST (0), PL_na), /* modifier */ + &weechat_perl_api_hook_modifier_cb, + SvPV (ST (1), PL_na))); /* perl function */ + PERL_RETURN_STRING_FREE(result); +} + +/* + * weechat::hook_modifier_exec: execute a modifier hook + */ + +static XS (XS_weechat_hook_modifier_exec) +{ + char *result; + dXSARGS; + + /* make C compiler happy */ + (void) cv; + + if (!perl_current_script) + { + WEECHAT_SCRIPT_MSG_NOT_INITIALIZED("hook_modifier_exec"); + PERL_RETURN_EMPTY; + } + + if (items < 3) + { + WEECHAT_SCRIPT_MSG_WRONG_ARGUMENTS("hook_modifier_exec"); + PERL_RETURN_EMPTY; + } + + result = weechat_hook_modifier_exec (SvPV (ST (0), PL_na), /* modifier */ + SvPV (ST (1), PL_na), /* modifier_data */ + SvPV (ST (2), PL_na)); /* string */ + PERL_RETURN_STRING_FREE(result); +} + /* * weechat::unhook: unhook something */ @@ -1487,7 +1573,7 @@ weechat_perl_api_input_data_cb (void *data, struct t_gui_buffer *buffer, { struct t_script_callback *script_callback; char *perl_argv[3]; - int *r, ret; + int *rc, ret; script_callback = (struct t_script_callback *)data; @@ -1495,16 +1581,16 @@ weechat_perl_api_input_data_cb (void *data, struct t_gui_buffer *buffer, perl_argv[1] = input_data; perl_argv[2] = NULL; - r = (int *) weechat_perl_exec (script_callback->script, - WEECHAT_SCRIPT_EXEC_INT, - script_callback->function, - perl_argv); - if (!r) + rc = (int *) weechat_perl_exec (script_callback->script, + WEECHAT_SCRIPT_EXEC_INT, + script_callback->function, + perl_argv); + if (!rc) ret = WEECHAT_RC_ERROR; else { - ret = *r; - free (r); + ret = *rc; + free (rc); } if (perl_argv[0]) free (perl_argv[0]); @@ -2723,6 +2809,8 @@ weechat_perl_api_init (pTHX) newXS ("weechat::hook_signal_send", XS_weechat_hook_signal_send, "weechat"); newXS ("weechat::hook_config", XS_weechat_hook_config, "weechat"); newXS ("weechat::hook_completion", XS_weechat_hook_completion, "weechat"); + newXS ("weechat::hook_modifier", XS_weechat_hook_modifier, "weechat"); + newXS ("weechat::hook_modifier_exec", XS_weechat_hook_modifier_exec, "weechat"); newXS ("weechat::unhook", XS_weechat_unhook, "weechat"); newXS ("weechat::unhook_all", XS_weechat_unhook_all, "weechat"); newXS ("weechat::buffer_new", XS_weechat_buffer_new, "weechat"); diff --git a/src/plugins/scripts/perl/weechat-perl.c b/src/plugins/scripts/perl/weechat-perl.c index 03862048a..dd278b1f2 100644 --- a/src/plugins/scripts/perl/weechat-perl.c +++ b/src/plugins/scripts/perl/weechat-perl.c @@ -110,19 +110,20 @@ weechat_perl_exec (struct t_plugin_script *script, char *func; unsigned int count; void *ret_value; - int *ret_i, mem_err; + int *ret_i, mem_err, length; SV *ret_s; /* this code is placed here to conform ISO C90 */ dSP; #ifndef MULTIPLICITY - int size = strlen (script->interpreter) + strlen(function) + 3; - func = (char *)malloc (size * sizeof(char)); + int length = strlen (script->interpreter) + strlen (function) + 3; + func = (char *)malloc (length * sizeof(char)); if (!func) return NULL; - snprintf (func, size, "%s::%s", (char *) script->interpreter, function); + snprintf (func, length, "%s::%s", (char *) script->interpreter, function); #else + (void) length; func = function; PERL_SET_CONTEXT (script->interpreter); #endif diff --git a/src/plugins/scripts/python/weechat-python-api.c b/src/plugins/scripts/python/weechat-python-api.c index 260dae1b5..dc8dda300 100644 --- a/src/plugins/scripts/python/weechat-python-api.c +++ b/src/plugins/scripts/python/weechat-python-api.c @@ -1551,6 +1551,99 @@ weechat_python_api_hook_completion (PyObject *self, PyObject *args) PYTHON_RETURN_STRING_FREE(result); } +/* + * weechat_python_api_hook_modifier_cb: callback for modifier hooked + */ + +char * +weechat_python_api_hook_modifier_cb (void *data, char *modifier, + char *modifier_data, char *string) +{ + struct t_script_callback *script_callback; + char *python_argv[4]; + + script_callback = (struct t_script_callback *)data; + + python_argv[0] = modifier; + python_argv[1] = modifier_data; + python_argv[2] = string; + python_argv[3] = NULL; + + return (char *)weechat_python_exec (script_callback->script, + WEECHAT_SCRIPT_EXEC_STRING, + script_callback->function, + python_argv); +} + +/* + * weechat_python_api_hook_modifier: hook a modifier + */ + +static PyObject * +weechat_python_api_hook_modifier (PyObject *self, PyObject *args) +{ + char *modifier, *function, *result; + PyObject *object; + + /* make C compiler happy */ + (void) self; + + if (!python_current_script) + { + WEECHAT_SCRIPT_MSG_NOT_INITIALIZED("hook_modifier"); + PYTHON_RETURN_EMPTY; + } + + modifier = NULL; + function = NULL; + + if (!PyArg_ParseTuple (args, "ss", &modifier, &function)) + { + WEECHAT_SCRIPT_MSG_WRONG_ARGUMENTS("hook_modifier"); + PYTHON_RETURN_EMPTY; + } + + result = script_ptr2str(script_api_hook_modifier (weechat_python_plugin, + python_current_script, + modifier, + &weechat_python_api_hook_modifier_cb, + function)); + PYTHON_RETURN_STRING_FREE(result); +} + +/* + * weechat_python_api_hook_modifier_exec: execute a modifier hook + */ + +static PyObject * +weechat_python_api_hook_modifier_exec (PyObject *self, PyObject *args) +{ + char *modifier, *modifier_data, *string, *result; + PyObject *object; + + /* make C compiler happy */ + (void) self; + + if (!python_current_script) + { + WEECHAT_SCRIPT_MSG_NOT_INITIALIZED("hook_modifier_exec"); + PYTHON_RETURN_EMPTY; + } + + modifier = NULL; + modifier_data = NULL; + string = NULL; + + if (!PyArg_ParseTuple (args, "sss", &modifier, &modifier_data, &string)) + { + WEECHAT_SCRIPT_MSG_WRONG_ARGUMENTS("hook_modifier_exec"); + PYTHON_RETURN_EMPTY; + } + + result = weechat_hook_modifier_exec (modifier, modifier_data, string); + PYTHON_RETURN_STRING_FREE(result); +} + /* * weechat_python_api_unhook: unhook something */ @@ -3160,6 +3253,8 @@ PyMethodDef weechat_python_funcs[] = { "hook_signal_send", &weechat_python_api_hook_signal_send, METH_VARARGS, "" }, { "hook_config", &weechat_python_api_hook_config, METH_VARARGS, "" }, { "hook_completion", &weechat_python_api_hook_completion, METH_VARARGS, "" }, + { "hook_modifier", &weechat_python_api_hook_modifier, METH_VARARGS, "" }, + { "hook_modifier_exec", &weechat_python_api_hook_modifier_exec, METH_VARARGS, "" }, { "unhook", &weechat_python_api_unhook, METH_VARARGS, "" }, { "unhook_all", &weechat_python_api_unhook_all, METH_VARARGS, "" }, { "buffer_new", &weechat_python_api_buffer_new, METH_VARARGS, "" }, diff --git a/src/plugins/scripts/ruby/weechat-ruby-api.c b/src/plugins/scripts/ruby/weechat-ruby-api.c index b77d16ed5..cbccb43a1 100644 --- a/src/plugins/scripts/ruby/weechat-ruby-api.c +++ b/src/plugins/scripts/ruby/weechat-ruby-api.c @@ -1777,6 +1777,114 @@ weechat_ruby_api_hook_completion (VALUE class, VALUE completion, RUBY_RETURN_STRING_FREE(result); } +/* + * weechat_ruby_api_hook_modifier_cb: callback for modifier hooked + */ + +char * +weechat_ruby_api_hook_modifier_cb (void *data, char *modifier, + char *modifier_data, char *string) +{ + struct t_script_callback *script_callback; + char *ruby_argv[4]; + + script_callback = (struct t_script_callback *)data; + + ruby_argv[0] = modifier; + ruby_argv[1] = modifier_data; + ruby_argv[2] = string; + ruby_argv[3] = NULL; + + return (char *)weechat_ruby_exec (script_callback->script, + WEECHAT_SCRIPT_EXEC_STRING, + script_callback->function, + ruby_argv); +} + +/* + * weechat_ruby_api_hook_modifier: hook a modifier + */ + +static VALUE +weechat_ruby_api_hook_modifier (VALUE class, VALUE modifier, VALUE function) +{ + char *c_modifier, *c_function, *result; + VALUE return_value; + + /* make C compiler happy */ + (void) class; + + if (!ruby_current_script) + { + WEECHAT_SCRIPT_MSG_NOT_INITIALIZED("hook_modifier"); + RUBY_RETURN_EMPTY; + } + + c_modifier = NULL; + c_function = NULL; + + if (NIL_P (modifier) || NIL_P (function)) + { + WEECHAT_SCRIPT_MSG_WRONG_ARGUMENTS("hook_modifier"); + RUBY_RETURN_EMPTY; + } + + Check_Type (modifier, T_STRING); + Check_Type (function, T_STRING); + + c_modifier = STR2CSTR (modifier); + c_function = STR2CSTR (function); + + result = script_ptr2str (script_api_hook_modifier (weechat_ruby_plugin, + ruby_current_script, + c_modifier, + &weechat_ruby_api_hook_modifier_cb, + c_function)); + RUBY_RETURN_STRING_FREE(result); +} + +/* + * weechat_ruby_api_hook_modifier_exec: execute a modifier hook + */ + +static VALUE +weechat_ruby_api_hook_modifier_exec (VALUE class, VALUE modifier, + VALUE modifier_data, VALUE string) +{ + char *c_modifier, *c_modifier_data, *c_string, *result; + VALUE return_value; + + /* make C compiler happy */ + (void) class; + + if (!ruby_current_script) + { + WEECHAT_SCRIPT_MSG_NOT_INITIALIZED("hook_modifier_exec"); + RUBY_RETURN_EMPTY; + } + + c_modifier = NULL; + c_modifier_data = NULL; + c_string = NULL; + + if (NIL_P (modifier) || NIL_P (modifier_data) || NIL_P (string)) + { + WEECHAT_SCRIPT_MSG_WRONG_ARGUMENTS("hook_modifier_exec"); + RUBY_RETURN_EMPTY; + } + + Check_Type (modifier, T_STRING); + Check_Type (modifier_data, T_STRING); + Check_Type (string, T_STRING); + + c_modifier = STR2CSTR (modifier); + c_modifier_data = STR2CSTR (modifier_data); + c_string = STR2CSTR (string); + + result = weechat_hook_modifier_exec (c_modifier, c_modifier_data, c_string); + RUBY_RETURN_STRING_FREE(result); +} + /* * weechat_ruby_api_unhook: unhook something */ @@ -3300,6 +3408,8 @@ weechat_ruby_api_init (VALUE ruby_mWeechat) rb_define_module_function (ruby_mWeechat, "hook_signal_send", &weechat_ruby_api_hook_signal_send, 3); rb_define_module_function (ruby_mWeechat, "hook_config", &weechat_ruby_api_hook_config, 3); rb_define_module_function (ruby_mWeechat, "hook_completion", &weechat_ruby_api_hook_completion, 2); + rb_define_module_function (ruby_mWeechat, "hook_modifier", &weechat_ruby_api_hook_modifier, 2); + rb_define_module_function (ruby_mWeechat, "hook_modifier_exec", &weechat_ruby_api_hook_modifier_exec, 3); rb_define_module_function (ruby_mWeechat, "unhook", &weechat_ruby_api_unhook, 1); rb_define_module_function (ruby_mWeechat, "unhook_all", &weechat_ruby_api_unhook_all, 0); rb_define_module_function (ruby_mWeechat, "buffer_new", &weechat_ruby_api_buffer_new, 3); diff --git a/src/plugins/scripts/script-api.c b/src/plugins/scripts/script-api.c index 92ec3ae3f..73a34e7be 100644 --- a/src/plugins/scripts/script-api.c +++ b/src/plugins/scripts/script-api.c @@ -385,6 +385,42 @@ script_api_hook_completion (struct t_weechat_plugin *weechat_plugin, return new_hook; } +/* + * script_api_hook_modifier: hook a modifier + * return new hook, NULL if error + */ + +struct t_hook * +script_api_hook_modifier (struct t_weechat_plugin *weechat_plugin, + struct t_plugin_script *script, + char *modifier, + char *(*callback)(void *data, char *modifier, + char *modifier_data, char *string), + char *function) +{ + struct t_script_callback *new_script_callback; + struct t_hook *new_hook; + + new_script_callback = script_callback_alloc (); + if (!new_script_callback) + return NULL; + + new_hook = weechat_hook_modifier (modifier, callback, new_script_callback); + if (!new_hook) + { + free (new_script_callback); + return NULL; + } + + new_script_callback->script = script; + new_script_callback->function = strdup (function); + new_script_callback->hook = new_hook; + + script_callback_add (script, new_script_callback); + + return new_hook; +} + /* * script_api_unhook: unhook something * return 1 if ok, 0 if error diff --git a/src/plugins/scripts/script-api.h b/src/plugins/scripts/script-api.h index 0483a4635..f4c3a9a29 100644 --- a/src/plugins/scripts/script-api.h +++ b/src/plugins/scripts/script-api.h @@ -87,6 +87,14 @@ extern struct t_hook *script_api_hook_completion (struct t_weechat_plugin *weech struct t_gui_buffer *buffer, struct t_weelist *list), char *function); +extern struct t_hook *script_api_hook_modifier (struct t_weechat_plugin *weechat_plugin, + struct t_plugin_script *script, + char *modifier, + char *(*callback)(void *data, + char *modifier, + char *modifier_data, + char *string), + char *function); extern int script_api_unhook (struct t_weechat_plugin *weechat_plugin, struct t_plugin_script *script, struct t_hook *hook); diff --git a/src/plugins/weechat-plugin.h b/src/plugins/weechat-plugin.h index 5815d7343..df41fc5b9 100644 --- a/src/plugins/weechat-plugin.h +++ b/src/plugins/weechat-plugin.h @@ -94,6 +94,7 @@ struct t_weechat_plugin char *(*iconv_from_internal) (char *charset, char *string); char *(*gettext) (char *string); char *(*ngettext) (char *single, char *plural, int count); + char *(*strndup) (char *string, int length); int (*strcasecmp) (char *string1, char *string2); int (*strncasecmp) (char *string1, char *string2, int max); int (*strcmp_ignore_chars) (char *string1, char *string2, @@ -155,7 +156,8 @@ struct t_weechat_plugin /* config files */ struct t_config_file *(*config_new) (struct t_weechat_plugin *plugin, - char *filename); + char *filename, + int (*callback_reload)(struct t_config_file *config_file)); struct t_config_section *(*config_new_section) (struct t_config_file *config_file, char *name, void (*callback_read) @@ -257,6 +259,16 @@ struct t_weechat_plugin struct t_gui_buffer *buffer, struct t_weelist *list), void *callback_data); + struct t_hook *(*hook_modifier) (struct t_weechat_plugin *plugin, + char *modifier, + char *(*callback)(void *data, + char *modifier, + char *modifier_data, + char *string), + void *callback_data); + char *(*hook_modifier_exec) (struct t_weechat_plugin *plugin, + char *modifier, char *modifier_data, + char *string); void (*unhook) (struct t_hook *hook); void (*unhook_all) (struct t_weechat_plugin *plugin); @@ -336,6 +348,8 @@ struct t_weechat_plugin #define weechat_gettext(string) weechat_plugin->gettext(string) #define weechat_ngettext(single,plural,number) \ weechat_plugin->ngettext(single, plural, number) +#define weechat_strndup(__string, __length) \ + weechat_plugin->strndup(__string, __length) #define weechat_strcasecmp(__string1, __string2) \ weechat_plugin->strcasecmp(__string1, __string2) #define weechat_strncasecmp(__string1, __string2, __max) \ @@ -435,8 +449,9 @@ struct t_weechat_plugin weechat_plugin->list_free(__list) /* config files */ -#define weechat_config_new(__filename) \ - weechat_plugin->config_new(weechat_plugin, __filename) +#define weechat_config_new(__filename, __callback_reload) \ + weechat_plugin->config_new(weechat_plugin, __filename, \ + __callback_reload) #define weechat_config_new_section(__config, __name, __cb_read, \ __cb_write_std, __cb_write_def) \ weechat_plugin->config_new_section(__config, __name, __cb_read, \ @@ -535,6 +550,13 @@ struct t_weechat_plugin #define weechat_hook_completion(__completion, __callback, __data) \ weechat_plugin->hook_completion(weechat_plugin, __completion, \ __callback, __data) +#define weechat_hook_modifier(__modifier, __callback, __data) \ + weechat_plugin->hook_modifier(weechat_plugin, __modifier, \ + __callback, __data) +#define weechat_hook_modifier_exec(__modifier, __modifier_data, \ + __string) \ + weechat_plugin->hook_modifier_exec(weechat_plugin, __modifier, \ + __modifier_data, __string) #define weechat_unhook(__hook) \ weechat_plugin->unhook( __hook) #define weechat_unhook_all() \ -- cgit v1.2.3