*** empty log message ***
[midnight-commander.git] / src / charsets.c
blobd9ceb1e7141145c73b404920d6595edd16e74c61
1 #include <config.h>
3 #ifdef HAVE_CHARSET
4 #include <stdlib.h>
5 #include <stdio.h>
6 #include <string.h>
7 #include <iconv.h>
9 #include "global.h"
10 #include "charsets.h"
12 int n_codepages = 0;
14 struct codepage_desc *codepages;
16 uchar conv_displ[256];
17 uchar conv_input[256];
18 uchar printable[256];
20 int load_codepages_list(void)
22 int result = -1;
23 FILE *f;
24 char *fname;
25 char buf[256];
26 extern char* mc_home;
27 extern int display_codepage;
28 char * default_codepage = NULL;
30 fname = concat_dir_and_file (mc_home, CHARSETS_INDEX);
31 if ( !( f = fopen( fname, "r" ) ) ) {
32 fprintf (stderr, _("Warning: file %s not found\n"), fname);
33 g_free (fname);
34 return -1;
36 g_free (fname);
38 for ( n_codepages=0; fgets( buf, sizeof (buf), f ); )
39 if ( buf[0] != '\n' && buf[0] != '\0' && buf [0] != '#' )
40 ++n_codepages;
41 rewind( f );
43 codepages = calloc( n_codepages + 1, sizeof(struct codepage_desc) );
45 for( n_codepages = 0; fgets( buf, sizeof buf, f ); ) {
46 /* split string into id and cpname */
47 char *p = buf;
48 int buflen = strlen( buf );
50 if ( *p == '\n' || *p == '\0' || *p == '#')
51 continue;
53 if ( buflen > 0 && buf[ buflen - 1 ] == '\n' )
54 buf[ buflen - 1 ] = '\0';
55 while ( *p != '\t' && *p != ' ' && *p != '\0' )
56 ++p;
57 if ( *p == '\0' )
58 goto fail;
60 *p++ = 0;
62 while ( *p == '\t' || *p == ' ' )
63 ++p;
64 if ( *p == '\0' )
65 goto fail;
67 if (strcmp (buf, "default") == 0) {
68 default_codepage = strdup (p);
69 continue;
72 codepages[n_codepages].id = strdup( buf );
73 codepages[n_codepages].name = strdup( p );
74 ++n_codepages;
77 if (default_codepage) {
78 display_codepage = get_codepage_index (default_codepage);
79 free (default_codepage);
82 result = n_codepages;
83 fail:
84 fclose( f );
85 return result;
88 #define OTHER_8BIT "Other_8_bit"
90 char *get_codepage_id( int n )
92 return (n < 0) ? OTHER_8BIT : codepages[ n ].id;
95 int get_codepage_index( const char *id )
97 int i;
98 if (strcmp( id, OTHER_8BIT ) == 0)
99 return -1;
100 for ( i=0; codepages[ i ].id; ++i )
101 if (strcmp( id, codepages[ i ].id ) == 0)
102 return i;
103 return -1;
106 static char translate_character( iconv_t cd, char c )
108 char outbuf[4], *obuf;
109 size_t ibuflen, obuflen, count;
111 char *ibuf = &c;
112 obuf = outbuf;
113 ibuflen = 1; obuflen = 4;
115 count = iconv(cd, &ibuf, &ibuflen, &obuf, &obuflen);
116 if (count >= 0 && ibuflen == 0)
117 return outbuf[0];
119 return UNKNCHAR;
122 char errbuf[255];
125 * FIXME: This assumes that ASCII is always the first encoding
126 * in mc.charsets
128 #define CP_ASCII 0
130 char* init_printable_table( int cpdisplay )
132 int i;
134 /* Fill printable characters table */
135 for (i=0; i<=127; ++i)
136 printable[i] = (i > 31 && i != 127);
138 for (i=128; i<=255; ++i) {
139 printable[i] = 1;
142 return NULL;
145 char* init_translation_table( int cpsource, int cpdisplay )
147 int i;
148 iconv_t cd;
149 char *cpsour, *cpdisp;
151 /* Fill inpit <-> display tables */
153 if (cpsource < 0 || cpdisplay < 0 || cpsource == cpdisplay) {
154 for (i=0; i<=255; ++i) {
155 conv_displ[i] = i;
156 conv_input[i] = i;
158 return NULL;
161 for (i=0; i<=127; ++i) {
162 conv_displ[i] = i;
163 conv_input[i] = i;
166 cpsour = codepages[ cpsource ].id;
167 cpdisp = codepages[ cpdisplay ].id;
169 /* display <- inpit table */
171 cd = iconv_open( cpdisp, cpsour );
172 if (cd == (iconv_t) -1) {
173 sprintf( errbuf, _("Cannot translate from %s to %s"), cpsour, cpdisp );
174 return errbuf;
177 for (i=128; i<=255; ++i)
178 conv_displ[i] = translate_character( cd, i );
180 iconv_close( cd );
182 /* inpit <- display table */
184 cd = iconv_open( cpsour, cpdisp );
185 if (cd == (iconv_t) -1) {
186 sprintf( errbuf, _("Cannot translate from %s to %s"), cpdisp, cpsour );
187 return errbuf;
190 for (i=128; i<=255; ++i) {
191 uchar ch;
192 ch = translate_character( cd, i );
193 conv_input[i] = (ch == UNKNCHAR) ? i : ch;
196 iconv_close( cd );
198 return NULL;
201 void convert_to_display( char *str )
203 while ((*str = conv_displ[ (uchar) *str ]))
204 str++;
207 void convert_from_input( char *str )
209 while ((*str = conv_input[ (uchar) *str ]))
210 str++;
212 #endif /* HAVE_CHARSET */