summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/help/in/recode.in14
-rw-r--r--src/core/recode.c142
-rw-r--r--src/core/recode.h10
-rw-r--r--src/fe-common/core/fe-recode.c199
-rw-r--r--src/fe-common/core/fe-recode.h7
5 files changed, 372 insertions, 0 deletions
diff --git a/docs/help/in/recode.in b/docs/help/in/recode.in
new file mode 100644
index 00000000..4f9781df
--- /dev/null
+++ b/docs/help/in/recode.in
@@ -0,0 +1,14 @@
+
+@SYNTAX:recode@
+
+RECODE
+ %|List the conversion database
+
+RECODE ADD %|[<target>] <charset>
+ %|Add an entry to the conversion database (if target is omitted,
+ the current channel or query will be used)
+
+RECODE REMOVE %|[<target>]
+ %|Remove an entry from the conversion database (if target is
+ omitted, the current channel or query will be used)
+
diff --git a/src/core/recode.c b/src/core/recode.c
new file mode 100644
index 00000000..733cc15f
--- /dev/null
+++ b/src/core/recode.c
@@ -0,0 +1,142 @@
+/*
+ recode.c : irssi
+
+ Copyright (C) 1999-2000 Timo Sirainen
+
+ 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#include "module.h"
+#include "settings.h"
+#include "lib-config/iconfig.h"
+
+#ifdef HAVE_GLIB2
+static gboolean recode_get_charset(const char **charset)
+{
+ *charset = settings_get_str("term_charset");
+ if (**charset)
+ /* we use the same test as in src/fe-text/term.c:123 */
+ return !g_strcasecmp(*charset, "utf-8");
+
+ return g_get_charset(charset);
+}
+#endif
+
+char *recode_in(const char *str, const char *target)
+{
+#ifdef HAVE_GLIB2
+ const char *from = NULL;
+ const char *to = NULL;
+ char *recoded = NULL;
+ gboolean term_is_utf8;
+ gboolean str_is_utf8;
+ gboolean translit;
+ int len;
+
+ if (!str)
+ return g_strdup(str);
+
+ len = strlen(str);
+
+ str_is_utf8 = g_utf8_validate(str, len, NULL);
+
+ translit = settings_get_bool("recode_transliterate");
+
+ /* check if the str is UTF-8 encoded as first */
+ if (target && !str_is_utf8)
+ from = iconfig_get_str("conversions", target, NULL);
+ else if (target && str_is_utf8)
+ from = "UTF-8";
+
+ term_is_utf8 = recode_get_charset(&to);
+
+ if (translit)
+ to = g_strdup_printf("%s//TRANSLIT", to);
+
+ if (from)
+ recoded = g_convert(str, len, to, from, NULL, NULL, NULL);
+
+ if (!recoded) {
+ if (term_is_utf8) {
+ if (!str_is_utf8)
+ from = settings_get_str("recode_fallback");
+
+ } else if (str_is_utf8)
+ from = "UTF-8";
+
+ if (from)
+ recoded = g_convert(str, len, to, from, NULL, NULL, NULL);
+
+ if (!recoded)
+ recoded = g_strdup(str);
+ }
+ return recoded;
+#else
+ return g_strdup(str);
+#endif
+}
+
+char *recode_out(const char *str, const char *target)
+{
+#ifdef HAVE_GLIB2
+ char *recoded = NULL;
+ const char *from = NULL;
+ gboolean translit;
+ gboolean term_is_utf8;
+ int len;
+
+ if (!str)
+ return g_strdup(str);
+
+ len = strlen(str);
+
+ translit = settings_get_bool("recode_transliterate");
+ if (target) {
+ const char *to = NULL;
+
+ to = iconfig_get_str("conversions", target, NULL);
+ if (!to)
+ /* default outgoing charset if no conversion is set */
+ to = settings_get_str("recode_out_default_charset");
+ if (to) {
+ if (translit)
+ to = g_strdup_printf("%s//TRANSLIT", to);
+
+ term_is_utf8 = recode_get_charset(&from);
+ recoded = g_convert(str, len, to, from, NULL, NULL, NULL);
+ }
+ }
+ if (!recoded)
+ recoded = g_strdup(str);
+
+ return recoded;
+#else
+ return g_strdup(str);
+#endif
+}
+
+void recode_init(void)
+{
+ settings_add_str("misc", "recode_fallback", "ISO8859-1");
+ settings_add_str("misc", "recode_out_default_charset", "");
+ settings_add_bool("misc", "recode_transliterate", TRUE);
+}
+
+void recode_deinit(void)
+{
+ settings_remove("recode_fallback");
+ settings_remove("recode_out_default_charset");
+ settings_remove("recode_transliterate");
+}
diff --git a/src/core/recode.h b/src/core/recode.h
new file mode 100644
index 00000000..47a11f09
--- /dev/null
+++ b/src/core/recode.h
@@ -0,0 +1,10 @@
+#ifndef __RECODE_H
+#define __RECODE_H
+
+char *recode_in (const char *str, const char *target);
+char *recode_out (const char *str, const char *target);
+
+void recode_init (void);
+void recode_deinit (void);
+
+#endif /* __RECODE_H */
diff --git a/src/fe-common/core/fe-recode.c b/src/fe-common/core/fe-recode.c
new file mode 100644
index 00000000..a693b5ec
--- /dev/null
+++ b/src/fe-common/core/fe-recode.c
@@ -0,0 +1,199 @@
+/*
+ fe-recode.c : irssi
+
+ Copyright (C) 1999-2000 Timo Sirainen
+
+ 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#include "module.h"
+#include "modules.h"
+#include "module-formats.h"
+#include "commands.h"
+#include "levels.h"
+#include "lib-config/iconfig.h"
+#include "settings.h"
+#include "printtext.h"
+#include "formats.h"
+#define SLIST_FOREACH(var, head) \
+for ((var) = (head); \
+ (var); \
+ (var) = g_slist_next((var)))
+
+#ifdef HAVE_GLIB2
+static gboolean is_valid_charset(const char *charset)
+{
+ const char *from="UTF-8";
+ const char *str="irssi";
+ char *recoded;
+ if (!charset)
+ return FALSE;
+ recoded = g_convert(str, strlen(str), charset, from, NULL, NULL, NULL);
+ if (recoded) {
+ g_free(recoded);
+ return TRUE;
+ } else
+ return FALSE;
+}
+
+static const char *fe_recode_get_target (WI_ITEM_REC *witem)
+{
+ if (witem && (witem->type == module_get_uniq_id_str("WINDOW ITEM TYPE", "QUERY")
+ || witem->type == module_get_uniq_id_str("WINDOW ITEM TYPE", "CHANNEL")))
+ return window_item_get_target(witem);
+
+ printformat(NULL, NULL, MSGLEVEL_CLIENTERROR, TXT_NOT_CHANNEL_OR_QUERY);
+ return NULL;
+}
+
+static int fe_recode_compare_func (CONFIG_NODE *node1, CONFIG_NODE *node2)
+{
+ return strcmp(node1->key, node2->key);
+}
+
+/* SYNTAX: RECODE */
+static void fe_recode_cmd (const char *data, SERVER_REC *server, WI_ITEM_REC *witem)
+{
+ if (*data)
+ command_runsub("recode", data, server, witem);
+ else {
+ CONFIG_NODE *conversions;
+ GSList *tmp;
+ GSList *sorted = NULL;
+
+ conversions = iconfig_node_traverse("conversions", FALSE);
+
+ for (tmp = conversions ? config_node_first(conversions->value) : NULL;
+ tmp != NULL;
+ tmp = config_node_next(tmp)) {
+ CONFIG_NODE *node = tmp->data;
+
+ if (node->type == NODE_TYPE_KEY)
+ sorted = g_slist_insert_sorted(sorted, node, (GCompareFunc) fe_recode_compare_func);
+ }
+
+ printformat(NULL, NULL, MSGLEVEL_CLIENTCRAP, TXT_RECODE_HEADER);
+ SLIST_FOREACH(tmp, sorted)
+ {
+ CONFIG_NODE *node = tmp->data;
+ printformat(NULL, NULL, MSGLEVEL_CLIENTCRAP, TXT_RECODE_LINE, node->key, node->value);
+ }
+
+ g_slist_free(sorted);
+ }
+}
+
+/* SYNTAX: RECODE ADD [<target>] <charset> */
+static void fe_recode_add_cmd (const char *data, SERVER_REC *server, WI_ITEM_REC *witem)
+{
+ const char *first;
+ const char *second;
+ const char *target;
+ const char *charset;
+ void *free_arg;
+
+ if (! cmd_get_params(data, &free_arg, 2, &first, &second))
+ return;
+
+ if (! *first)
+ cmd_return_error(CMDERR_NOT_ENOUGH_PARAMS);
+
+ if (*second) {
+ target = first;
+ charset = second;
+ } else {
+ target = fe_recode_get_target(witem);
+ charset = first;
+ if (! target)
+ goto end;
+ }
+ if (is_valid_charset(charset)) {
+ iconfig_set_str("conversions", target, charset);
+ printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE, TXT_CONVERSION_ADDED, target, charset);
+ } else
+ printformat(NULL, NULL, MSGLEVEL_CLIENTERROR, TXT_CONVERSION_NOT_SUPPORTED, charset);
+ end:
+ cmd_params_free(free_arg);
+}
+
+/* SYNTAX: RECODE REMOVE [<target>] */
+static void fe_recode_remove_cmd (const char *data, SERVER_REC *server, WI_ITEM_REC *witem)
+{
+ const char *target;
+ void *free_arg;
+
+ if (! cmd_get_params(data, &free_arg, 1, &target))
+ return;
+
+ if (! *target) {
+ target = fe_recode_get_target(witem);
+ if (! target)
+ goto end;
+ }
+
+ if (iconfig_get_str("conversions", target, NULL) == NULL)
+ printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE, TXT_CONVERSION_NOT_FOUND, target);
+ else {
+ iconfig_set_str("conversions", target, NULL);
+ printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE, TXT_CONVERSION_REMOVED, target);
+ }
+
+ end:
+ cmd_params_free(free_arg);
+}
+
+static void read_settings(void)
+{
+ const char *charset;
+
+ charset = settings_get_str("recode_fallback");
+ if (!is_valid_charset(charset)){
+ printformat(NULL, NULL, MSGLEVEL_CLIENTERROR, TXT_CONVERSION_NOT_SUPPORTED, charset);
+ settings_set_str("recode_fallback", "ISO8859-1");
+ }
+ charset = settings_get_str("term_charset");
+ if (charset && !is_valid_charset(charset)) {
+ printformat(NULL, NULL, MSGLEVEL_CLIENTERROR, TXT_CONVERSION_NOT_SUPPORTED, charset);
+ settings_set_str("term_charset", "ISO8859-1");
+ }
+ charset = settings_get_str("recode_out_default_charset");
+ if (charset && !is_valid_charset(charset)) {
+ printformat(NULL, NULL, MSGLEVEL_CLIENTERROR, TXT_CONVERSION_NOT_SUPPORTED, charset);
+ settings_set_str("recode_out_default_charset", "");
+ }
+}
+#endif
+
+void fe_recode_init (void)
+{
+/* FIXME: print this is not supported instead */
+#ifdef HAVE_GLIB2
+ command_bind("recode", NULL, (SIGNAL_FUNC) fe_recode_cmd);
+ command_bind("recode add", NULL, (SIGNAL_FUNC) fe_recode_add_cmd);
+ command_bind("recode remove", NULL, (SIGNAL_FUNC) fe_recode_remove_cmd);
+ signal_add("setup changed", (SIGNAL_FUNC) read_settings);
+#endif
+}
+
+void fe_recode_deinit (void)
+{
+/* FIXME: print this is not supported instead */
+#ifdef HAVE_GLIB2
+ command_unbind("recode", (SIGNAL_FUNC) fe_recode_cmd);
+ command_unbind("recode add", (SIGNAL_FUNC) fe_recode_add_cmd);
+ command_unbind("recode remove", (SIGNAL_FUNC) fe_recode_remove_cmd);
+ signal_remove("setup changed", (SIGNAL_FUNC) read_settings);
+#endif
+}
diff --git a/src/fe-common/core/fe-recode.h b/src/fe-common/core/fe-recode.h
new file mode 100644
index 00000000..9fc73289
--- /dev/null
+++ b/src/fe-common/core/fe-recode.h
@@ -0,0 +1,7 @@
+#ifndef __FE_RECODE_H
+#define __FE_RECODE_H
+
+void fe_recode_init (void);
+void fe_recode_deinit (void);
+
+#endif /* __FE_RECODE_H */