]>
Commit | Line | Data |
---|---|---|
ef416fc2 | 1 | /* |
2 | * "$Id: testi18n.c 4767 2005-10-10 19:23:23Z mike $" | |
3 | * | |
4 | * Internationalization test for Common UNIX Printing System (CUPS). | |
5 | * | |
6 | * Copyright 1997-2005 by Easy Software Products. | |
7 | * | |
8 | * These coded instructions, statements, and computer programs are | |
9 | * the property of Easy Software Products and are protected by Federal | |
10 | * copyright law. Distribution and use rights are outlined in the | |
11 | * file "LICENSE.txt" which should have been included with this file. | |
12 | * If this file is missing or damaged please contact Easy Software | |
13 | * Products at: | |
14 | * | |
15 | * Attn: CUPS Licensing Information | |
16 | * Easy Software Products | |
17 | * 44141 Airport View Drive, Suite 204 | |
18 | * Hollywood, Maryland 20636 USA | |
19 | * | |
20 | * Voice: (301) 373-9600 | |
21 | * EMail: cups-info@cups.org | |
22 | * WWW: http://www.cups.org | |
23 | * | |
24 | * Contents: | |
25 | * | |
26 | * main() - Main entry for internationalization test module. | |
27 | * print_synopsis() - Print program synopsis (help). | |
28 | * print_utf8() - Print UTF-8 string with (optional) message. | |
29 | * print_utf16() - Print UTF-16 string with (optional) message. | |
30 | * print_utf32() - Print UTF-32 string with (optional) message. | |
31 | * test_transcode() - Test 'transcode.c' module. | |
32 | * test_normalize() - Test 'normalize.c' module. | |
33 | */ | |
34 | ||
35 | /* | |
36 | * Include necessary headers... | |
37 | */ | |
38 | ||
39 | #include <stdio.h> | |
40 | #include <stdlib.h> | |
41 | #include <errno.h> | |
42 | #include <time.h> | |
43 | ||
44 | #include "language.h" | |
45 | #include "string.h" | |
46 | #include "transcode.h" | |
47 | #include "normalize.h" | |
48 | ||
49 | ||
50 | /* | |
51 | * Local Globals... | |
52 | */ | |
53 | ||
54 | static const char *program_synopsis[] = /* Program help */ | |
55 | { | |
56 | "testi18n [-vh]", | |
57 | " -v verbose (print each called function and result)", | |
58 | " -h help (print this synopsis)", | |
59 | "", | |
60 | "'testi18n' is a utility to test CUPS internationalization", | |
61 | "Copyright 1997-2005 by Easy Software Products.", | |
62 | NULL | |
63 | }; | |
64 | static int error_count = 0; /* Total error count */ | |
65 | ||
66 | ||
67 | /* | |
68 | * Local functions... | |
69 | */ | |
70 | ||
71 | static void print_synopsis(void); | |
72 | static void print_utf8(const char *msg, const cups_utf8_t *src); | |
73 | static void print_utf16(const char *msg, const cups_utf16_t *src); | |
74 | static void print_utf32(const char *msg, const cups_utf32_t *src); | |
75 | static int test_transcode(const int verbose); | |
76 | static int test_normalize(const int verbose); | |
77 | ||
78 | ||
79 | /* | |
80 | * 'main()' - Main entry for internationalization test module. | |
81 | */ | |
82 | ||
83 | int /* O - Exit code */ | |
84 | main(int argc, /* I - Argument Count */ | |
85 | char *argv[]) /* I - Arguments */ | |
86 | { | |
87 | int ai; /* Argument index */ | |
88 | char *ap; /* Argument pointer */ | |
89 | int verbose; /* Verbose flag */ | |
90 | int errors; /* Error count */ | |
91 | ||
92 | ||
93 | /* | |
94 | * Check for switches... | |
95 | */ | |
96 | ||
97 | verbose = 0; | |
98 | ||
99 | for (ai = 1; ai < argc; ai ++) | |
100 | { | |
101 | ap = argv[ai]; | |
102 | if (*ap != '-') | |
103 | break; | |
104 | ||
105 | for (ap ++; *ap != '\0'; ap ++) | |
106 | { | |
107 | switch (*ap) | |
108 | { | |
109 | case 'v': /* verbose */ | |
110 | verbose = 1; | |
111 | break; | |
112 | ||
113 | case 'h': /* help */ | |
114 | print_synopsis(); | |
115 | return (0); | |
116 | ||
117 | default: | |
118 | print_synopsis(); | |
119 | return (1); | |
120 | } | |
121 | } | |
122 | } | |
123 | ||
124 | /* | |
125 | * Test all internationalization modules and functions... | |
126 | */ | |
127 | ||
128 | errors = test_transcode(verbose); | |
129 | error_count += errors; | |
130 | printf("\ntesti18n: %d errors found in 'transcode.c'\n", errors); | |
131 | ||
132 | errors = test_normalize(verbose); | |
133 | error_count += errors; | |
134 | printf("\ntesti18n: %d errors found in 'normalize.c'\n", errors); | |
135 | ||
136 | return (error_count > 0); | |
137 | } | |
138 | ||
139 | ||
140 | /* | |
141 | * 'print_synopsis()' - Print program synopsis (help). | |
142 | */ | |
143 | ||
144 | static void | |
145 | print_synopsis(void) | |
146 | { | |
147 | int i; /* Looping variable */ | |
148 | ||
149 | ||
150 | for (i = 0; program_synopsis[i]; i ++) | |
151 | puts(program_synopsis[i]); | |
152 | } | |
153 | ||
154 | ||
155 | /* | |
156 | * 'print_utf8()' - Print UTF-8 string with (optional) message. | |
157 | */ | |
158 | ||
159 | void | |
160 | print_utf8(const char *msg, /* I - Message String */ | |
161 | const cups_utf8_t *src) /* I - UTF-8 Source String */ | |
162 | { | |
163 | if (msg != NULL) | |
164 | printf("%s:", msg); | |
165 | ||
166 | for (; *src; src ++) | |
167 | printf(" %02x", *src); | |
168 | printf("\n"); | |
169 | return; | |
170 | } | |
171 | ||
172 | ||
173 | /* | |
174 | * 'print_utf16()' - Print UTF-16 string with (optional) message. | |
175 | */ | |
176 | ||
177 | void | |
178 | print_utf16(const char *msg, /* I - Message String */ | |
179 | const cups_utf16_t *src) /* I - UTF-16 Source String */ | |
180 | { | |
181 | if (msg != NULL) | |
182 | printf("%s:", msg); | |
183 | for (; *src; src ++) | |
184 | printf(" %04x", (int) *src); | |
185 | printf("\n"); | |
186 | return; | |
187 | } | |
188 | ||
189 | ||
190 | /* | |
191 | * 'print_utf32()' - Print UTF-32 string with (optional) message. | |
192 | */ | |
193 | ||
194 | void | |
195 | print_utf32(const char *msg, /* I - Message String */ | |
196 | const cups_utf32_t *src) /* I - UTF-32 Source String */ | |
197 | { | |
198 | if (msg != NULL) | |
199 | printf("%s:", msg); | |
200 | for (; *src; src ++) | |
201 | printf(" %04x", (int) *src); | |
202 | printf("\n"); | |
203 | return; | |
204 | } | |
205 | ||
206 | ||
207 | /* | |
208 | * 'test_transcode()' - Test 'transcode.c' module. | |
209 | */ | |
210 | ||
211 | static int /* O - Zero or error count */ | |
212 | test_transcode(const int verbose) /* I - Verbose flag */ | |
213 | { | |
214 | FILE *fp; /* File pointer */ | |
215 | int count; /* File line counter */ | |
216 | char line[1024]; /* File line source string */ | |
217 | int len; /* Length (count) of string */ | |
218 | char legsrc[1024]; /* Legacy source string */ | |
219 | char legdest[1024]; /* Legacy destination string */ | |
220 | cups_utf8_t utf8latin[] = /* UTF-8 Latin-1 source */ | |
221 | { 0x41, 0x20, 0x21, 0x3D, 0x20, 0xC3, 0x84, 0x2E, 0x00 }; | |
222 | /* "A != <A WITH DIAERESIS>." - use ISO 8859-1 */ | |
223 | cups_utf8_t utf8repla[] = /* UTF-8 Latin-1 replacement */ | |
224 | { 0x41, 0x20, 0xE2, 0x89, 0xA2, 0x20, 0xC3, 0x84, 0x2E, 0x00 }; | |
225 | /* "A <NOT IDENTICAL TO> <A WITH DIAERESIS>." */ | |
226 | cups_utf8_t utf8greek[] = /* UTF-8 Greek source string */ | |
227 | { 0x41, 0x20, 0x21, 0x3D, 0x20, 0xCE, 0x91, 0x2E, 0x00 }; | |
228 | /* "A != <ALHPA>." - use ISO 8859-7 */ | |
229 | cups_utf8_t utf8japan[] = /* UTF-8 Japanese source */ | |
230 | { 0x41, 0x20, 0x21, 0x3D, 0x20, 0xEE, 0x9C, 0x80, 0x2E, 0x00 }; | |
231 | /* "A != <PRIVATE U+E700>." - use Windows 932 or EUC-JP */ | |
232 | cups_utf8_t utf8taiwan[] = /* UTF-8 Chinese source */ | |
233 | { 0x41, 0x20, 0x21, 0x3D, 0x20, 0xE4, 0xB9, 0x82, 0x2E, 0x00 }; | |
234 | /* "A != <CJK U+4E42>." - use Windows 950 (Big5) or EUC-TW */ | |
235 | cups_utf8_t utf8good[] = /* UTF-8 good 16-bit source */ | |
236 | { 0x41, 0x20, 0xE2, 0x89, 0xA2, 0x20, 0xC3, 0x84, 0x2E, 0x00 }; | |
237 | /* "A <NOT IDENTICAL TO> <A WITH DIAERESIS>." */ | |
238 | cups_utf8_t utf8bad[] = /* UTF-8 bad 16-bit source */ | |
239 | { 0x41, 0x20, 0xE2, 0x89, 0xA2, 0x20, 0xF8, 0x84, 0x2E, 0x00 }; | |
240 | /* "A <NOT IDENTICAL TO> <...bad stuff...>." */ | |
241 | cups_utf8_t utf8dest[1024]; /* UTF-8 destination string */ | |
242 | cups_utf16_t utf16sur[] = /* UTF-16 with surrogates */ | |
243 | { 0xD800, 0xDC00, 0x20, 0x21, 0x3D, 0x20, 0xC4, 0x2E, 0x00 }; | |
244 | /* "<Surrogate pair> != <A WITH DIAERESIS>." */ | |
245 | cups_utf16_t utf16src[1024]; /* UTF-16 source string */ | |
246 | cups_utf16_t utf16dest[1024]; /* UTF-16 destination string */ | |
247 | cups_utf32_t utf32src[1024]; /* UTF-32 source string */ | |
248 | cups_utf32_t utf32dest[1024]; /* UTF-32 destination string */ | |
249 | _cups_vmap_t *vmap; /* VBCS charmap pointer */ | |
250 | ||
251 | ||
252 | /* | |
253 | * Test with (inserted) and (deleted) leading BOM... | |
254 | */ | |
255 | ||
256 | if (verbose) | |
257 | { | |
258 | printf("\ntesti18n: Testing 'transcode.c'...\n"); | |
259 | printf(" testing with insert/delete leading BOM...\n"); | |
260 | } | |
261 | ||
262 | /* | |
263 | * Test UTF-8 to UTF-32/EUC-JP on demo file... | |
264 | */ | |
265 | ||
266 | if (verbose) | |
267 | { | |
268 | printf("\ntesti18n: Testing UTF-8 source 'utf8demo.txt'...\n"); | |
269 | printf(" testing UTF-8 to UTF-32...\n"); | |
270 | printf(" testing UTF-8 to EUC-JP...\n"); | |
271 | } | |
272 | ||
273 | if ((fp = fopen("utf8demo.txt", "r")) == NULL) | |
274 | return (1); | |
275 | ||
276 | for (count = 0;;) | |
277 | { | |
278 | if (fgets(line, 1024, fp) == NULL) | |
279 | break; | |
280 | ||
281 | count ++; | |
282 | ||
283 | len = cupsUTF8ToUTF32(utf32dest, (cups_utf8_t *)line, 1024); | |
284 | if (len < 0) | |
285 | printf(" error line: %d (UTF-8 to UTF-32)\n", count); | |
286 | ||
287 | len = cupsUTF8ToCharset(legdest, (cups_utf8_t *)line, 1024, CUPS_EUC_JP); | |
288 | if (len < 0) | |
289 | printf(" error line: %d (UTF-8 to EUC-JP)\n", count); | |
290 | } | |
291 | ||
292 | fclose(fp); | |
293 | ||
294 | if (verbose) | |
295 | printf(" total lines: %d\n", count); | |
296 | ||
297 | /* | |
298 | * Test VBCS charmap load for EUC-JP... | |
299 | */ | |
300 | ||
301 | if (verbose) | |
302 | printf("\ntesti18n: Loading VBCS charmap EUC-JP (Japanese)...\n"); | |
303 | ||
304 | vmap = (_cups_vmap_t *) cupsCharmapGet(CUPS_EUC_JP); | |
305 | if (vmap == NULL) | |
306 | return (1); | |
307 | ||
308 | if (verbose) | |
309 | { | |
310 | printf(" charcount: %d\n", vmap->charcount); | |
311 | printf(" widecount: %d\n", vmap->widecount); | |
312 | } | |
313 | ||
314 | /* | |
315 | * Test VBCS charmap load for EUC-TW... | |
316 | */ | |
317 | ||
318 | if (verbose) | |
319 | printf("\ntesti18n: Loading VBCS charmap EUC-TW (Taiwan)...\n"); | |
320 | ||
321 | vmap = (_cups_vmap_t *) cupsCharmapGet(CUPS_EUC_TW); | |
322 | if (vmap == NULL) | |
323 | return (1); | |
324 | ||
325 | if (verbose) | |
326 | { | |
327 | printf(" charcount: %d\n", vmap->charcount); | |
328 | printf(" widecount: %d\n", vmap->widecount); | |
329 | } | |
330 | ||
331 | /* | |
332 | * Test UTF-8 to legacy charset (ISO 8859-1)... | |
333 | */ | |
334 | ||
335 | if (verbose) | |
336 | printf("\ntesti18n: Testing UTF-8 to ISO 8859-1 (Latin1)...\n"); | |
337 | ||
338 | legdest[0] = 0; | |
339 | ||
340 | len = cupsUTF8ToCharset(legdest, utf8latin, 1024, CUPS_ISO8859_1); | |
341 | if (len < 0) | |
342 | return (1); | |
343 | ||
344 | if (verbose) | |
345 | { | |
346 | print_utf8(" utf8latin", utf8latin); | |
347 | print_utf8(" legdest ", (cups_utf8_t *) legdest); | |
348 | } | |
349 | ||
350 | strcpy(legsrc, legdest); | |
351 | ||
352 | len = cupsCharsetToUTF8(utf8dest, legsrc, 1024, CUPS_ISO8859_1); | |
353 | ||
354 | if (len < 0) | |
355 | return (1); | |
356 | ||
357 | if (len != strlen ((char *) utf8latin)) | |
358 | return (1); | |
359 | ||
360 | if (memcmp(utf8latin, utf8dest, len) != 0) | |
361 | return (1); | |
362 | ||
363 | /* | |
364 | * Test UTF-8 to Latin-1 (ISO 8859-1) with replacement... | |
365 | */ | |
366 | if (verbose) | |
367 | printf("\ntesti18n: Testing UTF-8 to ISO 8859-1 w/ replace...\n"); | |
368 | len = cupsUTF8ToCharset(legdest, utf8repla, 1024, CUPS_ISO8859_1); | |
369 | if (len < 0) | |
370 | return (1); | |
371 | if (verbose) | |
372 | { | |
373 | print_utf8(" utf8repla", utf8repla); | |
374 | print_utf8(" legdest ", (cups_utf8_t *) legdest); | |
375 | } | |
376 | ||
377 | /* | |
378 | * Test UTF-8 to legacy charset (ISO 8859-7)... | |
379 | */ | |
380 | if (verbose) | |
381 | printf("\ntesti18n: Testing UTF-8 to ISO 8859-7 (Greek)...\n"); | |
382 | legdest[0] = 0; | |
383 | len = cupsUTF8ToCharset(legdest, utf8greek, 1024, CUPS_ISO8859_7); | |
384 | if (len < 0) | |
385 | return (1); | |
386 | if (verbose) | |
387 | { | |
388 | print_utf8(" utf8greek", utf8greek); | |
389 | print_utf8(" legdest ", (cups_utf8_t *) legdest); | |
390 | } | |
391 | strcpy(legsrc, legdest); | |
392 | len = cupsCharsetToUTF8(utf8dest, legsrc, 1024, CUPS_ISO8859_7); | |
393 | if (len < 0) | |
394 | return (1); | |
395 | if (len != strlen ((char *) utf8greek)) | |
396 | return (1); | |
397 | if (memcmp(utf8greek, utf8dest, len) != 0) | |
398 | return (1); | |
399 | ||
400 | /* | |
401 | * Test UTF-8 to legacy charset (Windows 932)... | |
402 | */ | |
403 | if (verbose) | |
404 | printf("\ntesti18n: Testing UTF-8 to Windows 932 (Japanese)...\n"); | |
405 | legdest[0] = 0; | |
406 | len = cupsUTF8ToCharset(legdest, utf8japan, 1024, CUPS_WINDOWS_932); | |
407 | if (len < 0) | |
408 | return (1); | |
409 | if (verbose) | |
410 | { | |
411 | print_utf8(" utf8japan", utf8japan); | |
412 | print_utf8(" legdest ", (cups_utf8_t *) legdest); | |
413 | } | |
414 | strcpy(legsrc, legdest); | |
415 | len = cupsCharsetToUTF8(utf8dest, legsrc, 1024, CUPS_WINDOWS_932); | |
416 | if (len < 0) | |
417 | return (1); | |
418 | if (len != strlen ((char *) utf8japan)) | |
419 | return (1); | |
420 | if (memcmp(utf8japan, utf8dest, len) != 0) | |
421 | return (1); | |
422 | ||
423 | /* | |
424 | * Test UTF-8 to legacy charset (EUC-JP)... | |
425 | */ | |
426 | if (verbose) | |
427 | printf("\ntesti18n: Testing UTF-8 to EUC-JP (Japanese)...\n"); | |
428 | legdest[0] = 0; | |
429 | len = cupsUTF8ToCharset(legdest, utf8japan, 1024, CUPS_EUC_JP); | |
430 | if (len < 0) | |
431 | return (1); | |
432 | if (verbose) | |
433 | { | |
434 | print_utf8(" utf8japan", utf8japan); | |
435 | print_utf8(" legdest ", (cups_utf8_t *) legdest); | |
436 | } | |
437 | strcpy(legsrc, legdest); | |
438 | len = cupsCharsetToUTF8(utf8dest, legsrc, 1024, CUPS_EUC_JP); | |
439 | if (len < 0) | |
440 | return (1); | |
441 | if (len != strlen ((char *) utf8japan)) | |
442 | return (1); | |
443 | if (memcmp(utf8japan, utf8dest, len) != 0) | |
444 | return (1); | |
445 | ||
446 | /* | |
447 | * Test UTF-8 to legacy charset (Windows 950)... | |
448 | */ | |
449 | if (verbose) | |
450 | printf("\ntesti18n: Testing UTF-8 to Windows 950 (Chinese)...\n"); | |
451 | legdest[0] = 0; | |
452 | len = cupsUTF8ToCharset(legdest, utf8taiwan, 1024, CUPS_WINDOWS_950); | |
453 | if (len < 0) | |
454 | return (1); | |
455 | if (verbose) | |
456 | { | |
457 | print_utf8(" utf8taiwan", utf8taiwan); | |
458 | print_utf8(" legdest ", (cups_utf8_t *) legdest); | |
459 | } | |
460 | strcpy(legsrc, legdest); | |
461 | len = cupsCharsetToUTF8(utf8dest, legsrc, 1024, CUPS_WINDOWS_950); | |
462 | if (len < 0) | |
463 | return (1); | |
464 | if (len != strlen ((char *) utf8taiwan)) | |
465 | return (1); | |
466 | if (memcmp(utf8taiwan, utf8dest, len) != 0) | |
467 | return (1); | |
468 | ||
469 | /* | |
470 | * Test UTF-8 to legacy charset (EUC-TW)... | |
471 | */ | |
472 | if (verbose) | |
473 | printf("\ntesti18n: Testing UTF-8 to EUC-TW (Chinese)...\n"); | |
474 | legdest[0] = 0; | |
475 | len = cupsUTF8ToCharset(legdest, utf8taiwan, 1024, CUPS_EUC_TW); | |
476 | if (len < 0) | |
477 | return (1); | |
478 | if (verbose) | |
479 | { | |
480 | print_utf8(" utf8taiwan", utf8taiwan); | |
481 | print_utf8(" legdest ", (cups_utf8_t *) legdest); | |
482 | } | |
483 | strcpy(legsrc, legdest); | |
484 | len = cupsCharsetToUTF8(utf8dest, legsrc, 1024, CUPS_EUC_TW); | |
485 | if (len < 0) | |
486 | return (1); | |
487 | if (len != strlen ((char *) utf8taiwan)) | |
488 | return (1); | |
489 | if (memcmp(utf8taiwan, utf8dest, len) != 0) | |
490 | return (1); | |
491 | ||
492 | /* | |
493 | * Test UTF-8 (16-bit) to UTF-32 (w/ BOM)... | |
494 | */ | |
495 | if (verbose) | |
496 | printf("\ntesti18n: Testing UTF-8 to UTF-32 (w/ BOM)...\n"); | |
497 | len = cupsUTF8ToUTF32(utf32dest, utf8good, 1024); | |
498 | if (len < 0) | |
499 | return (1); | |
500 | if (verbose) | |
501 | { | |
502 | print_utf8(" utf8good ", utf8good); | |
503 | print_utf32(" utf32dest", utf32dest); | |
504 | } | |
505 | memcpy (utf32src, utf32dest, (len + 1) * sizeof(cups_utf32_t)); | |
506 | len = cupsUTF32ToUTF8(utf8dest, utf32src, 1024); | |
507 | if (len < 0) | |
508 | return (1); | |
509 | if (len != strlen ((char *) utf8good)) | |
510 | return (1); | |
511 | if (memcmp(utf8good, utf8dest, len) != 0) | |
512 | return (1); | |
513 | ||
514 | /* | |
515 | * Test invalid UTF-8 (16-bit) to UTF-32 (w/ BOM)... | |
516 | */ | |
517 | if (verbose) | |
518 | printf("\ntesti18n: Testing UTF-8 bad 16-bit source string...\n"); | |
519 | len = cupsUTF8ToUTF32(utf32dest, utf8bad, 1024); | |
520 | if (len >= 0) | |
521 | return (1); | |
522 | if (verbose) | |
523 | print_utf8(" utf8bad ", utf8bad); | |
524 | ||
525 | /* | |
526 | * Test UTF-8 (16-bit) to UTF-16 (w/ BOM)... | |
527 | */ | |
528 | if (verbose) | |
529 | printf("\ntesti18n: Testing UTF-8 to UTF-16 (w/ BOM)...\n"); | |
530 | len = cupsUTF8ToUTF16(utf16dest, utf8good, 1024); | |
531 | if (len < 0) | |
532 | return (1); | |
533 | if (verbose) | |
534 | { | |
535 | print_utf8(" utf8good ", utf8good); | |
536 | print_utf16(" utf16dest", utf16dest); | |
537 | } | |
538 | memcpy (utf16src, utf16dest, (len + 1) * sizeof(cups_utf16_t)); | |
539 | len = cupsUTF16ToUTF8(utf8dest, utf16src, 1024); | |
540 | if (len < 0) | |
541 | return (1); | |
542 | if (len != strlen ((char *) utf8good)) | |
543 | return (1); | |
544 | if (memcmp(utf8good, utf8dest, len) != 0) | |
545 | return (1); | |
546 | ||
547 | /* | |
548 | * Test UTF-16 to UTF-32 with surrogates... | |
549 | */ | |
550 | if (verbose) | |
551 | printf("\ntesti18n: Testing UTF-16 to UTF-32 w/ surrogates...\n"); | |
552 | len = cupsUTF16ToUTF32(utf32dest, utf16sur, 1024); | |
553 | if (len < 0) | |
554 | return (1); | |
555 | if (verbose) | |
556 | { | |
557 | print_utf16(" utf16sur ", utf16sur); | |
558 | print_utf32(" utf32dest", utf32dest); | |
559 | } | |
560 | ||
561 | /* | |
562 | * Test cupsCharmapFlush()... | |
563 | */ | |
564 | if (verbose) | |
565 | printf("\ntesti18n: Testing cupsCharmapFlush()...\n"); | |
566 | cupsCharmapFlush(); | |
567 | return (0); | |
568 | } | |
569 | ||
570 | ||
571 | /* | |
572 | * 'test_normalize()' - Test 'normalize.c' module. | |
573 | */ | |
574 | ||
575 | static int /* O - Zero or error count */ | |
576 | test_normalize(const int verbose) /* I - Verbose flag */ | |
577 | { | |
578 | FILE *fp; /* File pointer */ | |
579 | int count; /* File line counter */ | |
580 | char line[1024]; /* File line source string */ | |
581 | int len; /* Length (count) of string */ | |
582 | int diff; /* Difference of two strings */ | |
583 | int prop; /* Property of a character */ | |
584 | int i; /* Looping variable */ | |
585 | cups_utf32_t utf32char; /* UTF-32 character */ | |
586 | cups_utf8_t utf8src[1024]; /* UTF-8 source string */ | |
587 | cups_utf8_t utf8dest[1024]; /* UTF-8 destination string */ | |
588 | cups_utf16_t utf16src[] = /* UTF-16 non-normal source */ | |
589 | { 0x0149, 0x20, 0x21, 0x3D, 0x20, 0xC4, 0x2E, 0x00 }; | |
590 | /* "<SMALL N PRECEDED BY APOSTROPHE> != <A WITH DIAERESIS>." */ | |
591 | cups_utf16_t utf16dest[1024]; /* UTF-16 destination string */ | |
592 | cups_utf32_t utf32dest[1024]; /* UTF-32 destination string */ | |
593 | ||
594 | if (verbose) | |
595 | printf("\ntesti18n: Testing 'normalize.c'...\n"); | |
596 | ||
597 | /* | |
598 | * Test UTF-8 to NFKD/NFC/Properties on demo file... | |
599 | */ | |
600 | if (verbose) | |
601 | { | |
602 | printf("\ntesti18n: Testing UTF-8 source 'utf8demo.txt'...\n"); | |
603 | printf(" testing UTF-8 to NFKD...\n"); | |
604 | printf(" testing UTF-8 to NFC...\n"); | |
605 | printf(" testing UTF-8 to Character Properties...\n"); | |
606 | } | |
607 | if ((fp = fopen("utf8demo.txt", "r")) == NULL) | |
608 | return (1); | |
609 | for (count = 0;;) | |
610 | { | |
611 | if (fgets(line, 1024, fp) == NULL) | |
612 | break; | |
613 | count ++; | |
614 | len = cupsUTF8Normalize(utf8dest, (cups_utf8_t *)line, 1024, CUPS_NORM_NFKD); | |
615 | if (len < 0) | |
616 | printf(" error line: %d (UTF-8 to NFKD)\n", count); | |
617 | len = cupsUTF8Normalize(utf8dest, (cups_utf8_t *)line, 1024, CUPS_NORM_NFC); | |
618 | if (len < 0) | |
619 | printf(" error line: %d (UTF-8 to NFC)\n", count); | |
620 | len = cupsUTF8ToUTF32(utf32dest, (cups_utf8_t *)line, 1024); | |
621 | if (len < 0) | |
622 | { | |
623 | printf(" error line: %d (UTF-8 to UTF-32)\n", count); | |
624 | continue; | |
625 | } | |
626 | for (i = 0; i < len; i ++) | |
627 | { | |
628 | prop = cupsUTF32CharacterProperty(utf32dest[i], | |
629 | CUPS_PROP_GENERAL_CATEGORY); | |
630 | if (prop < 0) | |
631 | printf(" error line: %d (Prop - General Category)\n", count); | |
632 | prop = cupsUTF32CharacterProperty(utf32dest[i], | |
633 | CUPS_PROP_BIDI_CATEGORY); | |
634 | if (prop < 0) | |
635 | printf(" error line: %d (Prop - Bidi Category)\n", count); | |
636 | prop = cupsUTF32CharacterProperty(utf32dest[i], | |
637 | CUPS_PROP_COMBINING_CLASS); | |
638 | if (prop < 0) | |
639 | printf(" error line: %d (Prop - Combining Class)\n", count); | |
640 | prop = cupsUTF32CharacterProperty(utf32dest[i], | |
641 | CUPS_PROP_BREAK_CLASS); | |
642 | if (prop < 0) | |
643 | printf(" error line: %d (Prop - Break Class)\n", count); | |
644 | } | |
645 | } | |
646 | fclose(fp); | |
647 | if (verbose) | |
648 | printf(" total lines: %d\n", count); | |
649 | ||
650 | /* | |
651 | * Test UTF-8 normalization NFKD... | |
652 | */ | |
653 | if (verbose) | |
654 | printf("\ntesti18n: Testing UTF-8 normalization NFKD...\n"); | |
655 | len = cupsUTF16ToUTF8(utf8dest, utf16src, 1024); | |
656 | if (len < 0) | |
657 | return (1); | |
658 | strcpy((char *) utf8src, (char *) utf8dest); | |
659 | len = cupsUTF8Normalize(utf8dest, utf8src, 1024, CUPS_NORM_NFKD); | |
660 | if (len < 0) | |
661 | return (1); | |
662 | len = cupsUTF8ToUTF16(utf16dest, utf8dest, 1024); | |
663 | if (len < 0) | |
664 | return (1); | |
665 | if (verbose) | |
666 | { | |
667 | print_utf16(" utf16src ", utf16src); | |
668 | print_utf16(" utf16dest", utf16dest); | |
669 | } | |
670 | ||
671 | /* | |
672 | * Test UTF-8 normalization NFD... | |
673 | */ | |
674 | if (verbose) | |
675 | printf("\ntesti18n: Testing UTF-8 normalization NFD...\n"); | |
676 | len = cupsUTF8Normalize(utf8dest, utf8src, 1024, CUPS_NORM_NFD); | |
677 | if (len < 0) | |
678 | return (1); | |
679 | len = cupsUTF8ToUTF16(utf16dest, utf8dest, 1024); | |
680 | if (len < 0) | |
681 | return (1); | |
682 | if (verbose) | |
683 | { | |
684 | print_utf16(" utf16src ", utf16src); | |
685 | print_utf16(" utf16dest", utf16dest); | |
686 | } | |
687 | ||
688 | /* | |
689 | * Test UTF-8 normalization NFC... | |
690 | */ | |
691 | if (verbose) | |
692 | printf("\ntesti18n: Testing UTF-8 normalization NFC...\n"); | |
693 | len = cupsUTF8Normalize(utf8dest, utf8src, 1024, CUPS_NORM_NFC); | |
694 | if (len < 0) | |
695 | return (1); | |
696 | len = cupsUTF8ToUTF16(utf16dest, utf8dest, 1024); | |
697 | if (len < 0) | |
698 | return (1); | |
699 | if (verbose) | |
700 | { | |
701 | print_utf16(" utf16src ", utf16src); | |
702 | print_utf16(" utf16dest", utf16dest); | |
703 | } | |
704 | ||
705 | /* | |
706 | * Test UTF-8 simple case folding... | |
707 | */ | |
708 | if (verbose) | |
709 | printf("\ntesti18n: Testing UTF-8 simple case folding...\n"); | |
710 | len = cupsUTF8CaseFold(utf8dest, utf8src, 1024, CUPS_FOLD_SIMPLE); | |
711 | if (len < 0) | |
712 | return (1); | |
713 | len = cupsUTF8ToUTF16(utf16dest, utf8dest, 1024); | |
714 | if (len < 0) | |
715 | return (1); | |
716 | if (verbose) | |
717 | { | |
718 | print_utf16(" utf16src ", utf16src); | |
719 | print_utf16(" utf16dest", utf16dest); | |
720 | } | |
721 | ||
722 | /* | |
723 | * Test UTF-8 full case folding... | |
724 | */ | |
725 | if (verbose) | |
726 | printf("\ntesti18n: Testing UTF-8 full case folding...\n"); | |
727 | len = cupsUTF8CaseFold(utf8dest, utf8src, 1024, CUPS_FOLD_FULL); | |
728 | if (len < 0) | |
729 | return (1); | |
730 | len = cupsUTF8ToUTF16(utf16dest, utf8dest, 1024); | |
731 | if (len < 0) | |
732 | return (1); | |
733 | if (verbose) | |
734 | { | |
735 | print_utf16(" utf16src ", utf16src); | |
736 | print_utf16(" utf16dest", utf16dest); | |
737 | } | |
738 | ||
739 | /* | |
740 | * Test UTF-8 caseless comparison... | |
741 | */ | |
742 | if (verbose) | |
743 | printf("\ntesti18n: Testing UTF-8 caseless comparison..\n"); | |
744 | diff = cupsUTF8CompareCaseless(utf8src, utf8dest); | |
745 | if (verbose) | |
746 | printf(" diff: %d\n", diff); | |
747 | if (verbose) | |
748 | printf("\ntesti18n: Testing UTF-8 identifier comparison..\n"); | |
749 | diff = cupsUTF8CompareIdentifier(utf8src, utf8dest); | |
750 | if (verbose) | |
751 | printf(" diff: %d\n", diff); | |
752 | ||
753 | /* | |
754 | * Test UTF-32 character properties... | |
755 | */ | |
756 | if (verbose) | |
757 | printf("\ntesti18n: Testing UTF-32 character properties..\n"); | |
758 | utf32char = 0x02B0; | |
759 | prop = cupsUTF32CharacterProperty (utf32char, | |
760 | CUPS_PROP_GENERAL_CATEGORY); | |
761 | if (verbose) | |
762 | printf(" utf32char: %04lx general category %d\n", utf32char, prop); | |
763 | utf32char = 0x0621; | |
764 | prop = cupsUTF32CharacterProperty (utf32char, | |
765 | CUPS_PROP_BIDI_CATEGORY); | |
766 | if (verbose) | |
767 | printf(" utf32char: %04lx bidi category %d\n", utf32char, prop); | |
768 | utf32char = 0x0308; | |
769 | prop = cupsUTF32CharacterProperty (utf32char, | |
770 | CUPS_PROP_COMBINING_CLASS); | |
771 | if (verbose) | |
772 | printf(" utf32char: %04lx combining class %d\n", utf32char, prop); | |
773 | utf32char = 0x0009; | |
774 | prop = cupsUTF32CharacterProperty (utf32char, | |
775 | CUPS_PROP_BREAK_CLASS); | |
776 | if (verbose) | |
777 | printf(" utf32char: %04lx break class %d\n", utf32char, prop); | |
778 | ||
779 | /* | |
780 | * Test cupsNormalizeMapsFlush()... | |
781 | */ | |
782 | if (verbose) | |
783 | printf("\ntesti18n: Testing cupsNormalizeMapsFlush()...\n"); | |
784 | cupsNormalizeMapsFlush(); | |
785 | return (0); | |
786 | } | |
787 | ||
788 | ||
789 | /* | |
790 | * End of "$Id: testi18n.c 4767 2005-10-10 19:23:23Z mike $" | |
791 | */ |