]> git.ipfire.org Git - thirdparty/cups.git/blame - cups/testi18n.c
Import CUPS v2.0b1
[thirdparty/cups.git] / cups / testi18n.c
CommitLineData
ef416fc2 1/*
1a18c85c 2 * "$Id: testi18n.c 11558 2014-02-06 18:33:34Z msweet $"
ef416fc2 3 *
1a18c85c 4 * Internationalization test for CUPS.
ef416fc2 5 *
1a18c85c
MS
6 * Copyright 2007-2014 by Apple Inc.
7 * Copyright 1997-2006 by Easy Software Products.
ef416fc2 8 *
1a18c85c
MS
9 * These coded instructions, statements, and computer programs are the
10 * property of Apple Inc. and are protected by Federal copyright
11 * law. Distribution and use rights are outlined in the file "LICENSE.txt"
12 * which should have been included with this file. If this file is
13 * file is missing or damaged, see the license at "http://www.cups.org/".
ef416fc2 14 *
1a18c85c 15 * This file is subject to the Apple OS-Developed Software exception.
ef416fc2 16 */
17
18/*
19 * Include necessary headers...
20 */
21
71e16022
MS
22#include "string-private.h"
23#include "language-private.h"
ef416fc2 24#include <stdlib.h>
ef416fc2 25#include <time.h>
89d46774 26#include <unistd.h>
ef416fc2 27
ef416fc2 28
bf3816c7
MS
29/*
30 * Local globals...
31 */
32
33static const char * const lang_encodings[] =
34 { /* Encoding strings */
35 "us-ascii", "iso-8859-1",
36 "iso-8859-2", "iso-8859-3",
37 "iso-8859-4", "iso-8859-5",
38 "iso-8859-6", "iso-8859-7",
39 "iso-8859-8", "iso-8859-9",
40 "iso-8859-10", "utf-8",
41 "iso-8859-13", "iso-8859-14",
42 "iso-8859-15", "windows-874",
43 "windows-1250", "windows-1251",
44 "windows-1252", "windows-1253",
45 "windows-1254", "windows-1255",
46 "windows-1256", "windows-1257",
47 "windows-1258", "koi8-r",
48 "koi8-u", "iso-8859-11",
49 "iso-8859-16", "mac-roman",
50 "unknown", "unknown",
51 "unknown", "unknown",
52 "unknown", "unknown",
53 "unknown", "unknown",
54 "unknown", "unknown",
55 "unknown", "unknown",
56 "unknown", "unknown",
57 "unknown", "unknown",
58 "unknown", "unknown",
59 "unknown", "unknown",
60 "unknown", "unknown",
61 "unknown", "unknown",
62 "unknown", "unknown",
63 "unknown", "unknown",
64 "unknown", "unknown",
65 "unknown", "unknown",
66 "unknown", "unknown",
67 "windows-932", "windows-936",
68 "windows-949", "windows-950",
69 "windows-1361", "unknown",
70 "unknown", "unknown",
71 "unknown", "unknown",
72 "unknown", "unknown",
73 "unknown", "unknown",
74 "unknown", "unknown",
75 "unknown", "unknown",
76 "unknown", "unknown",
77 "unknown", "unknown",
78 "unknown", "unknown",
79 "unknown", "unknown",
80 "unknown", "unknown",
81 "unknown", "unknown",
82 "unknown", "unknown",
83 "unknown", "unknown",
84 "unknown", "unknown",
85 "unknown", "unknown",
86 "unknown", "unknown",
87 "unknown", "unknown",
88 "unknown", "unknown",
89 "unknown", "unknown",
90 "unknown", "unknown",
91 "unknown", "unknown",
92 "unknown", "unknown",
93 "unknown", "unknown",
94 "unknown", "unknown",
95 "unknown", "unknown",
96 "unknown", "unknown",
97 "unknown", "unknown",
98 "unknown", "unknown",
99 "euc-cn", "euc-jp",
100 "euc-kr", "euc-tw",
101 "jis-x0213"
102 };
103
104
ef416fc2 105/*
106 * Local functions...
107 */
108
ef416fc2 109static void print_utf8(const char *msg, const cups_utf8_t *src);
ef416fc2 110
111
112/*
113 * 'main()' - Main entry for internationalization test module.
114 */
115
116int /* O - Exit code */
117main(int argc, /* I - Argument Count */
118 char *argv[]) /* I - Arguments */
ef416fc2 119{
120 FILE *fp; /* File pointer */
121 int count; /* File line counter */
e1d6a774 122 int status, /* Status of current test */
123 errors; /* Error count */
ef416fc2 124 char line[1024]; /* File line source string */
125 int len; /* Length (count) of string */
e1d6a774 126 char legsrc[1024], /* Legacy source string */
127 legdest[1024], /* Legacy destination string */
128 *legptr; /* Pointer into legacy string */
ef416fc2 129 cups_utf8_t utf8latin[] = /* UTF-8 Latin-1 source */
130 { 0x41, 0x20, 0x21, 0x3D, 0x20, 0xC3, 0x84, 0x2E, 0x00 };
131 /* "A != <A WITH DIAERESIS>." - use ISO 8859-1 */
132 cups_utf8_t utf8repla[] = /* UTF-8 Latin-1 replacement */
133 { 0x41, 0x20, 0xE2, 0x89, 0xA2, 0x20, 0xC3, 0x84, 0x2E, 0x00 };
134 /* "A <NOT IDENTICAL TO> <A WITH DIAERESIS>." */
135 cups_utf8_t utf8greek[] = /* UTF-8 Greek source string */
136 { 0x41, 0x20, 0x21, 0x3D, 0x20, 0xCE, 0x91, 0x2E, 0x00 };
e1d6a774 137 /* "A != <ALPHA>." - use ISO 8859-7 */
ef416fc2 138 cups_utf8_t utf8japan[] = /* UTF-8 Japanese source */
139 { 0x41, 0x20, 0x21, 0x3D, 0x20, 0xEE, 0x9C, 0x80, 0x2E, 0x00 };
140 /* "A != <PRIVATE U+E700>." - use Windows 932 or EUC-JP */
141 cups_utf8_t utf8taiwan[] = /* UTF-8 Chinese source */
142 { 0x41, 0x20, 0x21, 0x3D, 0x20, 0xE4, 0xB9, 0x82, 0x2E, 0x00 };
143 /* "A != <CJK U+4E42>." - use Windows 950 (Big5) or EUC-TW */
ef416fc2 144 cups_utf8_t utf8dest[1024]; /* UTF-8 destination string */
ef416fc2 145 cups_utf32_t utf32dest[1024]; /* UTF-32 destination string */
ef416fc2 146
147
bf3816c7
MS
148 if (argc > 1)
149 {
150 int i; /* Looping var */
151 cups_encoding_t encoding; /* Source encoding */
152
153
154 if (argc != 3)
155 {
156 puts("Usage: ./testi18n [filename charset]");
157 return (1);
158 }
159
160 if ((fp = fopen(argv[1], "rb")) == NULL)
161 {
162 perror(argv[1]);
163 return (1);
164 }
165
166 for (i = 0, encoding = CUPS_AUTO_ENCODING;
167 i < (int)(sizeof(lang_encodings) / sizeof(lang_encodings[0]));
168 i ++)
88f9aafc 169 if (!_cups_strcasecmp(lang_encodings[i], argv[2]))
bf3816c7
MS
170 {
171 encoding = (cups_encoding_t)i;
172 break;
173 }
174
175 if (encoding == CUPS_AUTO_ENCODING)
176 {
177 fprintf(stderr, "%s: Unknown character set!\n", argv[2]);
178 return (1);
179 }
180
181 while (fgets(line, sizeof(line), fp))
182 {
183 if (cupsCharsetToUTF8(utf8dest, line, sizeof(utf8dest), encoding) < 0)
184 {
185 fprintf(stderr, "%s: Unable to convert line: %s", argv[1], line);
186 return (1);
187 }
188
189 fputs((char *)utf8dest, stdout);
190 }
191
192 fclose(fp);
193 return (0);
194 }
195
ef416fc2 196 /*
e1d6a774 197 * Start with some conversion tests from a UTF-8 test file.
ef416fc2 198 */
199
e1d6a774 200 errors = 0;
201
bf3816c7 202 if ((fp = fopen("utf8demo.txt", "rb")) == NULL)
ef416fc2 203 {
e1d6a774 204 perror("utf8demo.txt");
205 return (1);
ef416fc2 206 }
207
208 /*
e1d6a774 209 * cupsUTF8ToUTF32
ef416fc2 210 */
211
e1d6a774 212 fputs("cupsUTF8ToUTF32 of utfdemo.txt: ", stdout);
213
214 for (count = 0, status = 0; fgets(line, sizeof(line), fp);)
ef416fc2 215 {
e1d6a774 216 count ++;
217
218 if (cupsUTF8ToUTF32(utf32dest, (cups_utf8_t *)line, 1024) < 0)
219 {
220 printf("FAIL (UTF-8 to UTF-32 on line %d)\n", count);
221 errors ++;
222 status = 1;
223 break;
224 }
ef416fc2 225 }
226
e1d6a774 227 if (!status)
228 puts("PASS");
ef416fc2 229
e1d6a774 230 /*
231 * cupsUTF8ToCharset(CUPS_EUC_JP)
232 */
ef416fc2 233
e1d6a774 234 fputs("cupsUTF8ToCharset(CUPS_EUC_JP) of utfdemo.txt: ", stdout);
ef416fc2 235
e1d6a774 236 rewind(fp);
237
238 for (count = 0, status = 0; fgets(line, sizeof(line), fp);)
239 {
240 count ++;
ef416fc2 241
242 len = cupsUTF8ToCharset(legdest, (cups_utf8_t *)line, 1024, CUPS_EUC_JP);
243 if (len < 0)
e1d6a774 244 {
245 printf("FAIL (UTF-8 to EUC-JP on line %d)\n", count);
246 errors ++;
247 status = 1;
248 break;
249 }
ef416fc2 250 }
251
e1d6a774 252 if (!status)
253 puts("PASS");
254
ef416fc2 255 fclose(fp);
256
ef416fc2 257 /*
258 * Test UTF-8 to legacy charset (ISO 8859-1)...
259 */
260
e1d6a774 261 fputs("cupsUTF8ToCharset(CUPS_ISO8859_1): ", stdout);
ef416fc2 262
263 legdest[0] = 0;
264
265 len = cupsUTF8ToCharset(legdest, utf8latin, 1024, CUPS_ISO8859_1);
266 if (len < 0)
ef416fc2 267 {
e1d6a774 268 printf("FAIL (len=%d)\n", len);
269 errors ++;
ef416fc2 270 }
e1d6a774 271 else
272 puts("PASS");
ef416fc2 273
e1d6a774 274 /*
275 * cupsCharsetToUTF8
276 */
ef416fc2 277
e1d6a774 278 fputs("cupsCharsetToUTF8(CUPS_ISO8859_1): ", stdout);
ef416fc2 279
5a9febac 280 strlcpy(legsrc, legdest, sizeof(legsrc));
ef416fc2 281
e1d6a774 282 len = cupsCharsetToUTF8(utf8dest, legsrc, 1024, CUPS_ISO8859_1);
1a18c85c 283 if ((size_t)len != strlen((char *)utf8latin))
e1d6a774 284 {
89d46774 285 printf("FAIL (len=%d, expected %d)\n", len, (int)strlen((char *)utf8latin));
e1d6a774 286 print_utf8(" utf8latin", utf8latin);
287 print_utf8(" utf8dest", utf8dest);
288 errors ++;
289 }
1a18c85c 290 else if (memcmp(utf8latin, utf8dest, (size_t)len))
ef416fc2 291 {
e1d6a774 292 puts("FAIL (results do not match)");
293 print_utf8(" utf8latin", utf8latin);
294 print_utf8(" utf8dest", utf8dest);
295 errors ++;
ef416fc2 296 }
e1d6a774 297 else if (cupsUTF8ToCharset(legdest, utf8repla, 1024, CUPS_ISO8859_1) < 0)
298 {
299 puts("FAIL (replacement characters do not work!)");
300 errors ++;
301 }
302 else
303 puts("PASS");
ef416fc2 304
305 /*
e1d6a774 306 * Test UTF-8 to/from legacy charset (ISO 8859-7)...
ef416fc2 307 */
e1d6a774 308
309 fputs("cupsUTF8ToCharset(CUPS_ISO8859_7): ", stdout);
310
311 if (cupsUTF8ToCharset(legdest, utf8greek, 1024, CUPS_ISO8859_7) < 0)
ef416fc2 312 {
e1d6a774 313 puts("FAIL");
314 errors ++;
ef416fc2 315 }
e1d6a774 316 else
317 {
318 for (legptr = legdest; *legptr && *legptr != '?'; legptr ++);
319
320 if (*legptr)
321 {
322 puts("FAIL (unknown character)");
323 errors ++;
324 }
325 else
326 puts("PASS");
327 }
328
329 fputs("cupsCharsetToUTF8(CUPS_ISO8859_7): ", stdout);
330
5a9febac 331 strlcpy(legsrc, legdest, sizeof(legsrc));
e1d6a774 332
ef416fc2 333 len = cupsCharsetToUTF8(utf8dest, legsrc, 1024, CUPS_ISO8859_7);
1a18c85c 334 if ((size_t)len != strlen((char *)utf8greek))
e1d6a774 335 {
89d46774 336 printf("FAIL (len=%d, expected %d)\n", len, (int)strlen((char *)utf8greek));
e1d6a774 337 print_utf8(" utf8greek", utf8greek);
338 print_utf8(" utf8dest", utf8dest);
339 errors ++;
340 }
1a18c85c 341 else if (memcmp(utf8greek, utf8dest, (size_t)len))
e1d6a774 342 {
343 puts("FAIL (results do not match)");
344 print_utf8(" utf8greek", utf8greek);
345 print_utf8(" utf8dest", utf8dest);
346 errors ++;
347 }
348 else
349 puts("PASS");
ef416fc2 350
351 /*
e1d6a774 352 * Test UTF-8 to/from legacy charset (Windows 932)...
ef416fc2 353 */
e1d6a774 354
355 fputs("cupsUTF8ToCharset(CUPS_WINDOWS_932): ", stdout);
356
357 if (cupsUTF8ToCharset(legdest, utf8japan, 1024, CUPS_WINDOWS_932) < 0)
ef416fc2 358 {
e1d6a774 359 puts("FAIL");
360 errors ++;
ef416fc2 361 }
e1d6a774 362 else
363 {
364 for (legptr = legdest; *legptr && *legptr != '?'; legptr ++);
365
366 if (*legptr)
367 {
368 puts("FAIL (unknown character)");
369 errors ++;
370 }
371 else
372 puts("PASS");
373 }
374
375 fputs("cupsCharsetToUTF8(CUPS_WINDOWS_932): ", stdout);
376
5a9febac 377 strlcpy(legsrc, legdest, sizeof(legsrc));
e1d6a774 378
ef416fc2 379 len = cupsCharsetToUTF8(utf8dest, legsrc, 1024, CUPS_WINDOWS_932);
1a18c85c 380 if ((size_t)len != strlen((char *)utf8japan))
e1d6a774 381 {
89d46774 382 printf("FAIL (len=%d, expected %d)\n", len, (int)strlen((char *)utf8japan));
e1d6a774 383 print_utf8(" utf8japan", utf8japan);
384 print_utf8(" utf8dest", utf8dest);
385 errors ++;
386 }
1a18c85c 387 else if (memcmp(utf8japan, utf8dest, (size_t)len))
e1d6a774 388 {
389 puts("FAIL (results do not match)");
390 print_utf8(" utf8japan", utf8japan);
391 print_utf8(" utf8dest", utf8dest);
392 errors ++;
393 }
394 else
395 puts("PASS");
ef416fc2 396
397 /*
e1d6a774 398 * Test UTF-8 to/from legacy charset (EUC-JP)...
ef416fc2 399 */
e1d6a774 400
401 fputs("cupsUTF8ToCharset(CUPS_EUC_JP): ", stdout);
402
403 if (cupsUTF8ToCharset(legdest, utf8japan, 1024, CUPS_EUC_JP) < 0)
ef416fc2 404 {
e1d6a774 405 puts("FAIL");
406 errors ++;
ef416fc2 407 }
e1d6a774 408 else
409 {
410 for (legptr = legdest; *legptr && *legptr != '?'; legptr ++);
411
412 if (*legptr)
413 {
414 puts("FAIL (unknown character)");
415 errors ++;
416 }
417 else
418 puts("PASS");
419 }
420
0268488e 421#ifndef __linux
e1d6a774 422 fputs("cupsCharsetToUTF8(CUPS_EUC_JP): ", stdout);
423
5a9febac 424 strlcpy(legsrc, legdest, sizeof(legsrc));
e1d6a774 425
ef416fc2 426 len = cupsCharsetToUTF8(utf8dest, legsrc, 1024, CUPS_EUC_JP);
1a18c85c 427 if ((size_t)len != strlen((char *)utf8japan))
e1d6a774 428 {
89d46774 429 printf("FAIL (len=%d, expected %d)\n", len, (int)strlen((char *)utf8japan));
e1d6a774 430 print_utf8(" utf8japan", utf8japan);
431 print_utf8(" utf8dest", utf8dest);
432 errors ++;
433 }
1a18c85c 434 else if (memcmp(utf8japan, utf8dest, (size_t)len))
e1d6a774 435 {
436 puts("FAIL (results do not match)");
437 print_utf8(" utf8japan", utf8japan);
438 print_utf8(" utf8dest", utf8dest);
439 errors ++;
440 }
441 else
442 puts("PASS");
0268488e 443#endif /* !__linux */
ef416fc2 444
445 /*
e1d6a774 446 * Test UTF-8 to/from legacy charset (Windows 950)...
ef416fc2 447 */
e1d6a774 448
449 fputs("cupsUTF8ToCharset(CUPS_WINDOWS_950): ", stdout);
450
451 if (cupsUTF8ToCharset(legdest, utf8taiwan, 1024, CUPS_WINDOWS_950) < 0)
452 {
453 puts("FAIL");
454 errors ++;
455 }
456 else
ef416fc2 457 {
e1d6a774 458 for (legptr = legdest; *legptr && *legptr != '?'; legptr ++);
459
460 if (*legptr)
461 {
462 puts("FAIL (unknown character)");
463 errors ++;
464 }
465 else
466 puts("PASS");
ef416fc2 467 }
e1d6a774 468
469 fputs("cupsCharsetToUTF8(CUPS_WINDOWS_950): ", stdout);
470
5a9febac 471 strlcpy(legsrc, legdest, sizeof(legsrc));
e1d6a774 472
ef416fc2 473 len = cupsCharsetToUTF8(utf8dest, legsrc, 1024, CUPS_WINDOWS_950);
1a18c85c 474 if ((size_t)len != strlen((char *)utf8taiwan))
e1d6a774 475 {
89d46774 476 printf("FAIL (len=%d, expected %d)\n", len, (int)strlen((char *)utf8taiwan));
e1d6a774 477 print_utf8(" utf8taiwan", utf8taiwan);
478 print_utf8(" utf8dest", utf8dest);
479 errors ++;
480 }
1a18c85c 481 else if (memcmp(utf8taiwan, utf8dest, (size_t)len))
e1d6a774 482 {
483 puts("FAIL (results do not match)");
484 print_utf8(" utf8taiwan", utf8taiwan);
485 print_utf8(" utf8dest", utf8dest);
486 errors ++;
487 }
488 else
489 puts("PASS");
ef416fc2 490
491 /*
e1d6a774 492 * Test UTF-8 to/from legacy charset (EUC-TW)...
ef416fc2 493 */
e1d6a774 494
495 fputs("cupsUTF8ToCharset(CUPS_EUC_TW): ", stdout);
496
497 if (cupsUTF8ToCharset(legdest, utf8taiwan, 1024, CUPS_EUC_TW) < 0)
498 {
499 puts("FAIL");
500 errors ++;
501 }
502 else
ef416fc2 503 {
e1d6a774 504 for (legptr = legdest; *legptr && *legptr != '?'; legptr ++);
505
506 if (*legptr)
507 {
508 puts("FAIL (unknown character)");
509 errors ++;
510 }
511 else
512 puts("PASS");
ef416fc2 513 }
e1d6a774 514
515 fputs("cupsCharsetToUTF8(CUPS_EUC_TW): ", stdout);
516
5a9febac 517 strlcpy(legsrc, legdest, sizeof(legsrc));
e1d6a774 518
ef416fc2 519 len = cupsCharsetToUTF8(utf8dest, legsrc, 1024, CUPS_EUC_TW);
1a18c85c 520 if ((size_t)len != strlen((char *)utf8taiwan))
e1d6a774 521 {
89d46774 522 printf("FAIL (len=%d, expected %d)\n", len, (int)strlen((char *)utf8taiwan));
e1d6a774 523 print_utf8(" utf8taiwan", utf8taiwan);
524 print_utf8(" utf8dest", utf8dest);
525 errors ++;
526 }
1a18c85c 527 else if (memcmp(utf8taiwan, utf8dest, (size_t)len))
e1d6a774 528 {
529 puts("FAIL (results do not match)");
530 print_utf8(" utf8taiwan", utf8taiwan);
531 print_utf8(" utf8dest", utf8dest);
532 errors ++;
533 }
534 else
535 puts("PASS");
ef416fc2 536
e1d6a774 537#if 0
ef416fc2 538 /*
539 * Test UTF-8 (16-bit) to UTF-32 (w/ BOM)...
540 */
541 if (verbose)
542 printf("\ntesti18n: Testing UTF-8 to UTF-32 (w/ BOM)...\n");
543 len = cupsUTF8ToUTF32(utf32dest, utf8good, 1024);
544 if (len < 0)
545 return (1);
546 if (verbose)
547 {
548 print_utf8(" utf8good ", utf8good);
549 print_utf32(" utf32dest", utf32dest);
550 }
1a18c85c 551 memcpy(utf32src, utf32dest, (len + 1) * sizeof(cups_utf32_t));
ef416fc2 552 len = cupsUTF32ToUTF8(utf8dest, utf32src, 1024);
553 if (len < 0)
554 return (1);
555 if (len != strlen ((char *) utf8good))
556 return (1);
557 if (memcmp(utf8good, utf8dest, len) != 0)
558 return (1);
559
560 /*
561 * Test invalid UTF-8 (16-bit) to UTF-32 (w/ BOM)...
562 */
563 if (verbose)
564 printf("\ntesti18n: Testing UTF-8 bad 16-bit source string...\n");
565 len = cupsUTF8ToUTF32(utf32dest, utf8bad, 1024);
566 if (len >= 0)
567 return (1);
568 if (verbose)
569 print_utf8(" utf8bad ", utf8bad);
570
571 /*
e1d6a774 572 * Test _cupsCharmapFlush()...
ef416fc2 573 */
574 if (verbose)
e1d6a774 575 printf("\ntesti18n: Testing _cupsCharmapFlush()...\n");
576 _cupsCharmapFlush();
ef416fc2 577 return (0);
e1d6a774 578#endif /* 0 */
579
580 return (errors > 0);
ef416fc2 581}
582
583
584/*
e1d6a774 585 * 'print_utf8()' - Print UTF-8 string with (optional) message.
ef416fc2 586 */
587
e1d6a774 588static void
589print_utf8(const char *msg, /* I - Message String */
590 const cups_utf8_t *src) /* I - UTF-8 Source String */
ef416fc2 591{
58dc1933
MS
592 const char *prefix; /* Prefix string */
593
594
e1d6a774 595 if (msg)
596 printf("%s:", msg);
ef416fc2 597
58dc1933
MS
598 for (prefix = " "; *src; src ++)
599 {
600 printf("%s%02x", prefix, *src);
601
602 if ((src[0] & 0x80) && (src[1] & 0x80))
603 prefix = "";
604 else
605 prefix = " ";
606 }
ef416fc2 607
e1d6a774 608 putchar('\n');
609}
ef416fc2 610
ef416fc2 611
e1d6a774 612/*
1a18c85c 613 * End of "$Id: testi18n.c 11558 2014-02-06 18:33:34Z msweet $"
ef416fc2 614 */