Enable test case for bug #260
[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.8 2005-02-02 23:27:05 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     {  /* bug #258 */
141         "el" "\xe8" "am\xe8" "an", /* elaman where a is a" */
142         32,
143         "\x00\x00\x00" "e"
144         "\x00\x00\x00" "l"
145         "\x00\x00\x00" "a"
146         "\x00\x00\x03\x08"
147         "\x00\x00\x00" "m"
148         "\x00\x00\x00" "a"
149         "\x00\x00\x03\x08"
150         "\x00\x00\x00" "n"
151     }, 
152     { /* bug #260 */
153         "\xe5\xe8\x41",
154         12, "\x00\x00\x00\x41" "\x00\x00\x03\x04" "\x00\x00\x03\x08"
155     }, 
156     {
157         0, 0, 0
158     }
159     };
160     int i;
161     yaz_iconv_t cd;
162
163     cd = yaz_iconv_open("UCS4", "MARC8");
164     if (!cd)
165     {
166         printf ("tsticonv 20 yaz_iconv_open failed\n");
167         exit(20);
168     }
169     for (i = 0; ar[i].len; i++)
170     {
171         size_t r;
172         size_t expect_len = ar[i].len;
173         char *inbuf= (char*) ar[i].marc8_b;
174         size_t inbytesleft = strlen(inbuf);
175         char outbuf0[64];
176         char *outbuf = outbuf0;
177
178         while (inbytesleft)
179         {
180             size_t outbytesleft = outbuf0 + sizeof(outbuf0) - outbuf;
181             if (outbytesleft > 12)
182                 outbytesleft = 12;
183             r = yaz_iconv(cd, &inbuf, &inbytesleft, &outbuf, &outbytesleft);
184             if (r == (size_t) (-1))
185             {
186                 int e = yaz_iconv_error(cd);
187                 if (e != YAZ_ICONV_E2BIG)
188                 {
189                     printf ("tsticonv 21 i=%d e=%d\n", i, e);
190                     exit(21);
191                 }
192             }
193             else
194                 break;
195         }
196         compare_buffers("tsticonv 22", i,
197                         expect_len, ar[i].ucs4_b,
198                         outbuf - outbuf0, outbuf0);
199     }
200     yaz_iconv_close(cd);
201 }
202
203 static void tst_ucs4b_to_utf8()
204 {
205     static const char *ucs4_c[] = {
206         "\x00\x00\xFF\x1F\x00\x00\x00o",
207         "\x00\x00\xAE\x0E\x00\x00\xC0\xF4",
208         0
209     };
210     static const char *utf8_c[] = {
211         "\xEF\xBC\x9F\x6F",
212         "\xEA\xB8\x8E\xEC\x83\xB4",
213         0
214     };
215     
216     int i;
217     yaz_iconv_t cd;
218
219     cd = yaz_iconv_open("UTF8", "UCS4");
220     if (!cd)
221     {
222         printf ("tsticonv 30 yaz_iconv_open failed\n");
223         exit(30);
224     }
225     for (i = 0; ucs4_c[i]; i++)
226     {
227         size_t r;
228         char *inbuf= (char*) ucs4_c[i];
229         size_t inbytesleft = 8;
230         char outbuf0[24];
231         char *outbuf = outbuf0;
232         size_t outbytesleft = sizeof(outbuf0);
233
234         r = yaz_iconv(cd, &inbuf, &inbytesleft, &outbuf, &outbytesleft);
235         if (r == (size_t) (-1))
236         {
237             int e = yaz_iconv_error(cd);
238
239             printf ("tsticonv 31 i=%d e=%d\n", i, e);
240             exit(31);
241         }
242         compare_buffers("tsticonv 32", i,
243                         strlen(utf8_c[i]), utf8_c[i],
244                         outbuf - outbuf0, outbuf0);
245     }
246     yaz_iconv_close(cd);
247 }
248
249 static void dconvert(int mandatory, const char *tmpcode)
250 {
251     int i;
252     yaz_iconv_t cd;
253     for (i = 0; iso_8859_1_a[i]; i++)
254     {
255         size_t r;
256         char *inbuf = (char*) iso_8859_1_a[i];
257         size_t inbytesleft = strlen(inbuf);
258         char outbuf0[24];
259         char outbuf1[10];
260         char *outbuf = outbuf0;
261         size_t outbytesleft = sizeof(outbuf0);
262
263         cd = yaz_iconv_open(tmpcode, "ISO-8859-1");
264         if (!cd)
265         {
266             if (!mandatory)
267                 return;
268             printf ("tsticonv code=%s 1\n", tmpcode);
269             exit(1);
270         }
271         r = yaz_iconv(cd, &inbuf, &inbytesleft, &outbuf, &outbytesleft);
272         if (r == (size_t)(-1))
273         {
274             int e = yaz_iconv_error(cd);
275
276             printf ("tsticonv code=%s 2 e=%d\n", tmpcode, e);
277             exit(2);
278         }
279         yaz_iconv_close(cd);
280         
281         cd = yaz_iconv_open("ISO-8859-1", tmpcode);
282         if (!cd)
283         {
284             if (!mandatory)
285                 return;
286             printf ("tsticonv code=%s 3\n", tmpcode);
287             exit(3);
288         }
289         inbuf = outbuf0;
290         inbytesleft = sizeof(outbuf0) - outbytesleft;
291
292         outbuf = outbuf1;
293         outbytesleft = sizeof(outbuf1);
294         r = yaz_iconv(cd, &inbuf, &inbytesleft, &outbuf, &outbytesleft);
295         if (r == (size_t)(-1)) {
296             int e = yaz_iconv_error(cd);
297
298             printf ("tsticonv code=%s 4 e=%d\n", tmpcode, e);
299             exit(4);
300         }
301         compare_buffers("dconvert", i,
302                         strlen(iso_8859_1_a[i]), iso_8859_1_a[i],
303                         sizeof(outbuf1) - outbytesleft, outbuf1);
304         yaz_iconv_close(cd);
305     }
306 }
307         
308 int main (int argc, char **argv)
309 {
310     dconvert(1, "UTF-8");
311     dconvert(1, "ISO-8859-1");
312     dconvert(1, "UCS4");
313     dconvert(1, "UCS4LE");
314     dconvert(0, "CP865");
315     tst_marc8_to_iso_8859_1();
316     tst_marc8_to_ucs4b();
317     tst_ucs4b_to_utf8();
318     exit (0);
319 }