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