Added SILC Thread Queue API
[crypto.git] / apps / irssi / src / fe-common / core / translation.c
1 /*
2  translation.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 "module-formats.h"
23 #include "signals.h"
24 #include "line-split.h"
25 #include "misc.h"
26 #include "levels.h"
27 #include "settings.h"
28
29 #include "printtext.h"
30
31 unsigned char translation_in[256], translation_out[256];
32 static char *current_translation;
33
34 void translation_reset(void)
35 {
36         int n;
37
38         for (n = 0; n < 256; n++)
39                 translation_in[n] = (unsigned char) n;
40         for (n = 0; n < 256; n++)
41                 translation_out[n] = (unsigned char) n;
42 }
43
44 void translate_output(char *text)
45 {
46         while (*text != '\0') {
47                 *text = (char) translation_out[(int) (unsigned char) *text];
48                 text++;
49         }
50 }
51
52 #define gethex(a) \
53         (i_isdigit(a) ? ((a)-'0') : (i_toupper(a)-'A'+10))
54
55 void translation_parse_line(const char *str, int *pos)
56 {
57         const char *ptr;
58         int value;
59
60         for (ptr = str; *ptr != '\0'; ptr++) {
61                 if (ptr[0] != '0' || ptr[1] != 'x')
62                         break;
63                 ptr += 2;
64
65                 value = (gethex(ptr[0]) << 4) + gethex(ptr[1]);
66                 if (*pos < 256)
67                         translation_in[*pos] = (unsigned char) value;
68                 else
69                         translation_out[*pos-256] = (unsigned char) value;
70                 (*pos)++;
71
72                 ptr += 2;
73                 if (*ptr != ',') break;
74         }
75 }
76
77 int translation_read(const char *file)
78 {
79         char tmpbuf[1024], *str, *path;
80         LINEBUF_REC *buffer;
81         int f, pos, ret, recvlen;
82
83         g_return_val_if_fail(file != NULL, FALSE);
84
85         path = convert_home(file);
86         f = open(file, O_RDONLY);
87         g_free(path);
88
89         if (f == -1) {
90                 printformat(NULL, NULL, MSGLEVEL_CLIENTERROR,
91                             TXT_TRANSLATION_NOT_FOUND, file,
92                             g_strerror(errno));
93                 return FALSE;
94         }
95
96         pos = 0; buffer = NULL;
97         while (pos < 512) {
98                 recvlen = read(f, tmpbuf, sizeof(tmpbuf));
99
100                 ret = line_split(tmpbuf, recvlen, &str, &buffer);
101                 if (ret <= 0) break;
102
103                 translation_parse_line(str, &pos);
104         }
105         line_split_free(buffer);
106
107         close(f);
108         if (pos != 512) {
109                 translation_reset();
110                 printformat(NULL, NULL, MSGLEVEL_CLIENTERROR,
111                             TXT_TRANSLATION_FILE_ERROR, file);
112         }
113         return pos == 512;
114 }
115
116 static void read_settings(void)
117 {
118         const char *translation;
119
120         translation = settings_get_str("translation");
121         if (*translation == '\0') {
122                 if (current_translation != NULL) {
123                         g_free_and_null(current_translation);
124                         translation_reset();
125                 }
126                 return;
127         }
128
129         if (current_translation == NULL ||
130             strcmp(translation, current_translation) != 0) {
131                 g_free_not_null(current_translation);
132                 current_translation = g_strdup(translation);
133                 translation_read(translation);
134         }
135 }
136
137 void translation_init(void)
138 {
139         translation_reset();
140
141         current_translation = NULL;
142         settings_add_str("misc", "translation", "");
143         signal_add("setup changed", (SIGNAL_FUNC) read_settings);
144
145         read_settings();
146 }
147
148 void translation_deinit(void)
149 {
150         read_settings();
151         signal_remove("setup changed", (SIGNAL_FUNC) read_settings);
152 }