aacea86920d48c891ef21dedf87802f37d8ce132
[yaz-moved-to-github.git] / test / test_iconv.c
1 /* This file is part of the YAZ toolkit.
2  * Copyright (C) 1995-2012 Index Data
3  * See the file LICENSE for details.
4  */
5 #if HAVE_CONFIG_H
6 #include <config.h>
7 #endif
8
9 #include <stdlib.h>
10 #include <errno.h>
11 #include <string.h>
12
13 #include <yaz/yaz-util.h>
14 #include <yaz/test.h>
15
16 #define ESC "\x1b"
17
18 static int compare_buffers(char *msg, int no,
19                            int expect_len, const char *expect_buf,
20                            int got_len, const char *got_buf)
21 {
22     if (expect_len == got_len
23         && !memcmp(expect_buf, got_buf, expect_len))
24         return 1;
25
26     if (0) /* use 1 see how the buffers differ (for debug purposes) */
27     {
28         int i;
29         printf("tsticonv test=%s i=%d failed\n", msg, no);
30         printf("off got exp\n");
31         for (i = 0; i<got_len || i<expect_len; i++)
32         {
33             char got_char[10];
34             char expect_char[10];
35
36             if (i < got_len)
37                 sprintf(got_char, "%02X", got_buf[i]);
38             else
39                 sprintf(got_char, "?  ");
40
41             if (i < expect_len)
42                 sprintf(expect_char, "%02X", expect_buf[i]);
43             else
44                 sprintf(expect_char, "?  ");
45
46             printf("%02d  %s  %s %c\n",
47                    i, got_char, expect_char, got_buf[i] == expect_buf[i] ?
48                    ' ' : '*');
49
50         }
51     }
52     return 0;
53 }
54
55 static int tst_convert_l(yaz_iconv_t cd, size_t in_len, const char *in_buf,
56                          size_t expect_len, const char *expect_buf)
57 {
58     size_t r;
59     char *inbuf= (char*) in_buf;
60     size_t inbytesleft = in_len > 0 ? in_len : strlen(in_buf);
61     char outbuf0[64];
62     char *outbuf = outbuf0;
63
64     while (inbytesleft)
65     {
66         size_t outbytesleft = outbuf0 + sizeof(outbuf0) - outbuf;
67         if (outbytesleft > 12)
68             outbytesleft = 12;
69         r = yaz_iconv(cd, &inbuf, &inbytesleft, &outbuf, &outbytesleft);
70         if (r == (size_t) (-1))
71         {
72             int e = yaz_iconv_error(cd);
73             if (e != YAZ_ICONV_E2BIG)
74                 return 0;
75         }
76         else
77         {
78             yaz_iconv(cd, 0, 0, &outbuf, &outbytesleft);
79             break;
80         }
81     }
82
83     return compare_buffers("tsticonv 22", 0,
84                            expect_len, expect_buf,
85                            outbuf - outbuf0, outbuf0);
86 }
87
88 static int tst_convert_x(yaz_iconv_t cd, const char *buf, const char *cmpbuf,
89                          int expect_error)
90 {
91     int ret = 1;
92     WRBUF b = wrbuf_alloc();
93     char outbuf[16];
94     size_t inbytesleft = strlen(buf);
95     const char *inp = buf;
96     int rounds = 0;
97     for (rounds = 0; inbytesleft && rounds < (int) sizeof(outbuf); rounds++)
98     {
99         size_t outbytesleft = sizeof(outbuf);
100         char *outp = outbuf;
101         size_t r = yaz_iconv(cd, (char**) &inp,  &inbytesleft,
102                              &outp, &outbytesleft);
103         wrbuf_write(b, outbuf, outp - outbuf);
104         if (r == (size_t) (-1))
105         {
106             int e = yaz_iconv_error(cd);
107             if (e != YAZ_ICONV_E2BIG)
108             {
109                 if (expect_error != -1)
110                     if (e != expect_error)
111                         ret = 0;
112                 break;
113             }
114         }
115         else
116         {
117             size_t outbytesleft = sizeof(outbuf);
118             char *outp = outbuf;
119             r = yaz_iconv(cd, 0, 0, &outp, &outbytesleft);
120             wrbuf_write(b, outbuf, outp - outbuf);
121             if (expect_error != -1)
122                 if (expect_error)
123                     ret = 0;
124             break;
125         }
126     }
127     if (wrbuf_len(b) == strlen(cmpbuf)
128         && !memcmp(cmpbuf, wrbuf_buf(b), wrbuf_len(b)))
129         ;
130     else
131     {
132         WRBUF w = wrbuf_alloc();
133
134         ret = 0;
135         wrbuf_rewind(w);
136         wrbuf_puts_escaped(w, buf);
137         yaz_log(YLOG_LOG, "input %s", wrbuf_cstr(w));
138
139         wrbuf_rewind(w);
140         wrbuf_write_escaped(w, wrbuf_buf(b), wrbuf_len(b));
141         yaz_log(YLOG_LOG, "got %s", wrbuf_cstr(w));
142
143         wrbuf_rewind(w);
144         wrbuf_puts_escaped(w, cmpbuf);
145         yaz_log(YLOG_LOG, "exp %s", wrbuf_cstr(w));
146
147         wrbuf_destroy(w);
148     }
149
150     wrbuf_destroy(b);
151     return ret;
152 }
153
154 static int tst_convert(yaz_iconv_t cd, const char *buf, const char *cmpbuf)
155 {
156     return tst_convert_x(cd, buf, cmpbuf, 0);
157 }
158
159 /* some test strings in ISO-8859-1 format */
160 static const char *iso_8859_1_a[] = {
161     "ax" ,
162     "\xd8",
163     "eneb\346r",
164     "\xe5" "\xd8",
165     "\xe5" "\xd8" "b",
166     "\xe5" "\xe5",
167     0 };
168
169 static void tst_marc8_to_ucs4b(void)
170 {
171     yaz_iconv_t cd = yaz_iconv_open("UCS4", "MARC8");
172     YAZ_CHECK(cd);
173     if (!cd)
174         return;
175
176     YAZ_CHECK(tst_convert_l(
177                   cd,
178                   0,
179                   "\033$1" "\x21\x2B\x3B" /* FF1F */ "\033(B" "o",
180                   8,
181                   "\x00\x00\xFF\x1F" "\x00\x00\x00o"));
182     YAZ_CHECK(tst_convert_l(
183                   cd,
184                   0,
185                   "\033$1" "\x6F\x77\x29" /* AE0E */
186                   "\x6F\x52\x7C" /* c0F4 */ "\033(B",
187                   8,
188                   "\x00\x00\xAE\x0E" "\x00\x00\xC0\xF4"));
189     YAZ_CHECK(tst_convert_l(
190                   cd,
191                   0,
192                   "\033$1"
193                   "\x21\x50\x6E"  /* UCS 7CFB */
194                   "\x21\x51\x31"  /* UCS 7D71 */
195                   "\x21\x3A\x67"  /* UCS 5B89 */
196                   "\x21\x33\x22"  /* UCS 5168 */
197                   "\x21\x33\x53"  /* UCS 5206 */
198                   "\x21\x44\x2B"  /* UCS 6790 */
199                   "\033(B",
200                   24,
201                   "\x00\x00\x7C\xFB"
202                   "\x00\x00\x7D\x71"
203                   "\x00\x00\x5B\x89"
204                   "\x00\x00\x51\x68"
205                   "\x00\x00\x52\x06"
206                   "\x00\x00\x67\x90"));
207
208     YAZ_CHECK(tst_convert_l(
209                   cd,
210                   0,
211                   "\xB0\xB2",     /* AYN and oSLASH */
212                   8,
213                   "\x00\x00\x02\xBB"  "\x00\x00\x00\xF8"));
214     YAZ_CHECK(tst_convert_l(
215                   cd,
216                   0,
217                   "\xF6\x61",     /* a underscore */
218                   8,
219                   "\x00\x00\x00\x61"  "\x00\x00\x03\x32"));
220
221     YAZ_CHECK(tst_convert_l(
222                   cd,
223                   0,
224                   "\x61\xC2",     /* a, phonorecord mark */
225                   8,
226                   "\x00\x00\x00\x61"  "\x00\x00\x21\x17"));
227
228     /* bug #258 */
229     YAZ_CHECK(tst_convert_l(
230                   cd,
231                   0,
232                   "el" "\xe8" "am\xe8" "an", /* elaman where a is a" */
233                   32,
234                   "\x00\x00\x00" "e"
235                   "\x00\x00\x00" "l"
236                   "\x00\x00\x00" "a"
237                   "\x00\x00\x03\x08"
238                   "\x00\x00\x00" "m"
239                   "\x00\x00\x00" "a"
240                   "\x00\x00\x03\x08"
241                   "\x00\x00\x00" "n"));
242     /* bug #260 */
243     YAZ_CHECK(tst_convert_l(
244                   cd,
245                   0,
246                   "\xe5\xe8\x41",
247                   12,
248                   "\x00\x00\x00\x41" "\x00\x00\x03\x04" "\x00\x00\x03\x08"));
249     /* bug #416 */
250     YAZ_CHECK(tst_convert_l(
251                   cd,
252                   0,
253                   "\xEB\x74\xEC\x73",
254                   12,
255                   "\x00\x00\x00\x74" "\x00\x00\x03\x61" "\x00\x00\x00\x73"));
256     /* bug #416 */
257     YAZ_CHECK(tst_convert_l(
258                   cd,
259                   0,
260                   "\xFA\x74\xFB\x73",
261                   12,
262                   "\x00\x00\x00\x74" "\x00\x00\x03\x60" "\x00\x00\x00\x73"));
263
264     yaz_iconv_close(cd);
265 }
266
267 static void tst_ucs4b_to_utf8(void)
268 {
269     yaz_iconv_t cd = yaz_iconv_open("UTF8", "UCS4");
270     YAZ_CHECK(cd);
271     if (!cd)
272         return;
273     YAZ_CHECK(tst_convert_l(
274                   cd,
275                   8,
276                   "\x00\x00\xFF\x1F\x00\x00\x00o",
277                   4,
278                   "\xEF\xBC\x9F\x6F"));
279
280     YAZ_CHECK(tst_convert_l(
281                   cd,
282                   8,
283                   "\x00\x00\xAE\x0E\x00\x00\xC0\xF4",
284                   6,
285                   "\xEA\xB8\x8E\xEC\x83\xB4"));
286     yaz_iconv_close(cd);
287 }
288
289 static void dconvert(int mandatory, const char *tmpcode)
290 {
291     int i;
292     int ret;
293     yaz_iconv_t cd;
294     for (i = 0; iso_8859_1_a[i]; i++)
295     {
296         size_t r;
297         char *inbuf = (char*) iso_8859_1_a[i];
298         size_t inbytesleft = strlen(inbuf);
299         char outbuf0[24];
300         char outbuf1[10];
301         char *outbuf = outbuf0;
302         size_t outbytesleft = sizeof(outbuf0);
303
304         cd = yaz_iconv_open(tmpcode, "ISO-8859-1");
305         YAZ_CHECK(cd || !mandatory);
306         if (!cd)
307             return;
308         r = yaz_iconv(cd, &inbuf, &inbytesleft, &outbuf, &outbytesleft);
309         YAZ_CHECK(r != (size_t) (-1));
310
311         r = yaz_iconv(cd, 0, 0, &outbuf, &outbytesleft);
312         YAZ_CHECK(r != (size_t) (-1));
313         yaz_iconv_close(cd);
314         if (r == (size_t) (-1))
315             return;
316
317         cd = yaz_iconv_open("ISO-8859-1", tmpcode);
318         YAZ_CHECK(cd || !mandatory);
319         if (!cd)
320             return;
321         inbuf = outbuf0;
322         inbytesleft = sizeof(outbuf0) - outbytesleft;
323
324         outbuf = outbuf1;
325         outbytesleft = sizeof(outbuf1);
326         r = yaz_iconv(cd, &inbuf, &inbytesleft, &outbuf, &outbytesleft);
327         YAZ_CHECK(r != (size_t) (-1));
328
329         r = yaz_iconv(cd, 0, 0, &outbuf, &outbytesleft);
330         if (r == (size_t)(-1))
331         {
332             fprintf(stderr, "failed\n");
333         }
334         YAZ_CHECK(r != (size_t) (-1));
335
336         if (r != (size_t)(-1))
337         {
338             ret = compare_buffers("dconvert", i,
339                                   strlen(iso_8859_1_a[i]), iso_8859_1_a[i],
340                                   sizeof(outbuf1) - outbytesleft, outbuf1);
341             YAZ_CHECK(ret);
342         }
343         yaz_iconv_close(cd);
344     }
345 }
346
347 int utf8_check(unsigned c)
348 {
349     if (sizeof(c) >= 4)
350     {
351         size_t r;
352         char src[4];
353         char dst[4];
354         char utf8buf[6];
355         char *inbuf = src;
356         size_t inbytesleft = 4;
357         char *outbuf = utf8buf;
358         size_t outbytesleft = sizeof(utf8buf);
359         int i;
360         yaz_iconv_t cd = yaz_iconv_open("UTF-8", "UCS4LE");
361         if (!cd)
362             return 0;
363         for (i = 0; i<4; i++)
364             src[i] = c >> (i*8);
365
366         r = yaz_iconv(cd, &inbuf, &inbytesleft, &outbuf, &outbytesleft);
367         yaz_iconv_close(cd);
368
369         if (r == (size_t)(-1))
370             return 0;
371
372         cd = yaz_iconv_open("UCS4LE", "UTF-8");
373         if (!cd)
374             return 0;
375         inbytesleft = sizeof(utf8buf) - outbytesleft;
376         inbuf = utf8buf;
377
378         outbuf = dst;
379         outbytesleft = 4;
380
381         r = yaz_iconv(cd, &inbuf, &inbytesleft, &outbuf, &outbytesleft);
382         if (r == (size_t)(-1))
383             return 0;
384
385         yaz_iconv_close(cd);
386
387         if (memcmp(src, dst, 4))
388             return 0;
389     }
390     return 1;
391 }
392
393 static void tst_marc8_to_utf8(void)
394 {
395     yaz_iconv_t cd = yaz_iconv_open("UTF-8", "MARC8");
396
397     YAZ_CHECK(cd);
398     if (!cd)
399         return;
400
401     YAZ_CHECK(tst_convert(cd, "Cours de math",
402                           "Cours de math"));
403     /* COMBINING ACUTE ACCENT */
404     YAZ_CHECK(tst_convert(cd, "Cours de mathâe",
405                           "Cours de mathe\xcc\x81"));
406
407     YAZ_CHECK(tst_convert(cd, "\xea" "a", "a\xcc\x8a"));
408     YAZ_CHECK(tst_convert(cd, "a" "\xea" "\x1e", "a" "\x1e\xcc\x8a"));
409     YAZ_CHECK(tst_convert(cd, "a" "\xea" "p", "a" "p\xcc\x8a"));
410
411     YAZ_CHECK(tst_convert_x(cd, "a\xea", "a", YAZ_ICONV_EINVAL));
412     YAZ_CHECK(tst_convert(cd, "p", "\xcc\x8a")); /* note: missing p */
413     yaz_iconv(cd, 0, 0, 0, 0);     /* incomplete. so we have to reset */
414
415     /* bug #2115 */
416     YAZ_CHECK(tst_convert(cd, ESC "(N" ESC ")Qp" ESC "(B", "\xd0\x9f"));
417
418     YAZ_CHECK(tst_convert_x(cd, ESC , "", YAZ_ICONV_EINVAL));
419     YAZ_CHECK(tst_convert_x(cd, ESC "(", "", YAZ_ICONV_EINVAL));
420     YAZ_CHECK(tst_convert_x(cd, ESC "(B", "", 0));
421
422     YAZ_CHECK(tst_convert(cd, ESC "(B" "\x31", "1"));  /* ASCII in G0 */
423     YAZ_CHECK(tst_convert(cd, ESC ")B" "\xB1", "1"));  /* ASCII in G1 */
424
425     yaz_iconv_close(cd);
426 }
427
428 static void tst_marc8s_to_utf8(void)
429 {
430     yaz_iconv_t cd = yaz_iconv_open("UTF-8", "MARC8s");
431
432     YAZ_CHECK(cd);
433     if (!cd)
434         return;
435
436     YAZ_CHECK(tst_convert(cd, "Cours de math",
437                           "Cours de math"));
438     /* E9: LATIN SMALL LETTER E WITH ACUTE */
439     YAZ_CHECK(tst_convert(cd, "Cours de mathâe",
440                           "Cours de math\xc3\xa9"));
441
442     yaz_iconv_close(cd);
443 }
444
445
446 static void tst_marc8_to_latin1(void)
447 {
448     yaz_iconv_t cd = yaz_iconv_open("ISO-8859-1", "MARC8");
449
450     YAZ_CHECK(cd);
451     if (!cd)
452         return;
453
454     YAZ_CHECK(tst_convert(cd, "ax", "ax"));
455
456     /* latin capital letter o with stroke */
457     YAZ_CHECK(tst_convert(cd, "\xa2", "\xd8"));
458
459     /* with latin small letter ae */
460     YAZ_CHECK(tst_convert(cd, "eneb\xb5r", "eneb\346r"));
461
462     YAZ_CHECK(tst_convert(cd, "\xea" "a\xa2", "\xe5" "\xd8"));
463
464     YAZ_CHECK(tst_convert(cd, "\xea" "a\xa2" "b", "\xe5" "\xd8" "b"));
465
466     YAZ_CHECK(tst_convert(cd, "\xea" "a"  "\xea" "a", "\xe5" "\xe5"));
467
468     YAZ_CHECK(tst_convert(cd, "Cours de math",
469                           "Cours de math"));
470     YAZ_CHECK(tst_convert(cd, "Cours de mathâe",
471                           "Cours de mathé"));
472     YAZ_CHECK(tst_convert(cd, "12345678âe",
473                           "12345678é"));
474     YAZ_CHECK(tst_convert(cd, "123456789âe",
475                           "123456789é"));
476     YAZ_CHECK(tst_convert(cd, "1234567890âe",
477                           "1234567890é"));
478     YAZ_CHECK(tst_convert(cd, "12345678901âe",
479                           "12345678901é"));
480     YAZ_CHECK(tst_convert(cd, "Cours de mathâem",
481                           "Cours de mathém"));
482     YAZ_CHECK(tst_convert(cd, "Cours de mathâematiques",
483                           "Cours de mathématiques"));
484
485     yaz_iconv_close(cd);
486 }
487
488 static void tst_utf8_to_marc8(const char *marc8_type)
489 {
490     yaz_iconv_t cd = yaz_iconv_open(marc8_type, "UTF-8");
491
492     YAZ_CHECK(cd);
493     if (!cd)
494         return;
495
496     YAZ_CHECK(tst_convert(cd, "Cours ", "Cours "));
497
498     /** Pure ASCII. 11 characters (sizeof(outbuf)-1) */
499     YAZ_CHECK(tst_convert(cd, "Cours de mat", "Cours de mat"));
500
501     /** Pure ASCII. 12 characters (sizeof(outbuf)) */
502     YAZ_CHECK(tst_convert(cd, "Cours de math", "Cours de math"));
503
504     /** Pure ASCII. 13 characters (sizeof(outbuf)+1) */
505     YAZ_CHECK(tst_convert(cd, "Cours de math.", "Cours de math."));
506
507     /** UPPERCASE SCANDINAVIAN O */
508     YAZ_CHECK(tst_convert(cd, "S\xc3\x98", "S\xa2"));
509
510     /** ARING */
511     YAZ_CHECK(tst_convert(cd, "A" "\xCC\x8A", "\xEA" "A"));
512
513     /** A MACRON + UMLAUT, DIAERESIS */
514     YAZ_CHECK(tst_convert(cd, "A" "\xCC\x84" "\xCC\x88",
515                           "\xE5\xE8\x41"));
516
517     /* Ligature spanning two characters */
518     YAZ_CHECK(tst_convert(cd,
519                           "\x74" "\xCD\xA1" "\x73",  /* UTF-8 */
520                           "\xEB\x74\xEC\x73"));      /* MARC-8 */
521
522     /* Double title spanning two characters */
523     YAZ_CHECK(tst_convert(cd,
524                           "\x74" "\xCD\xA0" "\x73",  /* UTF-8 */
525                           "\xFA\x74\xFB\x73"));      /* MARC-8 */
526
527     /** Ideographic question mark (Unicode FF1F) */
528     YAZ_CHECK(tst_convert(cd,
529                           "\xEF\xBC\x9F" "o",        /* UTF-8 */
530                           "\033$1" "\x21\x2B\x3B" "\033(B" "o" ));
531
532
533     /** Ideographic space per ANSI Z39.64 */
534     YAZ_CHECK(tst_convert(cd,
535                           "\xe3\x80\x80" "o",        /* UTF-8 */
536                           "\033$1" "\x21\x23\x21" "\033(B" "o" ));
537
538     /** Superscript 0 . bug #642 */
539     YAZ_CHECK(tst_convert(cd,
540                           "(\xe2\x81\xb0)",        /* UTF-8 */
541                           "(\033p0\x1bs)"));
542
543
544     /** bug #1778 */
545     YAZ_CHECK(tst_convert(cd,
546                           /* offset 0x530 in UTF-8 rec marccol4.u8.marc */
547                           "\xE3\x83\xB3" "\xE3\x82\xBF"
548                           "\xCC\x84" "\xCC\x84" "\xE3\x83\xBC" /* UTF-8 */,
549                           "\x1B\x24\x31" "\x69\x25\x73"
550                           "\x1B\x28\x42" "\xE5\xE5" "\x1B\x24\x31"
551                           "\x69\x25\x3F"
552                           "\x69\x21\x3C" "\x1B\x28\x42"));
553
554
555     /** bug #2120 */
556     YAZ_CHECK(tst_convert(cd,
557                           "\xCE\x94\xCE\xB5\xCF\x84"
558                           "\xCE\xBF\xCF\x81\xCE\xB1"
559                           "\xCE\xBA\xCE\xB7\xCF\x82\x2C",
560
561                           "\x1B\x28\x53\x45\x66\x78\x72\x75"
562                           "\x61\x6D\x6A\x77"
563                           "\x1B\x28\x42\x2C"
564                   ));
565
566     {
567         char *inbuf0 = "\xe2\x81\xb0";
568         char *inbuf = inbuf0;
569         size_t inbytesleft = strlen(inbuf);
570         char outbuf0[64];
571         char *outbuf = outbuf0;
572         size_t outbytesleft = sizeof(outbuf0)-1;
573         size_t r;
574 #if 0
575         int i;
576 #endif
577         r = yaz_iconv(cd, &inbuf, &inbytesleft, &outbuf, &outbytesleft);
578         YAZ_CHECK(r != (size_t) (-1));
579
580 #if 0
581         *outbuf = '\0';  /* so we know when to stop printing */
582         for (i = 0; outbuf0[i]; i++)
583         {
584             int ch = outbuf0[i] & 0xff;
585             yaz_log(YLOG_LOG, "ch%d %02X %c", i, ch, ch >= ' ' ? ch : '?');
586         }
587 #endif
588
589         r = yaz_iconv(cd, 0, 0, &outbuf, &outbytesleft);
590         YAZ_CHECK(r != (size_t) (-1));
591         *outbuf = '\0';  /* for strcmp test below and printing */
592 #if 0
593         for (i = 0; outbuf0[i]; i++)
594         {
595             int ch = outbuf0[i] & 0xff;
596             yaz_log(YLOG_LOG, "ch%d %02X %c", i, ch, ch >= ' ' ? ch : '?');
597         }
598 #endif
599         YAZ_CHECK(strcmp("\033p0\x1bs", outbuf0) == 0);
600     }
601     yaz_iconv(cd, 0, 0, 0, 0);
602     yaz_iconv_close(cd);
603 }
604
605 static void tst_advance_to_utf8(void)
606 {
607     yaz_iconv_t cd = yaz_iconv_open("utf-8", "advancegreek");
608
609     YAZ_CHECK(cd);
610     if (!cd)
611         return;
612
613     YAZ_CHECK(tst_convert(cd, "Cours ", "Cours "));
614     yaz_iconv_close(cd);
615 }
616
617 static void tst_utf8_to_advance(void)
618 {
619     yaz_iconv_t cd = yaz_iconv_open("advancegreek", "utf-8");
620
621     YAZ_CHECK(cd);
622     if (!cd)
623         return;
624
625     YAZ_CHECK(tst_convert(cd, "Cours ", "Cours "));
626     yaz_iconv_close(cd);
627 }
628
629 static void tst_latin1_to_marc8(void)
630 {
631     yaz_iconv_t cd = yaz_iconv_open("MARC8", "ISO-8859-1");
632
633     YAZ_CHECK(cd);
634     if (!cd)
635         return;
636
637     YAZ_CHECK(tst_convert(cd, "Cours ", "Cours "));
638
639     /** Pure ASCII. 11 characters (sizeof(outbuf)-1) */
640     YAZ_CHECK(tst_convert(cd, "Cours de mat", "Cours de mat"));
641
642     /** Pure ASCII. 12 characters (sizeof(outbuf)) */
643     YAZ_CHECK(tst_convert(cd, "Cours de math", "Cours de math"));
644
645     /** Pure ASCII. 13 characters (sizeof(outbuf)) */
646     YAZ_CHECK(tst_convert(cd, "Cours de math.", "Cours de math."));
647
648     /** D8: UPPERCASE SCANDINAVIAN O */
649     YAZ_CHECK(tst_convert(cd, "S\xd8", "S\xa2"));
650
651     /** E9: LATIN SMALL LETTER E WITH ACUTE */
652     YAZ_CHECK(tst_convert(cd, "Cours de math\xe9", "Cours de mathâe"));
653     YAZ_CHECK(tst_convert(cd, "Cours de math", "Cours de math"
654                   ));
655     YAZ_CHECK(tst_convert(cd, "Cours de mathé", "Cours de mathâe" ));
656     YAZ_CHECK(tst_convert(cd, "12345678é","12345678âe"));
657     YAZ_CHECK(tst_convert(cd, "123456789é", "123456789âe"));
658     YAZ_CHECK(tst_convert(cd, "1234567890é","1234567890âe"));
659     YAZ_CHECK(tst_convert(cd, "12345678901é", "12345678901âe"));
660     YAZ_CHECK(tst_convert(cd, "Cours de mathém", "Cours de mathâem"));
661     YAZ_CHECK(tst_convert(cd, "Cours de mathématiques",
662                           "Cours de mathâematiques"));
663     yaz_iconv_close(cd);
664 }
665
666 static void tst_utf8_codes(void)
667 {
668     YAZ_CHECK(utf8_check(3));
669     YAZ_CHECK(utf8_check(127));
670     YAZ_CHECK(utf8_check(128));
671     YAZ_CHECK(utf8_check(255));
672     YAZ_CHECK(utf8_check(256));
673     YAZ_CHECK(utf8_check(900));
674     YAZ_CHECK(utf8_check(1000));
675     YAZ_CHECK(utf8_check(10000));
676     YAZ_CHECK(utf8_check(100000));
677     YAZ_CHECK(utf8_check(1000000));
678     YAZ_CHECK(utf8_check(10000000));
679     YAZ_CHECK(utf8_check(100000000));
680 }
681
682 static void tst_danmarc_to_latin1(void)
683 {
684     yaz_iconv_t cd = yaz_iconv_open("iso-8859-1", "danmarc");
685
686     YAZ_CHECK(cd);
687     if (!cd)
688         return;
689
690     YAZ_CHECK(tst_convert(cd, "ax", "ax"));
691
692     YAZ_CHECK(tst_convert(cd, "a@@b", "a@b"));
693     YAZ_CHECK(tst_convert(cd, "a@@@@b", "a@@b"));
694     YAZ_CHECK(tst_convert(cd, "@000ab", "\nb"));
695
696     YAZ_CHECK(tst_convert(cd, "@\xe5", "aa"));
697     YAZ_CHECK(tst_convert(cd, "@\xc5.", "Aa."));
698
699     yaz_iconv_close(cd);
700 }
701
702
703 int main (int argc, char **argv)
704 {
705     YAZ_CHECK_INIT(argc, argv);
706
707     tst_utf8_codes();
708
709     tst_marc8_to_utf8();
710
711     tst_marc8s_to_utf8();
712
713     tst_marc8_to_latin1();
714
715     tst_advance_to_utf8();
716     tst_utf8_to_advance();
717
718     tst_utf8_to_marc8("marc8");
719     tst_utf8_to_marc8("marc8lossy");
720     tst_utf8_to_marc8("marc8lossless");
721
722     tst_danmarc_to_latin1();
723
724     tst_latin1_to_marc8();
725
726     tst_marc8_to_ucs4b();
727     tst_ucs4b_to_utf8();
728
729     dconvert(1, "UTF-8");
730     dconvert(1, "ISO-8859-1");
731     dconvert(1, "UCS4");
732     dconvert(1, "UCS4LE");
733     dconvert(0, "CP865");
734
735     YAZ_CHECK_TERM;
736 }
737 /*
738  * Local variables:
739  * c-basic-offset: 4
740  * c-file-style: "Stroustrup"
741  * indent-tabs-mode: nil
742  * End:
743  * vim: shiftwidth=4 tabstop=8 expandtab
744  */
745