Better diagnostics for iconv test. Added case for bug #258
[yaz-moved-to-github.git] / test / tsticonv.c
1 /*
2  * Copyright (C) 1995-2005, Index Data ApS
3  * See the file LICENSE for details.
4  *
5  * $Id: tsticonv.c,v 1.6 2005-02-01 21:07:19 adam Exp $
6  */
7
8 #if HAVE_CONFIG_H
9 #include <config.h>
10 #endif
11
12 #include <stdlib.h>
13 #include <errno.h>
14 #include <string.h>
15 #include <ctype.h>
16
17 #include <yaz/yaz-util.h>
18
19 static int compare_buffers(char *msg, int no,
20                            int expect_len, const unsigned char *expect_buf,
21                            int got_len, const unsigned char *got_buf)
22 {
23     int i;
24     if (expect_len == got_len
25         && !memcmp(expect_buf, got_buf, expect_len))
26         return 1;
27     printf("tsticonv test=%s i=%d failed\n", msg, no);
28     printf("off got exp\n");
29     for (i = 0; i<got_len || i<expect_len; i++)
30     {
31         char got_char[10];
32         char expect_char[10];
33
34         if (i < got_len)
35             sprintf(got_char, "%02X", got_buf[i]);
36         else
37             sprintf(got_char, "?  ");
38
39         if (i < expect_len)
40             sprintf(expect_char, "%02X", expect_buf[i]);
41         else
42             sprintf(expect_char, "?  ");
43         
44         printf("%02d  %s  %s %c\n",
45                i, got_char, expect_char, got_buf[i] == expect_buf[i] ?
46                ' ' : '*');
47
48     }
49     exit(1);
50 }
51
52 /* some test strings in ISO-8859-1 format */
53 static const char *iso_8859_1_a[] = {
54     "ax" ,
55     "\330",
56     "eneb\346r",
57     0 };
58
59 /* same test strings in MARC-8 format */
60 static const char *marc8_a[] = {
61     "ax",   
62     "\xa2",          /* latin capital letter o with stroke */
63     "eneb\xb5r",     /* latin small letter ae */
64     0
65 };
66
67 static void tst_marc8_to_iso_8859_1()
68 {
69     int i;
70     yaz_iconv_t cd;
71
72     cd = yaz_iconv_open("ISO-8859-1", "MARC8");
73     if (!cd)
74     {
75         printf("tsticonv 10 yaz_iconv_open failed\n");
76         exit(10);
77     }
78     for (i = 0; iso_8859_1_a[i]; i++)
79     {
80         size_t r;
81         char *inbuf= (char*) marc8_a[i];
82         size_t inbytesleft = strlen(inbuf);
83         char outbuf0[32];
84         char *outbuf = outbuf0;
85         size_t outbytesleft = sizeof(outbuf0);
86
87         r = yaz_iconv(cd, &inbuf, &inbytesleft, &outbuf, &outbytesleft);
88         if (r == (size_t) (-1))
89         {
90             int e = yaz_iconv_error(cd);
91
92             printf ("tsticonv 11 i=%d e=%d\n", i, e);
93             exit(11);
94         }
95         compare_buffers("tsticonv 11", i,
96                         strlen(iso_8859_1_a[i]), iso_8859_1_a[i],
97                         outbuf - outbuf0, outbuf0);
98     }
99     yaz_iconv_close(cd);
100 }
101
102 static void tst_marc8_to_ucs4b()
103 {
104     static struct {
105         const unsigned char *marc8_b;
106         int len;
107         const unsigned char *ucs4_b;
108     } ar[] = {
109     { 
110         "\033$1" "\x21\x2B\x3B" /* FF1F */ "\033(B" "o",
111         8, "\x00\x00\xFF\x1F" "\x00\x00\x00o"
112     }, {
113         "\033$1" "\x6F\x77\x29" /* AE0E */ "\x6F\x52\x7C" /* c0F4 */ "\033(B",
114         8, "\x00\x00\xAE\x0E" "\x00\x00\xC0\xF4",
115     }, {
116         "\033$1"
117         "\x21\x50\x6E"  /* UCS 7CFB */
118         "\x21\x51\x31"  /* UCS 7D71 */
119         "\x21\x3A\x67"  /* UCS 5B89 */
120         "\x21\x33\x22"  /* UCS 5168 */
121         "\x21\x33\x53"  /* UCS 5206 */
122         "\x21\x44\x2B"  /* UCS 6790 */
123         "\033(B",
124         24, "\x00\x00\x7C\xFB"
125         "\x00\x00\x7D\x71"
126         "\x00\x00\x5B\x89"
127         "\x00\x00\x51\x68"
128         "\x00\x00\x52\x06"
129         "\x00\x00\x67\x90"
130     }, {
131         "\xB0\xB2",     /* AYN and oSLASH */
132         8, "\x00\x00\x02\xBB"  "\x00\x00\x00\xF8"
133     }, {
134         "\xF6\x61",     /* a underscore */
135         8, "\x00\x00\x00\x61"  "\x00\x00\x03\x32"
136     }, {
137         "\x61\xC2",     /* a, phonorecord mark */
138         8, "\x00\x00\x00\x61"  "\x00\x00\x21\x17"
139     }, {
140         "el" "\xe8" "am\xe8" "an", /* elaman where a is a" */
141         32,
142         "\x00\x00\x00" "e"
143         "\x00\x00\x00" "l"
144         "\x00\x00\x00" "a"
145         "\x00\x00\x03\x08"
146         "\x00\x00\x00" "m"
147         "\x00\x00\x00" "a"
148         "\x00\x00\x03\x08"
149         "\x00\x00\x00" "n"
150     }, {
151         0, 0, 0
152     }
153     };
154     int i;
155     yaz_iconv_t cd;
156
157     cd = yaz_iconv_open("UCS4", "MARC8");
158     if (!cd)
159     {
160         printf ("tsticonv 20 yaz_iconv_open failed\n");
161         exit(20);
162     }
163     for (i = 6; ar[i].len; i++)
164     {
165         size_t r;
166         size_t expect_len = ar[i].len;
167         char *inbuf= (char*) ar[i].marc8_b;
168         size_t inbytesleft = strlen(inbuf);
169         char outbuf0[64];
170         char *outbuf = outbuf0;
171
172         while (inbytesleft)
173         {
174             size_t outbytesleft = outbuf0 + sizeof(outbuf0) - outbuf;
175             if (outbytesleft > 12)
176                 outbytesleft = 12;
177             r = yaz_iconv(cd, &inbuf, &inbytesleft, &outbuf, &outbytesleft);
178             if (r == (size_t) (-1))
179             {
180                 int e = yaz_iconv_error(cd);
181                 if (e != YAZ_ICONV_E2BIG)
182                 {
183                     printf ("tsticonv 21 i=%d e=%d\n", i, e);
184                     exit(21);
185                 }
186             }
187             else
188                 break;
189         }
190         compare_buffers("tsticonv 22", i,
191                         expect_len, ar[i].ucs4_b,
192                         outbuf - outbuf0, outbuf0);
193     }
194     yaz_iconv_close(cd);
195 }
196
197 static void tst_ucs4b_to_utf8()
198 {
199     static const char *ucs4_c[] = {
200         "\x00\x00\xFF\x1F\x00\x00\x00o",
201         "\x00\x00\xAE\x0E\x00\x00\xC0\xF4",
202         0
203     };
204     static const char *utf8_c[] = {
205         "\xEF\xBC\x9F\x6F",
206         "\xEA\xB8\x8E\xEC\x83\xB4",
207         0
208     };
209     
210     int i;
211     yaz_iconv_t cd;
212
213     cd = yaz_iconv_open("UTF8", "UCS4");
214     if (!cd)
215     {
216         printf ("tsticonv 30 yaz_iconv_open failed\n");
217         exit(30);
218     }
219     for (i = 0; ucs4_c[i]; i++)
220     {
221         size_t r;
222         char *inbuf= (char*) ucs4_c[i];
223         size_t inbytesleft = 8;
224         char outbuf0[24];
225         char *outbuf = outbuf0;
226         size_t outbytesleft = sizeof(outbuf0);
227
228         r = yaz_iconv(cd, &inbuf, &inbytesleft, &outbuf, &outbytesleft);
229         if (r == (size_t) (-1))
230         {
231             int e = yaz_iconv_error(cd);
232
233             printf ("tsticonv 31 i=%d e=%d\n", i, e);
234             exit(31);
235         }
236         compare_buffers("tsticonv 32", i,
237                         strlen(utf8_c[i]), utf8_c[i],
238                         outbuf - outbuf0, outbuf0);
239     }
240     yaz_iconv_close(cd);
241 }
242
243 static void dconvert(int mandatory, const char *tmpcode)
244 {
245     int i;
246     yaz_iconv_t cd;
247     for (i = 0; iso_8859_1_a[i]; i++)
248     {
249         size_t r;
250         char *inbuf = (char*) iso_8859_1_a[i];
251         size_t inbytesleft = strlen(inbuf);
252         char outbuf0[24];
253         char outbuf1[10];
254         char *outbuf = outbuf0;
255         size_t outbytesleft = sizeof(outbuf0);
256
257         cd = yaz_iconv_open(tmpcode, "ISO-8859-1");
258         if (!cd)
259         {
260             if (!mandatory)
261                 return;
262             printf ("tsticonv code=%s 1\n", tmpcode);
263             exit(1);
264         }
265         r = yaz_iconv(cd, &inbuf, &inbytesleft, &outbuf, &outbytesleft);
266         if (r == (size_t)(-1))
267         {
268             int e = yaz_iconv_error(cd);
269
270             printf ("tsticonv code=%s 2 e=%d\n", tmpcode, e);
271             exit(2);
272         }
273         yaz_iconv_close(cd);
274         
275         cd = yaz_iconv_open("ISO-8859-1", tmpcode);
276         if (!cd)
277         {
278             if (!mandatory)
279                 return;
280             printf ("tsticonv code=%s 3\n", tmpcode);
281             exit(3);
282         }
283         inbuf = outbuf0;
284         inbytesleft = sizeof(outbuf0) - outbytesleft;
285
286         outbuf = outbuf1;
287         outbytesleft = sizeof(outbuf1);
288         r = yaz_iconv(cd, &inbuf, &inbytesleft, &outbuf, &outbytesleft);
289         if (r == (size_t)(-1)) {
290             int e = yaz_iconv_error(cd);
291
292             printf ("tsticonv code=%s 4 e=%d\n", tmpcode, e);
293             exit(4);
294         }
295         compare_buffers("dconvert", i,
296                         strlen(iso_8859_1_a[i]), iso_8859_1_a[i],
297                         sizeof(outbuf1) - outbytesleft, outbuf1);
298         yaz_iconv_close(cd);
299     }
300 }
301         
302 int main (int argc, char **argv)
303 {
304     dconvert(1, "UTF-8");
305     dconvert(1, "ISO-8859-1");
306     dconvert(1, "UCS4");
307     dconvert(1, "UCS4LE");
308     dconvert(0, "CP865");
309     tst_marc8_to_iso_8859_1();
310     tst_marc8_to_ucs4b();
311     tst_ucs4b_to_utf8();
312     exit (0);
313 }