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