1
0
mirror of https://github.com/irssi/irssi.git synced 2024-07-21 03:14:16 -04:00

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
This commit is contained in:
Valentin Batz 2004-09-15 12:11:43 +00:00 committed by senneth
parent 55bcc420a7
commit 8ea717b676
26 changed files with 657 additions and 197 deletions

1
TODO
View File

@ -46,7 +46,6 @@
20:47 <@Juerd> cras: for some reason irssi doesn't know this happens in a
query, and displays "< Juerd:> foo" in the status window
- set TOS field for all connections (DCC especially)
- /PROXY CTCP ON doesn't work well with multiple servers
22:51 [IRCNet] [zhafte] irssi muuten taitaa bugaa jos
pistää ACT oikeaan reunaan, vai onkohan se vain mun terminaali?
22:52 [IRCNet] [zhafte] menevät välillä päällekkäin

View File

@ -7,7 +7,7 @@ if test -n "`grep '^#undef VERSION' config.h.in`"; then
fi
AM_CONFIG_HEADER(config.h)
AM_INIT_AUTOMAKE(irssi, 0.8.10-rc4)
AM_INIT_AUTOMAKE(irssi, 0.8.10-rc5)
AM_MAINTAINER_MODE

View File

@ -5,11 +5,12 @@
-msgs: Maximum number of nicks in one /MSG command
-modes: Maximum number of mode changes in one /MODE command
-whois: Maximum number of nicks in one /WHOIS command
-cmdspeed: Same as /SET cmd_queue_speed, see section 3.1
-cmdspeed: Same as /SET cmd_queue_speed, see section 3.1
-cmdmax: Same as /SET cmd_max_at_once, see section 3.1
-nick, -user, -realname: Specify what nick/user/name to use
-host: Specify what host name to use, if you have multiple
-autosendcmd: Command to send after connecting to a server
-usermode: Specify what usermode to use on this network
-autosendcmd: Command to send after connecting to a server
With -autosendcmd argument you can automatically run any commands
after connecting to network. This is useful for automatically

View File

@ -12,3 +12,37 @@ RECODE REMOVE %|[<target>]
%|Remove an entry from the conversion database (if target is
omitted, the current channel or query will be used)
To specify your local charset you have to set term_charset
Example:
/SET term_charset <charset>
To see the recode settings: /SET recode
You can change them with /SET
Examples:
/SET recode_fallback <charset>
to set the fallback charset for incoming events
This charset will be used if a conversion with
the defined charset(/recode add) fails, and if no
charset for the target(query or channel) is defined at all.
/SET recode_out_default_charset <charset>
to set the global outgoing charset
When it's set to a charset it will be used instead
of the charset you have defined with /recode add
/SET recode_transliterate ON
to enable the global transliteration.
The transliteration is based on your locale settings,
if it doesn't work properly your locale settings may be wrong.
You can enable it per target by adding //TRANSLIT to the <charset>
Hint: <charset> can be almost everything listed by 'iconv -l'

View File

@ -80,7 +80,7 @@ $A .. $Z is important.
$Z time of day (hh:mm, can be changed with /SET timestamp_format)
$$ a literal '$'
$versiontim prints time of the irssi version in HHMM format
$versiontime prints time of the irssi version in HHMM format
$sysname system name (eg. Linux)
$sysrelease system release (eg. 2.2.18)
$sysarch system architecture (eg. i686)

View File

@ -38,7 +38,8 @@ enum {
CMDERR_CHAN_NOT_SYNCED, /* channel not fully synchronized yet */
CMDERR_ILLEGAL_PROTO, /* requires different chat protocol than the active server */
CMDERR_NOT_GOOD_IDEA, /* not good idea to do, -yes overrides this */
CMDERR_INVALID_TIME /* invalid time specification */
CMDERR_INVALID_TIME, /* invalid time specification */
CMDERR_INVALID_CHARSET /* invalid charset specification */
};
/* Return the full command for `alias' */

View File

@ -20,7 +20,10 @@
#include "module.h"
#include "settings.h"
#include "servers.h"
#include "signals.h"
#include "lib-config/iconfig.h"
#include "misc.h"
#ifdef HAVE_GLIB2
static gboolean recode_get_charset(const char **charset)
@ -29,39 +32,65 @@ static gboolean recode_get_charset(const char **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
gboolean is_valid_charset(const char *charset)
{
#ifdef HAVE_GLIB2
const char *from="UTF-8";
const char *str="irssi";
char *recoded;
gboolean valid;
if (!charset || *charset == '\0')
return FALSE;
recoded = g_convert(str, strlen(str), charset, from, NULL, NULL, NULL);
valid = (recoded != NULL);
g_free(recoded);
return valid;
#else
if (!charset || *charset =='\0')
return FALSE;
return TRUE;
#endif
}
static gboolean is_translit(const char *charset)
{
char *pos;
pos = stristr(charset, "//translit");
return (pos != NULL);
}
char *recode_in(const char *str, const char *target)
{
#ifdef HAVE_GLIB2
const char *from = NULL;
const char *to = NULL;
char *translit_to = NULL;
char *recoded = NULL;
gboolean term_is_utf8;
gboolean str_is_utf8;
gboolean translit;
gboolean term_is_utf8, str_is_utf8, 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");
if (target != NULL)
if (target != NULL && from == NULL)
from = iconfig_get_str("conversions", target, NULL);
term_is_utf8 = recode_get_charset(&to);
if (translit)
to = g_strdup_printf("%s//TRANSLIT", to);
if (translit && !is_translit(to))
to = translit_to = g_strconcat(to, "//TRANSLIT", NULL);
if (from)
recoded = g_convert(str, len, to, from, NULL, NULL, NULL);
@ -69,10 +98,10 @@ char *recode_in(const char *str, const char *target)
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);
@ -93,31 +122,34 @@ char *recode_out(const char *str, const char *target)
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;
char *translit_to = NULL;
/* default outgoing charset if set */
to = settings_get_str("recode_out_default_charset");
if (to == NULL || *to == '\0')
to = iconfig_get_str("conversions", target, NULL);
if (to && *to != '\0') {
if (translit && !is_translit(to))
to = translit_to = g_strconcat(to ,"//TRANSLIT", 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);
}
g_free(translit_to);
}
if (!recoded)
recoded = g_strdup(str);
return recoded;
#else
return g_strdup(str);
@ -128,7 +160,7 @@ 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);
settings_add_bool("misc", "recode_transliterate", FALSE);
}
void recode_deinit(void)

View File

@ -3,6 +3,7 @@
char *recode_in (const char *str, const char *target);
char *recode_out (const char *str, const char *target);
gboolean is_valid_charset(const char *charset);
void recode_init (void);
void recode_deinit (void);

View File

@ -25,6 +25,7 @@
#include "misc.h"
#include "lib-config/iconfig.h"
#include "recode.h"
#include "settings.h"
#include "default-config.h"
@ -393,8 +394,8 @@ static void sig_init_finished(void)
if (config_changed) {
/* some backwards compatibility changes were made to
config file, reload it */
g_warning("Some time and size related settings were "
"automatically changed to new format, please /SAVE");
g_warning("Some settings were automatically "
"updated, please /SAVE");
signal_emit("setup changed", 0);
}
}
@ -439,15 +440,41 @@ void settings_clean_invalid(void)
static int backwards_compatibility(const char *module, CONFIG_NODE *node,
CONFIG_NODE *parent)
{
const char *new_key;
const char *new_key, *new_module;
CONFIG_NODE *new_node;
char *new_value;
int old_value;
new_value = NULL; new_key = NULL; new_module = NULL;
/* fe-text term_type -> fe-common/core term_charset - for 0.8.10-> */
if (strcmp(module, "fe-text") == 0) {
if (strcasecmp(node->key, "term_type") == 0 ||
/* kludge for cvs-version where term_charset was in fe-text */
strcasecmp(node->key, "term_charset") == 0) {
new_module = "fe-common/core";
new_key = "term_charset";
new_value = !is_valid_charset(node->value) ? NULL :
g_strdup(node->value);
new_node = iconfig_node_traverse("settings", FALSE);
new_node = new_node == NULL ? NULL :
config_node_section(new_node, new_module, -1);
config_node_set_str(mainconfig, new_node,
new_key, new_value);
/* remove old */
config_node_set_str(mainconfig, parent,
node->key, NULL);
g_free(new_value);
config_changed = TRUE;
return new_key != NULL;
}
}
new_value = NULL, new_key = NULL;
/* FIXME: remove later - for 0.8.6 -> */
if (node->value == NULL || !is_numeric(node->value, '\0'))
return FALSE;
new_value = NULL; new_key = NULL;
old_value = atoi(node->value);
if (strcmp(module, "fe-text") == 0) {

View File

@ -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 \

View File

@ -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);

View File

@ -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;

View File

@ -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);
}

View File

@ -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;
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);
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", "");
}
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
}

View File

@ -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;
const char *p;
char *str, *out;
out = str = g_strdup(input);
for (p = input; *p != '\0'; p++) {
if (*p == 3) {
p++;
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;
}
/* mirc color */
get_mirc_color(&p, NULL, NULL);
p--;
continue;
}
if (*p == 4 && p[1] != '\0') {
if (p[1] >= FORMAT_STYLE_SPECIAL) {
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;
}
/* 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;
}
}
}

View File

@ -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 },

View File

@ -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,

View File

@ -2,6 +2,7 @@
#define MODULE_NAME "fe-common/core"
typedef guint32 unichar;
typedef struct {
time_t time;
char *nick;

View File

@ -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);
}

251
src/fe-common/core/utf8.c Normal file
View File

@ -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];
}

31
src/fe-common/core/utf8.h Normal file
View File

@ -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

View File

@ -24,6 +24,7 @@
#include "misc.h"
#include "settings.h"
#include "levels.h"
#include "recode.h"
#include "irc-servers.h"
#include "irc-channels.h"
@ -228,15 +229,17 @@ static void event_nick_in_use(IRC_SERVER_REC *server, const char *data)
static void event_topic_get(IRC_SERVER_REC *server, const char *data)
{
const char *channel;
char *params, *topic;
char *params, *topic, *recoded;
g_return_if_fail(data != NULL);
params = event_get_params(data, 3, NULL, &channel, &topic);
recoded = recode_in(topic, channel);
channel = get_visible_target(server, channel);
printformat(server, channel, MSGLEVEL_CRAP,
IRCTXT_TOPIC, channel, topic);
IRCTXT_TOPIC, channel, recoded);
g_free(params);
g_free(recoded);
}
static void event_topic_info(IRC_SERVER_REC *server, const char *data)

View File

@ -30,6 +30,7 @@
#include "servers-reconnect.h"
#include "queries.h"
#include "ignore.h"
#include "recode.h"
#include "irc-servers.h"
#include "irc-channels.h"
@ -44,57 +45,63 @@
static void event_privmsg(IRC_SERVER_REC *server, const char *data,
const char *nick, const char *addr)
{
char *params, *target, *msg;
char *params, *target, *msg, *recoded;
g_return_if_fail(data != NULL);
params = event_get_params(data, 2 | PARAM_FLAG_GETREST, &target, &msg);
if (nick == NULL) nick = server->real_address;
if (addr == NULL) addr = "";
recoded = recode_in(msg, target);
if (*target == '@' && ischannel(target[1])) {
/* Hybrid 6 feature, send msg to all ops in channel */
signal_emit("message irc op_public", 5,
server, msg, nick, addr,
server, recoded, nick, addr,
get_visible_target(server, target+1));
} else {
signal_emit(ischannel(*target) ?
"message public" : "message private", 5,
server, msg, nick, addr,
server, recoded, nick, addr,
get_visible_target(server, target));
}
g_free(params);
g_free(recoded);
}
static void ctcp_action(IRC_SERVER_REC *server, const char *data,
const char *nick, const char *addr,
const char *target)
{
g_return_if_fail(data != NULL);
char *recoded;
g_return_if_fail(data != NULL);
recoded = recode_in(data, target);
signal_emit("message irc action", 5,
server, data, nick, addr,
server, recoded, nick, addr,
get_visible_target(server, target));
g_free(recoded);
}
static void event_notice(IRC_SERVER_REC *server, const char *data,
const char *nick, const char *addr)
{
char *params, *target, *msg;
char *params, *target, *msg, *recoded;
g_return_if_fail(data != NULL);
params = event_get_params(data, 2 | PARAM_FLAG_GETREST, &target, &msg);
recoded = recode_in(msg, target);
if (nick == NULL) {
nick = server->real_address == NULL ?
server->connrec->address :
server->real_address;
}
signal_emit("message irc notice", 5, server, msg, nick, addr,
signal_emit("message irc notice", 5, server, recoded, nick, addr,
get_visible_target(server, target));
g_free(params);
g_free(recoded);
}
static void event_join(IRC_SERVER_REC *server, const char *data,
@ -116,15 +123,17 @@ static void event_join(IRC_SERVER_REC *server, const char *data,
static void event_part(IRC_SERVER_REC *server, const char *data,
const char *nick, const char *addr)
{
char *params, *channel, *reason;
char *params, *channel, *reason, *recoded;
g_return_if_fail(data != NULL);
params = event_get_params(data, 2 | PARAM_FLAG_GETREST,
&channel, &reason);
recoded = recode_in(reason, channel);
signal_emit("message part", 5, server,
get_visible_target(server, channel), nick, addr, reason);
get_visible_target(server, channel), nick, addr, recoded);
g_free(params);
g_free(recoded);
}
static void event_quit(IRC_SERVER_REC *server, const char *data,
@ -139,16 +148,18 @@ static void event_quit(IRC_SERVER_REC *server, const char *data,
static void event_kick(IRC_SERVER_REC *server, const char *data,
const char *kicker, const char *addr)
{
char *params, *channel, *nick, *reason;
char *params, *channel, *nick, *reason, *recoded;
g_return_if_fail(data != NULL);
params = event_get_params(data, 3 | PARAM_FLAG_GETREST,
&channel, &nick, &reason);
recoded = recode_in(reason, channel);
signal_emit("message kick", 6,
server, get_visible_target(server, channel),
nick, kicker, addr, reason);
nick, kicker, addr, recoded);
g_free(params);
g_free(recoded);
}
static void event_kill(IRC_SERVER_REC *server, const char *data,
@ -244,15 +255,17 @@ static void event_invite(IRC_SERVER_REC *server, const char *data,
static void event_topic(IRC_SERVER_REC *server, const char *data,
const char *nick, const char *addr)
{
char *params, *channel, *topic;
char *params, *channel, *topic, *recoded;
g_return_if_fail(data != NULL);
params = event_get_params(data, 2 | PARAM_FLAG_GETREST,
&channel, &topic);
recoded = recode_in(topic, channel);
signal_emit("message topic", 5, server,
get_visible_target(server, channel), topic, nick, addr);
get_visible_target(server, channel), recoded, nick, addr);
g_free(params);
g_free(recoded);
}
static void event_error(IRC_SERVER_REC *server, const char *data)

View File

@ -64,7 +64,6 @@ irssi_SOURCES = \
textbuffer-commands.c \
textbuffer-reformat.c \
textbuffer-view.c \
utf8.c \
irssi.c \
module-formats.c
@ -81,7 +80,6 @@ noinst_HEADERS = \
textbuffer.h \
textbuffer-view.h \
textbuffer-reformat.h \
utf8.h \
module.h \
module-formats.h

View File

@ -21,7 +21,6 @@
#include "module.h"
#include "signals.h"
#include "expandos.h"
#include "recode.h"
#include "special-vars.h"
#include "themes.h"
@ -687,8 +686,6 @@ void statusbar_item_default_handler(SBAR_ITEM_REC *item, int get_size_only,
SERVER_REC *server;
WI_ITEM_REC *wiitem;
char *tmpstr, *tmpstr2;
const char *target;
char *recoded;
int len;
if (str == NULL)
@ -727,11 +724,7 @@ void statusbar_item_default_handler(SBAR_ITEM_REC *item, int get_size_only,
tmpstr2 = reverse_controls(tmpstr);
g_free(tmpstr);
target = wiitem ? window_item_get_target(wiitem) : NULL;
recoded = recode_in(tmpstr2, target);
g_free(tmpstr2);
tmpstr = recoded;
tmpstr = tmpstr2;
if (get_size_only) {
item->min_size = item->max_size = format_get_length(tmpstr);
} else {

View File

@ -152,7 +152,6 @@ void term_common_init(void)
settings_add_bool("lookandfeel", "term_force_colors", FALSE);
settings_add_bool("lookandfeel", "term_auto_detach", FALSE);
settings_add_bool("lookandfeel", "mirc_blink_fix", FALSE);
settings_add_str("lookandfeel", "term_charset", "ISO8859-1");
force_colors = FALSE;
term_use_colors = term_has_colors() && settings_get_bool("colors");