Added SILC Thread Queue API
[runtime.git] / apps / irssi / src / core / recode.c
1 /*
2  recode.c : irssi
3
4     Copyright (C) 1999-2000 Timo Sirainen
5
6     This program is free software; you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by
8     the Free Software Foundation; either version 2 of the License, or
9     (at your option) any later version.
10
11     This program is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14     GNU General Public License for more details.
15
16     You should have received a copy of the GNU General Public License
17     along with this program; if not, write to the Free Software
18     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19 */
20
21 #include "module.h"
22 #include "settings.h"
23 #include "servers.h"
24 #include "signals.h"
25 #include "lib-config/iconfig.h"
26 #include "misc.h"
27
28 static gboolean recode_get_charset(const char **charset)
29 {
30         *charset = settings_get_str("term_charset");
31         if (**charset)
32                 /* we use the same test as in src/fe-text/term.c:123 */
33                 return (g_strcasecmp(*charset, "utf-8") == 0);
34
35 #ifdef HAVE_GLIB2
36         return g_get_charset(charset);
37 #else
38         return FALSE;
39 #endif
40 }
41
42 gboolean is_utf8(void)
43 {
44         const char *charset;
45
46         return recode_get_charset(&charset);
47 }
48
49 #ifdef HAVE_GLIB2
50 static gboolean is_translit(const char *charset)
51 {
52         char *pos;
53
54         pos = stristr(charset, "//translit");
55         return (pos != NULL);
56 }
57 #endif
58
59 gboolean is_valid_charset(const char *charset)
60 {
61 #ifdef HAVE_GLIB2
62         const char *from="UTF-8";
63         const char *str="irssi";
64         char *recoded, *to = NULL;
65         gboolean valid;
66
67         if (!charset || *charset == '\0')
68                 return FALSE;
69
70         if (settings_get_bool("recode_transliterate") && !is_translit(charset))
71                 charset = to = g_strconcat(charset, "//TRANSLIT", NULL);
72
73         recoded = g_convert(str, strlen(str), charset, from, NULL, NULL, NULL);
74         valid = (recoded != NULL);
75         g_free(recoded);
76         g_free(to);
77         return valid;
78 #else
79         if (!charset || *charset =='\0')
80                 return FALSE;
81         return TRUE;
82 #endif
83 }
84
85 char *recode_in(const SERVER_REC *server, const char *str, const char *target)
86 {
87 #ifdef HAVE_GLIB2
88         const char *from = NULL;
89         const char *to = NULL;
90         char *translit_to = NULL;
91         char *recoded = NULL;
92         gboolean term_is_utf8, str_is_utf8, translit, recode, autodetect;
93         int len;
94         int i;
95
96         if (!str)
97                 return NULL;
98
99         recode = settings_get_bool("recode");
100         if (!recode)
101                 return g_strdup(str);
102
103         len = strlen(str);
104
105         /* Only validate for UTF-8 if an 8-bit encoding. */
106         str_is_utf8 = 0;
107         for (i = 0; i < len; ++i) {
108                 if (str[i] & 0x80) {
109                         str_is_utf8 = g_utf8_validate(str, len, NULL);
110                         break;
111                 }
112         }
113         translit = settings_get_bool("recode_transliterate");
114         autodetect = settings_get_bool("recode_autodetect_utf8");
115         term_is_utf8 = recode_get_charset(&to);
116
117         if (autodetect && str_is_utf8)
118                 if (term_is_utf8)
119                         return g_strdup(str);
120                 else
121                         from = "UTF-8";
122                         
123         else {
124                 if (server != NULL && server->tag != NULL && target != NULL) {
125                         char *tagtarget = g_strdup_printf("%s/%s", server->tag, target);
126                         from = iconfig_get_str("conversions", tagtarget, NULL);
127                         g_free(tagtarget);
128                 }
129
130                 if (target != NULL && from == NULL)
131                         from = iconfig_get_str("conversions", target, NULL);
132
133                 if (from == NULL && server != NULL)
134                         from = iconfig_get_str("conversions", server->tag, NULL);
135
136         }
137
138         if (translit && !is_translit(to))
139                 to = translit_to = g_strconcat(to, "//TRANSLIT", NULL);
140                 
141         if (from)
142                 recoded = g_convert_with_fallback(str, len, to, from, NULL, NULL, NULL, NULL);
143
144         if (!recoded) {
145                 if (term_is_utf8) {
146                         if (!str_is_utf8)
147                                 from = settings_get_str("recode_fallback");
148
149                 } else if (str_is_utf8)
150                         from = "UTF-8";
151
152                 if (from)
153                         recoded = g_convert_with_fallback(str, len, to, from, NULL, NULL, NULL, NULL);
154
155                 if (!recoded)
156                         recoded = g_strdup(str);
157         }
158         g_free(translit_to);
159         return recoded;
160 #else
161         return g_strdup(str);
162 #endif
163 }
164
165 char *recode_out(const SERVER_REC *server, const char *str, const char *target)
166 {
167 #ifdef HAVE_GLIB2
168         char *recoded = NULL;
169         const char *from = NULL;
170         const char *to = NULL;
171         char *translit_to = NULL;
172         gboolean translit, term_is_utf8, recode;
173         int len;
174
175         if (!str)
176                 return NULL;
177
178         recode = settings_get_bool("recode");
179         if (!recode)
180                 return g_strdup(str);
181
182         len = strlen(str);
183
184         translit = settings_get_bool("recode_transliterate");
185
186         if (server != NULL && server->tag != NULL && target != NULL) {
187                 char *tagtarget = g_strdup_printf("%s/%s", server->tag, target);
188                 to = iconfig_get_str("conversions", tagtarget, NULL);
189                 g_free(tagtarget);
190         }
191         if (to == NULL || *to == '\0')
192                 to = iconfig_get_str("conversions", target, NULL);
193         if ((to == NULL || *to == '\0') && server != NULL)
194                 to = iconfig_get_str("conversions", server->tag, NULL);
195         if (to == NULL || *to == '\0')
196                 /* default outgoing charset if set */
197                 to = settings_get_str("recode_out_default_charset");
198
199         if (to && *to != '\0') {
200                 if (translit && !is_translit(to))
201                         to = translit_to = g_strconcat(to ,"//TRANSLIT", NULL);
202
203                 term_is_utf8 = recode_get_charset(&from);
204                 recoded = g_convert(str, len, to, from, NULL, NULL, NULL);
205         }
206         g_free(translit_to);
207         if (!recoded)
208                 recoded = g_strdup(str);
209
210         return recoded;
211 #else
212         return g_strdup(str);
213 #endif
214 }
215
216 void recode_init(void)
217 {
218         settings_add_bool("misc", "recode", TRUE);
219         settings_add_str("misc", "recode_fallback", "CP1252");
220         settings_add_str("misc", "recode_out_default_charset", "");
221         settings_add_bool("misc", "recode_transliterate", TRUE);
222         settings_add_bool("misc", "recode_autodetect_utf8", TRUE);
223 }
224
225 void recode_deinit(void)
226 {       
227
228 }