[ekg2-commit] r4034 - trunk/plugins/irc: trunk/plugins/irc/irc.c trunk/plugins/irc/irc.h trunk/plugins/irc/misc.c trunk/plugins/irc/session-pl.txt

SVN commit svn w toxygen.net
Sob, 28 Cze 2008, 18:33:47 CEST


Author: wiechu
Date: 2008-06-28 18:33:47 +0200 (Sat, 28 Jun 2008)
New Revision: 4034

Modified:
   trunk/plugins/irc/irc.c
   trunk/plugins/irc/irc.h
   trunk/plugins/irc/misc.c
   trunk/plugins/irc/session-pl.txt
Log:
    add auto_guess_encoding to irc session.

Modified: trunk/plugins/irc/irc.c
===================================================================
--- trunk/plugins/irc/irc.c	2008-06-27 22:03:00 UTC (rev 4033)
+++ trunk/plugins/irc/irc.c	2008-06-28 16:33:47 UTC (rev 4034)
@@ -487,6 +487,65 @@
 	j->conv_in = ekg_convert_string_init(val, NULL, &(j->conv_out));
 }
 
+static void irc_changed_auto_guess_encoding(session_t *s, const char *var) {
+	const char *val;
+	irc_private_t *j;
+	conv_in_out_t *e;
+	list_t el;
+
+	if (!s || !(j = s->priv))
+		return;
+	
+	/* Clean old list */
+	for (el=j->auto_guess_encoding; el;) {
+		e = el->data;
+		el = el->next;
+		if (e->conv_in != (void*) -1) {
+			ekg_convert_string_destroy(e->conv_in);
+			ekg_convert_string_destroy(e->conv_out);
+		}
+		list_remove(&el, e, 1);
+	}
+
+	if (!(val = session_get(s, var)) || !*val) {
+		return;
+	}
+
+	char **args;
+	args = array_make(val, ",", 0, 1, 0);
+	int i;
+	for (i=0; args[i]; i++) {
+		char *to = NULL;
+		char *from = args[i];
+		if (!xstrcasecmp(from, config_console_charset)) {
+			/* ekg2 can't convert when from and to are the same 
+			 * trick: lets convert iso-8859-2 -> iso8859-2; utf8 -> utf-8; etc.
+			 */
+			char *p = from, *q;
+			to = xmalloc(xstrlen(from)+2);
+			q = to;
+			while ( (*p=tolower(*p)) && (*p>='a') && (*p<='z') )
+			    *q++ = *p++;
+			if (*p == '-')
+			    p++;
+			else
+			    *q++ = '-';
+			while ( (*q++ = *p++) )
+			    ;
+			*q = '\0';
+		}
+		e = xmalloc(sizeof(conv_in_out_t));
+		e->conv_in = ekg_convert_string_init(from, to, &(e->conv_out));
+		if (e->conv_in)
+		    list_add(&(j->auto_guess_encoding), e);
+		else
+		    debug_error("auto_guess_encoding skips unknown '%s' value\n", from);
+		xfree(to);
+	}
+
+	array_free(args);
+
+}
 /*                                                                       *
  * ======================================== HANDLERS ------------------- *
  *                                                                       */
@@ -2139,6 +2198,7 @@
 	PLUGIN_VAR_ADD("auto_back",		VAR_INT, "0", 0, NULL),
 	PLUGIN_VAR_ADD("auto_connect",		VAR_BOOL, "0", 0, NULL),
 	PLUGIN_VAR_ADD("auto_find",		VAR_BOOL, "0", 0, NULL),		/* it's really auto_whois */
+	PLUGIN_VAR_ADD("auto_guess_encoding",	VAR_STR, NULL, 0, irc_changed_auto_guess_encoding),
 	PLUGIN_VAR_ADD("auto_reconnect",	VAR_INT, "10", 0, NULL), 
 	PLUGIN_VAR_ADD("auto_channel_sync",	VAR_BOOL, "1", 0, NULL),		/* like channel_sync in irssi; better DO NOT turn it off! */
 	PLUGIN_VAR_ADD("auto_lusers_sync", 	VAR_BOOL, "0", 0, NULL),		/* sync lusers, stupid ;(,  G->dj: well why ? */

Modified: trunk/plugins/irc/irc.h
===================================================================
--- trunk/plugins/irc/irc.h	2008-06-27 22:03:00 UTC (rev 4033)
+++ trunk/plugins/irc/irc.h	2008-06-28 16:33:47 UTC (rev 4034)
@@ -63,10 +63,18 @@
 
 	list_t awaylog;
 
+	list_t auto_guess_encoding;
+
 	void *conv_in;
 	void *conv_out;
 } irc_private_t;
 
+/* data for private->auto_guess_encoding */
+typedef struct {
+	void *conv_in;
+	void *conv_out;
+} conv_in_out_t;
+
 typedef struct _irc_awaylog_t {
 	char *channame;	/* channel name, (null if priv) */
 	char *uid;	/* nickname who wrote to us	*/

Modified: trunk/plugins/irc/misc.c
===================================================================
--- trunk/plugins/irc/misc.c	2008-06-27 22:03:00 UTC (rev 4033)
+++ trunk/plugins/irc/misc.c	2008-06-28 16:33:47 UTC (rev 4034)
@@ -22,6 +22,7 @@
 #include <time.h>
 #include <unistd.h>
 #include <sys/time.h>
+#include <iconv.h>
 
 #ifndef NO_POSIX_SYSTEM
 #include <arpa/inet.h>
@@ -56,6 +57,55 @@
 
 #define OMITCOLON(x) ((*x)==':'?(x+1):(x))
 
+static char *try_convert_string_p(const char *ps, iconv_t cd) {
+#ifdef HAVE_ICONV
+	char *s = (char *) ps;
+		/* we can assume that both from and to aren't NULL in EKG2,
+		 * and cd is NULL in case of error, not -1 */
+	if (cd) {
+		char *buf, *ib, *ob;
+		size_t ibl, obl;
+
+		ib = s, ibl = xstrlen(s) + 1;
+		obl = 16 * ibl;
+		ob = buf = xmalloc(obl + 1);
+
+		iconv (cd, &ib, &ibl, &ob, &obl);
+
+		if (!ibl) {
+			*ob = '\0';
+			buf = (char*)xrealloc((void*)buf, xstrlen(buf)+1);
+			return buf;
+		}
+		xfree(buf);
+	}
+#endif
+	return NULL;
+}
+
+static char *irc_convert_in(irc_private_t *j, const char *line) {
+	char *recoded;
+	conv_in_out_t *e;
+	list_t el;
+
+	/* auto guess encoding */
+	for (el=j->auto_guess_encoding; el; el=el->next) {
+		e = el->data;
+		recoded = try_convert_string_p(line, e->conv_in);
+		if (recoded)
+			return recoded;
+	}
+
+	/* default recode */
+	if (j->conv_in == (void *) -1)
+		return NULL;
+
+	if (!(recoded = ekg_convert_string_p(line, j->conv_in)))
+		debug_error("[irc] ekg_convert_string_p() failed [%x] using not recoded text\n", j->conv_in);
+
+	return recoded;
+}
+
 /* cos co blabla, zwraca liczbe pochlonietych znakow przez '*' XXX */
 static int do_sample_wildcard_match(const char *str, const char *matchstr, const char stopon) {
 	int i;
@@ -625,17 +675,8 @@
 
 				xfree(chanp->topic);
 
-				if (j->conv_in != (void *) -1) {
-					char *recoded = ekg_convert_string_p(__topic, j->conv_in);
-					if (recoded) {
-						chanp->topic   = recoded;
-					} else {
-						debug_error("[irc] ekg_convert_string_p() failed [%x] using not recoded text\n", j->conv_in);
-						chanp->topic   = xstrdup(__topic);
-					}
-				} else
-					chanp->topic = xstrdup(__topic);
-
+				char *recoded = irc_convert_in(j, __topic);
+				chanp->topic  = recoded ? recoded : xstrdup(__topic);
 				coloured = irc_ircoldcolstr_to_ekgcolstr(s, 
 						chanp->topic, 1);
 				print_window(dest, s, 0, irccommands[ecode].name,
@@ -1077,6 +1118,7 @@
 	time_t		sent;
 	int		secure = 0, xosd_to_us = 0, xosd_is_priv = 0;
 	char		*ignore_nick = NULL;
+	char *recoded;
 
 	prv = !xstrcasecmp(param[1], "privmsg");
 	if (!prv && xstrcasecmp(param[1], "notice"))
@@ -1084,18 +1126,12 @@
 
 	mw = session_int_get(s, "make_window");
 
-	if (j->conv_in != (void *) -1) {
-		char *recoded = ekg_convert_string_p(OMITCOLON(param[3]), j->conv_in);
+	recoded = irc_convert_in(j, OMITCOLON(param[3]));
 
-		if (!recoded)
-			debug_error("[irc] ekg_convert_string_p() failed [%x] using not recoded text\n", j->conv_in);
+	ctcpstripped = ctcp_parser(s, prv, param[0], param[2], recoded ? recoded : OMITCOLON(param[3]));
 
-		ctcpstripped = ctcp_parser(s, prv, param[0], param[2], recoded ? recoded : OMITCOLON(param[3]));
+	xfree(recoded);
 
-		xfree(recoded);
-	} else
-		ctcpstripped = ctcp_parser(s, prv, param[0], param[2], OMITCOLON(param[3]));
-
 	if ((t = xstrchr(param[0], '!'))) *t='\0';
 	me = xstrdup(t?t+1:"");
 	xosd_nick = OMITCOLON(param[0]);
@@ -1490,16 +1526,8 @@
 	__topicby = OMITCOLON(param[0]);
 	__topic   = OMITCOLON(param[3]);
 	if (xstrlen(__topic)) {
-		if (j->conv_in != (void *) -1) {
-			char *recoded = ekg_convert_string_p(__topic, j->conv_in);
-			if (recoded) {
-				chanp->topic   = recoded;
-			} else {
-				debug_error("[irc] ekg_convert_string_p() failed [%x] using not recoded text\n", j->conv_in);
-				chanp->topic   = xstrdup(__topic);
-			}
-		} else
-			chanp->topic   = xstrdup(__topic);
+		char *recoded = irc_convert_in(j, __topic);
+		chanp->topic  = recoded ? recoded : xstrdup(__topic);;
 		chanp->topicby = xstrdup(__topicby);
 		coloured = irc_ircoldcolstr_to_ekgcolstr(s, chanp->topic, 1);
 		print_window(dest, s, 0, "IRC_TOPIC_CHANGE", session_name(s),

Modified: trunk/plugins/irc/session-pl.txt
===================================================================
--- trunk/plugins/irc/session-pl.txt	2008-06-27 22:03:00 UTC (rev 4033)
+++ trunk/plugins/irc/session-pl.txt	2008-06-28 16:33:47 UTC (rev 4034)
@@ -2,6 +2,12 @@
 // (c) 2004-2005 Michal 'GiM' Spadlinski
 //		Jakub 'darkjames' Zawadzki
 
+auto_guess_encoding
+	typ: tekst
+	domyślna wartość: brak
+	
+	lista kodowań, według których będziemy próbować przekodować przychodzący tekst
+
 ban_type
 	typ: liczba
 	domyślna wartość: 10



Więcej informacji o liście dyskusyjnej ekg2-commit