summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSebastien Helleu <flashcode@flashtux.org>2008-01-24 16:50:20 +0100
committerSebastien Helleu <flashcode@flashtux.org>2008-01-24 16:50:20 +0100
commited26a0389c06250f02329fa477d2cffe7df59b5e (patch)
treeecfade4a588ba8c8dcd31d0894afabe8fbad5aad /src
parent25c5bc64217bce570afc36e57b0e838f54f08465 (diff)
downloadweechat-ed26a0389c06250f02329fa477d2cffe7df59b5e.zip
Add of "modifier" hook, migration of charset plugin to new API, SIGHUP signal catched (reload all config files), better config files reloading
Diffstat (limited to 'src')
-rw-r--r--src/core/wee-command.c108
-rw-r--r--src/core/wee-command.h4
-rw-r--r--src/core/wee-config-file.c4
-rw-r--r--src/core/wee-config-file.h8
-rw-r--r--src/core/wee-config.c42
-rw-r--r--src/core/wee-hook.c196
-rw-r--r--src/core/wee-hook.h20
-rw-r--r--src/core/wee-string.c9
-rw-r--r--src/core/wee-string.h4
-rw-r--r--src/gui/curses/gui-curses-color.c2
-rw-r--r--src/gui/curses/gui-curses-main.c17
-rw-r--r--src/gui/curses/gui-curses-window.c4
-rw-r--r--src/gui/gui-completion.c4
-rw-r--r--src/gui/gui-keyboard.c4
-rw-r--r--src/plugins/alias/alias.c66
-rw-r--r--src/plugins/charset/Makefile.am2
-rw-r--r--src/plugins/charset/charset.c900
-rw-r--r--src/plugins/charset/charset.h33
-rw-r--r--src/plugins/demo/demo.c5
-rw-r--r--src/plugins/fifo/fifo.c5
-rw-r--r--src/plugins/irc/irc-config.c129
-rw-r--r--src/plugins/irc/irc-config.h1
-rw-r--r--src/plugins/irc/irc-protocol.c2
-rw-r--r--src/plugins/irc/irc-protocol.h4
-rw-r--r--src/plugins/irc/irc-server.c112
-rw-r--r--src/plugins/irc/irc-server.h5
-rw-r--r--src/plugins/irc/irc.c8
-rw-r--r--src/plugins/logger/logger.c5
-rw-r--r--src/plugins/plugin-config.c40
-rw-r--r--src/plugins/plugin.c5
-rw-r--r--src/plugins/scripts/lua/weechat-lua-api.c112
-rw-r--r--src/plugins/scripts/perl/weechat-perl-api.c104
-rw-r--r--src/plugins/scripts/perl/weechat-perl.c9
-rw-r--r--src/plugins/scripts/python/weechat-python-api.c95
-rw-r--r--src/plugins/scripts/ruby/weechat-ruby-api.c110
-rw-r--r--src/plugins/scripts/script-api.c36
-rw-r--r--src/plugins/scripts/script-api.h8
-rw-r--r--src/plugins/weechat-plugin.h28
38 files changed, 1506 insertions, 744 deletions
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
@@ -415,6 +415,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;
@@ -1160,23 +1180,6 @@ config_weechat_read ()
}
/*
- * 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
* < 0 if error
@@ -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
@@ -257,6 +257,30 @@ hook_valid_for_plugin (struct t_weechat_plugin *plugin, struct t_hook *hook)
}
/*
+ * 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 <signal.h>
#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
@@ -129,6 +130,16 @@ gui_main_quit ()
}
/*
+ * 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 <stdlib.h>
-#include <stdarg.h>
#include <string.h>
-#include <signal.h>
-#include <libgen.h>
#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;
}
@@ -417,6 +416,20 @@ alias_free_all ()
}
/*
+ * 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;
@@ -538,34 +552,6 @@ alias_config_read ()
}
/*
- * 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 <http://www.gnu.org/licenses/>.
*/
-/* weechat-charset.c: Charset plugin for WeeChat */
+/* charset.c: Charset plugin for WeeChat */
#include <stdio.h>
@@ -26,6 +26,7 @@
#include <iconv.h>
#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 <flashcode@flashtux.org>
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+
+#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
@@ -208,6 +208,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;
@@ -727,74 +786,6 @@ irc_config_read ()
}
/*
- * 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
* < 0 if error
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 <http://www.gnu.org/licenses/>.
*/
-/* 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
@@ -282,6 +282,26 @@ plugin_config_free_all ()
}
/*
+ * 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
* -1 = option not found
@@ -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",
@@ -359,23 +380,6 @@ plugin_config_read ()
}
/*
- * 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
* < 0 if error
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
@@ -1753,6 +1753,114 @@ weechat_lua_api_hook_completion (lua_State *L)
}
/*
+ * 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
@@ -1423,6 +1423,92 @@ static XS (XS_weechat_hook_completion)
}
/*
+ * 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
@@ -1552,6 +1552,99 @@ weechat_python_api_hook_completion (PyObject *self, PyObject *args)
}
/*
+ * 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
@@ -1778,6 +1778,114 @@ weechat_ruby_api_hook_completion (VALUE class, VALUE completion,
}
/*
+ * 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
@@ -386,6 +386,42 @@ script_api_hook_completion (struct t_weechat_plugin *weechat_plugin,
}
/*
+ * 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() \