1*16d86563SAlexander Pyhalov /*
2*16d86563SAlexander Pyhalov  * CDDL HEADER START
3*16d86563SAlexander Pyhalov  *
4*16d86563SAlexander Pyhalov  * The contents of this file are subject to the terms of the
5*16d86563SAlexander Pyhalov  * Common Development and Distribution License (the "License").
6*16d86563SAlexander Pyhalov  * You may not use this file except in compliance with the License.
7*16d86563SAlexander Pyhalov  *
8*16d86563SAlexander Pyhalov  * You can obtain a copy of the license at src/OPENSOLARIS.LICENSE
9*16d86563SAlexander Pyhalov  * or http://www.opensolaris.org/os/licensing.
10*16d86563SAlexander Pyhalov  * See the License for the specific language governing permissions
11*16d86563SAlexander Pyhalov  * and limitations under the License.
12*16d86563SAlexander Pyhalov  *
13*16d86563SAlexander Pyhalov  * When distributing Covered Code, include this CDDL HEADER in each
14*16d86563SAlexander Pyhalov  * file and include the License file at src/OPENSOLARIS.LICENSE.
15*16d86563SAlexander Pyhalov  * If applicable, add the following below this CDDL HEADER, with the
16*16d86563SAlexander Pyhalov  * fields enclosed by brackets "[]" replaced with your own identifying
17*16d86563SAlexander Pyhalov  * information: Portions Copyright [yyyy] [name of copyright owner]
18*16d86563SAlexander Pyhalov  *
19*16d86563SAlexander Pyhalov  * CDDL HEADER END
20*16d86563SAlexander Pyhalov  */
21*16d86563SAlexander Pyhalov /*
22*16d86563SAlexander Pyhalov  * Copyright (c) 1999 by Sun Microsystems, Inc.
23*16d86563SAlexander Pyhalov  * All rights reserved.
24*16d86563SAlexander Pyhalov  */
25*16d86563SAlexander Pyhalov 
26*16d86563SAlexander Pyhalov 
27*16d86563SAlexander Pyhalov /*
28*16d86563SAlexander Pyhalov  * This program convert Additional Codeset Characters from 0x00 through 0xff
29*16d86563SAlexander Pyhalov  * to UTF-8 codeset. And also again converting the chacter in UTF-8 to original
30*16d86563SAlexander Pyhalov  * codeset.
31*16d86563SAlexander Pyhalov  * For example,
32*16d86563SAlexander Pyhalov  *               IBM -> UTF-8 -> IBM
33*16d86563SAlexander Pyhalov  *                (1)     (2)     (3)
34*16d86563SAlexander Pyhalov  *                            -> Unicode Scaler
35*16d86563SAlexander Pyhalov  *                                (4)
36*16d86563SAlexander Pyhalov  *                           output     (1) (2) (4)line by line
37*16d86563SAlexander Pyhalov  *                           comparing  (1) (3)
38*16d86563SAlexander Pyhalov  */
39*16d86563SAlexander Pyhalov 
40*16d86563SAlexander Pyhalov #include <stdio.h>
41*16d86563SAlexander Pyhalov #include <libgen.h>
42*16d86563SAlexander Pyhalov #include <stdlib.h>
43*16d86563SAlexander Pyhalov #include <unistd.h>
44*16d86563SAlexander Pyhalov #include <locale.h>
45*16d86563SAlexander Pyhalov #include <iconv.h>
46*16d86563SAlexander Pyhalov #include <string.h>
47*16d86563SAlexander Pyhalov #include <errno.h>
48*16d86563SAlexander Pyhalov #include <sys/types.h>
49*16d86563SAlexander Pyhalov #include <sys/wait.h>
50*16d86563SAlexander Pyhalov 
51*16d86563SAlexander Pyhalov static void mk_data(char *,char *);
52*16d86563SAlexander Pyhalov 
53*16d86563SAlexander Pyhalov char *	ME;
54*16d86563SAlexander Pyhalov int	status;
55*16d86563SAlexander Pyhalov static int	flag_check = 0; /* check with data file */
56*16d86563SAlexander Pyhalov 
57*16d86563SAlexander Pyhalov static struct  {
58*16d86563SAlexander Pyhalov 	unsigned int	from;
59*16d86563SAlexander Pyhalov 	unsigned int	u4;
60*16d86563SAlexander Pyhalov } tbl[0x10000];
61*16d86563SAlexander Pyhalov 
62*16d86563SAlexander Pyhalov 
63*16d86563SAlexander Pyhalov void
usage(int status)64*16d86563SAlexander Pyhalov usage(int status)
65*16d86563SAlexander Pyhalov {
66*16d86563SAlexander Pyhalov 	fprintf(stderr, "Usage: %s from-code\n", ME);
67*16d86563SAlexander Pyhalov 	exit(status);
68*16d86563SAlexander Pyhalov }
69*16d86563SAlexander Pyhalov 
70*16d86563SAlexander Pyhalov void
validate(int i,iconv_t cd,iconv_t cd2,iconv_t cd3)71*16d86563SAlexander Pyhalov validate(int i, iconv_t cd, iconv_t cd2, iconv_t cd3)
72*16d86563SAlexander Pyhalov {
73*16d86563SAlexander Pyhalov 	uchar_t		source_buf[1024];
74*16d86563SAlexander Pyhalov 	uchar_t		result_buf[1024];
75*16d86563SAlexander Pyhalov 	uchar_t		tmp_buf[1024];
76*16d86563SAlexander Pyhalov 	const uchar_t *	source;
77*16d86563SAlexander Pyhalov 	uchar_t *		result;
78*16d86563SAlexander Pyhalov 	uchar_t *		tmp;
79*16d86563SAlexander Pyhalov 	size_t		source_len;
80*16d86563SAlexander Pyhalov 	size_t		result_len;
81*16d86563SAlexander Pyhalov 	size_t		result_len2;
82*16d86563SAlexander Pyhalov 	size_t		tmp_len;
83*16d86563SAlexander Pyhalov 	size_t		s;
84*16d86563SAlexander Pyhalov 	int		j;
85*16d86563SAlexander Pyhalov 	ulong_t   	l;
86*16d86563SAlexander Pyhalov 
87*16d86563SAlexander Pyhalov #ifdef _LITTLE_ENDIAN
88*16d86563SAlexander Pyhalov #define CHECKWITHFILE \
89*16d86563SAlexander Pyhalov 	if( flag_check > 0 ) { \
90*16d86563SAlexander Pyhalov 		l = 0U; \
91*16d86563SAlexander Pyhalov 		for( j =  sizeof (tmp_buf) - tmp_len -1; \
92*16d86563SAlexander Pyhalov 		     j >= ((i == 0) ? 2: 0); j--) \
93*16d86563SAlexander Pyhalov 			l = (l << 8) + ((uint_t)tmp_buf[j]); \
94*16d86563SAlexander Pyhalov 		if (l != tbl[i].u4 ) fprintf(stderr, "%x != %x \n", l, tbl[i].u4 ); \
95*16d86563SAlexander Pyhalov 	}
96*16d86563SAlexander Pyhalov #else
97*16d86563SAlexander Pyhalov #define CHECKWITHFILE \
98*16d86563SAlexander Pyhalov 	if( flag_check > 0 ) { \
99*16d86563SAlexander Pyhalov 		l = 0U; \
100*16d86563SAlexander Pyhalov 		j = ((i == 0) ? 2: 0); \
101*16d86563SAlexander Pyhalov 		for(; j < sizeof (tmp_buf) - tmp_len ; j++) \
102*16d86563SAlexander Pyhalov 			l = (l << 8) + ((uint_t)tmp_buf[j]); \
103*16d86563SAlexander Pyhalov 		if (l != tbl[i].u4 ) fprintf(stderr, "%x != %x \n", l, tbl[i].u4 ); \
104*16d86563SAlexander Pyhalov 	}
105*16d86563SAlexander Pyhalov #endif
106*16d86563SAlexander Pyhalov 
107*16d86563SAlexander Pyhalov #define PRINTUNICODE \
108*16d86563SAlexander Pyhalov 	tmp = tmp_buf; \
109*16d86563SAlexander Pyhalov 	tmp_len = sizeof (tmp_buf); \
110*16d86563SAlexander Pyhalov 	result = result_buf; \
111*16d86563SAlexander Pyhalov 	result_len2 = sizeof (result_buf) - result_len; \
112*16d86563SAlexander Pyhalov 	s = iconv(cd2, (const char**)&result, &result_len2, (char**)&tmp, &tmp_len); \
113*16d86563SAlexander Pyhalov 	if (s != 0) { \
114*16d86563SAlexander Pyhalov 		printf(" \n stoped \n"); \
115*16d86563SAlexander Pyhalov 		fprintf(stderr, "fail to con_LITTLE_ENDIANvert UTF-8 to Unicode\n"); \
116*16d86563SAlexander Pyhalov 		exit (status); \
117*16d86563SAlexander Pyhalov 	} \
118*16d86563SAlexander Pyhalov 	printf("\t"); \
119*16d86563SAlexander Pyhalov 	for( j = 0; j < sizeof (tmp_buf) - tmp_len ; j++) \
120*16d86563SAlexander Pyhalov 		printf("%02x", (uchar_t)tmp_buf[j]); \
121*16d86563SAlexander Pyhalov 	CHECKWITHFILE
122*16d86563SAlexander Pyhalov 
123*16d86563SAlexander Pyhalov #define COMPARE \
124*16d86563SAlexander Pyhalov 	tmp = tmp_buf; \
125*16d86563SAlexander Pyhalov 	tmp_len = sizeof (tmp_buf); \
126*16d86563SAlexander Pyhalov 	result = result_buf; \
127*16d86563SAlexander Pyhalov 	result_len2 = sizeof (result_buf) - result_len; \
128*16d86563SAlexander Pyhalov 	s = iconv(cd3, (const char**)&result, &result_len2, (char**)&tmp, &tmp_len); \
129*16d86563SAlexander Pyhalov 	if (s != 0) { \
130*16d86563SAlexander Pyhalov 		printf(" \n WARNING \n"); \
131*16d86563SAlexander Pyhalov 		fprintf(stderr, "fail to convert UTF-8 to Orignal Codeset(%x)\n",\
132*16d86563SAlexander Pyhalov 		i); \
133*16d86563SAlexander Pyhalov 		fprintf(stderr, "errno=%d %d %d\n", \
134*16d86563SAlexander Pyhalov 			errno, \
135*16d86563SAlexander Pyhalov 			sizeof (result_buf) - result_len - result_len2, \
136*16d86563SAlexander Pyhalov 			result - result_buf); \
137*16d86563SAlexander Pyhalov 		exit (status); \
138*16d86563SAlexander Pyhalov 	} \
139*16d86563SAlexander Pyhalov 	printf("\t"); \
140*16d86563SAlexander Pyhalov 	if ((sizeof (tmp_buf) - tmp_len != 1) || \
141*16d86563SAlexander Pyhalov 	    ((uchar_t)tmp_buf[0] != (uchar_t)i )) { \
142*16d86563SAlexander Pyhalov 		printf("\t-> 0x%2x \n warning \n", (uchar_t)tmp_buf[0] ); \
143*16d86563SAlexander Pyhalov 		fprintf(stderr, " Converting answer is not the same (0x%02x) for  (0x%02x)\n", \
144*16d86563SAlexander Pyhalov 		(uchar_t)tmp_buf[0], i); \
145*16d86563SAlexander Pyhalov 	}
146*16d86563SAlexander Pyhalov 
147*16d86563SAlexander Pyhalov #define DATASIZE 1
148*16d86563SAlexander Pyhalov 
149*16d86563SAlexander Pyhalov 	source_buf[0] = i;
150*16d86563SAlexander Pyhalov 	source = source_buf;
151*16d86563SAlexander Pyhalov 	source_len = DATASIZE;
152*16d86563SAlexander Pyhalov 
153*16d86563SAlexander Pyhalov 	result = result_buf;
154*16d86563SAlexander Pyhalov 	result_len = sizeof (result_buf);
155*16d86563SAlexander Pyhalov 
156*16d86563SAlexander Pyhalov 	s = iconv(cd, (const char**)&source, &source_len, (char**)&result, &result_len);
157*16d86563SAlexander Pyhalov 
158*16d86563SAlexander Pyhalov 	status = 1;
159*16d86563SAlexander Pyhalov 	if (((size_t)(0)) == s) {
160*16d86563SAlexander Pyhalov 		if ((source_len != 0) ||
161*16d86563SAlexander Pyhalov 		    ((source - source_buf) != DATASIZE)) {
162*16d86563SAlexander Pyhalov 			fprintf(stderr, ": %d %d %d\n",
163*16d86563SAlexander Pyhalov 				errno,
164*16d86563SAlexander Pyhalov 				source_len,
165*16d86563SAlexander Pyhalov 				source - source_buf);
166*16d86563SAlexander Pyhalov 			exit(status);
167*16d86563SAlexander Pyhalov 		}
168*16d86563SAlexander Pyhalov 		printf("0x%02x\t0x", i);
169*16d86563SAlexander Pyhalov 		for( j = 0; j < sizeof (result_buf) - result_len ; j++)
170*16d86563SAlexander Pyhalov 			printf("%02x", (uchar_t)result_buf[j]);
171*16d86563SAlexander Pyhalov 		PRINTUNICODE
172*16d86563SAlexander Pyhalov 		COMPARE
173*16d86563SAlexander Pyhalov 		printf("\n");
174*16d86563SAlexander Pyhalov 		return;
175*16d86563SAlexander Pyhalov 	}
176*16d86563SAlexander Pyhalov 
177*16d86563SAlexander Pyhalov 	status += 1;
178*16d86563SAlexander Pyhalov 	if (((size_t)(-1)) == s) {
179*16d86563SAlexander Pyhalov 		if (errno == EILSEQ) {
180*16d86563SAlexander Pyhalov 			printf("0x%02x	EILSEQ\n", i);
181*16d86563SAlexander Pyhalov 			return;
182*16d86563SAlexander Pyhalov 		}
183*16d86563SAlexander Pyhalov 		fprintf(stderr, "Error for source 0x%02x(%d): %d %d %d %d %d\n",
184*16d86563SAlexander Pyhalov 			i, i,
185*16d86563SAlexander Pyhalov 			errno,
186*16d86563SAlexander Pyhalov 			(DATASIZE) - source_len, /* not converted size */
187*16d86563SAlexander Pyhalov 			source - source_buf,
188*16d86563SAlexander Pyhalov 			(sizeof (result_buf)) - result_len,
189*16d86563SAlexander Pyhalov 			result - result_buf);
190*16d86563SAlexander Pyhalov 		exit(status);
191*16d86563SAlexander Pyhalov 	}
192*16d86563SAlexander Pyhalov 
193*16d86563SAlexander Pyhalov 	status += 1;
194*16d86563SAlexander Pyhalov 	exit(status);
195*16d86563SAlexander Pyhalov }
196*16d86563SAlexander Pyhalov 
main(int argc,char ** argv)197*16d86563SAlexander Pyhalov main(int argc, char ** argv)
198*16d86563SAlexander Pyhalov {
199*16d86563SAlexander Pyhalov 	int		r;
200*16d86563SAlexander Pyhalov 	char *		p;
201*16d86563SAlexander Pyhalov 	iconv_t		cd;
202*16d86563SAlexander Pyhalov 	iconv_t		cd2;
203*16d86563SAlexander Pyhalov 	iconv_t		cd3;
204*16d86563SAlexander Pyhalov 	int		i, j, k;
205*16d86563SAlexander Pyhalov 	char		*dir;
206*16d86563SAlexander Pyhalov 
207*16d86563SAlexander Pyhalov 	ME = basename(argv[0]);
208*16d86563SAlexander Pyhalov 	setlocale(LC_ALL, "");
209*16d86563SAlexander Pyhalov 	status = 100;
210*16d86563SAlexander Pyhalov 
211*16d86563SAlexander Pyhalov 	for (j = 1;  j < argc; j++) {
212*16d86563SAlexander Pyhalov 		if (argv[j][0] != '-')
213*16d86563SAlexander Pyhalov 			break;
214*16d86563SAlexander Pyhalov 		for (k = 1; ; k++) {
215*16d86563SAlexander Pyhalov 			if (argv[j][k] == '\0')
216*16d86563SAlexander Pyhalov 				break;
217*16d86563SAlexander Pyhalov 			if (argv[j][k] == 'c') {
218*16d86563SAlexander Pyhalov 				flag_check = 1;
219*16d86563SAlexander Pyhalov 				j++;
220*16d86563SAlexander Pyhalov 				if (j >= argc) usage(-1);
221*16d86563SAlexander Pyhalov 				dir = argv[j];
222*16d86563SAlexander Pyhalov 				continue;
223*16d86563SAlexander Pyhalov 			}
224*16d86563SAlexander Pyhalov 		}
225*16d86563SAlexander Pyhalov 	}
226*16d86563SAlexander Pyhalov 	if (j >= argc) usage(-1);
227*16d86563SAlexander Pyhalov 
228*16d86563SAlexander Pyhalov 
229*16d86563SAlexander Pyhalov 	if( flag_check > 0 ) mk_data(dir, argv[j]);
230*16d86563SAlexander Pyhalov 
231*16d86563SAlexander Pyhalov 	cd = iconv_open("UTF-8", argv[j]);
232*16d86563SAlexander Pyhalov 	if (((iconv_t)(-1)) == cd) {
233*16d86563SAlexander Pyhalov 		perror("iconv_open");
234*16d86563SAlexander Pyhalov 		exit(status);
235*16d86563SAlexander Pyhalov 	}
236*16d86563SAlexander Pyhalov 
237*16d86563SAlexander Pyhalov 	cd2 = iconv_open("UCS-2", "UTF-8");
238*16d86563SAlexander Pyhalov 	if (((iconv_t)(-1)) == cd2) {
239*16d86563SAlexander Pyhalov 		perror("iconv_open for UTF-8");
240*16d86563SAlexander Pyhalov 		exit(status);
241*16d86563SAlexander Pyhalov 	}
242*16d86563SAlexander Pyhalov 
243*16d86563SAlexander Pyhalov 	cd3 = iconv_open(argv[j], "UTF-8");
244*16d86563SAlexander Pyhalov 	if (((iconv_t)(-1)) == cd3) {
245*16d86563SAlexander Pyhalov 		perror("iconv_open for reverse");
246*16d86563SAlexander Pyhalov 		exit(status);
247*16d86563SAlexander Pyhalov 	}
248*16d86563SAlexander Pyhalov 
249*16d86563SAlexander Pyhalov 	/*
250*16d86563SAlexander Pyhalov 	 *	main logic
251*16d86563SAlexander Pyhalov 	 */
252*16d86563SAlexander Pyhalov 	for (i = 0; i <= 0xff; i++)
253*16d86563SAlexander Pyhalov 		validate(i, cd, cd2, cd3);
254*16d86563SAlexander Pyhalov 
255*16d86563SAlexander Pyhalov 	status = 200;
256*16d86563SAlexander Pyhalov 	r = iconv_close(cd);
257*16d86563SAlexander Pyhalov 	if (-1 == r) {
258*16d86563SAlexander Pyhalov 		perror("iconv_close");
259*16d86563SAlexander Pyhalov 		exit(status);
260*16d86563SAlexander Pyhalov 	}
261*16d86563SAlexander Pyhalov 
262*16d86563SAlexander Pyhalov 	r = iconv_close(cd2);
263*16d86563SAlexander Pyhalov 	if (-1 == r) {
264*16d86563SAlexander Pyhalov 		perror("iconv_close for UTF-8");
265*16d86563SAlexander Pyhalov 		exit(status);
266*16d86563SAlexander Pyhalov 	}
267*16d86563SAlexander Pyhalov 
268*16d86563SAlexander Pyhalov 	return (0);
269*16d86563SAlexander Pyhalov }
270*16d86563SAlexander Pyhalov 
271*16d86563SAlexander Pyhalov static void
mk_data(char * dir,char * name)272*16d86563SAlexander Pyhalov mk_data(char *dir, char* name)
273*16d86563SAlexander Pyhalov {
274*16d86563SAlexander Pyhalov 	register int	i, j;
275*16d86563SAlexander Pyhalov 	char		buf[BUFSIZ], num[100];
276*16d86563SAlexander Pyhalov 	unsigned int	l, k;
277*16d86563SAlexander Pyhalov 	FILE		*fd;
278*16d86563SAlexander Pyhalov 	char		file[BUFSIZ];
279*16d86563SAlexander Pyhalov 
280*16d86563SAlexander Pyhalov 	sprintf( file, "%s/%s.txt", dir, name);
281*16d86563SAlexander Pyhalov 	if ((fd = fopen(file, "r")) == NULL) {
282*16d86563SAlexander Pyhalov 		perror("fopen");
283*16d86563SAlexander Pyhalov 		exit (-1);
284*16d86563SAlexander Pyhalov 	}
285*16d86563SAlexander Pyhalov 	/* for information file, pari data is created */
286*16d86563SAlexander Pyhalov 	while (fgets(buf, BUFSIZ, fd)) {
287*16d86563SAlexander Pyhalov 		i = 0;
288*16d86563SAlexander Pyhalov 		while (buf[i] && isspace(buf[i]))
289*16d86563SAlexander Pyhalov 			i++;
290*16d86563SAlexander Pyhalov 		if (buf[i] == '#' || buf[i] == '\0')
291*16d86563SAlexander Pyhalov 			continue;
292*16d86563SAlexander Pyhalov 
293*16d86563SAlexander Pyhalov 		for (j = 0; !isspace(buf[i]); i++, j++)
294*16d86563SAlexander Pyhalov 			num[j] = buf[i];
295*16d86563SAlexander Pyhalov 		num[j] = '\0';
296*16d86563SAlexander Pyhalov 
297*16d86563SAlexander Pyhalov 		k = strtol(num, (char **)NULL, 16);
298*16d86563SAlexander Pyhalov 
299*16d86563SAlexander Pyhalov 		while (isspace(buf[i]))
300*16d86563SAlexander Pyhalov 			i++;
301*16d86563SAlexander Pyhalov 
302*16d86563SAlexander Pyhalov 		if (buf[i] == '#' || buf[i] == '\0')
303*16d86563SAlexander Pyhalov 			/* undefined */
304*16d86563SAlexander Pyhalov 			continue;
305*16d86563SAlexander Pyhalov 
306*16d86563SAlexander Pyhalov 		for (j = 0; !isspace(buf[i]); i++, j++)
307*16d86563SAlexander Pyhalov 			num[j] = buf[i];
308*16d86563SAlexander Pyhalov 		num[j] = '\0';
309*16d86563SAlexander Pyhalov 
310*16d86563SAlexander Pyhalov 		l = strtol(num, (char **)NULL, 16);
311*16d86563SAlexander Pyhalov 
312*16d86563SAlexander Pyhalov 		tbl[k].u4 = l;
313*16d86563SAlexander Pyhalov 		tbl[k].from = k;
314*16d86563SAlexander Pyhalov 	}
315*16d86563SAlexander Pyhalov }
316