xref: /plan9/sys/src/cmd/tcs/tcs.c (revision 853458f38e7eb3a48cfa3a36aefdb799375e398a)
1219b2ee8SDavid du Colombier #ifndef PLAN9
2219b2ee8SDavid du Colombier #include	<sys/types.h>
3219b2ee8SDavid du Colombier #include	<stdio.h>
4219b2ee8SDavid du Colombier #include	<unistd.h>
5219b2ee8SDavid du Colombier #include	<stdlib.h>
6219b2ee8SDavid du Colombier #include	<fcntl.h>
7219b2ee8SDavid du Colombier #include	<string.h>
8219b2ee8SDavid du Colombier #include	<errno.h>
9219b2ee8SDavid du Colombier #include	"plan9.h"
10219b2ee8SDavid du Colombier #else /* PLAN9 */
113e12c5d1SDavid du Colombier #include	<u.h>
123e12c5d1SDavid du Colombier #include	<libc.h>
133e12c5d1SDavid du Colombier #include	<bio.h>
14219b2ee8SDavid du Colombier #endif /* PLAN9 */
15bd389b36SDavid du Colombier #include	"cyrillic.h"
16426d2b71SDavid du Colombier #include	"misc.h"
17426d2b71SDavid du Colombier #include	"ms.h"
18426d2b71SDavid du Colombier #include	"8859.h"
19bd389b36SDavid du Colombier #include	"big5.h"
20bd389b36SDavid du Colombier #include	"gb.h"
213e12c5d1SDavid du Colombier #include	"hdr.h"
22219b2ee8SDavid du Colombier #include	"conv.h"
233e12c5d1SDavid du Colombier 
243e12c5d1SDavid du Colombier void usage(void);
253e12c5d1SDavid du Colombier void list(void);
263e12c5d1SDavid du Colombier int squawk = 1;
273e12c5d1SDavid du Colombier int clean = 0;
283e12c5d1SDavid du Colombier int verbose = 0;
293e12c5d1SDavid du Colombier long ninput, noutput, nrunes, nerrors;
30bd389b36SDavid du Colombier char *file = "stdin";
31219b2ee8SDavid du Colombier char *argv0;
32219b2ee8SDavid du Colombier Rune runes[N];
33219b2ee8SDavid du Colombier char obuf[UTFmax*N];	/* maximum bloat from N runes */
34219b2ee8SDavid du Colombier long tab[NRUNE];
35219b2ee8SDavid du Colombier #ifndef	PLAN9
36219b2ee8SDavid du Colombier extern char version[];
37219b2ee8SDavid du Colombier #endif
383e12c5d1SDavid du Colombier 
393e12c5d1SDavid du Colombier void intable(int, long *, struct convert *);
403e12c5d1SDavid du Colombier void unicode_in(int, long *, struct convert *);
413e12c5d1SDavid du Colombier void unicode_out(Rune *, int, long *);
423e12c5d1SDavid du Colombier 
43219b2ee8SDavid du Colombier int
main(int argc,char ** argv)443e12c5d1SDavid du Colombier main(int argc, char **argv)
453e12c5d1SDavid du Colombier {
463e12c5d1SDavid du Colombier 	char *from = "utf";
473e12c5d1SDavid du Colombier 	char *to = "utf";
483e12c5d1SDavid du Colombier 	int fd;
493e12c5d1SDavid du Colombier 	int listem = 0;
503e12c5d1SDavid du Colombier 	struct convert *t, *f;
513e12c5d1SDavid du Colombier 
523e12c5d1SDavid du Colombier 	ARGBEGIN {
537dd7cddfSDavid du Colombier 	case 'c':
547dd7cddfSDavid du Colombier 		clean = 1;
557dd7cddfSDavid du Colombier 		break;
567dd7cddfSDavid du Colombier 	case 'f':
57acfb0edcSDavid du Colombier 		from = EARGF(usage());
587dd7cddfSDavid du Colombier 		break;
597dd7cddfSDavid du Colombier 	case 'l':
607dd7cddfSDavid du Colombier 		listem = 1;
617dd7cddfSDavid du Colombier 		break;
627dd7cddfSDavid du Colombier 	case 's':
637dd7cddfSDavid du Colombier 		squawk = 0;
647dd7cddfSDavid du Colombier 		break;
657dd7cddfSDavid du Colombier 	case 't':
66acfb0edcSDavid du Colombier 		to = EARGF(usage());
677dd7cddfSDavid du Colombier 		break;
687dd7cddfSDavid du Colombier 	case 'v':
697dd7cddfSDavid du Colombier 		verbose = 1;
707dd7cddfSDavid du Colombier 		break;
717dd7cddfSDavid du Colombier 	default:
727dd7cddfSDavid du Colombier 		usage();
737dd7cddfSDavid du Colombier 		break;
743e12c5d1SDavid du Colombier 	} ARGEND
757dd7cddfSDavid du Colombier 
763e12c5d1SDavid du Colombier 	USED(argc);
773e12c5d1SDavid du Colombier 	if(verbose)
783e12c5d1SDavid du Colombier 		squawk = 1;
793e12c5d1SDavid du Colombier 	if(listem){
803e12c5d1SDavid du Colombier 		list();
81219b2ee8SDavid du Colombier 		EXIT(0, 0);
823e12c5d1SDavid du Colombier 	}
833e12c5d1SDavid du Colombier 	if(!from || !to)
843e12c5d1SDavid du Colombier 		usage();
853e12c5d1SDavid du Colombier 	f = conv(from, 1);
863e12c5d1SDavid du Colombier 	t = conv(to, 0);
873e12c5d1SDavid du Colombier #define	PROC	{if(f->flags&Table)\
883e12c5d1SDavid du Colombier 			intable(fd, (long *)f->data, t);\
893e12c5d1SDavid du Colombier 		else\
90219b2ee8SDavid du Colombier 			((Infn)(f->fn))(fd, (long *)0, t);}
913e12c5d1SDavid du Colombier 	if(*argv){
923e12c5d1SDavid du Colombier 		while(*argv){
93bd389b36SDavid du Colombier 			file = *argv;
94219b2ee8SDavid du Colombier #ifndef PLAN9
95219b2ee8SDavid du Colombier 			if((fd = open(*argv, 0)) < 0){
96219b2ee8SDavid du Colombier 				EPR "%s: %s: %s\n", argv0, *argv, strerror(errno));
97219b2ee8SDavid du Colombier #else /* PLAN9 */
98219b2ee8SDavid du Colombier 			if((fd = open(*argv, OREAD)) < 0){
99219b2ee8SDavid du Colombier 				EPR "%s: %s: %r\n", argv0, *argv);
100219b2ee8SDavid du Colombier #endif /* PLAN9 */
101219b2ee8SDavid du Colombier 				EXIT(1, "open failure");
1023e12c5d1SDavid du Colombier 			}
1033e12c5d1SDavid du Colombier 			PROC
1043e12c5d1SDavid du Colombier 			close(fd);
1053e12c5d1SDavid du Colombier 			argv++;
1063e12c5d1SDavid du Colombier 		}
1073e12c5d1SDavid du Colombier 	} else {
1083e12c5d1SDavid du Colombier 		fd = 0;
1093e12c5d1SDavid du Colombier 		PROC
1103e12c5d1SDavid du Colombier 	}
1113e12c5d1SDavid du Colombier 	if(verbose)
112219b2ee8SDavid du Colombier 		EPR "%s: %ld input bytes, %ld runes, %ld output bytes (%ld errors)\n", argv0,
1133e12c5d1SDavid du Colombier 			ninput, nrunes, noutput, nerrors);
114219b2ee8SDavid du Colombier 	EXIT(((nerrors && squawk)? 1:0), ((nerrors && squawk)? "conversion error":0));
115219b2ee8SDavid du Colombier 	return(0);	/* shut up compiler */
1163e12c5d1SDavid du Colombier }
1173e12c5d1SDavid du Colombier 
1183e12c5d1SDavid du Colombier void
1193e12c5d1SDavid du Colombier usage(void)
1203e12c5d1SDavid du Colombier {
121219b2ee8SDavid du Colombier 	EPR "Usage: %s [-slv] [-f cs] [-t cs] [file ...]\n", argv0);
1224ac975e2SDavid du Colombier 	verbose = 1;
1233e12c5d1SDavid du Colombier 	list();
124219b2ee8SDavid du Colombier 	EXIT(1, "usage");
1253e12c5d1SDavid du Colombier }
1263e12c5d1SDavid du Colombier 
1273e12c5d1SDavid du Colombier void
1283e12c5d1SDavid du Colombier list(void)
1293e12c5d1SDavid du Colombier {
1303e12c5d1SDavid du Colombier 	struct convert *c;
1313e12c5d1SDavid du Colombier 	char ch = verbose?'\t':' ';
1323e12c5d1SDavid du Colombier 
133219b2ee8SDavid du Colombier #ifndef	PLAN9
134219b2ee8SDavid du Colombier 	EPR "%s version = '%s'\n", argv0, version);
135219b2ee8SDavid du Colombier #endif
1363e12c5d1SDavid du Colombier 	if(verbose)
137219b2ee8SDavid du Colombier 		EPR "character sets:\n");
1383e12c5d1SDavid du Colombier 	else
139219b2ee8SDavid du Colombier 		EPR "cs:");
1403e12c5d1SDavid du Colombier 	for(c = convert; c->name; c++){
1413e12c5d1SDavid du Colombier 		if((c->flags&From) && c[1].name && (strcmp(c[1].name, c->name) == 0)){
142219b2ee8SDavid du Colombier 			EPR "%c%s", ch, c->name);
1433e12c5d1SDavid du Colombier 			c++;
1443e12c5d1SDavid du Colombier 		} else if(c->flags&Table)
145219b2ee8SDavid du Colombier 			EPR "%c%s", ch, c->name);
1463e12c5d1SDavid du Colombier 		else if(c->flags&From)
147219b2ee8SDavid du Colombier 			EPR "%c%s(from)", ch, c->name);
1483e12c5d1SDavid du Colombier 		else
149219b2ee8SDavid du Colombier 			EPR "%c%s(to)", ch, c->name);
1503e12c5d1SDavid du Colombier 		if(verbose)
151219b2ee8SDavid du Colombier 			EPR "\t%s\n", c->chatter);
1523e12c5d1SDavid du Colombier 	}
1533e12c5d1SDavid du Colombier 	if(!verbose)
154219b2ee8SDavid du Colombier 		EPR "\n");
1553e12c5d1SDavid du Colombier }
1563e12c5d1SDavid du Colombier 
157b85a8364SDavid du Colombier 
1583e12c5d1SDavid du Colombier struct convert *
1593e12c5d1SDavid du Colombier conv(char *name, int from)
1603e12c5d1SDavid du Colombier {
1613e12c5d1SDavid du Colombier 	struct convert *c;
1623e12c5d1SDavid du Colombier 
1633e12c5d1SDavid du Colombier 	for(c = convert; c->name; c++){
164b85a8364SDavid du Colombier 		if(cistrcmp(c->name, name) != 0)
1653e12c5d1SDavid du Colombier 			continue;
1663e12c5d1SDavid du Colombier 		if(c->flags&Table)
1673e12c5d1SDavid du Colombier 			return(c);
1683e12c5d1SDavid du Colombier 		if(((c->flags&From) == 0) == (from == 0))
1693e12c5d1SDavid du Colombier 			return(c);
1703e12c5d1SDavid du Colombier 	}
171219b2ee8SDavid du Colombier 	EPR "%s: charset `%s' unknown\n", argv0, name);
172219b2ee8SDavid du Colombier 	EXIT(1, "unknown character set");
173219b2ee8SDavid du Colombier 	return(0);	/* just shut the compiler up */
1743e12c5d1SDavid du Colombier }
1753e12c5d1SDavid du Colombier 
1763e12c5d1SDavid du Colombier void
177219b2ee8SDavid du Colombier swab2(char *b, int n)
1783e12c5d1SDavid du Colombier {
1793e12c5d1SDavid du Colombier 	char *e, p;
1803e12c5d1SDavid du Colombier 
1813e12c5d1SDavid du Colombier 	for(e = b+n; b < e; b++){
1823e12c5d1SDavid du Colombier 		p = *b;
1833e12c5d1SDavid du Colombier 		*b = b[1];
1843e12c5d1SDavid du Colombier 		*++b = p;
1853e12c5d1SDavid du Colombier 	}
1863e12c5d1SDavid du Colombier }
1873e12c5d1SDavid du Colombier 
1883e12c5d1SDavid du Colombier void
1893e12c5d1SDavid du Colombier unicode_in(int fd, long *notused, struct convert *out)
1903e12c5d1SDavid du Colombier {
1913e12c5d1SDavid du Colombier 	Rune buf[N];
1923e12c5d1SDavid du Colombier 	int n;
1933e12c5d1SDavid du Colombier 	int swabme;
1943e12c5d1SDavid du Colombier 
1953e12c5d1SDavid du Colombier 	USED(notused);
1963e12c5d1SDavid du Colombier 	if(read(fd, (char *)buf, 2) != 2)
1973e12c5d1SDavid du Colombier 		return;
1983e12c5d1SDavid du Colombier 	ninput += 2;
1993e12c5d1SDavid du Colombier 	switch(buf[0])
2003e12c5d1SDavid du Colombier 	{
2013e12c5d1SDavid du Colombier 	default:
2023e12c5d1SDavid du Colombier 		OUT(out, buf, 1);
2033e12c5d1SDavid du Colombier 	case 0xFEFF:
2043e12c5d1SDavid du Colombier 		swabme = 0;
2053e12c5d1SDavid du Colombier 		break;
2063e12c5d1SDavid du Colombier 	case 0xFFFE:
2073e12c5d1SDavid du Colombier 		swabme = 1;
2083e12c5d1SDavid du Colombier 		break;
2093e12c5d1SDavid du Colombier 	}
2103e12c5d1SDavid du Colombier 	while((n = read(fd, (char *)buf, 2*N)) > 0){
2113e12c5d1SDavid du Colombier 		ninput += n;
212b85a8364SDavid du Colombier 		if(swabme)
213b85a8364SDavid du Colombier 			swab2((char *)buf, n);
2143e12c5d1SDavid du Colombier 		if(n&1){
2153e12c5d1SDavid du Colombier 			if(squawk)
216219b2ee8SDavid du Colombier 				EPR "%s: odd byte count in %s\n", argv0, file);
2173e12c5d1SDavid du Colombier 			nerrors++;
2183e12c5d1SDavid du Colombier 			if(clean)
2193e12c5d1SDavid du Colombier 				n--;
220b85a8364SDavid du Colombier 			else
221b85a8364SDavid du Colombier 				buf[n++/2] = Runeerror;
2223e12c5d1SDavid du Colombier 		}
223b85a8364SDavid du Colombier 		OUT(out, buf, n/2);
2243e12c5d1SDavid du Colombier 	}
225b85a8364SDavid du Colombier 	OUT(out, buf, 0);
226b85a8364SDavid du Colombier }
227b85a8364SDavid du Colombier 
228b85a8364SDavid du Colombier void
229b85a8364SDavid du Colombier unicode_in_be(int fd, long *notused, struct convert *out)
230b85a8364SDavid du Colombier {
231b85a8364SDavid du Colombier 	int i, n;
232b85a8364SDavid du Colombier 	Rune buf[N], r;
233b85a8364SDavid du Colombier 	uchar *p;
234b85a8364SDavid du Colombier 
235b85a8364SDavid du Colombier 	USED(notused);
236b85a8364SDavid du Colombier 	while((n = read(fd, (char *)buf, 2*N)) > 0){
237b85a8364SDavid du Colombier 		ninput += n;
238b85a8364SDavid du Colombier 		p = (uchar*)buf;
239b85a8364SDavid du Colombier 		for(i=0; i<n/2; i++){
240b85a8364SDavid du Colombier 			r = *p++<<8;
241b85a8364SDavid du Colombier 			r |= *p++;
242b85a8364SDavid du Colombier 			buf[i] = r;
243b85a8364SDavid du Colombier 		}
244b85a8364SDavid du Colombier 		if(n&1){
245b85a8364SDavid du Colombier 			if(squawk)
246b85a8364SDavid du Colombier 				EPR "%s: odd byte count in %s\n", argv0, file);
247b85a8364SDavid du Colombier 			nerrors++;
248b85a8364SDavid du Colombier 			if(clean)
249b85a8364SDavid du Colombier 				n--;
250b85a8364SDavid du Colombier 			else
251b85a8364SDavid du Colombier 				buf[n++/2] = Runeerror;
252b85a8364SDavid du Colombier 		}
253b85a8364SDavid du Colombier 		OUT(out, buf, n/2);
254b85a8364SDavid du Colombier 	}
255b85a8364SDavid du Colombier 	OUT(out, buf, 0);
256b85a8364SDavid du Colombier }
257b85a8364SDavid du Colombier 
258b85a8364SDavid du Colombier void
259b85a8364SDavid du Colombier unicode_in_le(int fd, long *notused, struct convert *out)
260b85a8364SDavid du Colombier {
261b85a8364SDavid du Colombier 	int i, n;
262b85a8364SDavid du Colombier 	Rune buf[N], r;
263b85a8364SDavid du Colombier 	uchar *p;
264b85a8364SDavid du Colombier 
265b85a8364SDavid du Colombier 	USED(notused);
266b85a8364SDavid du Colombier 	while((n = read(fd, (char *)buf, 2*N)) > 0){
267b85a8364SDavid du Colombier 		ninput += n;
268b85a8364SDavid du Colombier 		p = (uchar*)buf;
269b85a8364SDavid du Colombier 		for(i=0; i<n/2; i++){
270b85a8364SDavid du Colombier 			r = *p++;
271b85a8364SDavid du Colombier 			r |= *p++<<8;
272b85a8364SDavid du Colombier 			buf[i] = r;
273b85a8364SDavid du Colombier 		}
274b85a8364SDavid du Colombier 		if(n&1){
275b85a8364SDavid du Colombier 			if(squawk)
276b85a8364SDavid du Colombier 				EPR "%s: odd byte count in %s\n", argv0, file);
277b85a8364SDavid du Colombier 			nerrors++;
278b85a8364SDavid du Colombier 			if(clean)
279b85a8364SDavid du Colombier 				n--;
280b85a8364SDavid du Colombier 			else
281b85a8364SDavid du Colombier 				buf[n++/2] = Runeerror;
282b85a8364SDavid du Colombier 		}
2833e12c5d1SDavid du Colombier 		OUT(out, buf, n/2);
2843e12c5d1SDavid du Colombier 	}
285ec46fab0SDavid du Colombier 	OUT(out, buf, 0);
2863e12c5d1SDavid du Colombier }
2873e12c5d1SDavid du Colombier 
2883e12c5d1SDavid du Colombier void
2893e12c5d1SDavid du Colombier unicode_out(Rune *base, int n, long *notused)
2903e12c5d1SDavid du Colombier {
2913e12c5d1SDavid du Colombier 	static int first = 1;
2923e12c5d1SDavid du Colombier 
2933e12c5d1SDavid du Colombier 	USED(notused);
2943e12c5d1SDavid du Colombier 	nrunes += n;
2953e12c5d1SDavid du Colombier 	if(first){
296219b2ee8SDavid du Colombier 		unsigned short x = 0xFEFF;
2973e12c5d1SDavid du Colombier 		noutput += 2;
2983e12c5d1SDavid du Colombier 		write(1, (char *)&x, 2);
2993e12c5d1SDavid du Colombier 		first = 0;
3003e12c5d1SDavid du Colombier 	}
3013e12c5d1SDavid du Colombier 	noutput += 2*n;
3023e12c5d1SDavid du Colombier 	write(1, (char *)base, 2*n);
3033e12c5d1SDavid du Colombier }
3043e12c5d1SDavid du Colombier 
3053e12c5d1SDavid du Colombier void
306b85a8364SDavid du Colombier unicode_out_be(Rune *base, int n, long *notused)
307b85a8364SDavid du Colombier {
308b85a8364SDavid du Colombier 	int i;
309b85a8364SDavid du Colombier 	uchar *p;
310b85a8364SDavid du Colombier 	Rune r;
311b85a8364SDavid du Colombier 
312b85a8364SDavid du Colombier 	USED(notused);
313b85a8364SDavid du Colombier 	p = (uchar*)base;
314b85a8364SDavid du Colombier 	for(i=0; i<n; i++){
315b85a8364SDavid du Colombier 		r = base[i];
316b85a8364SDavid du Colombier 		*p++ = r>>8;
317b85a8364SDavid du Colombier 		*p++ = r;
318b85a8364SDavid du Colombier 	}
319b85a8364SDavid du Colombier 	nrunes += n;
320b85a8364SDavid du Colombier 	noutput += 2*n;
321b85a8364SDavid du Colombier 	write(1, (char *)base, 2*n);
322b85a8364SDavid du Colombier }
323b85a8364SDavid du Colombier 
324b85a8364SDavid du Colombier void
325b85a8364SDavid du Colombier unicode_out_le(Rune *base, int n, long *notused)
326b85a8364SDavid du Colombier {
327b85a8364SDavid du Colombier 	int i;
328b85a8364SDavid du Colombier 	uchar *p;
329b85a8364SDavid du Colombier 	Rune r;
330b85a8364SDavid du Colombier 
331b85a8364SDavid du Colombier 	USED(notused);
332b85a8364SDavid du Colombier 	p = (uchar*)base;
333b85a8364SDavid du Colombier 	for(i=0; i<n; i++){
334b85a8364SDavid du Colombier 		r = base[i];
335b85a8364SDavid du Colombier 		*p++ = r;
336b85a8364SDavid du Colombier 		*p++ = r>>8;
337b85a8364SDavid du Colombier 	}
338b85a8364SDavid du Colombier 	nrunes += n;
339b85a8364SDavid du Colombier 	noutput += 2*n;
340b85a8364SDavid du Colombier 	write(1, (char *)base, 2*n);
341b85a8364SDavid du Colombier }
342b85a8364SDavid du Colombier 
343b85a8364SDavid du Colombier void
344219b2ee8SDavid du Colombier intable(int fd, long *table, struct convert *out)
3453e12c5d1SDavid du Colombier {
3463e12c5d1SDavid du Colombier 	uchar buf[N];
3473e12c5d1SDavid du Colombier 	uchar *p, *e;
3483e12c5d1SDavid du Colombier 	Rune *r;
3493e12c5d1SDavid du Colombier 	int n;
3503e12c5d1SDavid du Colombier 	long c;
3513e12c5d1SDavid du Colombier 
3523e12c5d1SDavid du Colombier 	while((n = read(fd, (char *)buf, N)) > 0){
3533e12c5d1SDavid du Colombier 		ninput += n;
3543e12c5d1SDavid du Colombier 		r = runes;
3553e12c5d1SDavid du Colombier 		for(p = buf, e = buf+n; p < e; p++){
356219b2ee8SDavid du Colombier 			c = table[*p];
3573e12c5d1SDavid du Colombier 			if(c < 0){
3583e12c5d1SDavid du Colombier 				if(squawk)
359219b2ee8SDavid du Colombier 					EPR "%s: bad char 0x%x near byte %ld in %s\n", argv0, *p, ninput+(p-e), file);
3603e12c5d1SDavid du Colombier 				nerrors++;
3613e12c5d1SDavid du Colombier 				if(clean)
3623e12c5d1SDavid du Colombier 					continue;
3633e12c5d1SDavid du Colombier 				c = BADMAP;
3643e12c5d1SDavid du Colombier 			}
3653e12c5d1SDavid du Colombier 			*r++ = c;
3663e12c5d1SDavid du Colombier 		}
3673e12c5d1SDavid du Colombier 		OUT(out, runes, r-runes);
3683e12c5d1SDavid du Colombier 	}
369ec46fab0SDavid du Colombier 	OUT(out, runes, 0);
3703e12c5d1SDavid du Colombier 	if(n < 0){
371219b2ee8SDavid du Colombier #ifdef	PLAN9
372219b2ee8SDavid du Colombier 		EPR "%s: input read: %r\n", argv0);
373219b2ee8SDavid du Colombier #else
374219b2ee8SDavid du Colombier 		EPR "%s: input read: %s\n", argv0, strerror(errno));
375219b2ee8SDavid du Colombier #endif
376219b2ee8SDavid du Colombier 		EXIT(1, "input read error");
3773e12c5d1SDavid du Colombier 	}
3783e12c5d1SDavid du Colombier }
3793e12c5d1SDavid du Colombier 
3803e12c5d1SDavid du Colombier void
3813e12c5d1SDavid du Colombier outtable(Rune *base, int n, long *map)
3823e12c5d1SDavid du Colombier {
383219b2ee8SDavid du Colombier 	long c;
3843e12c5d1SDavid du Colombier 	char *p;
3853e12c5d1SDavid du Colombier 	int i;
3863e12c5d1SDavid du Colombier 
3873e12c5d1SDavid du Colombier 	nrunes += n;
388219b2ee8SDavid du Colombier 	for(i = 0; i < NRUNE; i++)
389219b2ee8SDavid du Colombier 		tab[i] = -1;
3903e12c5d1SDavid du Colombier 	for(i = 0; i < 256; i++)
3913e12c5d1SDavid du Colombier 		if(map[i] >= 0)
3923e12c5d1SDavid du Colombier 			tab[map[i]] = i;
3933e12c5d1SDavid du Colombier 	for(i = 0, p = obuf; i < n; i++){
3943e12c5d1SDavid du Colombier 		c = tab[base[i]];
3953e12c5d1SDavid du Colombier 		if(c < 0){
3963e12c5d1SDavid du Colombier 			if(squawk)
397219b2ee8SDavid du Colombier 				EPR "%s: rune 0x%x not in output cs\n", argv0, base[i]);
3983e12c5d1SDavid du Colombier 			nerrors++;
3993e12c5d1SDavid du Colombier 			if(clean)
4003e12c5d1SDavid du Colombier 				continue;
4013e12c5d1SDavid du Colombier 			c = BADMAP;
4023e12c5d1SDavid du Colombier 		}
4033e12c5d1SDavid du Colombier 		*p++ = c;
4043e12c5d1SDavid du Colombier 	}
4053e12c5d1SDavid du Colombier 	noutput += p-obuf;
4063e12c5d1SDavid du Colombier 	write(1, obuf, p-obuf);
4073e12c5d1SDavid du Colombier }
4083e12c5d1SDavid du Colombier 
4093e12c5d1SDavid du Colombier long tabascii[256] =
4103e12c5d1SDavid du Colombier {
4113e12c5d1SDavid du Colombier 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,
4123e12c5d1SDavid du Colombier 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,
4133e12c5d1SDavid du Colombier 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,
4143e12c5d1SDavid du Colombier 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
4153e12c5d1SDavid du Colombier 0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f,
4163e12c5d1SDavid du Colombier 0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5a,0x5b,0x5c,0x5d,0x5e,0x5f,
4173e12c5d1SDavid du Colombier 0x60,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,
4183e12c5d1SDavid du Colombier 0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7a,0x7b,0x7c,0x7d,0x7e,0x7f,
419219b2ee8SDavid du Colombier   -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,
4203e12c5d1SDavid du Colombier   -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,
4213e12c5d1SDavid du Colombier   -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,
4223e12c5d1SDavid du Colombier   -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,
4233e12c5d1SDavid du Colombier   -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,
4243e12c5d1SDavid du Colombier   -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,
4253e12c5d1SDavid du Colombier   -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,
4263e12c5d1SDavid du Colombier   -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,
4273e12c5d1SDavid du Colombier };
4283e12c5d1SDavid du Colombier 
429219b2ee8SDavid du Colombier long tabmsdos[256] =	/* from jhelling@cs.ruu.nl (Jeroen Hellingman) */
430219b2ee8SDavid du Colombier {
431219b2ee8SDavid du Colombier 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,
432219b2ee8SDavid du Colombier 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,
433219b2ee8SDavid du Colombier 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,
434219b2ee8SDavid du Colombier 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
435219b2ee8SDavid du Colombier 0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f,
436219b2ee8SDavid du Colombier 0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5a,0x5b,0x5c,0x5d,0x5e,0x5f,
437219b2ee8SDavid du Colombier 0x60,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,
438219b2ee8SDavid du Colombier 0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7a,0x7b,0x7c,0x7d,0x7e,0x7f,
439219b2ee8SDavid du Colombier 0x00c7, 0x00fc, 0x00e9, 0x00e2, 0x00e4, 0x00e0, 0x00e5, 0x00e7, /* latin */
440219b2ee8SDavid du Colombier 0x00ea, 0x00eb, 0x00e8, 0x00ef, 0x00ee, 0x00ec, 0x00c4, 0x00c5,
441219b2ee8SDavid du Colombier 0x00c9, 0x00e6, 0x00c6, 0x00f4, 0x00f6, 0x00f2, 0x00fb, 0x00f9,
442219b2ee8SDavid du Colombier 0x00ff, 0x00d6, 0x00dc, 0x00a2, 0x00a3, 0x00a5, 0x20a7, 0x0192,
443219b2ee8SDavid du Colombier 0x00e1, 0x00ed, 0x00f3, 0x00fa, 0x00f1, 0x00d1, 0x00aa, 0x00ba,
444219b2ee8SDavid du Colombier 0x00bf, 0x2310, 0x00ac, 0x00bd, 0x00bc, 0x00a1, 0x00ab, 0x00bb,
445219b2ee8SDavid du Colombier 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, /* forms */
446219b2ee8SDavid du Colombier 0x2555, 0x2563, 0x2551, 0x2557, 0x255d, 0x255c, 0x255b, 0x2510,
447219b2ee8SDavid du Colombier 0x2514, 0x2534, 0x252c, 0x251c, 0x2500, 0x253c, 0x255e, 0x255f,
448219b2ee8SDavid du Colombier 0x255a, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256c, 0x2567,
449219b2ee8SDavid du Colombier 0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256b,
450219b2ee8SDavid du Colombier 0x256a, 0x2518, 0x250c, 0x2588, 0x2584, 0x258c, 0x2590, 0x2580,
451219b2ee8SDavid du Colombier 0x03b1, 0x00df, 0x0393, 0x03c0, 0x03a3, 0x03c3, 0x00b5, 0x03c4, /* greek */
452219b2ee8SDavid du Colombier 0x03a6, 0x0398, 0x2126, 0x03b4, 0x221e, 0x2205, 0x2208, 0x2229,
453219b2ee8SDavid du Colombier 0x2261, 0x00b1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00f7, 0x2248, /* math */
454219b2ee8SDavid du Colombier 0x00b0, 0x2022, 0x00b7, 0x221a, 0x207f, 0x00b2, 0x220e, 0x00a0,
455219b2ee8SDavid du Colombier };
456219b2ee8SDavid du Colombier long tabmsdos2[256] =	/* from jhelling@cs.ruu.nl (Jeroen Hellingman) */
457219b2ee8SDavid du Colombier {
458219b2ee8SDavid du Colombier 0x0000, 0x263a, 0x263b, 0x2665, 0x2666, 0x2663, 0x2660, 0x2022,
459219b2ee8SDavid du Colombier 0x25d8, 0x25cb, 0x25d9, 0x2642, 0x2640, 0x266a, 0x266b, 0x263c,
460219b2ee8SDavid du Colombier 0x25b6, 0x25c0, 0x2195, 0x203c, 0x00b6, 0x00a7, 0x2043, 0x21a8,
461219b2ee8SDavid du Colombier 0x2191, 0x2193, 0x2192, 0x2190, 0x2319, 0x2194, 0x25b2, 0x25bc,
462219b2ee8SDavid du Colombier 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,
463219b2ee8SDavid du Colombier 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
464219b2ee8SDavid du Colombier 0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f,
465219b2ee8SDavid du Colombier 0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5a,0x5b,0x5c,0x5d,0x5e,0x5f,
466219b2ee8SDavid du Colombier 0x60,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,
467219b2ee8SDavid du Colombier 0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7a,0x7b,0x7c,0x7d,0x7e,0x7f,
468219b2ee8SDavid du Colombier 0x00c7, 0x00fc, 0x00e9, 0x00e2, 0x00e4, 0x00e0, 0x00e5, 0x00e7, /* latin */
469219b2ee8SDavid du Colombier 0x00ea, 0x00eb, 0x00e8, 0x00ef, 0x00ee, 0x00ec, 0x00c4, 0x00c5,
470219b2ee8SDavid du Colombier 0x00c9, 0x00e6, 0x00c6, 0x00f4, 0x00f6, 0x00f2, 0x00fb, 0x00f9,
471219b2ee8SDavid du Colombier 0x00ff, 0x00d6, 0x00dc, 0x00a2, 0x00a3, 0x00a5, 0x20a7, 0x0192,
472219b2ee8SDavid du Colombier 0x00e1, 0x00ed, 0x00f3, 0x00fa, 0x00f1, 0x00d1, 0x00aa, 0x00ba,
473219b2ee8SDavid du Colombier 0x00bf, 0x2310, 0x00ac, 0x00bd, 0x00bc, 0x00a1, 0x00ab, 0x00bb,
474219b2ee8SDavid du Colombier 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, /* forms */
475219b2ee8SDavid du Colombier 0x2555, 0x2563, 0x2551, 0x2557, 0x255d, 0x255c, 0x255b, 0x2510,
476219b2ee8SDavid du Colombier 0x2514, 0x2534, 0x252c, 0x251c, 0x2500, 0x253c, 0x255e, 0x255f,
477219b2ee8SDavid du Colombier 0x255a, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256c, 0x2567,
478219b2ee8SDavid du Colombier 0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256b,
479219b2ee8SDavid du Colombier 0x256a, 0x2518, 0x250c, 0x2588, 0x2584, 0x258c, 0x2590, 0x2580,
480219b2ee8SDavid du Colombier 0x03b1, 0x00df, 0x0393, 0x03c0, 0x03a3, 0x03c3, 0x00b5, 0x03c4, /* greek */
481219b2ee8SDavid du Colombier 0x03a6, 0x0398, 0x2126, 0x03b4, 0x221e, 0x2205, 0x2208, 0x2229,
482219b2ee8SDavid du Colombier 0x2261, 0x00b1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00f7, 0x2248, /* math */
483219b2ee8SDavid du Colombier 0x00b0, 0x2022, 0x00b7, 0x221a, 0x207f, 0x00b2, 0x220e, 0x00a0,
484219b2ee8SDavid du Colombier };
4853e12c5d1SDavid du Colombier struct convert convert[] =
4863e12c5d1SDavid du Colombier {	/* if two entries have the same name, put the from one first */
487219b2ee8SDavid du Colombier 	{ "8859-1", "Latin-1 (Western and Northern Europe including Italian)", Table, (void *)tab8859_1 },
488219b2ee8SDavid du Colombier 	{ "8859-2", "Latin-2 (Eastern Europe except Turkey and the Baltic countries)", Table, (void *)tab8859_2 },
489219b2ee8SDavid du Colombier 	{ "8859-3", "Latin-3 (Mediterranean, South Africa, Esperanto)", Table, (void *)tab8859_3 },
490219b2ee8SDavid du Colombier 	{ "8859-4", "Latin-4 (Scandinavia and the Baltic countries; obsolete)", Table, (void *)tab8859_4 },
4913e12c5d1SDavid du Colombier 	{ "8859-5", "Part 5 (Cyrillic)", Table, (void *)tab8859_5 },
4923e12c5d1SDavid du Colombier 	{ "8859-6", "Part 6 (Arabic)", Table, (void *)tab8859_6 },
4933e12c5d1SDavid du Colombier 	{ "8859-7", "Part 7 (Greek)", Table, (void *)tab8859_7 },
4943e12c5d1SDavid du Colombier 	{ "8859-8", "Part 8 (Hebrew)", Table, (void *)tab8859_8 },
495219b2ee8SDavid du Colombier 	{ "8859-9", "Latin-5 (Turkey, Western Europe except Icelandic and Faroese)", Table, (void *)tab8859_9 },
496219b2ee8SDavid du Colombier 	{ "8859-10", "Latin-6 (Northern Europe)", Table, (void *)tab8859_10 },
497d9306527SDavid du Colombier 	{ "8859-15", "Latin-9 (Western Europe)", Table, (void *)tab8859_15 },
49874f16c81SDavid du Colombier 	{ "ascii", "7-bit ASCII", Table, (void *)tabascii },
49974f16c81SDavid du Colombier 	{ "atari", "ATARI-ST character set", Table, (void *)tabatari },
500219b2ee8SDavid du Colombier 	{ "av", "Alternativnyj Variant", Table, (void *)tabav },
50174f16c81SDavid du Colombier 	{ "big5", "Big 5 (HKU)", From|Func, 0, (Fnptr)big5_in },
50274f16c81SDavid du Colombier 	{ "big5", "Big 5 (HKU)", Func, 0, (Fnptr)big5_out },
50374f16c81SDavid du Colombier 	{ "ebcdic", "EBCDIC", Table, (void *)tabebcdic },	/* 6f is recommended bad map */
50474f16c81SDavid du Colombier 	{ "euc-k", "Korean EUC: ASCII+KS C 5601 1987", From|Func, 0, (Fnptr)uksc_in },
50574f16c81SDavid du Colombier 	{ "euc-k", "Korean EUC: ASCII+KS C 5601 1987", Func, 0, (Fnptr)uksc_out },
506*853458f3SDavid du Colombier  	{ "euc-kr", "Korean EUC: ASCII+KS C 5601 1987", From|Func, 0, (Fnptr)uksc_in },
507*853458f3SDavid du Colombier  	{ "euc-kr", "Korean EUC: ASCII+KS C 5601 1987", Func, 0, (Fnptr)uksc_out },
508*853458f3SDavid du Colombier  	{ "ks_c_5601-1987", "Korean EUC: ASCII+KS C 5601 1987", From|Func, 0, (Fnptr)uksc_in },
509*853458f3SDavid du Colombier  	{ "ks_c_5601-1987", "Korean EUC: ASCII+KS C 5601 1987", Func, 0, (Fnptr)uksc_out },
510b85a8364SDavid du Colombier 	{ "gb2312", "GB2312-80 (Chinese)", From|Func, 0, (Fnptr)gb_in },
511b85a8364SDavid du Colombier 	{ "gb2312", "GB2312-80 (Chinese)", Func, 0, (Fnptr)gb_out },
51243751f27SDavid du Colombier 	{ "gbk", "GBK (Chinese)", From|Func, 0, (Fnptr)gbk_in },
51343751f27SDavid du Colombier 	{ "gbk", "GBK (Chinese)", Func, 0, (Fnptr)gbk_out },
51474f16c81SDavid du Colombier 	{ "html", "HTML", From|Func, 0, (Fnptr)html_in },
51574f16c81SDavid du Colombier 	{ "html", "HTML", Func, 0, (Fnptr)html_out },
516b85a8364SDavid du Colombier 	{ "ibm437", "IBM Code Page 437 (US)", Table, (void*)tabcp437 },
517b85a8364SDavid du Colombier 	{ "ibm720", "IBM Code Page 720 (Arabic)", Table, (void*)tabcp720 },
518b85a8364SDavid du Colombier 	{ "ibm737", "IBM Code Page 737 (Greek)", Table, (void*)tabcp737 },
519b85a8364SDavid du Colombier 	{ "ibm775", "IBM Code Page 775 (Baltic)", Table, (void*)tabcp775 },
520b85a8364SDavid du Colombier 	{ "ibm850", "IBM Code Page 850 (Multilingual Latin I)", Table, (void*)tabcp850 },
521b85a8364SDavid du Colombier 	{ "ibm852", "IBM Code Page 852 (Latin II)", Table, (void*)tabcp852 },
522b85a8364SDavid du Colombier 	{ "ibm855", "IBM Code Page 855 (Cyrillic)", Table, (void*)tabcp855 },
523b85a8364SDavid du Colombier 	{ "ibm857", "IBM Code Page 857 (Turkish)", Table, (void*)tabcp857 },
524b85a8364SDavid du Colombier 	{ "ibm858", "IBM Code Page 858 (Multilingual Latin I+Euro)", Table, (void*)tabcp858 },
525b85a8364SDavid du Colombier 	{ "ibm862", "IBM Code Page 862 (Hebrew)", Table, (void*)tabcp862 },
526b85a8364SDavid du Colombier 	{ "ibm866", "IBM Code Page 866 (Russian)", Table, (void*)tabcp866 },
527b85a8364SDavid du Colombier 	{ "ibm874", "IBM Code Page 874 (Thai)", Table, (void*)tabcp874 },
528b85a8364SDavid du Colombier 	{ "iso-2022-jp", "alias for jis-kanji (MIME)", From|Func, 0, (Fnptr)jisjis_in },
529b85a8364SDavid du Colombier 	{ "iso-2022-jp", "alias for jis-kanji (MIME)", Func, 0, (Fnptr)jisjis_out },
530b85a8364SDavid du Colombier 	{ "iso-8859-1", "alias for 8859-1 (MIME)", Table, (void *)tab8859_1 },
531b85a8364SDavid du Colombier 	{ "iso-8859-2", "alias for 8859-2 (MIME)", Table, (void *)tab8859_2 },
532b85a8364SDavid du Colombier 	{ "iso-8859-3", "alias for 8859-3 (MIME)", Table, (void *)tab8859_3 },
533b85a8364SDavid du Colombier 	{ "iso-8859-4", "alias for 8859-4 (MIME)", Table, (void *)tab8859_4 },
534b85a8364SDavid du Colombier 	{ "iso-8859-5", "alias for 8859-5 (MIME)", Table, (void *)tab8859_5 },
535b85a8364SDavid du Colombier 	{ "iso-8859-6", "alias for 8859-6 (MIME)", Table, (void *)tab8859_6 },
536b85a8364SDavid du Colombier 	{ "iso-8859-7", "alias for 8859-7 (MIME)", Table, (void *)tab8859_7 },
537b85a8364SDavid du Colombier 	{ "iso-8859-8", "alias for 8859-8 (MIME)", Table, (void *)tab8859_8 },
538b85a8364SDavid du Colombier 	{ "iso-8859-9", "alias for 8859-9 (MIME)", Table, (void *)tab8859_9 },
539b85a8364SDavid du Colombier 	{ "iso-8859-10", "alias for 8859-10 (MIME)", Table, (void *)tab8859_10 },
540b85a8364SDavid du Colombier 	{ "iso-8859-15", "alias for 8859-15 (MIME)", Table, (void *)tab8859_15 },
541219b2ee8SDavid du Colombier 	{ "jis", "guesses at the JIS encoding", From|Func, 0, (Fnptr)jis_in },
5424ac975e2SDavid du Colombier 	{ "jis-kanji", "ISO 2022-JP (Japanese)", From|Func, 0, (Fnptr)jisjis_in },
5434ac975e2SDavid du Colombier 	{ "jis-kanji", "ISO 2022-JP (Japanese)", Func, 0, (Fnptr)jisjis_out },
54474f16c81SDavid du Colombier 	{ "koi8", "KOI-8 (GOST 19769-74)", Table, (void *)tabkoi8 },
545b85a8364SDavid du Colombier 	{ "koi8-r", "alias for koi8 (MIME)", Table, (void *)tabkoi8 },
546b85a8364SDavid du Colombier 	{ "latin1", "alias for 8859-1", Table, (void *)tab8859_1 },
547426d2b71SDavid du Colombier 	{ "macrom", "Macintosh Standard Roman character set", Table, (void *)tabmacroman },
548b85a8364SDavid du Colombier 	{ "microsoft", "alias for windows1252", Table, (void *)tabcp1252 },
549219b2ee8SDavid du Colombier 	{ "ms-kanji", "Microsoft, or Shift-JIS", From|Func, 0, (Fnptr)msjis_in },
550219b2ee8SDavid du Colombier 	{ "ms-kanji", "Microsoft, or Shift-JIS", Func, 0, (Fnptr)msjis_out },
551b85a8364SDavid du Colombier 	{ "msdos", "IBM PC (alias for ibm437)", Table, (void *)tabcp437 },
552b85a8364SDavid du Colombier 	{ "msdos2", "IBM PC (ibm437 with graphics in C0)", Table, (void *)tabmsdos2 },
55374f16c81SDavid du Colombier 	{ "next", "NEXTSTEP character set", Table, (void *)tabnextstep },
55474f16c81SDavid du Colombier 	{ "ov", "Osnovnoj Variant", Table, (void *)tabov },
555b85a8364SDavid du Colombier 	{ "ps2", "IBM PS/2: (alias for ibm850)", Table, (void *)tabcp850 },
55674f16c81SDavid du Colombier 	{ "sf1", "ISO-646: Finnish/Swedish SF-1 variant", Table, (void *)tabsf1 },
55774f16c81SDavid du Colombier 	{ "sf2", "ISO-646: Finnish/Swedish SF-2 variant (recommended)", Table, (void *)tabsf2 },
558b85a8364SDavid du Colombier 	{ "tis-620", "Thai+ASCII (TIS 620-1986)", Table, (void *)tabtis620 },
559ec46fab0SDavid du Colombier 	{ "tune", "TUNE (Tamil)", From|Func, 0, (Fnptr)tune_in },
560ec46fab0SDavid du Colombier 	{ "tune", "TUNE (Tamil)", Func, 0, (Fnptr)tune_out },
56174f16c81SDavid du Colombier 	{ "ucode", "Russian U-code", Table, (void *)tabucode },
56274f16c81SDavid du Colombier 	{ "ujis", "EUC-JX: JIS 0208", From|Func, 0, (Fnptr)ujis_in },
56374f16c81SDavid du Colombier 	{ "ujis", "EUC-JX: JIS 0208", Func, 0, (Fnptr)ujis_out },
56474f16c81SDavid du Colombier 	{ "unicode", "Unicode 1.1", From|Func, 0, (Fnptr)unicode_in },
56574f16c81SDavid du Colombier 	{ "unicode", "Unicode 1.1", Func, 0, (Fnptr)unicode_out },
566b85a8364SDavid du Colombier 	{ "unicode-be", "Unicode 1.1 big-endian", From|Func, 0, (Fnptr)unicode_in_be },
567b85a8364SDavid du Colombier 	{ "unicode-be", "Unicode 1.1 big-endian", Func, 0, (Fnptr)unicode_out_be },
568b85a8364SDavid du Colombier 	{ "unicode-le", "Unicode 1.1 little-endian", From|Func, 0, (Fnptr)unicode_in_le },
569b85a8364SDavid du Colombier 	{ "unicode-le", "Unicode 1.1 little-endian", Func, 0, (Fnptr)unicode_out_le },
570b85a8364SDavid du Colombier 	{ "us-ascii", "alias for ascii (MIME)", Table, (void *)tabascii },
57174f16c81SDavid du Colombier 	{ "utf", "FSS-UTF a.k.a. UTF-8", From|Func, 0, (Fnptr)utf_in },
57274f16c81SDavid du Colombier 	{ "utf", "FSS-UTF a.k.a. UTF-8", Func, 0, (Fnptr)utf_out },
573b85a8364SDavid du Colombier 	{ "utf1", "UTF-1 (ISO 10646 Annex A)", From|Func, 0, (Fnptr)isoutf_in },
574b85a8364SDavid du Colombier 	{ "utf1", "UTF-1 (ISO 10646 Annex A)", Func, 0, (Fnptr)isoutf_out },
575b85a8364SDavid du Colombier 	{ "utf-8", "alias for utf (MIME)", From|Func, 0, (Fnptr)utf_in },
576b85a8364SDavid du Colombier 	{ "utf-8", "alias for utf (MIME)", Func, 0, (Fnptr)utf_out },
577b85a8364SDavid du Colombier 	{ "utf-16", "alias for unicode (MIME)", From|Func, 0, (Fnptr)unicode_in },
578b85a8364SDavid du Colombier 	{ "utf-16", "alias for unicode (MIME)", Func, 0, (Fnptr)unicode_out },
579b85a8364SDavid du Colombier 	{ "utf-16be", "alias for unicode-be (MIME)", From|Func, 0, (Fnptr)unicode_in_be },
580b85a8364SDavid du Colombier 	{ "utf-16be", "alias for unicode-be (MIME)", Func, 0, (Fnptr)unicode_out_be },
581b85a8364SDavid du Colombier 	{ "utf-16le", "alias for unicode-le (MIME)", From|Func, 0, (Fnptr)unicode_in_le },
582b85a8364SDavid du Colombier 	{ "utf-16le", "alias for unicode-le (MIME)", Func, 0, (Fnptr)unicode_out_le },
583219b2ee8SDavid du Colombier 	{ "viet1", "Vietnamese VSCII-1 (1993)", Table, (void *)tabviet1 },
584219b2ee8SDavid du Colombier 	{ "viet2", "Vietnamese VSCII-2 (1993)", Table, (void *)tabviet2 },
585b85a8364SDavid du Colombier 	{ "vscii", "Vietnamese VISCII 1.1 (1992)", Table, (void *)tabviscii },
586a49e8198SDavid du Colombier 	{ "windows-1250", "Windows Code Page 1250 (Central Europe)", Table, (void *)tabcp1250 },
587a49e8198SDavid du Colombier 	{ "windows-1251", "Windows Code Page 1251 (Cyrillic)", Table, (void *)tabcp1251 },
588a49e8198SDavid du Colombier 	{ "windows-1252", "Windows Code Page 1252 (Latin I)", Table, (void *)tabcp1252 },
589a49e8198SDavid du Colombier 	{ "windows-1253", "Windows Code Page 1253 (Greek)", Table, (void *)tabcp1253 },
590a49e8198SDavid du Colombier 	{ "windows-1254", "Windows Code Page 1254 (Turkish)", Table, (void *)tabcp1254 },
591a49e8198SDavid du Colombier 	{ "windows-1255", "Windows Code Page 1255 (Hebrew)", Table, (void *)tabcp1255 },
592a49e8198SDavid du Colombier 	{ "windows-1256", "Windows Code Page 1256 (Arabic)", Table, (void *)tabcp1256 },
593a49e8198SDavid du Colombier 	{ "windows-1257", "Windows Code Page 1257 (Baltic)", Table, (void *)tabcp1257 },
594a49e8198SDavid du Colombier 	{ "windows-1258", "Windows Code Page 1258 (Vietnam)", Table, (void *)tabcp1258 },
5953e12c5d1SDavid du Colombier 	{ 0 },
5963e12c5d1SDavid du Colombier };
597