]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/tcs/tcs.c
stats: show amount of reclaimable pages (add -r flag)
[plan9front.git] / sys / src / cmd / tcs / tcs.c
1 #ifndef PLAN9
2 #include        <sys/types.h>
3 #include        <stdio.h>
4 #include        <unistd.h>
5 #include        <stdlib.h>
6 #include        <fcntl.h>
7 #include        <string.h>
8 #include        <errno.h>
9 #include        "plan9.h"
10 #else /* PLAN9 */
11 #include        <u.h>
12 #include        <libc.h>
13 #include        <bio.h>
14 #endif /* PLAN9 */
15 #include        "cyrillic.h"
16 #include        "misc.h"
17 #include        "ms.h"
18 #include        "8859.h"
19 #include        "big5.h"
20 #include        "gb.h"
21 #include        "hdr.h"
22 #include        "conv.h"
23
24 void usage(void);
25 void list(void);
26 int squawk = 1;
27 int clean = 0;
28 int verbose = 0;
29 long ninput, noutput, nrunes, nerrors;
30 char *file = "stdin";
31 char *argv0;
32 Rune runes[N];
33 char obuf[UTFmax*N];    /* maximum bloat from N runes */
34 long tab[NRUNE];
35 #ifndef PLAN9
36 extern char version[];
37 #endif
38
39 void intable(int, long *, struct convert *);
40 void unicode_in(int, long *, struct convert *);
41 void unicode_out(Rune *, int, long *);
42
43 int
44 main(int argc, char **argv)
45 {
46         char *from = "utf";
47         char *to = "utf";
48         int fd;
49         int listem = 0;
50         struct convert *t, *f;
51
52         ARGBEGIN {
53         case 'c':
54                 clean = 1;
55                 break;
56         case 'f':
57                 from = EARGF(usage());
58                 break;  
59         case 'l':
60                 listem = 1;
61                 break;
62         case 's':
63                 squawk = 0;
64                 break;
65         case 't':
66                 to = EARGF(usage());
67                 break;
68         case 'v':
69                 verbose = 1;
70                 break;
71         default:
72                 usage();
73                 break;
74         } ARGEND
75
76         if(verbose)
77                 squawk = 1;
78         if(listem){
79                 list();
80                 EXIT(0, 0);
81         }
82         if(!from || !to)
83                 usage();
84         f = conv(from, 1);
85         t = conv(to, 0);
86 #define PROC    {if(f->flags&Table)\
87                         intable(fd, (long *)f->data, t);\
88                 else\
89                         ((Infn)(f->fn))(fd, (long *)0, t);}
90         if(*argv){
91                 while(*argv){
92                         file = *argv;
93 #ifndef PLAN9
94                         if((fd = open(*argv, 0)) < 0){
95                                 EPR "%s: %s: %s\n", argv0, *argv, strerror(errno));
96 #else /* PLAN9 */
97                         if((fd = open(*argv, OREAD)) < 0){
98                                 EPR "%s: %s: %r\n", argv0, *argv);
99 #endif /* PLAN9 */
100                                 EXIT(1, "open failure");
101                         }
102                         PROC
103                         close(fd);
104                         argv++;
105                 }
106         } else {
107                 fd = 0;
108                 PROC
109         }
110         if(verbose)
111                 EPR "%s: %ld input bytes, %ld runes, %ld output bytes (%ld errors)\n", argv0,
112                         ninput, nrunes, noutput, nerrors);
113         EXIT(((nerrors && squawk)? 1:0), ((nerrors && squawk)? "conversion error":0));
114         return(0);      /* shut up compiler */
115 }
116
117 void
118 usage(void)
119 {
120         EPR "Usage: %s [-slv] [-f cs] [-t cs] [file ...]\n", argv0);
121         verbose = 1;
122         list();
123         EXIT(1, "usage");
124 }
125
126 void
127 list(void)
128 {
129         struct convert *c;
130         char ch = verbose?'\t':' ';
131
132 #ifndef PLAN9
133         EPR "%s version = '%s'\n", argv0, version);
134 #endif
135         if(verbose)
136                 EPR "character sets:\n");
137         else
138                 EPR "cs:");
139         for(c = convert; c->name; c++){
140                 if((c->flags&From) && c[1].name && (strcmp(c[1].name, c->name) == 0)){
141                         EPR "%c%s", ch, c->name);
142                         c++;
143                 } else if(c->flags&Table)
144                         EPR "%c%s", ch, c->name);
145                 else if(c->flags&From)
146                         EPR "%c%s(from)", ch, c->name);
147                 else
148                         EPR "%c%s(to)", ch, c->name);
149                 if(verbose)
150                         EPR "\t%s\n", c->chatter);
151         }
152         if(!verbose)
153                 EPR "\n");
154 }
155
156 char*
157 aliasname(char *name)
158 {
159         static struct {
160                 char *alias;
161                 char *name;
162         } tab[] = {
163 #include "alias.h"
164                 /* not generated by the script */
165                 "utf8", "utf",
166                 "euc_jp", "jis",
167                 "euc_kr", "euc-k",
168                 "windows-874", "tis",
169         };
170         int i;
171         for(i=0; i<nelem(tab); i++)
172                 if(cistrcmp(tab[i].alias, name) == 0)
173                         return tab[i].name;
174         return name;
175 }
176
177 struct convert *
178 conv(char *name, int from)
179 {
180         struct convert *c;
181
182         name = aliasname(name);
183         for(c = convert; c->name; c++){
184                 if(cistrcmp(c->name, name) != 0)
185                         continue;
186                 if(c->flags&Table)
187                         return(c);
188                 if(((c->flags&From) == 0) == (from == 0))
189                         return(c);
190         }
191         EPR "%s: charset `%s' unknown\n", argv0, name);
192         EXIT(1, "unknown character set");
193         return(0);      /* just shut the compiler up */
194 }
195
196 static int
197 cread(int fd, void *buf, int len, int mod)
198 {
199         char *off = buf;
200
201         len -= (len % mod);
202 Again:
203         len = read(fd, off, len);
204         if(len <= 0)
205                 return len;
206         off += len;
207         len = off - (char*)buf;
208         if((len % mod) != 0){
209                 len = mod - (len % mod);
210                 goto Again;
211         }
212         return len;
213 }
214
215 void
216 unicode_in_be(int fd, long *, struct convert *out)
217 {
218         uchar buf[2*N], *p, *e;
219         Rune *r, r2;
220         int n;
221
222         r2 = 0;
223         while((n = cread(fd, (char*)buf, 2*N, 2)) > 0){
224                 ninput += n;
225                 p = buf;
226                 e = buf + n;
227                 r = runes;
228                 while(p < e){
229                         *r = *p++ << 8;
230                         *r |= *p++;
231                         if(fixsurrogate(r, r2)){
232                                 r2 = *r;
233                                 continue;
234                         }
235                         r2 = 0;
236                         r++;
237                 }
238                 if(r > runes){
239                         OUT(out, runes, r-runes);
240                 }
241         }
242         OUT(out, runes, 0);
243 }
244
245 void
246 unicode_in_le(int fd, long *, struct convert *out)
247 {
248         uchar buf[2*N], *p, *e;
249         Rune *r, r2;
250         int n;
251
252         r2 = 0;
253         while((n = cread(fd, (char*)buf, 2*N, 2)) > 0){
254                 ninput += n;
255                 p = buf;
256                 e = buf + n;
257                 r = runes;
258                 while(p < e){
259                         *r = *p++;
260                         *r |= *p++ << 8;
261                         if(fixsurrogate(r, r2)){
262                                 r2 = *r;
263                                 continue;
264                         }
265                         r2 = 0;
266                         r++;
267                 }
268                 if(r > runes){
269                         OUT(out, runes, r-runes);
270                 }
271         }
272         OUT(out, runes, 0);
273 }
274
275 void
276 unicode_in(int fd, long *notused, struct convert *out)
277 {
278         uchar bom[2];
279         Rune r;
280
281         if(cread(fd, (char *)bom, 2, 2) != 2)
282                 return;
283         ninput += 2;
284         r = bom[0];
285         r |= bom[1]<<8;
286         switch(r)
287         {
288         default:
289                 OUT(out, &r, 1);
290         case 0xFEFF:
291                 unicode_in_le(fd, notused, out);
292                 break;
293         case 0xFFFE:
294                 unicode_in_be(fd, notused, out);
295                 break;
296         }
297 }
298
299 void
300 unicode_out_be(Rune *base, int n, long *)
301 {
302         int i;
303         uchar *p;
304         unsigned long r;
305
306         p = (uchar*)base;
307         for(i=0; i<n; i++){
308                 r = base[i];
309                 if(r > 0xFFFF){
310                         r -= 0x10000;
311                         *p++ = ((r>>18)&3) + 0xD8;
312                         *p++ = r>>10;
313                         *p++ = ((r>>8)&3) + 0xDC;
314                         *p++ = r;
315                 } else {
316                         *p++ = r>>8;
317                         *p++ = r;
318                 }
319         }
320         nrunes += n;
321         n = p - (uchar*)base;
322         noutput += n;
323         write(1, (char *)base, n);
324 }
325
326 void
327 unicode_out_le(Rune *base, int n, long *)
328 {
329         int i;
330         uchar *p;
331         unsigned long r;
332
333         p = (uchar*)base;
334         for(i=0; i<n; i++){
335                 r = base[i];
336                 if(r > 0xFFFF){
337                         r -= 0x10000;
338                         *p++ = r>>10;
339                         *p++ = ((r>>18)&3) + 0xD8;
340                         *p++ = r;
341                         *p++ = ((r>>8)&3) + 0xDC;
342                 } else {
343                         *p++ = r;
344                         *p++ = r>>8;
345                 }
346         }
347         nrunes += n;
348         n = p - (uchar*)base;
349         noutput += n;
350         write(1, (char *)base, n);
351 }
352
353 void
354 unicode_out(Rune *base, int n, long *notused)
355 {
356         static Rune first = 0xFEFF;
357
358         if(first){
359                 unicode_out_le(&first, 1, notused);
360                 first = 0;
361         }
362         unicode_out_le(base, n, notused);
363 }
364
365 void
366 intable(int fd, long *table, struct convert *out)
367 {
368         uchar buf[N];
369         uchar *p, *e;
370         Rune *r;
371         int n;
372         long c;
373
374         while((n = read(fd, (char *)buf, N)) > 0){
375                 ninput += n;
376                 r = runes;
377                 for(p = buf, e = buf+n; p < e; p++){
378                         c = table[*p];
379                         if(c < 0){
380                                 if(squawk)
381                                         EPR "%s: bad char 0x%x near byte %zd in %s\n", argv0, *p, ninput+(p-e), file);
382                                 nerrors++;
383                                 if(clean)
384                                         continue;
385                                 c = BADMAP;
386                         }
387                         *r++ = c;
388                 }
389                 OUT(out, runes, r-runes);
390         }
391         OUT(out, runes, 0);
392         if(n < 0){
393 #ifdef  PLAN9
394                 EPR "%s: input read: %r\n", argv0);
395 #else
396                 EPR "%s: input read: %s\n", argv0, strerror(errno));
397 #endif
398                 EXIT(1, "input read error");
399         }
400 }
401
402 void
403 outtable(Rune *base, int n, long *map)
404 {
405         long c;
406         char *p;
407         int i;
408
409         nrunes += n;
410         for(i = 0; i < NRUNE; i++)
411                 tab[i] = -1;
412         for(i = 0; i < 256; i++)
413                 if(map[i] >= 0)
414                         tab[map[i]] = i;
415         for(i = 0, p = obuf; i < n; i++){
416                 c = base[i];
417                 if(c < NRUNE)
418                         c = tab[c];
419                 else
420                         c = -1;
421                 if(c < 0){
422                         if(squawk)
423                                 EPR "%s: rune 0x%x not in output cs\n", argv0, base[i]);
424                         nerrors++;
425                         if(clean)
426                                 continue;
427                         c = BADMAP;
428                 }
429                 *p++ = c;
430         }
431         noutput += p-obuf;
432         write(1, obuf, p-obuf);
433 }
434
435 int
436 fixsurrogate(Rune *rp, Rune r2)
437 {
438         Rune r1;
439
440         r1 = *rp;
441         if(r1 >= 0xD800 && r1 <= 0xDBFF){
442                 if(r2 >= 0xDC00 && r2 <= 0xDFFF){
443                         *rp = 0x10000 + (((r1 - 0xD800)<<10) | (r2 - 0xDC00));
444                         return 0;
445                 }
446                 return 1;
447         } else
448         if(r1 >= 0xDC00 && r1 <= 0xDFFF){
449                 if(r2 >= 0xD800 && r2 <= 0xDBFF){
450                         *rp = 0x10000 + (((r2 - 0xD800)<<10) | (r1 - 0xDC00));
451                         return 0;
452                 }
453                 return 1;
454         }
455         return 0;
456 }
457
458 long tabascii[256] =
459 {
460 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,
461 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,
462 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,
463 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
464 0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f,
465 0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5a,0x5b,0x5c,0x5d,0x5e,0x5f,
466 0x60,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,
467 0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7a,0x7b,0x7c,0x7d,0x7e,0x7f,
468   -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,
469   -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,
470   -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,
471   -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,
472   -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,
473   -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,
474   -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,
475   -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,
476 };
477
478 long tabmsdos[256] =    /* from jhelling@cs.ruu.nl (Jeroen Hellingman) */
479 {
480 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,
481 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,
482 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,
483 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
484 0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f,
485 0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5a,0x5b,0x5c,0x5d,0x5e,0x5f,
486 0x60,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,
487 0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7a,0x7b,0x7c,0x7d,0x7e,0x7f,
488 0x00c7, 0x00fc, 0x00e9, 0x00e2, 0x00e4, 0x00e0, 0x00e5, 0x00e7, /* latin */
489 0x00ea, 0x00eb, 0x00e8, 0x00ef, 0x00ee, 0x00ec, 0x00c4, 0x00c5,
490 0x00c9, 0x00e6, 0x00c6, 0x00f4, 0x00f6, 0x00f2, 0x00fb, 0x00f9,
491 0x00ff, 0x00d6, 0x00dc, 0x00a2, 0x00a3, 0x00a5, 0x20a7, 0x0192,
492 0x00e1, 0x00ed, 0x00f3, 0x00fa, 0x00f1, 0x00d1, 0x00aa, 0x00ba,
493 0x00bf, 0x2310, 0x00ac, 0x00bd, 0x00bc, 0x00a1, 0x00ab, 0x00bb,
494 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, /* forms */
495 0x2555, 0x2563, 0x2551, 0x2557, 0x255d, 0x255c, 0x255b, 0x2510,
496 0x2514, 0x2534, 0x252c, 0x251c, 0x2500, 0x253c, 0x255e, 0x255f,
497 0x255a, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256c, 0x2567,
498 0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256b, 
499 0x256a, 0x2518, 0x250c, 0x2588, 0x2584, 0x258c, 0x2590, 0x2580,
500 0x03b1, 0x00df, 0x0393, 0x03c0, 0x03a3, 0x03c3, 0x00b5, 0x03c4, /* greek */
501 0x03a6, 0x0398, 0x2126, 0x03b4, 0x221e, 0x2205, 0x2208, 0x2229,
502 0x2261, 0x00b1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00f7, 0x2248, /* math */
503 0x00b0, 0x2022, 0x00b7, 0x221a, 0x207f, 0x00b2, 0x220e, 0x00a0,
504 };
505 long tabmsdos2[256] =   /* from jhelling@cs.ruu.nl (Jeroen Hellingman) */
506 {
507 0x0000, 0x263a, 0x263b, 0x2665, 0x2666, 0x2663, 0x2660, 0x2022,
508 0x25d8, 0x25cb, 0x25d9, 0x2642, 0x2640, 0x266a, 0x266b, 0x263c,
509 0x25b6, 0x25c0, 0x2195, 0x203c, 0x00b6, 0x00a7, 0x2043, 0x21a8,
510 0x2191, 0x2193, 0x2192, 0x2190, 0x2319, 0x2194, 0x25b2, 0x25bc,
511 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,
512 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
513 0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f,
514 0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5a,0x5b,0x5c,0x5d,0x5e,0x5f,
515 0x60,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,
516 0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7a,0x7b,0x7c,0x7d,0x7e,0x7f,
517 0x00c7, 0x00fc, 0x00e9, 0x00e2, 0x00e4, 0x00e0, 0x00e5, 0x00e7, /* latin */
518 0x00ea, 0x00eb, 0x00e8, 0x00ef, 0x00ee, 0x00ec, 0x00c4, 0x00c5,
519 0x00c9, 0x00e6, 0x00c6, 0x00f4, 0x00f6, 0x00f2, 0x00fb, 0x00f9,
520 0x00ff, 0x00d6, 0x00dc, 0x00a2, 0x00a3, 0x00a5, 0x20a7, 0x0192,
521 0x00e1, 0x00ed, 0x00f3, 0x00fa, 0x00f1, 0x00d1, 0x00aa, 0x00ba,
522 0x00bf, 0x2310, 0x00ac, 0x00bd, 0x00bc, 0x00a1, 0x00ab, 0x00bb,
523 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, /* forms */
524 0x2555, 0x2563, 0x2551, 0x2557, 0x255d, 0x255c, 0x255b, 0x2510,
525 0x2514, 0x2534, 0x252c, 0x251c, 0x2500, 0x253c, 0x255e, 0x255f,
526 0x255a, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256c, 0x2567,
527 0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256b, 
528 0x256a, 0x2518, 0x250c, 0x2588, 0x2584, 0x258c, 0x2590, 0x2580,
529 0x03b1, 0x00df, 0x0393, 0x03c0, 0x03a3, 0x03c3, 0x00b5, 0x03c4, /* greek */
530 0x03a6, 0x0398, 0x2126, 0x03b4, 0x221e, 0x2205, 0x2208, 0x2229,
531 0x2261, 0x00b1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00f7, 0x2248, /* math */
532 0x00b0, 0x2022, 0x00b7, 0x221a, 0x207f, 0x00b2, 0x220e, 0x00a0,
533 };
534 struct convert convert[] =
535 {       /* if two entries have the same name, put the from one first */
536         { "8859-1", "Latin-1 (Western and Northern Europe including Italian)", Table, (void *)tab8859_1 },
537         { "8859-2", "Latin-2 (Eastern Europe except Turkey and the Baltic countries)", Table, (void *)tab8859_2 },
538         { "8859-3", "Latin-3 (Mediterranean, South Africa, Esperanto)", Table, (void *)tab8859_3 },
539         { "8859-4", "Latin-4 (Scandinavia and the Baltic countries; obsolete)", Table, (void *)tab8859_4 },
540         { "8859-5", "Part 5 (Cyrillic)", Table, (void *)tab8859_5 },
541         { "8859-6", "Part 6 (Arabic)", Table, (void *)tab8859_6 },
542         { "8859-7", "Part 7 (Greek)", Table, (void *)tab8859_7 },
543         { "8859-8", "Part 8 (Hebrew)", Table, (void *)tab8859_8 },
544         { "8859-9", "Latin-5 (Turkey, Western Europe except Icelandic and Faroese)", Table, (void *)tab8859_9 },
545         { "8859-10", "Latin-6 (Northern Europe)", Table, (void *)tab8859_10 },
546         { "8859-15", "Latin-9 (Western Europe)", Table, (void *)tab8859_15 },
547         { "ascii", "7-bit ASCII", Table, (void *)tabascii },
548         { "atari", "ATARI-ST character set", Table, (void *)tabatari },
549         { "av", "Alternativnyj Variant", Table, (void *)tabav },
550         { "big5", "Big 5 (HKU)", From|Func, 0, (Fnptr)big5_in },
551         { "big5", "Big 5 (HKU)", Func, 0, (Fnptr)big5_out },
552         { "ebcdic", "EBCDIC", Table, (void *)tabebcdic },       /* 6f is recommended bad map */
553         { "euc-k", "Korean EUC: ASCII+KS C 5601 1987", From|Func, 0, (Fnptr)uksc_in },
554         { "euc-k", "Korean EUC: ASCII+KS C 5601 1987", Func, 0, (Fnptr)uksc_out },
555         { "gb2312", "GB2312-80 (Chinese)", From|Func, 0, (Fnptr)gb_in },
556         { "gb2312", "GB2312-80 (Chinese)", Func, 0, (Fnptr)gb_out },
557         { "gbk", "GBK (Chinese)", From|Func, 0, (Fnptr)gbk_in },
558         { "gbk", "GBK (Chinese)", Func, 0, (Fnptr)gbk_out },
559         { "html", "HTML", From|Func, 0, (Fnptr)html_in },
560         { "html", "HTML", Func, 0, (Fnptr)html_out },
561         { "ibm437", "IBM Code Page 437 (US)", Table, (void*)tabcp437 },
562         { "ibm720", "IBM Code Page 720 (Arabic)", Table, (void*)tabcp720 },
563         { "ibm737", "IBM Code Page 737 (Greek)", Table, (void*)tabcp737 },
564         { "ibm775", "IBM Code Page 775 (Baltic)", Table, (void*)tabcp775 },
565         { "ibm850", "IBM Code Page 850 (Multilingual Latin I)", Table, (void*)tabcp850 },
566         { "ibm852", "IBM Code Page 852 (Latin II)", Table, (void*)tabcp852 },
567         { "ibm855", "IBM Code Page 855 (Cyrillic)", Table, (void*)tabcp855 },
568         { "ibm857", "IBM Code Page 857 (Turkish)", Table, (void*)tabcp857 },
569         { "ibm858", "IBM Code Page 858 (Multilingual Latin I+Euro)", Table, (void*)tabcp858 },
570         { "ibm862", "IBM Code Page 862 (Hebrew)", Table, (void*)tabcp862 },
571         { "ibm866", "IBM Code Page 866 (Russian)", Table, (void*)tabcp866 },
572         { "ibm874", "IBM Code Page 874 (Thai)", Table, (void*)tabcp874 },
573         { "iso-2022-jp", "alias for jis-kanji (MIME)", From|Func, 0, (Fnptr)jisjis_in },
574         { "iso-2022-jp", "alias for jis-kanji (MIME)", Func, 0, (Fnptr)jisjis_out },
575         { "iso-8859-1", "alias for 8859-1 (MIME)", Table, (void *)tab8859_1 },
576         { "iso-8859-2", "alias for 8859-2 (MIME)", Table, (void *)tab8859_2 },
577         { "iso-8859-3", "alias for 8859-3 (MIME)", Table, (void *)tab8859_3 },
578         { "iso-8859-4", "alias for 8859-4 (MIME)", Table, (void *)tab8859_4 },
579         { "iso-8859-5", "alias for 8859-5 (MIME)", Table, (void *)tab8859_5 },
580         { "iso-8859-6", "alias for 8859-6 (MIME)", Table, (void *)tab8859_6 },
581         { "iso-8859-7", "alias for 8859-7 (MIME)", Table, (void *)tab8859_7 },
582         { "iso-8859-8", "alias for 8859-8 (MIME)", Table, (void *)tab8859_8 },
583         { "iso-8859-9", "alias for 8859-9 (MIME)", Table, (void *)tab8859_9 },
584         { "iso-8859-10", "alias for 8859-10 (MIME)", Table, (void *)tab8859_10 },
585         { "iso-8859-15", "alias for 8859-15 (MIME)", Table, (void *)tab8859_15 },
586         { "jis", "guesses at the JIS encoding", From|Func, 0, (Fnptr)jis_in },
587         { "jis-kanji", "ISO 2022-JP (Japanese)", From|Func, 0, (Fnptr)jisjis_in },
588         { "jis-kanji", "ISO 2022-JP (Japanese)", Func, 0, (Fnptr)jisjis_out },
589         { "koi8", "KOI-8 (GOST 19769-74)", Table, (void *)tabkoi8 },
590         { "koi8-r", "alias for koi8 (MIME)", Table, (void *)tabkoi8 },
591         { "latin1", "alias for 8859-1", Table, (void *)tab8859_1 },
592         { "macrom", "Macintosh Standard Roman character set", Table, (void *)tabmacroman },
593         { "microsoft", "alias for windows1252", Table, (void *)tabcp1252 },
594         { "ms-kanji", "Microsoft, or Shift-JIS", From|Func, 0, (Fnptr)msjis_in },
595         { "ms-kanji", "Microsoft, or Shift-JIS", Func, 0, (Fnptr)msjis_out },
596         { "msdos", "IBM PC (alias for ibm437)", Table, (void *)tabcp437 },
597         { "msdos2", "IBM PC (ibm437 with graphics in C0)", Table, (void *)tabmsdos2 },
598         { "next", "NEXTSTEP character set", Table, (void *)tabnextstep },
599         { "ov", "Osnovnoj Variant", Table, (void *)tabov },
600         { "ps2", "IBM PS/2: (alias for ibm850)", Table, (void *)tabcp850 },
601         { "sf1", "ISO-646: Finnish/Swedish SF-1 variant", Table, (void *)tabsf1 },
602         { "sf2", "ISO-646: Finnish/Swedish SF-2 variant (recommended)", Table, (void *)tabsf2 },
603         { "tis-620", "Thai+ASCII (TIS 620-1986)", Table, (void *)tabtis620 },
604         { "tune", "TUNE (Tamil)", From|Func, 0, (Fnptr)tune_in },
605         { "tune", "TUNE (Tamil)", Func, 0, (Fnptr)tune_out },
606         { "ucode", "Russian U-code", Table, (void *)tabucode },
607         { "ujis", "EUC-JX: JIS 0208", From|Func, 0, (Fnptr)ujis_in },
608         { "ujis", "EUC-JX: JIS 0208", Func, 0, (Fnptr)ujis_out },
609         { "unicode", "Unicode 1.1", From|Func, 0, (Fnptr)unicode_in },
610         { "unicode", "Unicode 1.1", Func, 0, (Fnptr)unicode_out },
611         { "unicode-be", "Unicode 1.1 big-endian", From|Func, 0, (Fnptr)unicode_in_be },
612         { "unicode-be", "Unicode 1.1 big-endian", Func, 0, (Fnptr)unicode_out_be },
613         { "unicode-le", "Unicode 1.1 little-endian", From|Func, 0, (Fnptr)unicode_in_le },
614         { "unicode-le", "Unicode 1.1 little-endian", Func, 0, (Fnptr)unicode_out_le },
615         { "us-ascii", "alias for ascii (MIME)", Table, (void *)tabascii },
616         { "utf", "FSS-UTF a.k.a. UTF-8", From|Func, 0, (Fnptr)utf_in },
617         { "utf", "FSS-UTF a.k.a. UTF-8", Func, 0, (Fnptr)utf_out },
618         { "utf1", "UTF-1 (ISO 10646 Annex A)", From|Func, 0, (Fnptr)isoutf_in },
619         { "utf1", "UTF-1 (ISO 10646 Annex A)", Func, 0, (Fnptr)isoutf_out },
620         { "utf-8", "alias for utf (MIME)", From|Func, 0, (Fnptr)utf_in },
621         { "utf-8", "alias for utf (MIME)", Func, 0, (Fnptr)utf_out },
622         { "utf-16", "alias for unicode (MIME)", From|Func, 0, (Fnptr)unicode_in },
623         { "utf-16", "alias for unicode (MIME)", Func, 0, (Fnptr)unicode_out },
624         { "utf-16be", "alias for unicode-be (MIME)", From|Func, 0, (Fnptr)unicode_in_be },
625         { "utf-16be", "alias for unicode-be (MIME)", Func, 0, (Fnptr)unicode_out_be },
626         { "utf-16le", "alias for unicode-le (MIME)", From|Func, 0, (Fnptr)unicode_in_le },
627         { "utf-16le", "alias for unicode-le (MIME)", Func, 0, (Fnptr)unicode_out_le },
628         { "viet1", "Vietnamese VSCII-1 (1993)", Table, (void *)tabviet1 },
629         { "viet2", "Vietnamese VSCII-2 (1993)", Table, (void *)tabviet2 },
630         { "vscii", "Vietnamese VISCII 1.1 (1992)", Table, (void *)tabviscii },
631         { "windows-1250", "Windows Code Page 1250 (Central Europe)", Table, (void *)tabcp1250 },
632         { "windows-1251", "Windows Code Page 1251 (Cyrillic)", Table, (void *)tabcp1251 },
633         { "windows-1252", "Windows Code Page 1252 (Latin I)", Table, (void *)tabcp1252 },
634         { "windows-1253", "Windows Code Page 1253 (Greek)", Table, (void *)tabcp1253 },
635         { "windows-1254", "Windows Code Page 1254 (Turkish)", Table, (void *)tabcp1254 },
636         { "windows-1255", "Windows Code Page 1255 (Hebrew)", Table, (void *)tabcp1255 },
637         { "windows-1256", "Windows Code Page 1256 (Arabic)", Table, (void *)tabcp1256 },
638         { "windows-1257", "Windows Code Page 1257 (Baltic)", Table, (void *)tabcp1257 },
639         { "windows-1258", "Windows Code Page 1258 (Vietnam)", Table, (void *)tabcp1258 },
640         { 0 },
641 };