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