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