summaryrefslogtreecommitdiff
path: root/src/fe-common/core
diff options
context:
space:
mode:
authorValentin Batz <senneth@irssi.org>2004-09-15 12:11:43 +0000
committersenneth <senneth@dbcabf3a-b0e7-0310-adc4-f8d773084564>2004-09-15 12:11:43 +0000
commit8ea717b67609a7ddaa6481e49fc638a4b40e84e8 (patch)
tree10e28c5a7f6ade72b86ad7fd8c680320ecafa36b /src/fe-common/core
parent55bcc420a713d5bfac3813f7bc002de0b0c13538 (diff)
downloadirssi-8ea717b67609a7ddaa6481e49fc638a4b40e84e8.zip
Fixed memleak in recode.c, fixed typo in special_vars.txt, fixed bug 105, fixed bug 106
git-svn-id: http://svn.irssi.org/repos/irssi/trunk@3295 dbcabf3a-b0e7-0310-adc4-f8d773084564
Diffstat (limited to 'src/fe-common/core')
-rw-r--r--src/fe-common/core/Makefile.am2
-rw-r--r--src/fe-common/core/fe-common-core.c10
-rw-r--r--src/fe-common/core/fe-core-commands.c3
-rw-r--r--src/fe-common/core/fe-messages.c16
-rw-r--r--src/fe-common/core/fe-recode.c122
-rw-r--r--src/fe-common/core/formats.c181
-rw-r--r--src/fe-common/core/module-formats.c4
-rw-r--r--src/fe-common/core/module-formats.h2
-rw-r--r--src/fe-common/core/module.h1
-rw-r--r--src/fe-common/core/printtext.c10
-rw-r--r--src/fe-common/core/utf8.c251
-rw-r--r--src/fe-common/core/utf8.h31
12 files changed, 496 insertions, 137 deletions
diff --git a/src/fe-common/core/Makefile.am b/src/fe-common/core/Makefile.am
index 75ff7a9a..c0b53177 100644
--- a/src/fe-common/core/Makefile.am
+++ b/src/fe-common/core/Makefile.am
@@ -25,6 +25,7 @@ libfe_common_core_a_SOURCES = \
fe-queries.c \
fe-server.c \
fe-settings.c \
+ utf8.c \
formats.c \
hilight-text.c \
keyboard.c \
@@ -51,6 +52,7 @@ pkginc_fe_common_core_HEADERS = \
fe-exec.h \
fe-messages.h \
fe-queries.h \
+ utf8.h \
formats.h \
hilight-text.h \
keyboard.h \
diff --git a/src/fe-common/core/fe-common-core.c b/src/fe-common/core/fe-common-core.c
index 147d5448..443204cb 100644
--- a/src/fe-common/core/fe-common-core.c
+++ b/src/fe-common/core/fe-common-core.c
@@ -25,10 +25,14 @@
#include "levels.h"
#include "settings.h"
#include "irssi-version.h"
+#ifdef HAVE_NL_LANGINFO
+# include <langinfo.h>
+#endif
#include "servers.h"
#include "channels.h"
#include "servers-setup.h"
+#include "recode.h"
#include "autorun.h"
#include "fe-core-commands.h"
@@ -170,7 +174,11 @@ void fe_common_core_init(void)
settings_add_bool("lookandfeel", "use_status_window", TRUE);
settings_add_bool("lookandfeel", "use_msgs_window", FALSE);
-
+#if defined (HAVE_NL_LANGINFO) && defined(CODESET)
+ settings_add_str("lookandfeel", "term_charset", nl_langinfo(CODESET));
+#else
+ settings_add_str("lookandfeel", "term_charset", "ISO8859-1");
+#endif
themes_init();
theme_register(fecommon_core_formats);
diff --git a/src/fe-common/core/fe-core-commands.c b/src/fe-common/core/fe-core-commands.c
index cc1f587c..13ddc8ac 100644
--- a/src/fe-common/core/fe-core-commands.c
+++ b/src/fe-common/core/fe-core-commands.c
@@ -48,7 +48,8 @@ static int ret_texts[] = {
TXT_CHAN_NOT_SYNCED,
TXT_ILLEGAL_PROTO,
TXT_NOT_GOOD_IDEA,
- TXT_INVALID_TIME
+ TXT_INVALID_TIME,
+ TXT_INVALID_CHARSET
};
int command_hide_output;
diff --git a/src/fe-common/core/fe-messages.c b/src/fe-common/core/fe-messages.c
index f0015f20..d5b011c5 100644
--- a/src/fe-common/core/fe-messages.c
+++ b/src/fe-common/core/fe-messages.c
@@ -31,6 +31,7 @@
#include "channels.h"
#include "nicklist.h"
#include "ignore.h"
+#include "recode.h"
#include "window-items.h"
#include "fe-queries.h"
@@ -330,7 +331,7 @@ static void sig_message_quit(SERVER_REC *server, const char *nick,
WINDOW_REC *window;
GString *chans;
GSList *tmp, *windows;
- char *print_channel;
+ char *print_channel, *recoded;
int once, count;
if (ignore_check(server, nick, address, NULL, reason, MSGLEVEL_QUITS))
@@ -363,10 +364,12 @@ static void sig_message_quit(SERVER_REC *server, const char *nick,
window = window_item_window((WI_ITEM_REC *) rec);
if (g_slist_find(windows, window) == NULL) {
windows = g_slist_append(windows, window);
+ recoded = recode_in(reason, rec->visible_name);
printformat(server, rec->visible_name,
MSGLEVEL_QUITS,
- TXT_QUIT, nick, address, reason,
+ TXT_QUIT, nick, address, recoded,
rec->visible_name);
+ g_free(recoded);
}
}
count++;
@@ -378,17 +381,22 @@ static void sig_message_quit(SERVER_REC *server, const char *nick,
display the quit there too */
QUERY_REC *query = query_find(server, nick);
if (query != NULL) {
+ recoded = recode_in(reason, nick);
printformat(server, nick, MSGLEVEL_QUITS,
- TXT_QUIT, nick, address, reason, "");
+ TXT_QUIT, nick, address, recoded, "");
+ g_free(recoded);
}
}
if (once || count == 0) {
if (chans->len > 0)
g_string_truncate(chans, chans->len-1);
+ /* at least recode_fallback will be used */
+ recoded = recode_in(reason, NULL);
printformat(server, print_channel, MSGLEVEL_QUITS,
count <= 1 ? TXT_QUIT : TXT_QUIT_ONCE,
- nick, address, reason, chans->str);
+ nick, address, recoded, chans->str);
+ g_free(recoded);
}
g_string_free(chans, TRUE);
}
diff --git a/src/fe-common/core/fe-recode.c b/src/fe-common/core/fe-recode.c
index a693b5ec..a46e3547 100644
--- a/src/fe-common/core/fe-recode.c
+++ b/src/fe-common/core/fe-recode.c
@@ -27,26 +27,21 @@
#include "settings.h"
#include "printtext.h"
#include "formats.h"
+#include "recode.h"
+
+#ifdef HAVE_NL_LANGINFO
+# include <langinfo.h>
+#endif
+
#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;
-}
+const char *recode_fallback = NULL;
+const char *recode_out_default = NULL;
+const char *term_charset = NULL;
static const char *fe_recode_get_target (WI_ITEM_REC *witem)
{
@@ -123,7 +118,7 @@ static void fe_recode_add_cmd (const char *data, SERVER_REC *server, WI_ITEM_REC
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);
+ signal_emit("error command", 2, GINT_TO_POINTER(CMDERR_INVALID_CHARSET), charset);
end:
cmd_params_free(free_arg);
}
@@ -156,23 +151,76 @@ static void fe_recode_remove_cmd (const char *data, SERVER_REC *server, WI_ITEM_
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", "");
- }
+ const char *old_term_charset = g_strdup (term_charset);
+ const char *old_recode_fallback = g_strdup (recode_fallback);
+ const char *old_recode_out_default = g_strdup (recode_out_default);
+
+ recode_fallback = settings_get_str("recode_fallback");
+ if (!is_valid_charset(recode_fallback)) {
+ signal_emit("error command", 2, GINT_TO_POINTER(CMDERR_INVALID_CHARSET), recode_fallback);
+ settings_set_str("recode_fallback", old_recode_fallback != NULL ? old_recode_fallback : "ISO8859-1");
+ }
+ recode_fallback = g_strdup(settings_get_str("recode_fallback"));
+
+ term_charset = settings_get_str("term_charset");
+ if (!is_valid_charset(term_charset)) {
+#if defined (HAVE_NL_LANGINFO) && defined(CODESET)
+ settings_set_str("term_charset", is_valid_charset(old_term_charset) ? old_term_charset : nl_langinfo(CODESET));
+#else
+ settings_set_str("term_charset", is_valid_charset(old_term_charset) ? old_term_charset : "ISO8859-1");
+#endif
+ /* FIXME: move the check of term_charset into fe-text/term.c
+ it breaks the proper term_input_type
+ setup and reemitting of the signal is kludgy */
+ if (g_strcasecmp(term_charset, old_term_charset) != 0);
+ signal_emit("setup changed", 0);
+ }
+ term_charset = g_strdup(settings_get_str("term_charset"));
+
+ recode_out_default = settings_get_str("recode_out_default_charset");
+ if (recode_out_default != NULL && *recode_out_default != '\0')
+ if( !is_valid_charset(recode_out_default)) {
+ signal_emit("error command", 2, GINT_TO_POINTER(CMDERR_INVALID_CHARSET), recode_out_default);
+ settings_set_str("recode_out_default_charset", old_recode_out_default);
+ }
+ recode_out_default = g_strdup(settings_get_str("recode_out_default_charset"));
+}
+
+static void message_own_public(const SERVER_REC *server, const char *msg,
+ const char *target)
+{
+ char *recoded;
+ recoded = recode_in(msg, target);
+ signal_continue(3, server, recoded, target);
+ g_free(recoded);
+}
+
+static void message_own_private(const SERVER_REC *server, const char *msg,
+ const char *target, const char *orig_target)
+{
+ char *recoded;
+ recoded = recode_in(msg, target);
+ signal_continue(4, server, recoded, target, orig_target);
+ g_free(recoded);
+}
+
+static void message_irc_own_action(const SERVER_REC *server, const char *msg,
+ const char *nick, const char *addr,
+ const char *target)
+{
+ char *recoded;
+ recoded = recode_in(msg, target);
+ signal_continue(5, server, recoded, nick, addr, target);
+ g_free(recoded);
+}
+
+static void message_irc_own_notice(const SERVER_REC *server, const char *msg,
+ const char *channel)
+{
+ char *recoded;
+ recoded = recode_in(msg, channel);
+ signal_continue(3, server, recoded, channel);
+ g_free(recoded);
}
#endif
@@ -184,6 +232,11 @@ void fe_recode_init (void)
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);
+ signal_add("message own_public", (SIGNAL_FUNC) message_own_public);
+ signal_add("message own_private", (SIGNAL_FUNC) message_own_private);
+ signal_add("message irc own_action", (SIGNAL_FUNC) message_irc_own_action);
+ signal_add("message irc own_notice", (SIGNAL_FUNC) message_irc_own_notice);
+ read_settings();
#endif
}
@@ -195,5 +248,10 @@ void fe_recode_deinit (void)
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);
+ signal_remove("message own_public", (SIGNAL_FUNC) message_own_public);
+ signal_remove("message own_private", (SIGNAL_FUNC) message_own_private);
+ signal_remove("message irc own_action", (SIGNAL_FUNC) message_irc_own_action);
+ signal_remove("message irc own_notice", (SIGNAL_FUNC) message_irc_own_notice);
#endif
}
+
diff --git a/src/fe-common/core/formats.c b/src/fe-common/core/formats.c
index 2470ba26..3fcb8066 100644
--- a/src/fe-common/core/formats.c
+++ b/src/fe-common/core/formats.c
@@ -32,6 +32,9 @@
#include "formats.h"
#include "themes.h"
#include "translation.h"
+#ifdef HAVE_GLIB2
+#include "utf8.h"
+#endif
static const char *format_backs = "04261537";
static const char *format_fores = "kbgcrmyw";
@@ -66,13 +69,13 @@ static void format_expand_code(const char **format, GString *out, int *flags)
int set;
if (flags == NULL) {
- /* flags are being ignored - skip the code */
+ /* flags are being ignored - skip the code */
while (**format != ']')
(*format)++;
- return;
+ return;
}
- set = TRUE;
+ set = TRUE;
(*format)++;
while (**format != ']' && **format != '\0') {
if (**format == '+')
@@ -94,7 +97,7 @@ static void format_expand_code(const char **format, GString *out, int *flags)
(*format)++;
}
g_string_append_c(out, ',');
- (*format)--;
+ (*format)--;
break;
case 's':
case 'S':
@@ -104,12 +107,12 @@ static void format_expand_code(const char **format, GString *out, int *flags)
break;
case 't':
*flags |= set ? PRINT_FLAG_SET_TIMESTAMP :
- PRINT_FLAG_UNSET_TIMESTAMP;
- break;
+ PRINT_FLAG_UNSET_TIMESTAMP;
+ break;
case 'T':
*flags |= set ? PRINT_FLAG_SET_SERVERTAG :
- PRINT_FLAG_UNSET_SERVERTAG;
- break;
+ PRINT_FLAG_UNSET_SERVERTAG;
+ break;
}
(*format)++;
@@ -120,12 +123,12 @@ int format_expand_styles(GString *out, const char **format, int *flags)
{
char *p, fmt;
- fmt = **format;
+ fmt = **format;
switch (fmt) {
case '{':
case '}':
case '%':
- /* escaped char */
+ /* escaped char */
g_string_append_c(out, fmt);
break;
case 'U':
@@ -165,7 +168,7 @@ int format_expand_styles(GString *out, const char **format, int *flags)
g_string_append_c(out, FORMAT_STYLE_DEFAULTS);
break;
case '>':
- /* clear to end of line */
+ /* clear to end of line */
g_string_append_c(out, 4);
g_string_append_c(out, FORMAT_STYLE_CLRTOEOL);
break;
@@ -175,7 +178,7 @@ int format_expand_styles(GString *out, const char **format, int *flags)
break;
case '[':
/* code */
- format_expand_code(format, out, flags);
+ format_expand_code(format, out, flags);
break;
default:
/* check if it's a background color */
@@ -219,10 +222,10 @@ void format_read_arglist(va_list va, FORMAT_REC *format,
{
int num, len, bufpos;
- g_return_if_fail(format->params < arglist_size);
+ g_return_if_fail(format->params < arglist_size);
bufpos = 0;
- arglist[format->params] = NULL;
+ arglist[format->params] = NULL;
for (num = 0; num < format->params; num++) {
switch (format->paramtypes[num]) {
case FORMAT_STRING:
@@ -255,7 +258,7 @@ void format_read_arglist(va_list va, FORMAT_REC *format,
arglist[num] = buffer+bufpos;
len = g_snprintf(buffer+bufpos, buffer_size-bufpos,
"%ld", l);
- bufpos += len+1;
+ bufpos += len+1;
break;
}
case FORMAT_FLOAT: {
@@ -279,14 +282,14 @@ void format_create_dest(TEXT_DEST_REC *dest,
void *server, const char *target,
int level, WINDOW_REC *window)
{
- format_create_dest_tag(dest, server, NULL, target, level, window);
+ format_create_dest_tag(dest, server, NULL, target, level, window);
}
void format_create_dest_tag(TEXT_DEST_REC *dest, void *server,
const char *server_tag, const char *target,
int level, WINDOW_REC *window)
{
- memset(dest, 0, sizeof(TEXT_DEST_REC));
+ memset(dest, 0, sizeof(TEXT_DEST_REC));
dest->server = server;
dest->server_tag = server != NULL ? SERVER(server)->tag : server_tag;
@@ -345,7 +348,7 @@ int format_get_length(const char *str)
str++;
if (*str != '%' &&
format_expand_styles(tmp, &str, NULL)) {
- str++;
+ str++;
continue;
}
@@ -356,13 +359,13 @@ int format_get_length(const char *str)
#ifdef HAVE_GLIB2
len += advance(&str, utf8);
#else
- len++;
+ len++;
str++;
#endif
}
g_string_free(tmp, TRUE);
- return len;
+ return len;
}
/* Return how many characters in `str' must be skipped before `len'
@@ -389,27 +392,27 @@ int format_real_length(const char *str, int len)
str++;
if (*str != '%' &&
format_expand_styles(tmp, &str, NULL)) {
- str++;
+ str++;
continue;
}
/* %% or unknown %code, written as-is */
if (*str != '%') {
if (--len == 0)
- break;
+ break;
}
}
#ifdef HAVE_GLIB2
len -= advance(&str, utf8);
#else
- len--;
+ len--;
str++;
#endif
}
g_string_free(tmp, TRUE);
- return (int) (str-start);
+ return (int) (str-start);
}
char *format_string_expand(const char *text, int *flags)
@@ -417,7 +420,7 @@ char *format_string_expand(const char *text, int *flags)
GString *out;
char code, *ret;
- g_return_val_if_fail(text != NULL, NULL);
+ g_return_val_if_fail(text != NULL, NULL);
out = g_string_new(NULL);
@@ -478,7 +481,7 @@ static char *format_get_text_args(TEXT_DEST_REC *dest,
if (ret != NULL) {
/* string shouldn't end with \003 or it could
mess up the next one or two characters */
- int diff;
+ int diff;
int len = strlen(ret);
while (len > 0 && ret[len-1] == 3) len--;
diff = strlen(ret)-len;
@@ -548,7 +551,7 @@ char *format_get_text_theme_charargs(THEME_REC *theme, const char *module,
if (module_theme == NULL)
return NULL;
- text = module_theme->expanded_formats[formatnum];
+ text = module_theme->expanded_formats[formatnum];
return format_get_text_args(dest, text, args);
}
@@ -594,7 +597,7 @@ char *format_add_linestart(const char *text, const char *linestart)
ret = str->str;
g_string_free(str, FALSE);
- return ret;
+ return ret;
}
char *format_add_lineend(const char *text, const char *linestart)
@@ -619,7 +622,7 @@ char *format_add_lineend(const char *text, const char *linestart)
ret = str->str;
g_string_free(str, FALSE);
- return ret;
+ return ret;
}
#define LINE_START_IRSSI_LEVEL \
@@ -635,16 +638,16 @@ char *format_get_level_tag(THEME_REC *theme, TEXT_DEST_REC *dest)
{
int format;
- /* check for flags if we want to override defaults */
+ /* check for flags if we want to override defaults */
if (dest->flags & PRINT_FLAG_UNSET_LINE_START)
return NULL;
if (dest->flags & PRINT_FLAG_SET_LINE_START)
format = TXT_LINE_START;
- else if (dest->flags & PRINT_FLAG_SET_LINE_START_IRSSI)
+ else if (dest->flags & PRINT_FLAG_SET_LINE_START_IRSSI)
format = TXT_LINE_START_IRSSI;
else {
- /* use defaults */
+ /* use defaults */
if (dest->level & LINE_START_IRSSI_LEVEL)
format = TXT_LINE_START_IRSSI;
else if ((dest->level & NOT_LINE_START_LEVEL) == 0)
@@ -658,20 +661,20 @@ char *format_get_level_tag(THEME_REC *theme, TEXT_DEST_REC *dest)
static char *get_timestamp(THEME_REC *theme, TEXT_DEST_REC *dest, time_t t)
{
- char *format, str[256];
+ char *format, str[256];
struct tm *tm;
int diff;
if ((timestamp_level & dest->level) == 0)
return NULL;
- /* check for flags if we want to override defaults */
+ /* check for flags if we want to override defaults */
if (dest->flags & PRINT_FLAG_UNSET_TIMESTAMP)
return NULL;
if ((dest->flags & PRINT_FLAG_SET_TIMESTAMP) == 0 &&
(dest->level & (MSGLEVEL_NEVER|MSGLEVEL_LASTLOG)) != 0)
- return NULL;
+ return NULL;
if (timestamp_timeout > 0) {
@@ -685,7 +688,7 @@ static char *get_timestamp(THEME_REC *theme, TEXT_DEST_REC *dest, time_t t)
format = format_get_text_theme(theme, MODULE_NAME, dest,
TXT_TIMESTAMP);
if (strftime(str, sizeof(str), format, tm) <= 0)
- str[0] = '\0';
+ str[0] = '\0';
g_free(format);
return g_strdup(str);
}
@@ -695,9 +698,9 @@ static char *get_server_tag(THEME_REC *theme, TEXT_DEST_REC *dest)
int count = 0;
if (dest->server_tag == NULL || hide_server_tags)
- return NULL;
+ return NULL;
- /* check for flags if we want to override defaults */
+ /* check for flags if we want to override defaults */
if (dest->flags & PRINT_FLAG_UNSET_SERVERTAG)
return NULL;
@@ -718,7 +721,7 @@ static char *get_server_tag(THEME_REC *theme, TEXT_DEST_REC *dest)
}
if (count < 2)
- return NULL;
+ return NULL;
}
return format_get_text_theme(theme, MODULE_NAME, dest,
@@ -842,7 +845,7 @@ static void get_mirc_color(const char **str, int *fg_ret, int *bg_ret)
/* foreground color */
if (**str != ',') {
fg = **str-'0';
- (*str)++;
+ (*str)++;
if (i_isdigit(**str)) {
fg = fg*10 + (**str-'0');
(*str)++;
@@ -879,7 +882,7 @@ int strip_real_length(const char *str, int len,
{
const char *start = str;
- if (last_color_pos != NULL)
+ if (last_color_pos != NULL)
*last_color_pos = -1;
if (last_color_len != NULL)
*last_color_len = -1;
@@ -890,25 +893,25 @@ int strip_real_length(const char *str, int len,
if (last_color_pos != NULL)
*last_color_pos = (int) (str-start);
- str++;
+ str++;
get_mirc_color(&str, NULL, NULL);
- if (last_color_len != NULL)
+ if (last_color_len != NULL)
*last_color_len = (int) (str-mircstart);
} else if (*str == 4 && str[1] != '\0') {
if (str[1] < FORMAT_STYLE_SPECIAL && str[2] != '\0') {
if (last_color_pos != NULL)
*last_color_pos = (int) (str-start);
- if (last_color_len != NULL)
- *last_color_len = 3;
+ if (last_color_len != NULL)
+ *last_color_len = 3;
str++;
} else if (str[1] == FORMAT_STYLE_DEFAULTS) {
if (last_color_pos != NULL)
*last_color_pos = (int) (str-start);
- if (last_color_len != NULL)
- *last_color_len = 2;
+ if (last_color_len != NULL)
+ *last_color_len = 2;
}
- str += 2;
+ str += 2;
} else {
if (!IS_COLOR_CODE(*str)) {
if (len-- == 0)
@@ -923,61 +926,61 @@ int strip_real_length(const char *str, int len,
char *strip_codes(const char *input)
{
- const char *p;
- char *str, *out;
-
- out = str = g_strdup(input);
- for (p = input; *p != '\0'; p++) {
- if (*p == 3) {
- p++;
-
- /* mirc color */
- get_mirc_color(&p, NULL, NULL);
- p--;
- continue;
- }
-
- if (*p == 4 && p[1] != '\0') {
- if (p[1] >= FORMAT_STYLE_SPECIAL) {
- p++;
- continue;
- }
-
- /* irssi color */
- if (p[2] != '\0') {
- p += 2;
- continue;
- }
+ const char *p;
+ char *str, *out;
+
+ out = str = g_strdup(input);
+ for (p = input; *p != '\0'; p++) {
+ if (*p == 3) {
+ p++;
+
+ /* mirc color */
+ get_mirc_color(&p, NULL, NULL);
+ p--;
+ continue;
+ }
+
+ if (*p == 4 && p[1] != '\0') {
+ if (p[1] >= FORMAT_STYLE_SPECIAL) {
+ p++;
+ continue;
+ }
+
+ /* irssi color */
+ if (p[2] != '\0') {
+ p += 2;
+ continue;
+ }
}
if (*p == 27 && p[1] != '\0') {
- p++;
+ p++;
p = get_ansi_color(current_theme, p, NULL, NULL, NULL);
p--;
} else if (!IS_COLOR_CODE(*p))
- *out++ = *p;
- }
+ *out++ = *p;
+ }
- *out = '\0';
- return str;
+ *out = '\0';
+ return str;
}
/* send a fully parsed text string for GUI to print */
void format_send_to_gui(TEXT_DEST_REC *dest, const char *text)
{
- THEME_REC *theme;
+ THEME_REC *theme;
char *dup, *str, *ptr, type;
int fgcolor, bgcolor;
int flags;
- theme = dest->window != NULL && dest->window->theme != NULL ?
+ theme = dest->window != NULL && dest->window->theme != NULL ?
dest->window->theme : current_theme;
dup = str = g_strdup(text);
flags = 0; fgcolor = theme->default_color; bgcolor = -1;
while (*str != '\0') {
- type = '\0';
+ type = '\0';
for (ptr = str; *ptr != '\0'; ptr++) {
if (IS_COLOR_CODE(*ptr) || *ptr == '\n') {
type = *ptr;
@@ -991,14 +994,14 @@ void format_send_to_gui(TEXT_DEST_REC *dest, const char *text)
if (type == 7) {
/* bell */
if (settings_get_bool("bell_beeps"))
- signal_emit("beep", 0);
+ signal_emit("beep", 0);
} else if (type == 4 && *ptr == FORMAT_STYLE_CLRTOEOL) {
- /* clear to end of line */
+ /* clear to end of line */
flags |= GUI_PRINT_FLAG_CLRTOEOL;
}
if (*str != '\0' || (flags & GUI_PRINT_FLAG_CLRTOEOL)) {
- /* send the text to gui handler */
+ /* send the text to gui handler */
signal_emit_id(signal_gui_print_text, 6, dest->window,
GINT_TO_POINTER(fgcolor),
GINT_TO_POINTER(bgcolor),
@@ -1055,7 +1058,7 @@ void format_send_to_gui(TEXT_DEST_REC *dest, const char *text)
while (*ptr != ',' && *ptr != '\0')
ptr++;
if (*ptr != '\0') *ptr++ = '\0';
- ptr--;
+ ptr--;
signal_emit_id(signal_gui_print_text, 6,
dest->window, NULL, NULL,
GINT_TO_POINTER(GUI_PRINT_FLAG_INDENT_FUNC),
@@ -1063,12 +1066,12 @@ void format_send_to_gui(TEXT_DEST_REC *dest, const char *text)
break;
}
case FORMAT_STYLE_DEFAULTS:
- fgcolor = theme->default_color;
+ fgcolor = theme->default_color;
bgcolor = -1;
flags &= GUI_PRINT_FLAG_INDENT|GUI_PRINT_FLAG_MONOSPACE;
break;
case FORMAT_STYLE_CLRTOEOL:
- break;
+ break;
default:
if (*ptr != FORMAT_COLOR_NOCHANGE) {
fgcolor = (unsigned char) *ptr-'0';
@@ -1090,8 +1093,8 @@ void format_send_to_gui(TEXT_DEST_REC *dest, const char *text)
flags &= ~GUI_PRINT_FLAG_BLINK;
else {
/* blink */
- bgcolor -= 8;
- flags |= GUI_PRINT_FLAG_BLINK;
+ bgcolor -= 8;
+ flags |= GUI_PRINT_FLAG_BLINK;
}
}
}
diff --git a/src/fe-common/core/module-formats.c b/src/fe-common/core/module-formats.c
index 2bd4c23d..6d13ed08 100644
--- a/src/fe-common/core/module-formats.c
+++ b/src/fe-common/core/module-formats.c
@@ -218,6 +218,7 @@ FORMAT_REC fecommon_core_formats[] = {
{ "invalid_time", "Invalid timestamp", 0 },
{ "invalid_level", "Invalid message level", 0 },
{ "invalid_size", "Invalid size", 0 },
+ { "invalid_charset", "Invalid charset: $0", 1, { 0 } },
/* ---- */
{ NULL, "Themes", 0 },
@@ -253,7 +254,6 @@ FORMAT_REC fecommon_core_formats[] = {
{ "conversion_added", "Added {hilight $0}/{hilight $1} to conversion database", 2, { FORMAT_STRING, FORMAT_STRING } },
{ "conversion_removed", "Removed {hilight $0} from conversion database", 1, { FORMAT_STRING } },
{ "conversion_not_found", "{hilight $0} not found in conversion database", 1, { FORMAT_STRING } },
- { "conversion_not_supported", "Conversion to the character set {hilight $0} is not supported",1, { FORMAT_STRING } },
{ "recode_header", "%#Target Character set", 0 },
{ "recode_line", "%#%|$[!30]0 $1", 2, { FORMAT_STRING, FORMAT_STRING } },
@@ -261,7 +261,7 @@ FORMAT_REC fecommon_core_formats[] = {
{ NULL, "Misc", 0 },
{ "unknown_chat_protocol", "Unknown chat protocol: $0", 1, { 0 } },
- { "unknown_chatnet", "Unknown chat network: $0 (create it with /IRCNET ADD)", 1, { 0 } },
+ { "unknown_chatnet", "Unknown chat network: $0 (create it with /NETWORK ADD)", 1, { 0 } },
{ "not_toggle", "Value must be either ON, OFF or TOGGLE", 0 },
{ "perl_error", "Perl error: $0", 1, { 0 } },
{ "bind_header", "%#Key Action", 0 },
diff --git a/src/fe-common/core/module-formats.h b/src/fe-common/core/module-formats.h
index 95465c33..ea9af5d2 100644
--- a/src/fe-common/core/module-formats.h
+++ b/src/fe-common/core/module-formats.h
@@ -187,6 +187,7 @@ enum {
TXT_INVALID_TIME,
TXT_INVALID_LEVEL,
TXT_INVALID_SIZE,
+ TXT_INVALID_CHARSET,
TXT_FILL_11,
@@ -219,7 +220,6 @@ enum {
TXT_CONVERSION_ADDED,
TXT_CONVERSION_REMOVED,
TXT_CONVERSION_NOT_FOUND,
- TXT_CONVERSION_NOT_SUPPORTED,
TXT_RECODE_HEADER,
TXT_RECODE_LINE,
diff --git a/src/fe-common/core/module.h b/src/fe-common/core/module.h
index 203e3a30..51b61b3e 100644
--- a/src/fe-common/core/module.h
+++ b/src/fe-common/core/module.h
@@ -2,6 +2,7 @@
#define MODULE_NAME "fe-common/core"
+typedef guint32 unichar;
typedef struct {
time_t time;
char *nick;
diff --git a/src/fe-common/core/printtext.c b/src/fe-common/core/printtext.c
index e51da230..a3d34a22 100644
--- a/src/fe-common/core/printtext.c
+++ b/src/fe-common/core/printtext.c
@@ -23,7 +23,6 @@
#include "modules.h"
#include "signals.h"
#include "commands.h"
-#include "recode.h"
#include "settings.h"
#include "levels.h"
@@ -160,7 +159,7 @@ void printformat_module_gui(const char *module, int formatnum, ...)
static void print_line(TEXT_DEST_REC *dest, const char *text)
{
THEME_REC *theme;
- char *str, *recoded, *tmp, *stripped;
+ char *str, *tmp, *stripped;
g_return_if_fail(dest != NULL);
g_return_if_fail(text != NULL);
@@ -171,15 +170,12 @@ static void print_line(TEXT_DEST_REC *dest, const char *text)
format_add_lineend(text, tmp);
g_free_not_null(tmp);
- recoded = recode_in(str, dest->target);
-
/* send both the formatted + stripped (for logging etc.) */
- stripped = strip_codes(recoded);
- signal_emit_id(signal_print_text, 3, dest, recoded, stripped);
+ stripped = strip_codes(str);
+ signal_emit_id(signal_print_text, 3, dest, str, stripped);
g_free_and_null(dest->hilight_color);
g_free(str);
- g_free(recoded);
g_free(stripped);
}
diff --git a/src/fe-common/core/utf8.c b/src/fe-common/core/utf8.c
new file mode 100644
index 00000000..4049991d
--- /dev/null
+++ b/src/fe-common/core/utf8.c
@@ -0,0 +1,251 @@
+/* utf8.c - Operations on UTF-8 strings.
+ *
+ * Copyright (C) 2002 Timo Sirainen
+ *
+ * Based on GLib code by
+ *
+ * Copyright (C) 1999 Tom Tromey
+ * Copyright (C) 2000 Red Hat, Inc.
+ *
+ * UTF-8 width tables based on locale data from GNU libc by
+ *
+ * Copyright (C) 1991-2002 Free Software Foundation, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "module.h"
+
+#define UTF8_COMPUTE(Char, Mask, Len) \
+ if (Char < 128) \
+ { \
+ Len = 1; \
+ Mask = 0x7f; \
+ } \
+ else if ((Char & 0xe0) == 0xc0) \
+ { \
+ Len = 2; \
+ Mask = 0x1f; \
+ } \
+ else if ((Char & 0xf0) == 0xe0) \
+ { \
+ Len = 3; \
+ Mask = 0x0f; \
+ } \
+ else if ((Char & 0xf8) == 0xf0) \
+ { \
+ Len = 4; \
+ Mask = 0x07; \
+ } \
+ else if ((Char & 0xfc) == 0xf8) \
+ { \
+ Len = 5; \
+ Mask = 0x03; \
+ } \
+ else if ((Char & 0xfe) == 0xfc) \
+ { \
+ Len = 6; \
+ Mask = 0x01; \
+ } \
+ else \
+ Len = -1;
+
+#define UTF8_GET(Result, Chars, Count, Mask, Len) \
+ (Result) = (Chars)[0] & (Mask); \
+ for ((Count) = 1; (Count) < (Len); ++(Count)) \
+ { \
+ if (((Chars)[(Count)] & 0xc0) != 0x80) \
+ { \
+ (Result) = -1; \
+ break; \
+ } \
+ (Result) <<= 6; \
+ (Result) |= ((Chars)[(Count)] & 0x3f); \
+ }
+
+unichar get_utf8_char(const unsigned char **ptr, int len)
+{
+ int i, result, mask, chrlen;
+
+ mask = 0;
+ UTF8_COMPUTE(**ptr, mask, chrlen);
+ if (chrlen == -1)
+ return (unichar) -2;
+
+ if (chrlen > len)
+ return (unichar) -1;
+
+ UTF8_GET(result, *ptr, i, mask, chrlen);
+ if (result == -1)
+ return (unichar) -2;
+
+ *ptr += chrlen-1;
+ return result;
+}
+
+int strlen_utf8(const char *str)
+{
+ const unsigned char *p = (const unsigned char *) str;
+ int len;
+
+ len = 0;
+ while (*p != '\0' && get_utf8_char(&p, 6) > 0) {
+ len++;
+ p++;
+ }
+ return len;
+}
+
+int utf16_char_to_utf8(unichar c, char *outbuf)
+{
+ int len, i, first;
+
+ len = 0;
+ if (c < 0x80) {
+ first = 0;
+ len = 1;
+ } else if (c < 0x800) {
+ first = 0xc0;
+ len = 2;
+ } else if (c < 0x10000) {
+ first = 0xe0;
+ len = 3;
+ } else if (c < 0x200000) {
+ first = 0xf0;
+ len = 4;
+ } else if (c < 0x4000000) {
+ first = 0xf8;
+ len = 5;
+ } else {
+ first = 0xfc;
+ len = 6;
+ }
+
+ if (outbuf) {
+ for (i = len - 1; i > 0; --i) {
+ outbuf[i] = (c & 0x3f) | 0x80;
+ c >>= 6;
+ }
+ outbuf[0] = c | first;
+ }
+
+ return len;
+}
+
+void utf8_to_utf16(const char *str, unichar *out)
+{
+ const unsigned char *p = (const unsigned char *) str;
+ int i, result, mask, len;
+
+ while (*p != '\0') {
+ mask = 0;
+ UTF8_COMPUTE(*p, mask, len);
+ if (len == -1)
+ break;
+
+ UTF8_GET(result, p, i, mask, len);
+ if (result == -1)
+ break;
+
+ p += len;
+ *out++ = result;
+ }
+
+ *out = '\0';
+}
+
+void utf16_to_utf8(const unichar *str, char *out)
+{
+ int len;
+
+ while (*str != '\0') {
+ len = utf16_char_to_utf8(*str, out);
+ out += len;
+
+ str++;
+ }
+ *out = '\0';
+}
+
+static const unichar wcc[] = {
+ 0x0, 0x300, 0x34F, 0x360, 0x363, 0x483, 0x487, 0x488, 0x48A, 0x591,
+ 0x5A2, 0x5A3, 0x5BA, 0x5BB, 0x5BE, 0x5BF, 0x5C0, 0x5C1, 0x5C3, 0x5C4,
+ 0x5C5, 0x64B, 0x656, 0x670, 0x671, 0x6D6, 0x6E5, 0x6E7, 0x6E9, 0x6EA,
+ 0x6EE, 0x70F, 0x710, 0x711, 0x712, 0x730, 0x74B, 0x7A6, 0x7B1, 0x901,
+ 0x903, 0x93C, 0x93D, 0x941, 0x949, 0x94D, 0x94E, 0x951, 0x955, 0x962,
+ 0x964, 0x981, 0x982, 0x9BC, 0x9BD, 0x9C1, 0x9C5, 0x9CD, 0x9CE, 0x9E2,
+ 0x9E4, 0xA02, 0xA03, 0xA3C, 0xA3D, 0xA41, 0xA43, 0xA47, 0xA49, 0xA4B,
+ 0xA4E, 0xA70, 0xA72, 0xA81, 0xA83, 0xABC, 0xABD, 0xAC1, 0xAC6, 0xAC7,
+ 0xAC9, 0xACD, 0xACE, 0xB01, 0xB02, 0xB3C, 0xB3D, 0xB3F, 0xB40, 0xB41,
+ 0xB44, 0xB4D, 0xB4E, 0xB56, 0xB57, 0xB82, 0xB83, 0xBC0, 0xBC1, 0xBCD,
+ 0xBCE, 0xC3E, 0xC41, 0xC46, 0xC49, 0xC4A, 0xC4E, 0xC55, 0xC57, 0xCBF,
+ 0xCC0, 0xCC6, 0xCC7, 0xCCC, 0xCCE, 0xD41, 0xD44, 0xD4D, 0xD4E, 0xDCA,
+ 0xDCB, 0xDD2, 0xDD5, 0xDD6, 0xDD7, 0xE31, 0xE32, 0xE34, 0xE3B, 0xE47,
+ 0xE4F, 0xEB1, 0xEB2, 0xEB4, 0xEBA, 0xEBB, 0xEBD, 0xEC8, 0xECE, 0xF18,
+ 0xF1A, 0xF35, 0xF36, 0xF37, 0xF38, 0xF39, 0xF3A, 0xF71, 0xF7F, 0xF80,
+ 0xF85, 0xF86, 0xF88, 0xF90, 0xF98, 0xF99, 0xFBD, 0xFC6, 0xFC7, 0x102D,
+ 0x1031, 0x1032, 0x1033, 0x1036, 0x1038, 0x1039, 0x103A, 0x1058, 0x105A,
+ 0x1100, 0x1160, 0x17B7, 0x17BE, 0x17C6, 0x17C7, 0x17C9, 0x17D4, 0x180B,
+ 0x180F, 0x18A9, 0x18AA, 0x200B, 0x2010, 0x202A, 0x202F, 0x206A, 0x2070,
+ 0x20D0, 0x20E4, 0x2E80, 0x3008, 0x300C, 0x3014, 0x3016, 0x3018, 0x301C,
+ 0x302A, 0x3030, 0x303F, 0x3041, 0x3095, 0x3099, 0x309B, 0xA4C7, 0xAC00,
+ 0xD7A4, 0xF8F0, 0xF900, 0xFA2E, 0xFB1E, 0xFB1F, 0xFE20, 0xFE24, 0xFE30,
+ 0xFE6C, 0xFEFF, 0xFF00, 0xFF01, 0xFF5F, 0xFFE0, 0xFFE7, 0xFFF9, 0xFFFC,
+#if 1
+ 0x1D167, 0x1D16A, 0x1D173, 0x1D183, 0x1D185, 0x1D18C, 0x1D1AA, 0x1D1AE,
+ 0x20000, 0x2A6D7, 0x2F800, 0x2FA1E, 0xE0001, 0xE0002, 0xE0020, 0xE0080
+#endif
+};
+
+static const int wccnum = sizeof(wcc) / sizeof(wcc[0]) - 1;
+
+static const char wws[] = {
+ 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
+ 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
+ 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
+ 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
+ 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
+ 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
+ 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
+ 1, 2, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 2, 1, 2,
+ 1, 2, 1, 2, 0, 2, 1, 2, 1, 0, 2, 1, 2, 1, 0, 2, 1, 0, 1, 0, 1, 2, 1, 0,
+ 1, 2, 1, 2, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 2, 1, 2, 1, 0, 1, 0, 1, -1
+};
+
+int utf8_width(unichar c)
+{
+ int p, q, r;
+ unichar d;
+
+ if (c < wcc[1])
+ return 1;
+
+ p = 0;
+ q = wccnum;
+
+ while (p < q - 1) {
+ r = (p + q)/2;
+ d = wcc[r];
+ if (d < c)
+ p = r;
+ else if (d > c)
+ q = r;
+ else
+ return wws[r];
+ }
+
+ return wws[p];
+}
diff --git a/src/fe-common/core/utf8.h b/src/fe-common/core/utf8.h
new file mode 100644
index 00000000..456c6bf8
--- /dev/null
+++ b/src/fe-common/core/utf8.h
@@ -0,0 +1,31 @@
+#ifndef __UTF8_H
+#define __UTF8_H
+
+/* Returns -2 = invalid, -1 = need more data, otherwise unichar. */
+unichar get_utf8_char(const unsigned char **ptr, int len);
+
+/* Returns length of UTF8 string */
+int strlen_utf8(const char *str);
+
+/* UTF-8 -> unichar string. The NUL is copied as well. */
+void utf8_to_utf16(const char *str, unichar *out);
+
+/* unichar -> UTF-8 string. outbuf must be at least 6 chars long.
+ Returns outbuf string length. */
+int utf16_char_to_utf8(unichar c, char *outbuf);
+
+/* unichar -> UTF-8 string. The NUL is copied as well.
+ Make sure out is at least 6 x length of str. */
+void utf16_to_utf8(const unichar *str, char *out);
+
+/* XXX I didn't check the encoding range of big5+. This is standard big5. */
+#define is_big5_los(lo) (0x40 <= (lo) && (lo) <= 0x7E) /* standard */
+#define is_big5_lox(lo) (0x80 <= (lo) && (lo) <= 0xFE) /* extended */
+#define is_big5_lo(lo) ((is_big5_los(lo) || is_big5_lox(lo)))
+#define is_big5_hi(hi) (0x81 <= (hi) && (hi) <= 0xFE)
+#define is_big5(hi,lo) (is_big5_hi(hi) && is_big5_lo(lo))
+
+/* Returns width for character (0-2). */
+int utf8_width(unichar c);
+
+#endif