removed old libs
[TestXSLT.git] / libiconv / tests / table-from.c
1 /* Copyright (C) 2000-2002 Free Software Foundation, Inc.
2    This file is part of the GNU LIBICONV Library.
3
4    The GNU LIBICONV Library is free software; you can redistribute it
5    and/or modify it under the terms of the GNU Library General Public
6    License as published by the Free Software Foundation; either version 2
7    of the License, or (at your option) any later version.
8
9    The GNU LIBICONV Library is distributed in the hope that it will be
10    useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12    Library General Public License for more details.
13
14    You should have received a copy of the GNU Library General Public
15    License along with the GNU LIBICONV Library; see the file COPYING.LIB.
16    If not, write to the Free Software Foundation, Inc., 59 Temple Place -
17    Suite 330, Boston, MA 02111-1307, USA.  */
18
19 /* Create a table from CHARSET to Unicode. */
20
21 #include "config.h"
22
23 #include <stddef.h>
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <string.h>
27 #include <iconv.h>
28 #include <errno.h>
29
30 /* If nonzero, ignore conversions outside Unicode plane 0. */
31 static int bmp_only;
32
33 static const char* hexbuf (unsigned char buf[], unsigned int buflen)
34 {
35   static char msg[50];
36   switch (buflen) {
37     case 1: sprintf(msg,"0x%02X",buf[0]); break;
38     case 2: sprintf(msg,"0x%02X%02X",buf[0],buf[1]); break;
39     case 3: sprintf(msg,"0x%02X%02X%02X",buf[0],buf[1],buf[2]); break;
40     case 4: sprintf(msg,"0x%02X%02X%02X%02X",buf[0],buf[1],buf[2],buf[3]); break;
41     default: abort();
42   }
43   return msg;
44 }
45
46 static int try (iconv_t cd, unsigned char buf[], unsigned int buflen, unsigned int* out)
47 {
48   const char* inbuf = (const char*) buf;
49   size_t inbytesleft = buflen;
50   char* outbuf = (char*) out;
51   size_t outbytesleft = 3*sizeof(unsigned int);
52   size_t result;
53   iconv(cd,NULL,NULL,NULL,NULL);
54   result = iconv(cd,(ICONV_CONST char**)&inbuf,&inbytesleft,&outbuf,&outbytesleft);
55   if (result != (size_t)(-1))
56     result = iconv(cd,NULL,NULL,&outbuf,&outbytesleft);
57   if (result == (size_t)(-1)) {
58     if (errno == EILSEQ) {
59       return -1;
60     } else if (errno == EINVAL) {
61       return 0;
62     } else {
63       int saved_errno = errno;
64       fprintf(stderr,"%s: iconv error: ",hexbuf(buf,buflen));
65       errno = saved_errno;
66       perror("");
67       exit(1);
68     }
69   } else if (result > 0) /* ignore conversions with transliteration */ {
70     return -1;
71   } else {
72     if (inbytesleft != 0) {
73       fprintf(stderr,"%s: inbytes = %ld, outbytes = %ld\n",hexbuf(buf,buflen),(long)(buflen-inbytesleft),(long)(3*sizeof(unsigned int)-outbytesleft));
74       exit(1);
75     }
76     return (3*sizeof(unsigned int)-outbytesleft)/sizeof(unsigned int);
77   }
78 }
79
80 /* Returns the out[] buffer as a Unicode value, formatted as 0x%04X. */
81 static const char* ucs4_decode (const unsigned int* out, unsigned int outlen)
82 {
83   static char hexbuf[21];
84   char* p = hexbuf;
85   while (outlen > 0) {
86     if (p > hexbuf)
87       *p++ = ' ';
88     sprintf (p, "0x%04X", out[0]);
89     out += 1; outlen -= 1;
90     if (bmp_only && strlen(p) > 6)
91       return NULL;
92     p += strlen(p);
93   }
94   return hexbuf;
95 }
96
97 int main (int argc, char* argv[])
98 {
99   const char* charset;
100   iconv_t cd;
101   int search_depth;
102
103   if (argc != 2) {
104     fprintf(stderr,"Usage: table-from charset\n");
105     exit(1);
106   }
107   charset = argv[1];
108
109   cd = iconv_open("UCS-4-INTERNAL",charset);
110   if (cd == (iconv_t)(-1)) {
111     perror("iconv_open");
112     exit(1);
113   }
114
115   /* When testing UTF-8 or GB18030, stop at 0x10000, otherwise the output
116      file gets too big. */
117   bmp_only = (strcmp(charset,"UTF-8") == 0 || strcmp(charset,"GB18030") == 0);
118   search_depth = (strcmp(charset,"UTF-8") == 0 ? 3 : 4);
119
120   {
121     unsigned int out[3];
122     unsigned char buf[4];
123     unsigned int i0, i1, i2, i3;
124     int result;
125     for (i0 = 0; i0 < 0x100; i0++) {
126       buf[0] = i0;
127       result = try(cd,buf,1,out);
128       if (result < 0) {
129       } else if (result > 0) {
130         const char* unicode = ucs4_decode(out,result);
131         if (unicode != NULL)
132           printf("0x%02X\t%s\n",i0,unicode);
133       } else {
134         for (i1 = 0; i1 < 0x100; i1++) {
135           buf[1] = i1;
136           result = try(cd,buf,2,out);
137           if (result < 0) {
138           } else if (result > 0) {
139             const char* unicode = ucs4_decode(out,result);
140             if (unicode != NULL)
141               printf("0x%02X%02X\t%s\n",i0,i1,unicode);
142           } else {
143             for (i2 = 0; i2 < 0x100; i2++) {
144               buf[2] = i2;
145               result = try(cd,buf,3,out);
146               if (result < 0) {
147               } else if (result > 0) {
148                 const char* unicode = ucs4_decode(out,result);
149                 if (unicode != NULL)
150                   printf("0x%02X%02X%02X\t%s\n",i0,i1,i2,unicode);
151               } else if (search_depth > 3) {
152                 for (i3 = 0; i3 < 0x100; i3++) {
153                   buf[3] = i3;
154                   result = try(cd,buf,4,out);
155                   if (result < 0) {
156                   } else if (result > 0) {
157                     const char* unicode = ucs4_decode(out,result);
158                     if (unicode != NULL)
159                       printf("0x%02X%02X%02X%02X\t%s\n",i0,i1,i2,i3,unicode);
160                   } else {
161                     fprintf(stderr,"%s: incomplete byte sequence\n",hexbuf(buf,4));
162                     exit(1);
163                   }
164                 }
165               }
166             }
167           }
168         }
169       }
170     }
171   }
172
173   if (iconv_close(cd) < 0) {
174     perror("iconv_close");
175     exit(1);
176   }
177
178   if (ferror(stdin) || ferror(stdout)) {
179     fprintf(stderr,"I/O error\n");
180     exit(1);
181   }
182
183   exit(0);
184 }