Updated italian translation
[midnight-commander.git] / src / charsets.c
blob5666c23e3de876f3d8cb3a9908df283b7212c799
1 /* Text conversion from one charset to another.
3 Copyright (C) 2001 Walery Studennikov <despair@sama.ru>
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 #include <config.h>
22 #ifdef HAVE_CHARSET
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <string.h>
28 #include <iconv.h>
30 #include "global.h"
31 #include "charsets.h"
33 int n_codepages = 0;
35 struct codepage_desc *codepages;
37 unsigned char conv_displ[256];
38 unsigned char conv_input[256];
40 int
41 load_codepages_list (void)
43 int result = -1;
44 FILE *f;
45 char *fname;
46 char buf[256];
47 extern char *mc_home;
48 extern int display_codepage;
49 char *default_codepage = NULL;
51 fname = concat_dir_and_file (mc_home, CHARSETS_INDEX);
52 if (!(f = fopen (fname, "r"))) {
53 fprintf (stderr, _("Warning: file %s not found\n"), fname);
54 g_free (fname);
55 return -1;
57 g_free (fname);
59 for (n_codepages = 0; fgets (buf, sizeof (buf), f);)
60 if (buf[0] != '\n' && buf[0] != '\0' && buf[0] != '#')
61 ++n_codepages;
62 rewind (f);
64 codepages = g_new0 (struct codepage_desc, n_codepages + 1);
66 for (n_codepages = 0; fgets (buf, sizeof buf, f);) {
67 /* split string into id and cpname */
68 char *p = buf;
69 int buflen = strlen (buf);
71 if (*p == '\n' || *p == '\0' || *p == '#')
72 continue;
74 if (buflen > 0 && buf[buflen - 1] == '\n')
75 buf[buflen - 1] = '\0';
76 while (*p != '\t' && *p != ' ' && *p != '\0')
77 ++p;
78 if (*p == '\0')
79 goto fail;
81 *p++ = 0;
83 while (*p == '\t' || *p == ' ')
84 ++p;
85 if (*p == '\0')
86 goto fail;
88 if (strcmp (buf, "default") == 0) {
89 default_codepage = g_strdup (p);
90 continue;
93 codepages[n_codepages].id = g_strdup (buf);
94 codepages[n_codepages].name = g_strdup (p);
95 ++n_codepages;
98 if (default_codepage) {
99 display_codepage = get_codepage_index (default_codepage);
100 g_free (default_codepage);
103 result = n_codepages;
104 fail:
105 fclose (f);
106 return result;
109 void
110 free_codepages_list (void)
112 if (n_codepages > 0) {
113 int i;
114 for (i = 0; i < n_codepages; i++) {
115 g_free (codepages[i].id);
116 g_free (codepages[i].name);
118 n_codepages = 0;
119 g_free (codepages);
120 codepages = 0;
124 #define OTHER_8BIT "Other_8_bit"
126 const char *
127 get_codepage_id (int n)
129 return (n < 0) ? OTHER_8BIT : codepages[n].id;
133 get_codepage_index (const char *id)
135 int i;
136 if (strcmp (id, OTHER_8BIT) == 0)
137 return -1;
138 for (i = 0; codepages[i].id; ++i)
139 if (strcmp (id, codepages[i].id) == 0)
140 return i;
141 return -1;
144 static char
145 translate_character (iconv_t cd, char c)
147 char outbuf[4], *obuf;
148 size_t ibuflen, obuflen, count;
150 ICONV_CONST char *ibuf = &c;
151 obuf = outbuf;
152 ibuflen = 1;
153 obuflen = 4;
155 count = iconv (cd, &ibuf, &ibuflen, &obuf, &obuflen);
156 if (count != ((size_t) -1) && ibuflen == 0)
157 return outbuf[0];
159 return UNKNCHAR;
162 char errbuf[255];
165 * FIXME: This assumes that ASCII is always the first encoding
166 * in mc.charsets
168 #define CP_ASCII 0
170 const char *
171 init_translation_table (int cpsource, int cpdisplay)
173 int i;
174 iconv_t cd;
175 const char *cpsour, *cpdisp;
177 /* Fill inpit <-> display tables */
179 if (cpsource < 0 || cpdisplay < 0 || cpsource == cpdisplay) {
180 for (i = 0; i <= 255; ++i) {
181 conv_displ[i] = i;
182 conv_input[i] = i;
184 return NULL;
187 for (i = 0; i <= 127; ++i) {
188 conv_displ[i] = i;
189 conv_input[i] = i;
192 cpsour = codepages[cpsource].id;
193 cpdisp = codepages[cpdisplay].id;
195 /* display <- inpit table */
197 cd = iconv_open (cpdisp, cpsour);
198 if (cd == (iconv_t) - 1) {
199 g_snprintf (errbuf, sizeof (errbuf),
200 _("Cannot translate from %s to %s"), cpsour, cpdisp);
201 return errbuf;
204 for (i = 128; i <= 255; ++i)
205 conv_displ[i] = translate_character (cd, i);
207 iconv_close (cd);
209 /* inpit <- display table */
211 cd = iconv_open (cpsour, cpdisp);
212 if (cd == (iconv_t) - 1) {
213 g_snprintf (errbuf, sizeof (errbuf),
214 _("Cannot translate from %s to %s"), cpdisp, cpsour);
215 return errbuf;
218 for (i = 128; i <= 255; ++i) {
219 unsigned char ch;
220 ch = translate_character (cd, i);
221 conv_input[i] = (ch == UNKNCHAR) ? i : ch;
224 iconv_close (cd);
226 return NULL;
229 void
230 convert_to_display (char *str)
232 if (!str)
233 return;
235 while (*str) {
236 *str = conv_displ[(unsigned char) *str];
237 str++;
241 void
242 convert_from_input (char *str)
244 if (!str)
245 return;
247 while (*str) {
248 *str = conv_input[(unsigned char) *str];
249 str++;
252 #endif /* HAVE_CHARSET */