diff options
Diffstat (limited to 'src/plugins')
-rw-r--r-- | src/plugins/Makefile.am | 6 | ||||
-rw-r--r-- | src/plugins/charset/Makefile.am | 26 | ||||
-rw-r--r-- | src/plugins/charset/weechat-charset.c | 668 | ||||
-rw-r--r-- | src/plugins/charset/weechat-charset.h | 33 | ||||
-rw-r--r-- | src/plugins/plugins-config.c | 28 | ||||
-rw-r--r-- | src/plugins/plugins-interface.c | 152 | ||||
-rw-r--r-- | src/plugins/plugins.c | 10 | ||||
-rw-r--r-- | src/plugins/scripts/lua/weechat-lua.c | 88 | ||||
-rw-r--r-- | src/plugins/scripts/perl/weechat-perl.c | 77 | ||||
-rw-r--r-- | src/plugins/scripts/python/weechat-python.c | 55 | ||||
-rw-r--r-- | src/plugins/scripts/ruby/weechat-ruby.c | 77 | ||||
-rw-r--r-- | src/plugins/scripts/weechat-script.c | 141 | ||||
-rw-r--r-- | src/plugins/scripts/weechat-script.h | 21 | ||||
-rw-r--r-- | src/plugins/weechat-plugin.h | 13 |
14 files changed, 1292 insertions, 103 deletions
diff --git a/src/plugins/Makefile.am b/src/plugins/Makefile.am index 47b08b9e0..22137a1ab 100644 --- a/src/plugins/Makefile.am +++ b/src/plugins/Makefile.am @@ -37,7 +37,11 @@ if PLUGIN_ASPELL aspell_dir = aspell endif -SUBDIRS = $(script_dir) $(aspell_dir) +if PLUGIN_CHARSET +charset_dir = charset +endif + +SUBDIRS = $(script_dir) $(aspell_dir) $(charset_dir) noinst_LIBRARIES = lib_weechat_plugins.a diff --git a/src/plugins/charset/Makefile.am b/src/plugins/charset/Makefile.am new file mode 100644 index 000000000..437077d6c --- /dev/null +++ b/src/plugins/charset/Makefile.am @@ -0,0 +1,26 @@ +# Copyright (c) 2003-2006 FlashCode <flashcode@flashtux.org> +# +# 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 2 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, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +# + +INCLUDES = -DLOCALEDIR=\"$(datadir)/locale\" $(CHARSET_CFLAGS) + +libdir = ${weechat_libdir}/plugins + +lib_LTLIBRARIES = charset.la + +charset_la_SOURCES = weechat-charset.h weechat-charset.c +charset_la_LDFLAGS = -module +charset_la_LIBADD = $(CHARSET_LFLAGS) diff --git a/src/plugins/charset/weechat-charset.c b/src/plugins/charset/weechat-charset.c new file mode 100644 index 000000000..c5adaf894 --- /dev/null +++ b/src/plugins/charset/weechat-charset.c @@ -0,0 +1,668 @@ +/* + * Copyright (c) 2003-2006 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 2 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, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* weechat-charset.c: Charset plugin for WeeChat */ + +#include <stdio.h> +#include <stdlib.h> +#define __USE_GNU +#include <string.h> +#include <iconv.h> + +#include "../weechat-plugin.h" +#include "weechat-charset.h" + + +char *weechat_charset_excluded_cmd[] = { "ping", "pong", NULL }; + +char *weechat_charset_terminal = NULL; +char *weechat_charset_internal = NULL; + +/* set to 1 by /charset debug (hidden option) */ +int weechat_charset_debug = 0; + + +/* + * weechat_charset_strndup: define strndup function if not existing (FreeBSD and maybe other) + */ + +char * +weechat_charset_strndup (char *string, int length) +{ + char *result; + + if ((int)strlen (string) < length) + return strdup (string); + + result = (char *)malloc (length + 1); + if (!result) + return NULL; + + memcpy (result, string, length); + result[length] = '\0'; + + return result; +} + +/* + * weechat_charset_default_decode: set "global.decode" option if needed + */ + +void +weechat_charset_default_decode (t_weechat_plugin *plugin) +{ + 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]) + { + /* 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."); + } + if (global_decode) + free (global_decode); +} + +/* + * weechat_charset_check: check if a charset is valid + * if a charset is NULL, internal charset is used + */ + +int +weechat_charset_check (char *charset) +{ + iconv_t cd; + + if (!charset || !charset[0]) + return 0; + + cd = iconv_open (charset, weechat_charset_internal); + if (cd == (iconv_t)(-1)) + return 0; + + iconv_close (cd); + return 1; +} + +/* + * weechat_charset_get_config: read a charset in config file + * we first in this order: channel, server, global + */ + +char * +weechat_charset_get_config (t_weechat_plugin *plugin, + char *type, char *server, char *channel) +{ + 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); + } + + /* channel not found, we try server only */ + if (server) + { + 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); + } + + /* 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); + + /* nothing found => no decode/encode for this message! */ + return NULL; +} + +/* + * weechat_charset_set_config: set a charset in config file + */ + +void +weechat_charset_set_config (t_weechat_plugin *plugin, + char *type, char *server, char *channel, char *value) +{ + 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); + else + return; + + plugin->set_plugin_config (plugin, option, value); +} + +/* + * weechat_charset_command_allowed: return 1 if command can be decoded/encoded + */ + +int +weechat_charset_command_allowed (char *command) +{ + int i; + + if (!command) + return 0; + + for (i = 0; weechat_charset_excluded_cmd[i]; i++) + { + if (strcasecmp (weechat_charset_excluded_cmd[i], command) == 0) + return 0; + } + + /* command can be decoded/recoded */ + return 1; +} + +/* + * weechat_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) +{ + char *pos, *pos2, *pos3; + + *nick = NULL; + *command = NULL; + *channel = NULL; + *pos_args = NULL; + if (message[0] == ':') + { + pos = message + 1; + pos2 = strchr (pos, '!'); + if (pos2) + *nick = weechat_charset_strndup (pos, pos2 - pos); + else + { + pos2 = strchr (pos, ' '); + if (pos2) + *nick = weechat_charset_strndup (pos, pos2 - pos); + } + pos = strchr (message, ' '); + if (!pos) + pos = message; + } + else + pos = message; + + if (pos && pos[0]) + { + while (pos[0] == ' ') + pos++; + pos2 = strchr (pos, ' '); + if (pos2) + { + *command = strndup (pos, pos2 - pos); + pos2++; + while (pos2[0] == ' ') + pos2++; + if (pos2[0] == ':') + *pos_args = pos2 + 1; + else + { + if ((pos2[0] == '#') || (pos2[0] == '&') + || (pos2[0] == '+') || (pos2[0] == '!')) + { + pos3 = strchr (pos2, ' '); + if (pos3) + *channel = weechat_charset_strndup (pos2, pos3 - pos2); + else + *channel = strdup (pos2); + } + else + { + pos3 = strchr (pos2, ' '); + if (!*nick) + { + if (pos3) + *nick = weechat_charset_strndup (pos2, pos3 - pos2); + else + *nick = strdup (pos2); + } + } + if (pos3) + { + while (pos3[0] == ' ') + pos3++; + *pos_args = (pos3[0] == ':') ? pos3 + 1 : pos3; + } + } + } + } +} + +/* + * weechat_charset_irc_in: transform charset for incoming messages + * convert from any charset to WeeChat internal + */ + +char * +weechat_charset_irc_in (t_weechat_plugin *plugin, int argc, char **argv, + char *handler_args, void *handler_pointer) +{ + char *nick, *command, *channel, *charset, *ptr_args; + char *decoded, *output; + int length; + + /* make gcc happy */ + (void) argc; + (void) handler_args; + (void) handler_pointer; + + output = NULL; + + weechat_charset_parse_irc_msg (argv[1], &nick, &command, &channel, &ptr_args); + + if (weechat_charset_command_allowed (command)) + { + 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); + + if (ptr_args && charset) + { + decoded = plugin->iconv_to_internal (plugin, charset, ptr_args); + if (decoded) + { + length = strlen (decoded) + (ptr_args - argv[1]) + 1; + output = (char *)malloc (length + 1); + strncpy (output, argv[1], ptr_args - argv[1]); + output[ptr_args - argv[1]] = '\0'; + strcat (output, decoded); + free (decoded); + } + } + + if (charset) + free (charset); + } + + if (nick) + free (nick); + if (command) + free (command); + if (channel) + free (channel); + + return output; +} + +/* + * weechat_charset_irc_out: transform charset for outgoing messages + * convert from WeeChat internal charset to other + */ + +char * +weechat_charset_irc_out (t_weechat_plugin *plugin, int argc, char **argv, + char *handler_args, void *handler_pointer) +{ + char *nick, *command, *channel, *charset, *ptr_args; + char *encoded, *output; + int length; + + /* make gcc happy */ + (void) argc; + (void) handler_args; + (void) handler_pointer; + + output = NULL; + + weechat_charset_parse_irc_msg (argv[1], &nick, &command, &channel, &ptr_args); + + if (weechat_charset_command_allowed (command)) + { + 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); + + if (ptr_args && charset) + { + encoded = plugin->iconv_from_internal (plugin, charset, ptr_args); + if (encoded) + { + length = strlen (encoded) + (ptr_args - argv[1]) + 1; + output = (char *)malloc (length + 1); + strncpy (output, argv[1], ptr_args - argv[1]); + output[ptr_args - argv[1]] = '\0'; + strcat (output, encoded); + free (encoded); + } + } + + if (charset) + free (charset); + } + + if (nick) + free (nick); + if (command) + free (command); + if (channel) + free (channel); + + return output; +} + +/* + * weechat_charset_display: display charsets (global/server/channel) + */ + +void +weechat_charset_display (t_weechat_plugin *plugin, + int display_on_server, char *server, char *channel) +{ + char *decode, *encode; + static char option[1024]; + + decode = NULL; + encode = NULL; + + /* 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)"); + } + + /* 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)"); + } + + if (decode) + free (decode); + if (encode) + free (encode); +} + +/* + * weechat_charset_cmd: /charset command + */ + +int +weechat_charset_cmd (t_weechat_plugin *plugin, + int cmd_argc, char **cmd_argv, + char *handler_args, void *handler_pointer) +{ + int argc; + char **argv, *server, *channel; + + if (cmd_argc < 3) + return PLUGIN_RC_KO; + + /* make gcc happy */ + (void) handler_args; + (void) handler_pointer; + + if (cmd_argv[2]) + argv = plugin->explode_string (plugin, cmd_argv[2], " ", 0, &argc); + else + { + argv = NULL; + argc = 0; + } + + /* get command context */ + server = plugin->get_info (plugin, "server", NULL); + channel = plugin->get_info (plugin, "channel", NULL); + + switch (argc) + { + 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) + { + 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); + } + else + { + 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) + { + weechat_charset_set_config (plugin, "encode", server, channel, argv[1]); + weechat_charset_display (plugin, 0, server, channel); + } + else + plugin->print_server (plugin, + "Charset error: unknown option \"%s\"", + argv[0]); + } + break; + } + + if (server) + free (server); + if (channel) + free (channel); + + return PLUGIN_RC_OK; +} + +/* + * weechat_plugin_init: init charset plugin + */ + +int +weechat_plugin_init (t_weechat_plugin *plugin) +{ + t_plugin_modifier *msg_irc_in, *msg_irc_out; + t_plugin_handler *cmd_handler; + + /* get terminal & internal charsets */ + weechat_charset_terminal = plugin->get_info (plugin, "charset_terminal", NULL); + weechat_charset_internal = plugin->get_info (plugin, "charset_internal", NULL); + + /* display message */ + plugin->print_server (plugin, "Charset plugin starting, terminal charset: %s (WeeChat internal: %s)", + weechat_charset_terminal, weechat_charset_internal); + + /* set global default decode charset */ + weechat_charset_default_decode (plugin); + + /* 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_plugin_end: end charset plugin + */ + +void +weechat_plugin_end (t_weechat_plugin *plugin) +{ + /* make gcc happy */ + (void) plugin; + + if (weechat_charset_terminal) + free (weechat_charset_terminal); + if (weechat_charset_internal) + free (weechat_charset_internal); +} diff --git a/src/plugins/charset/weechat-charset.h b/src/plugins/charset/weechat-charset.h new file mode 100644 index 000000000..2073198a0 --- /dev/null +++ b/src/plugins/charset/weechat-charset.h @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2003-2006 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 2 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, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* weechat-charset.h: Charset plugin support for WeeChat */ + +#ifndef WEECHAT_CHARSET__H +#define WEECHAT_CHARSET__H 1 + +#define _PLUGIN_NAME "charset" +#define _PLUGIN_VERSION "0.1" +#define _PLUGIN_DESC "Charset plugin for WeeChat" + +char plugin_name[] = _PLUGIN_NAME; +char plugin_version[] = _PLUGIN_VERSION; +char plugin_description[] = _PLUGIN_DESC; + +#endif /* WEECHAT_CHARSET__H */ diff --git a/src/plugins/plugins-config.c b/src/plugins/plugins-config.c index e609f4422..833d47536 100644 --- a/src/plugins/plugins-config.c +++ b/src/plugins/plugins-config.c @@ -230,7 +230,7 @@ plugin_config_read () char *filename; FILE *file; int line_number; - char line[1024], *ptr_line, *pos, *pos2; + char line[1024], *ptr_line, *ptr_line2, *pos, *pos2; filename_length = strlen (weechat_home) + strlen (WEECHAT_PLUGINS_CONFIG_NAME) + 2; @@ -250,6 +250,14 @@ plugin_config_read () line_number++; if (ptr_line) { + /* encode line to internal charset */ + ptr_line2 = weechat_iconv_to_internal (NULL, ptr_line); + if (ptr_line2) + { + snprintf (line, sizeof (line) - 1, "%s", ptr_line2); + free (ptr_line2); + } + /* skip spaces */ while (ptr_line[0] == ' ') ptr_line++; @@ -357,19 +365,19 @@ plugin_config_write () } current_time = time (NULL); - fprintf (file, _("#\n# %s plugins configuration file, created by " - "%s v%s on %s"), - PACKAGE_NAME, PACKAGE_NAME, PACKAGE_VERSION, - ctime (¤t_time)); - fprintf (file, _("# WARNING! Be careful when editing this file, " - "WeeChat writes this file when options are updated.\n#\n")); + weechat_iconv_fprintf (file, _("#\n# %s plugins configuration file, created by " + "%s v%s on %s"), + PACKAGE_NAME, PACKAGE_NAME, PACKAGE_VERSION, + ctime (¤t_time)); + weechat_iconv_fprintf (file, _("# WARNING! Be careful when editing this file, " + "WeeChat writes this file when options are updated.\n#\n")); for (ptr_plugin_option = plugin_options; ptr_plugin_option; ptr_plugin_option = ptr_plugin_option->next_option) { - fprintf (file, "%s = \"%s\"\n", - ptr_plugin_option->name, - ptr_plugin_option->value); + weechat_iconv_fprintf (file, "%s = \"%s\"\n", + ptr_plugin_option->name, + ptr_plugin_option->value); } fclose (file); diff --git a/src/plugins/plugins-interface.c b/src/plugins/plugins-interface.c index f9298cee6..b70ba9655 100644 --- a/src/plugins/plugins-interface.c +++ b/src/plugins/plugins-interface.c @@ -31,11 +31,13 @@ #include <string.h> #include <sys/types.h> #include <sys/stat.h> + #include "../common/weechat.h" #include "plugins.h" #include "plugins-config.h" #include "../common/command.h" #include "../common/log.h" +#include "../common/utf8.h" #include "../common/util.h" #include "../common/weeconfig.h" #include "../irc/irc.h" @@ -164,6 +166,7 @@ weechat_plugin_print (t_weechat_plugin *plugin, t_gui_buffer *ptr_buffer; va_list argptr; static char buf[8192]; + char *buf2; if (!plugin || !message) return; @@ -172,8 +175,12 @@ weechat_plugin_print (t_weechat_plugin *plugin, va_start (argptr, message); vsnprintf (buf, sizeof (buf) - 1, message, argptr); va_end (argptr); + + buf2 = weechat_iconv_to_internal (plugin->charset, buf); irc_display_prefix (NULL, ptr_buffer, PREFIX_PLUGIN); - gui_printf (ptr_buffer, "%s\n", buf); + gui_printf (ptr_buffer, "%s\n", (buf2) ? buf2 : buf); + if (buf2) + free (buf2); } /* @@ -185,6 +192,7 @@ weechat_plugin_print_server (t_weechat_plugin *plugin, char *message, ...) { va_list argptr; static char buf[8192]; + char *buf2; if (!plugin || !message) return; @@ -192,8 +200,12 @@ weechat_plugin_print_server (t_weechat_plugin *plugin, char *message, ...) va_start (argptr, message); vsnprintf (buf, sizeof (buf) - 1, message, argptr); va_end (argptr); + + buf2 = weechat_iconv_to_internal (plugin->charset, buf); irc_display_prefix (NULL, NULL, PREFIX_PLUGIN); - gui_printf (NULL, "%s\n", buf); + gui_printf (NULL, "%s\n", (buf2) ? buf2 : buf); + if (buf2) + free (buf2); } /* @@ -205,6 +217,7 @@ weechat_plugin_print_infobar (t_weechat_plugin *plugin, int time_displayed, char { va_list argptr; static char buf[1024]; + char *buf2; if (!plugin || (time_displayed < 0) || !message) return; @@ -212,7 +225,12 @@ weechat_plugin_print_infobar (t_weechat_plugin *plugin, int time_displayed, char va_start (argptr, message); vsnprintf (buf, sizeof (buf) - 1, message, argptr); va_end (argptr); - gui_infobar_printf (time_displayed, COLOR_WIN_INFOBAR, "%s", buf); + + buf2 = weechat_iconv_to_internal (plugin->charset, buf); + gui_infobar_printf (time_displayed, COLOR_WIN_INFOBAR, "%s", + (buf2) ? buf2 : buf); + if (buf2) + free (buf2); } /* @@ -239,7 +257,7 @@ weechat_plugin_infobar_remove (t_weechat_plugin *plugin, int how_many) } /* - * weechat_plugin_log: add a message on logs + * weechat_plugin_log: add a message in buffer log file */ void @@ -249,6 +267,7 @@ weechat_plugin_log (t_weechat_plugin *plugin, t_gui_buffer *ptr_buffer; va_list argptr; static char buf[8192]; + char *buf2; if (!plugin || !message) return; @@ -258,8 +277,12 @@ weechat_plugin_log (t_weechat_plugin *plugin, { va_start (argptr, message); vsnprintf (buf, sizeof (buf) - 1, message, argptr); - va_end (argptr); - gui_log_write_line (ptr_buffer, buf); + va_end (argptr); + + buf2 = weechat_iconv_to_internal (plugin->charset, buf); + gui_log_write_line (ptr_buffer, (buf2) ? buf2 : buf); + if (buf2) + free (buf2); } } @@ -406,6 +429,7 @@ weechat_plugin_exec_command (t_weechat_plugin *plugin, { t_irc_server *ptr_server; t_irc_channel *ptr_channel; + char *command2; if (!plugin || !command) return; @@ -421,12 +445,15 @@ weechat_plugin_exec_command (t_weechat_plugin *plugin, } else { + command2 = weechat_iconv_to_internal (plugin->charset, command); if (ptr_server && ptr_channel) - user_command (ptr_server, ptr_channel, command, 0); + user_command (ptr_server, ptr_channel, (command2) ? command2 : command, 0); else if (ptr_server && (ptr_server->buffer)) - user_command (ptr_server, NULL, command, 0); + user_command (ptr_server, NULL, (command2) ? command2 : command, 0); else - user_command (NULL, NULL, command, 0); + user_command (NULL, NULL, (command2) ? command2 : command, 0); + if (command2) + free (command2); } } @@ -471,6 +498,14 @@ weechat_plugin_get_info (t_weechat_plugin *plugin, char *info, char *server) { return strdup (WEECHAT_SHAREDIR); } + else if (ascii_strcasecmp (info, "charset_terminal") == 0) + { + return strdup (local_charset); + } + else if (ascii_strcasecmp (info, "charset_internal") == 0) + { + return strdup (WEECHAT_INTERNAL_CHARSET); + } else if (ascii_strcasecmp (info, "inactivity") == 0) { if (gui_last_activity_time == 0) @@ -480,13 +515,17 @@ weechat_plugin_get_info (t_weechat_plugin *plugin, char *info, char *server) return_str = (char *) malloc (32); if (!return_str) return NULL; - snprintf (return_str, 32, "%ld", inactivity); + snprintf (return_str, 32, "%ld", (long int)inactivity); return return_str; } else if (ascii_strcasecmp (info, "input") == 0) { if (gui_current_window->buffer->has_input) - return strdup (gui_current_window->buffer->input_buffer); + { + return_str = weechat_iconv_from_internal (plugin->charset, + gui_current_window->buffer->input_buffer); + return (return_str) ? return_str : strdup (""); + } else return strdup (""); } @@ -868,9 +907,6 @@ weechat_plugin_get_server_info (t_weechat_plugin *plugin) new_server_info->autojoin = (ptr_server->autojoin) ? strdup (ptr_server->autojoin) : strdup (""); new_server_info->autorejoin = ptr_server->autorejoin; new_server_info->notify_levels = (ptr_server->notify_levels) ? strdup (ptr_server->notify_levels) : strdup (""); - new_server_info->charset_decode_iso = (ptr_server->charset_decode_iso) ? strdup (ptr_server->charset_decode_iso) : strdup (""); - new_server_info->charset_decode_utf = (ptr_server->charset_decode_utf) ? strdup (ptr_server->charset_decode_utf) : strdup (""); - new_server_info->charset_encode = (ptr_server->charset_encode) ? strdup (ptr_server->charset_encode) : strdup (""); new_server_info->is_connected = ptr_server->is_connected; new_server_info->ssl_connected = ptr_server->ssl_connected; new_server_info->nick = (ptr_server->nick) ? strdup (ptr_server->nick) : strdup (""); @@ -931,12 +967,6 @@ weechat_plugin_free_server_info (t_weechat_plugin *plugin, t_plugin_server_info free (server_info->autojoin); if (server_info->notify_levels) free (server_info->notify_levels); - if (server_info->charset_decode_iso) - free (server_info->charset_decode_iso); - if (server_info->charset_decode_utf) - free (server_info->charset_decode_utf); - if (server_info->charset_encode) - free (server_info->charset_encode); if (server_info->nick) free (server_info->nick); new_server_info = server_info->next_server; @@ -1116,7 +1146,8 @@ weechat_plugin_free_nick_info (t_weechat_plugin *plugin, t_plugin_nick_info *nic void weechat_plugin_input_color (t_weechat_plugin *plugin, int color, int start, int length) { - int i; + int i, begin, end; + char *pos1, *pos2; if (!plugin || (!gui_current_window->buffer->has_input) @@ -1131,8 +1162,23 @@ weechat_plugin_input_color (t_weechat_plugin *plugin, int color, int start, int gui_input_init_color_mask (gui_current_window->buffer); else { + if (local_utf8) + { + begin = start; + end = start + length - 1; + } + else + { + pos1 = utf8_add_offset (gui_current_window->buffer->input_buffer, + start); + pos2 = pos1; + for (i = 0; i < length; i++) + pos2 = utf8_next_char (pos2); + begin = pos1 - gui_current_window->buffer->input_buffer; + end = begin + (pos2 - pos1) - 1; + } color %= GUI_NUM_IRC_COLORS; - for (i = start; i < start + length; i++) + for (i = begin; i <= end; i++) { gui_current_window->buffer->input_buffer_color_mask[i] = '0' + color; @@ -1317,6 +1363,7 @@ weechat_plugin_get_buffer_data (t_weechat_plugin *plugin, char *server, char *ch t_gui_buffer *ptr_buffer; t_plugin_buffer_line *buffer_line, *last_buffer_line, *new_buffer_line; t_gui_line *ptr_line; + char *data1, *data2; if (!plugin) return NULL; @@ -1336,8 +1383,19 @@ weechat_plugin_get_buffer_data (t_weechat_plugin *plugin, char *server, char *ch { new_buffer_line->date = ptr_line->date; new_buffer_line->nick = (ptr_line->nick) ? strdup (ptr_line->nick) : NULL; - new_buffer_line->data = (ptr_line->data) ? - (char *) gui_color_decode ((unsigned char *)(ptr_line->data + ptr_line->ofs_start_message), 0) : NULL; + if (ptr_line->data) + { + data1 = (char *) gui_color_decode ((unsigned char *)(ptr_line->data + ptr_line->ofs_start_message), 0); + data2 = (data1) ? weechat_iconv_from_internal (plugin->charset, data1) : NULL; + if (data2) + new_buffer_line->data = data2; + else + new_buffer_line->data = ptr_line->data; + if (data1) + free (data1); + } + else + new_buffer_line->data = NULL; new_buffer_line->prev_line = last_buffer_line; new_buffer_line->next_line = NULL; @@ -1375,3 +1433,49 @@ weechat_plugin_free_buffer_data (t_weechat_plugin *plugin, t_plugin_buffer_line buffer_line = new_buffer_line; } } + +/* + * weechat_plugin_set_charset: set plugin charset + */ + +void +weechat_plugin_set_charset (t_weechat_plugin *plugin, char *charset) +{ + if (!plugin || !charset) + return; + + if (plugin->charset) + free (plugin->charset); + + plugin->charset = (charset) ? strdup (charset) : NULL; +} + +/* + * weechat_plugin_iconv_to_internal: encode string from a charset to WeeChat + * internal charset + */ + +char * +weechat_plugin_iconv_to_internal (t_weechat_plugin *plugin, + char *charset, char *string) +{ + if (!plugin || !string) + return NULL; + + return weechat_iconv_to_internal (charset, string); +} + +/* + * weechat_plugin_iconv_from_internal: encode string from WeeChat internal + * charset to another + */ + +char * +weechat_plugin_iconv_from_internal (t_weechat_plugin *plugin, + char *charset, char *string) +{ + if (!plugin || !string) + return NULL; + + return weechat_iconv_from_internal (charset, string); +} diff --git a/src/plugins/plugins.c b/src/plugins/plugins.c index 469800e2a..2932f10c2 100644 --- a/src/plugins/plugins.c +++ b/src/plugins/plugins.c @@ -949,7 +949,7 @@ plugin_load (char *filename) { char *full_name; void *handle; - char *name, *description, *version; + char *name, *description, *version, *charset; t_weechat_init_func *init_func; t_weechat_plugin *new_plugin; @@ -1015,6 +1015,8 @@ plugin_load (char *filename) free (full_name); return NULL; } + /* look for plugin charset (optional) */ + charset = dlsym (handle, "plugin_charset"); /* look for plugin init function */ init_func = dlsym (handle, "weechat_plugin_init"); if (!init_func) @@ -1037,6 +1039,7 @@ plugin_load (char *filename) new_plugin->name = strdup (name); new_plugin->description = strdup (description); new_plugin->version = strdup (version); + new_plugin->charset = (charset) ? strdup (charset) : NULL; /* functions */ new_plugin->ascii_strcasecmp = &weechat_ascii_strcasecmp; @@ -1080,6 +1083,9 @@ plugin_load (char *filename) new_plugin->free_buffer_info = &weechat_plugin_free_buffer_info; new_plugin->get_buffer_data = &weechat_plugin_get_buffer_data; new_plugin->free_buffer_data = &weechat_plugin_free_buffer_data; + new_plugin->set_charset = &weechat_plugin_set_charset; + new_plugin->iconv_to_internal = &weechat_plugin_iconv_to_internal; + new_plugin->iconv_from_internal = &weechat_plugin_iconv_from_internal; /* handlers */ new_plugin->handlers = NULL; @@ -1265,6 +1271,8 @@ plugin_remove (t_weechat_plugin *plugin) free (plugin->description); if (plugin->version) free (plugin->version); + if (plugin->charset) + free (plugin->charset); free (plugin); weechat_plugins = new_weechat_plugins; diff --git a/src/plugins/scripts/lua/weechat-lua.c b/src/plugins/scripts/lua/weechat-lua.c index 1db5ccc1e..424c5bb20 100644 --- a/src/plugins/scripts/lua/weechat-lua.c +++ b/src/plugins/scripts/lua/weechat-lua.c @@ -224,7 +224,7 @@ weechat_lua_modifier (t_weechat_plugin *plugin, static int weechat_lua_register (lua_State *L) { - const char *name, *version, *shutdown_func, *description; + const char *name, *version, *shutdown_func, *description, *charset; int n; /* make gcc happy */ @@ -236,10 +236,11 @@ weechat_lua_register (lua_State *L) version = NULL; shutdown_func = NULL; description = NULL; + charset = NULL; n = lua_gettop (lua_current_interpreter); - if (n != 4) + if ((n < 4) || (n > 5)) { lua_plugin->print_server (lua_plugin, "Lua error: wrong parameters for " @@ -247,12 +248,24 @@ weechat_lua_register (lua_State *L) lua_pushnumber (lua_current_interpreter, 0); return 1; } - - name = lua_tostring (lua_current_interpreter, -4); - version = lua_tostring (lua_current_interpreter, -3); - shutdown_func = lua_tostring (lua_current_interpreter, -2); - description = lua_tostring (lua_current_interpreter, -1); + switch (n) + { + case 4: + name = lua_tostring (lua_current_interpreter, -4); + version = lua_tostring (lua_current_interpreter, -3); + shutdown_func = lua_tostring (lua_current_interpreter, -2); + description = lua_tostring (lua_current_interpreter, -1); + break; + case 5: + name = lua_tostring (lua_current_interpreter, -5); + version = lua_tostring (lua_current_interpreter, -4); + shutdown_func = lua_tostring (lua_current_interpreter, -3); + description = lua_tostring (lua_current_interpreter, -2); + charset = lua_tostring (lua_current_interpreter, -1); + break; + } + if (weechat_script_search (lua_plugin, &lua_scripts, (char *) name)) { /* error: another scripts already exists with this name! */ @@ -273,7 +286,8 @@ weechat_lua_register (lua_State *L) (char *) name, (char *) version, (char *) shutdown_func, - (char *) description); + (char *) description, + (char *) charset); if (lua_current_script) { lua_plugin->print_server (lua_plugin, @@ -292,6 +306,51 @@ weechat_lua_register (lua_State *L) } /* + * weechat_lua_set_charset: set script charset + */ + +static int +weechat_lua_set_charset (lua_State *L) +{ + const char *charset; + int n; + + /* make gcc happy */ + (void) L; + + if (!lua_current_script) + { + lua_plugin->print_server (lua_plugin, + "Lua error: unable to set charset, " + "script not initialized"); + lua_pushnumber (lua_current_interpreter, 0); + return 1; + } + + charset = NULL; + + n = lua_gettop (lua_current_interpreter); + + if (n != 1) + { + lua_plugin->print_server (lua_plugin, + "Lua error: wrong parameters for " + "\"set_charset\" function"); + lua_pushnumber (lua_current_interpreter, 0); + return 1; + } + + charset = lua_tostring (lua_current_interpreter, -1); + + weechat_script_set_charset (lua_plugin, + lua_current_script, + (char *) charset); + + lua_pushnumber (lua_current_interpreter, 1); + return 1; +} + +/* * weechat_lua_print: print message into a buffer (current or specified one) */ @@ -1531,18 +1590,6 @@ weechat_lua_get_server_info (lua_State *L) lua_pushstring (lua_current_interpreter, ptr_server->notify_levels); lua_rawset (lua_current_interpreter, -3); - lua_pushstring (lua_current_interpreter, "charset_decode_iso"); - lua_pushstring (lua_current_interpreter, ptr_server->charset_decode_iso); - lua_rawset (lua_current_interpreter, -3); - - lua_pushstring (lua_current_interpreter, "charset_decode_utf"); - lua_pushstring (lua_current_interpreter, ptr_server->charset_decode_utf); - lua_rawset (lua_current_interpreter, -3); - - lua_pushstring (lua_current_interpreter, "charset_encode"); - lua_pushstring (lua_current_interpreter, ptr_server->charset_encode); - lua_rawset (lua_current_interpreter, -3); - lua_pushstring (lua_current_interpreter, "is_connected"); lua_pushnumber (lua_current_interpreter, ptr_server->is_connected); lua_rawset (lua_current_interpreter, -3); @@ -2062,6 +2109,7 @@ weechat_lua_constant_plugin_rc_ok_ignore_all (lua_State *L) static const struct luaL_reg weechat_lua_funcs[] = { { "register", weechat_lua_register }, + { "set_charset", weechat_lua_set_charset }, { "print", weechat_lua_print }, { "print_server", weechat_lua_print_server }, { "print_infobar", weechat_lua_print_infobar }, diff --git a/src/plugins/scripts/perl/weechat-perl.c b/src/plugins/scripts/perl/weechat-perl.c index 2566e373c..70133387e 100644 --- a/src/plugins/scripts/perl/weechat-perl.c +++ b/src/plugins/scripts/perl/weechat-perl.c @@ -271,11 +271,11 @@ weechat_perl_timer_handler (t_weechat_plugin *plugin, int argc, char **argv, char *handler_args, void *handler_pointer) { + int *r, ret; + /* make gcc happy */ (void) argc; (void) argv; - int *r; - int ret; r = (int *) weechat_perl_exec (plugin, (t_plugin_script *)handler_pointer, SCRIPT_EXEC_INT, @@ -343,7 +343,7 @@ weechat_perl_modifier (t_weechat_plugin *plugin, static XS (XS_weechat_register) { - char *name, *version, *shutdown_func, *description; + char *name, *version, *shutdown_func, *description, *charset; dXSARGS; /* make gcc happy */ @@ -352,7 +352,7 @@ static XS (XS_weechat_register) perl_current_script = NULL; - if (items != 4) + if ((items < 4) || (items > 5)) { perl_plugin->print_server (perl_plugin, "Perl error: wrong parameters for " @@ -364,6 +364,7 @@ static XS (XS_weechat_register) version = SvPV (ST (1), PL_na); shutdown_func = SvPV (ST (2), PL_na); description = SvPV (ST (3), PL_na); + charset = (items == 5) ? SvPV (ST (4), PL_na) : NULL; if (weechat_script_search (perl_plugin, &perl_scripts, name)) { @@ -382,7 +383,7 @@ static XS (XS_weechat_register) (perl_current_script_filename) ? perl_current_script_filename : "", name, version, shutdown_func, - description); + description, charset); if (perl_current_script) { perl_plugin->print_server (perl_plugin, @@ -399,6 +400,40 @@ static XS (XS_weechat_register) } /* + * weechat::set_charset: set script charset + */ + +static XS (XS_weechat_set_charset) +{ + dXSARGS; + + /* make gcc happy */ + (void) cv; + + if (!perl_current_script) + { + perl_plugin->print_server (perl_plugin, + "Perl error: unable to set charset, " + "script not initialized"); + XSRETURN_EMPTY; + } + + if (items < 1) + { + perl_plugin->print_server (perl_plugin, + "Perl error: wrong parameters for " + "\"set_charset\" function"); + XSRETURN_EMPTY; + } + + weechat_script_set_charset (perl_plugin, + perl_current_script, + SvPV (ST (0), PL_na)); + + XSRETURN_YES; +} + +/* * weechat::print: print message into a buffer (current or specified one) */ @@ -438,9 +473,9 @@ static XS (XS_weechat_print) server_name = SvPV (ST (2), PL_na); } - perl_plugin->print (perl_plugin, - server_name, channel_name, - "%s", message); + weechat_script_print (perl_plugin, perl_current_script, + server_name, channel_name, + "%s", message); XSRETURN_YES; } @@ -475,7 +510,8 @@ static XS (XS_weechat_print_server) message = SvPV (ST (0), PL_na); - perl_plugin->print_server (perl_plugin, "%s", message); + weechat_script_print_server (perl_plugin, perl_current_script, + "%s", message); XSRETURN_YES; } @@ -507,10 +543,9 @@ static XS (XS_weechat_print_infobar) XSRETURN_NO; } - perl_plugin->print_infobar (perl_plugin, - SvIV (ST (0)), - "%s", - SvPV (ST (1), PL_na)); + weechat_script_print_infobar (perl_plugin, perl_current_script, + SvIV (ST (0)), + "%s", SvPV (ST (1), PL_na)); XSRETURN_YES; } @@ -580,9 +615,9 @@ static XS (XS_weechat_log) server_name = SvPV (ST (2), PL_na); } - perl_plugin->log (perl_plugin, - server_name, channel_name, - "%s", message); + weechat_script_log (perl_plugin, perl_current_script, + server_name, channel_name, + "%s", message); XSRETURN_YES; } @@ -625,9 +660,9 @@ static XS (XS_weechat_command) server_name = SvPV (ST (2), PL_na); } - perl_plugin->exec_command (perl_plugin, - server_name, channel_name, - SvPV (ST (0), PL_na)); + weechat_script_exec_command (perl_plugin, perl_current_script, + server_name, channel_name, + SvPV (ST (0), PL_na)); XSRETURN_YES; } @@ -1338,9 +1373,6 @@ static XS (XS_weechat_get_server_info) hv_store (server_hash_member, "autojoin", 8, newSVpv (ptr_server->autojoin, 0), 0); hv_store (server_hash_member, "autorejoin", 10, newSViv (ptr_server->autorejoin), 0); hv_store (server_hash_member, "notify_levels", 13, newSVpv (ptr_server->notify_levels, 0), 0); - hv_store (server_hash_member, "charset_decode_iso", 18, newSVpv (ptr_server->charset_decode_iso, 0), 0); - hv_store (server_hash_member, "charset_decode_utf", 18, newSVpv (ptr_server->charset_decode_utf, 0), 0); - hv_store (server_hash_member, "charset_encode", 14, newSVpv (ptr_server->charset_encode, 0), 0); hv_store (server_hash_member, "is_connected", 12, newSViv (ptr_server->is_connected), 0); hv_store (server_hash_member, "ssl_connected", 13, newSViv (ptr_server->ssl_connected), 0); hv_store (server_hash_member, "nick", 4, newSVpv (ptr_server->nick, 0), 0); @@ -1755,6 +1787,7 @@ weechat_perl_xs_init (pTHX) /* interface functions */ newXS ("weechat::register", XS_weechat_register, "weechat"); + newXS ("weechat::set_charset", XS_weechat_set_charset, "weechat"); newXS ("weechat::print", XS_weechat_print, "weechat"); newXS ("weechat::print_server", XS_weechat_print_server, "weechat"); newXS ("weechat::print_infobar", XS_weechat_print_infobar, "weechat"); diff --git a/src/plugins/scripts/python/weechat-python.c b/src/plugins/scripts/python/weechat-python.c index b4f35281e..5495cebaa 100644 --- a/src/plugins/scripts/python/weechat-python.c +++ b/src/plugins/scripts/python/weechat-python.c @@ -266,7 +266,7 @@ weechat_python_modifier (t_weechat_plugin *plugin, static PyObject * weechat_python_register (PyObject *self, PyObject *args) { - char *name, *version, *shutdown_func, *description; + char *name, *version, *shutdown_func, *description, *charset; /* make gcc happy */ (void) self; @@ -277,8 +277,10 @@ weechat_python_register (PyObject *self, PyObject *args) version = NULL; shutdown_func = NULL; description = NULL; + charset = NULL; - if (!PyArg_ParseTuple (args, "ssss", &name, &version, &shutdown_func, &description)) + if (!PyArg_ParseTuple (args, "ssss|s", &name, &version, &shutdown_func, + &description, &charset)) { python_plugin->print_server (python_plugin, "Python error: wrong parameters for " @@ -303,7 +305,7 @@ weechat_python_register (PyObject *self, PyObject *args) (python_current_script_filename) ? python_current_script_filename : "", name, version, shutdown_func, - description); + description, charset); if (python_current_script) { python_plugin->print_server (python_plugin, @@ -318,6 +320,46 @@ weechat_python_register (PyObject *self, PyObject *args) } /* + * weechat_python_set_charset: set script charset + */ + +static PyObject * +weechat_python_set_charset (PyObject *self, PyObject *args) +{ + char *charset; + + /* make gcc happy */ + (void) self; + + if (!python_current_script) + { + python_plugin->print_server (python_plugin, + "Python error: unable to set charset, " + "script not initialized"); + Py_INCREF(Py_None); + return Py_None; + } + + charset = NULL; + + if (!PyArg_ParseTuple (args, "s", &charset)) + { + python_plugin->print_server (python_plugin, + "Python error: wrong parameters for " + "\"set_charset\" function"); + Py_INCREF(Py_None); + return Py_None; + } + + if (charset) + weechat_script_set_charset (python_plugin, + python_current_script, + charset); + + return Py_BuildValue ("i", 1); +} + +/* * weechat_python_print: print message into a buffer (current or specified one) */ @@ -1303,12 +1345,6 @@ weechat_python_get_server_info (PyObject *self, PyObject *args) Py_BuildValue("i", ptr_server->autorejoin)); PyDict_SetItem(server_hash_member, Py_BuildValue("s", "notify_levels"), Py_BuildValue("s", ptr_server->notify_levels)); - PyDict_SetItem(server_hash_member, Py_BuildValue("s", "charset_decode_iso"), - Py_BuildValue("s", ptr_server->charset_decode_iso)); - PyDict_SetItem(server_hash_member, Py_BuildValue("s", "charset_decode_utf"), - Py_BuildValue("s", ptr_server->charset_decode_utf)); - PyDict_SetItem(server_hash_member, Py_BuildValue("s", "charset_encode"), - Py_BuildValue("s", ptr_server->charset_encode)); PyDict_SetItem(server_hash_member, Py_BuildValue("s", "is_connected"), Py_BuildValue("i", ptr_server->is_connected)); PyDict_SetItem(server_hash_member, Py_BuildValue("s", "ssl_connected"), @@ -1714,6 +1750,7 @@ weechat_python_get_buffer_data (PyObject *self, PyObject *args) static PyMethodDef weechat_python_funcs[] = { { "register", weechat_python_register, METH_VARARGS, "" }, + { "set_charset", weechat_python_set_charset, METH_VARARGS, "" }, { "prnt", weechat_python_print, METH_VARARGS, "" }, { "print_server", weechat_python_print_server, METH_VARARGS, "" }, { "print_infobar", weechat_python_print_infobar, METH_VARARGS, "" }, diff --git a/src/plugins/scripts/ruby/weechat-ruby.c b/src/plugins/scripts/ruby/weechat-ruby.c index d6f4dcd45..2ee79d7ec 100644 --- a/src/plugins/scripts/ruby/weechat-ruby.c +++ b/src/plugins/scripts/ruby/weechat-ruby.c @@ -303,15 +303,28 @@ weechat_ruby_modifier (t_weechat_plugin *plugin, */ static VALUE -weechat_ruby_register (VALUE class, VALUE name, VALUE version, - VALUE shutdown_func, VALUE description) +weechat_ruby_register (int argc, VALUE *argv, VALUE class) { - char *c_name, *c_version, *c_shutdown_func, *c_description; + VALUE name, version, shutdown_func, description, charset; + char *c_name, *c_version, *c_shutdown_func, *c_description, *c_charset; /* make gcc happy */ (void) class; ruby_current_script = NULL; + + name = Qnil; + version = Qnil; + shutdown_func = Qnil; + description = Qnil; + charset = Qnil; + c_name = NULL; + c_version = NULL; + c_shutdown_func = NULL; + c_description = NULL; + c_charset = NULL; + + rb_scan_args (argc, argv, "41", &name, &version, &shutdown_func, &description, &charset); if (NIL_P (name) || NIL_P (version) || NIL_P (shutdown_func) || NIL_P (description)) { @@ -331,6 +344,12 @@ weechat_ruby_register (VALUE class, VALUE name, VALUE version, c_shutdown_func = STR2CSTR (shutdown_func); c_description = STR2CSTR (description); + if (!NIL_P (charset)) + { + Check_Type (charset, T_STRING); + c_charset = STR2CSTR (charset); + } + if (weechat_script_search (ruby_plugin, &ruby_scripts, c_name)) { /* error: another scripts already exists with this name! */ @@ -348,7 +367,7 @@ weechat_ruby_register (VALUE class, VALUE name, VALUE version, (ruby_current_script_filename) ? ruby_current_script_filename : "", c_name, c_version, c_shutdown_func, - c_description); + c_description, c_charset); if (ruby_current_script) { ruby_plugin->print_server (ruby_plugin, @@ -363,6 +382,47 @@ weechat_ruby_register (VALUE class, VALUE name, VALUE version, } /* + * weechat_ruby_set_charset: set script charset + */ + +static VALUE +weechat_ruby_set_charset (VALUE class, VALUE charset) +{ + char *c_charset; + + /* make gcc happy */ + (void) class; + + if (!ruby_current_script) + { + ruby_plugin->print_server (ruby_plugin, + "Ruby error: unable to set charset, " + "script not initialized"); + return INT2FIX (0); + } + + c_charset = NULL; + + if (NIL_P (c_charset)) + { + ruby_plugin->print_server (ruby_plugin, + "Ruby error: wrong parameters for " + "\"set_charset\" function"); + return INT2FIX (0); + } + + Check_Type (charset, T_STRING); + c_charset = STR2CSTR (charset); + + if (c_charset) + weechat_script_set_charset (ruby_plugin, + ruby_current_script, + c_charset); + + return INT2FIX (1); +} + +/* * weechat_ruby_print: print message into a buffer (current or specified one) */ @@ -1523,12 +1583,6 @@ weechat_ruby_get_server_info (VALUE class) INT2FIX(ptr_server->autorejoin)); rb_hash_aset (server_hash_member, rb_str_new2("notify_levels"), rb_str_new2(ptr_server->notify_levels)); - rb_hash_aset (server_hash_member, rb_str_new2("charset_decode_iso"), - rb_str_new2(ptr_server->charset_decode_iso)); - rb_hash_aset (server_hash_member, rb_str_new2("charset_decode_utf"), - rb_str_new2(ptr_server->charset_decode_utf)); - rb_hash_aset (server_hash_member, rb_str_new2("charset_encode"), - rb_str_new2(ptr_server->charset_encode)); rb_hash_aset (server_hash_member, rb_str_new2("is_connected"), INT2FIX(ptr_server->is_connected)); rb_hash_aset (server_hash_member, rb_str_new2("ssl_connected"), @@ -2420,7 +2474,8 @@ weechat_plugin_init (t_weechat_plugin *plugin) rb_define_const(ruby_mWeechat, "PLUGIN_RC_OK_IGNORE_WEECHAT", INT2NUM(PLUGIN_RC_OK_IGNORE_WEECHAT)); rb_define_const(ruby_mWeechat, "PLUGIN_RC_OK_IGNORE_PLUGINS", INT2NUM(PLUGIN_RC_OK_IGNORE_PLUGINS)); rb_define_const(ruby_mWeechat, "PLUGIN_RC_OK_IGNORE_ALL", INT2NUM(PLUGIN_RC_OK_IGNORE_ALL)); - rb_define_module_function (ruby_mWeechat, "register", weechat_ruby_register, 4); + rb_define_module_function (ruby_mWeechat, "register", weechat_ruby_register, -1); + rb_define_module_function (ruby_mWeechat, "set_charset", weechat_ruby_set_charset, 1); rb_define_module_function (ruby_mWeechat, "print", weechat_ruby_print, -1); rb_define_module_function (ruby_mWeechat, "print_server", weechat_ruby_print_server, 1); rb_define_module_function (ruby_mWeechat, "print_infobar", weechat_ruby_print_infobar, 2); diff --git a/src/plugins/scripts/weechat-script.c b/src/plugins/scripts/weechat-script.c index 6ca3717ee..d0d136f9a 100644 --- a/src/plugins/scripts/weechat-script.c +++ b/src/plugins/scripts/weechat-script.c @@ -22,6 +22,7 @@ #include <stdlib.h> #include <unistd.h> +#include <stdarg.h> #include <stdio.h> #include <string.h> #include <sys/types.h> @@ -199,7 +200,8 @@ weechat_script_add (t_weechat_plugin *plugin, t_plugin_script **script_list, char *filename, char *name, char *version, - char *shutdown_func, char *description) + char *shutdown_func, char *description, + char *charset) { t_plugin_script *new_script; @@ -221,6 +223,7 @@ weechat_script_add (t_weechat_plugin *plugin, new_script->version = strdup (version); new_script->shutdown_func = strdup (shutdown_func); new_script->description = strdup (description); + new_script->charset = (charset) ? strdup (charset) : NULL; /* add new script to list */ if ((*script_list)) @@ -288,6 +291,8 @@ weechat_script_remove (t_weechat_plugin *plugin, free (script->version); if (script->shutdown_func) free (script->shutdown_func); + if (script->charset) + free (script->charset); /* remove script from list */ if (script->prev_script) @@ -302,6 +307,122 @@ weechat_script_remove (t_weechat_plugin *plugin, } /* + * weechat_script_print: print a message on a server or channel buffer + */ + +void +weechat_script_print (t_weechat_plugin *plugin, + t_plugin_script *script, + char *server, char *channel, + char *message, ...) +{ + va_list argptr; + static char buf[8192]; + char *buf2; + + va_start (argptr, message); + vsnprintf (buf, sizeof (buf) - 1, message, argptr); + va_end (argptr); + + buf2 = (script->charset && script->charset[0]) ? + plugin->iconv_to_internal (plugin, script->charset, buf) : NULL; + plugin->print (plugin, server, channel, (buf2) ? buf2 : buf); + if (buf2) + free (buf2); +} + +/* + * weechat_script_print_server: print a message on server buffer + */ + +void +weechat_script_print_server (t_weechat_plugin *plugin, + t_plugin_script *script, + char *message, ...) +{ + va_list argptr; + static char buf[8192]; + char *buf2; + + va_start (argptr, message); + vsnprintf (buf, sizeof (buf) - 1, message, argptr); + va_end (argptr); + + buf2 = (script->charset && script->charset[0]) ? + plugin->iconv_to_internal (plugin, script->charset, buf) : NULL; + plugin->print_server (plugin, (buf2) ? buf2 : buf); + if (buf2) + free (buf2); +} + +/* + * weechat_script_print_infobar: print a message in infobar + */ + +void +weechat_script_print_infobar (t_weechat_plugin *plugin, + t_plugin_script *script, + int time_displayed, char *message, ...) +{ + va_list argptr; + static char buf[1024]; + char *buf2; + + va_start (argptr, message); + vsnprintf (buf, sizeof (buf) - 1, message, argptr); + va_end (argptr); + + buf2 = (script->charset && script->charset[0]) ? + plugin->iconv_to_internal (plugin, script->charset, buf) : NULL; + plugin->print_infobar (plugin, time_displayed, (buf2) ? buf2 : buf); + if (buf2) + free (buf2); +} + +/* + * weechat_script_log: add a message in buffer log file + */ + +void +weechat_script_log (t_weechat_plugin *plugin, + t_plugin_script *script, + char *server, char *channel, char *message, ...) +{ + va_list argptr; + static char buf[1024]; + char *buf2; + + va_start (argptr, message); + vsnprintf (buf, sizeof (buf) - 1, message, argptr); + va_end (argptr); + + buf2 = (script->charset && script->charset[0]) ? + plugin->iconv_to_internal (plugin, script->charset, buf) : NULL; + plugin->log (plugin, server, channel, (buf2) ? buf2 : buf); + if (buf2) + free (buf2); +} + +/* + * weechat_script_exec_command: execute a command (simulate user entry) + */ + +void +weechat_script_exec_command (t_weechat_plugin *plugin, + t_plugin_script *script, + char *server, char *channel, char *command) +{ + char *command2; + + command2 = (script->charset && script->charset[0]) ? + plugin->iconv_to_internal (plugin, script->charset, command) : NULL; + plugin->exec_command (plugin, server, channel, + (command2) ? command2 : command); + if (command2) + free (command2); +} + +/* * weechat_script_remove_handler: remove a handler for a script * for a msg handler, arg1=irc command, arg2=function * for a cmd handler, arg1=command, arg2=function @@ -494,3 +615,21 @@ weechat_script_set_plugin_config (t_weechat_plugin *plugin, return return_code; } + +/* + * weechat_script_set_charset: set charset for script + */ + +void +weechat_script_set_charset (t_weechat_plugin *plugin, + t_plugin_script *script, + char *charset) +{ + /* make gcc happy */ + (void) plugin; + + if (script->charset) + free (script->charset); + + script->charset = (charset) ? strdup (charset) : NULL; +} diff --git a/src/plugins/scripts/weechat-script.h b/src/plugins/scripts/weechat-script.h index c3c61caf0..53fcde6fa 100644 --- a/src/plugins/scripts/weechat-script.h +++ b/src/plugins/scripts/weechat-script.h @@ -38,6 +38,7 @@ struct t_plugin_script char *description; /* plugin description */ char *version; /* plugin version */ char *shutdown_func; /* function when script is unloaded */ + char *charset; /* script charset */ t_plugin_script *prev_script; /* link to previous script */ t_plugin_script *next_script; /* link to next script */ @@ -51,9 +52,24 @@ extern char *weechat_script_search_full_name (t_weechat_plugin *, char *, char *); extern t_plugin_script *weechat_script_add (t_weechat_plugin *, t_plugin_script **, char *, char *, - char *, char *, char *); + char *, char *, char *, char *); extern void weechat_script_remove (t_weechat_plugin *, t_plugin_script **, t_plugin_script *); +extern void weechat_script_print (t_weechat_plugin *, + t_plugin_script *, + char *, char *, char *, ...); +extern void weechat_script_print_server (t_weechat_plugin *, + t_plugin_script *, + char *, ...); +extern void weechat_script_print_infobar (t_weechat_plugin *, + t_plugin_script *, + int, char *, ...); +extern void weechat_script_log (t_weechat_plugin *, + t_plugin_script *, + char *, char *, char *, ...); +extern void weechat_script_exec_command (t_weechat_plugin *, + t_plugin_script *, + char *, char *, char *); extern void weechat_script_remove_handler (t_weechat_plugin *, t_plugin_script *, char *, char *); @@ -72,5 +88,8 @@ extern char *weechat_script_get_plugin_config (t_weechat_plugin *, extern int weechat_script_set_plugin_config (t_weechat_plugin *, t_plugin_script *, char *, char *); +extern void weechat_script_set_charset (t_weechat_plugin *, + t_plugin_script *, + char *); #endif /* weechat-script.h */ diff --git a/src/plugins/weechat-plugin.h b/src/plugins/weechat-plugin.h index 1b9901f3e..144f62495 100644 --- a/src/plugins/weechat-plugin.h +++ b/src/plugins/weechat-plugin.h @@ -101,9 +101,6 @@ struct t_plugin_server_info char *autojoin; /* channels to automatically join */ int autorejoin; /* auto rejoin channels when kicked */ char *notify_levels; /* channels notify levels */ - char *charset_decode_iso; /* channels charsets for decoding ISO */ - char *charset_decode_utf; /* channels charsets for decoding UTF */ - char *charset_encode; /* channels charsets for encoding msgs */ int is_connected; /* 1 if WeeChat is connected to server */ int ssl_connected; /* = 1 if connected with SSL */ char *nick; /* current nickname */ @@ -279,6 +276,7 @@ struct t_weechat_plugin char *name; /* plugin name */ char *description; /* plugin description */ char *version; /* plugin version */ + char *charset; /* charset used by plugin */ /* plugin handlers */ t_plugin_handler *handlers; /* pointer to first handler */ @@ -361,6 +359,10 @@ struct t_weechat_plugin void (*free_buffer_info) (t_weechat_plugin *, t_plugin_buffer_info *); t_plugin_buffer_line *(*get_buffer_data) (t_weechat_plugin *, char *, char *); void (*free_buffer_data) (t_weechat_plugin *, t_plugin_buffer_line *); + + void (*set_charset) (t_weechat_plugin *, char *); + char *(*iconv_to_internal) (t_weechat_plugin *, char *, char *); + char *(*iconv_from_internal) (t_weechat_plugin *, char *, char *); /* WeeChat developers: ALWAYS add new functions at the end */ }; @@ -433,4 +435,9 @@ extern void weechat_plugin_free_buffer_info (t_weechat_plugin *, t_plugin_buffer extern t_plugin_buffer_line *weechat_plugin_get_buffer_data (t_weechat_plugin *, char *, char *); extern void weechat_plugin_free_buffer_data (t_weechat_plugin *, t_plugin_buffer_line *); +/* iconv functions */ +extern void weechat_plugin_set_charset (t_weechat_plugin *, char *); +extern char *weechat_plugin_iconv_to_internal (t_weechat_plugin *, char *, char *); +extern char *weechat_plugin_iconv_from_internal (t_weechat_plugin *, char *, char *); + #endif /* weechat-plugin.h */ |