]> git.saurik.com Git - apple/icu.git/blame - icuSources/test/cintltst/cloctst.c
ICU-3.13.tar.gz
[apple/icu.git] / icuSources / test / cintltst / cloctst.c
CommitLineData
b75a7d8f
A
1/********************************************************************
2 * COPYRIGHT:
3 * Copyright (c) 1997-2003, International Business Machines Corporation and
4 * others. All Rights Reserved.
5 ********************************************************************/
6/********************************************************************************
7*
8* File CLOCTST.C
9*
10* Modification History:
11* Name Description
12* Madhu Katragadda Ported for C API
13*********************************************************************************
14*/
15#include <stdlib.h>
16#include <stdio.h>
17#include <string.h>
18#include "unicode/utypes.h"
19#include "unicode/putil.h"
20#include "cloctst.h"
21#include "unicode/uloc.h"
22#include "unicode/uscript.h"
23#include "unicode/uchar.h"
24#include "unicode/ustring.h"
25#include "unicode/uset.h"
26#include "cintltst.h"
27#include "cstring.h"
28#include "unicode/ures.h"
29
30#define LENGTHOF(array) (int32_t)(sizeof(array)/sizeof((array)[0]))
31
32#ifdef WIN32
33#include "locmap.h"
34#endif
35
36static void TestNullDefault(void);
37static void VerifyTranslation(void);
38void PrintDataTable();
39
40/*---------------------------------------------------
41 table of valid data
42 --------------------------------------------------- */
43#define LOCALE_SIZE 5
44#define LOCALE_INFO_SIZE 23
45
46static const char* rawData2[LOCALE_INFO_SIZE][LOCALE_SIZE] = {
47 /* language code */
48 { "en", "fr", "hr", "el", "no" },
49 /* country code */
50 { "US", "FR", "HR", "GR", "NO" },
51 /* variant code */
52 { "", "", "", "", "NY" },
53 /* full name */
54 { "en_US", "fr_FR", "hr_HR", "el_GR", "no_NO_NY" },
55 /* ISO-3 language */
56 { "eng", "fra", "hrv", "ell", "nor" },
57 /* ISO-3 country */
58 { "USA", "FRA", "HRV", "GRC", "NOR" },
59 /* LCID (not currently public) */
60 { "409", "40c", "41a", "408", "814" },
61
62 /* display language (English) */
63 { "English", "French", "Croatian", "Greek", "Norwegian" },
64 /* display country (English) */
65 { "United States", "France", "Croatia", "Greece", "Norway" },
66 /* display variant (English) */
67 { "", "", "", "", "Nynorsk" },
68 /* display name (English) */
69 { "English (United States)", "French (France)", "Croatian (Croatia)", "Greek (Greece)", "Norwegian (Norway, Nynorsk)" },
70
71 /* display language (French) */
72 { "anglais", "fran\\u00E7ais", "croate", "grec", "norv\\u00E9gien" },
73 /* display country (French) */
74 { "\\u00C9tats-Unis", "France", "Croatie", "Gr\\u00E8ce", "Norv\\u00E8ge" },
75 /* display variant (French) */
76 { "", "", "", "", "Nynorsk" },
77 /* display name (French) */
78 { "anglais (\\u00C9tats-Unis)", "fran\\u00E7ais (France)", "croate (Croatie)", "grec (Gr\\u00E8ce)", "norv\\u00E9gien (Norv\\u00E8ge, Nynorsk)" },
79
80 /* display language (Croatian) */
81 { "", "", "hrvatski", "", "" },
82 /* display country (Croatian) */
83 { "", "", "Hrvatska", "", "" },
84 /* display variant (Croatian) */
85 { "", "", "", "", "Nynorsk" },
86 /* display name (Croatian) */
87 { "", "", "hrvatski (Hrvatska)", "", "" },
88
89 /* display language (Greek) */
90 {
91 "\\u0391\\u03b3\\u03b3\\u03bb\\u03b9\\u03ba\\u03ac",
92 "\\u0393\\u03b1\\u03bb\\u03bb\\u03b9\\u03ba\\u03ac",
93 "\\u039a\\u03c1\\u03bf\\u03b1\\u03c4\\u03b9\\u03ba\\u03ac",
94 "\\u03b5\\u03bb\\u03bb\\u03b7\\u03bd\\u03b9\\u03ba\\u03ac",
95 "\\u039d\\u03bf\\u03c1\\u03b2\\u03b7\\u03b3\\u03b9\\u03ba\\u03ac"
96 },
97 /* display country (Greek) */
98 {
99 "\\u0397\\u03bd\\u03c9\\u03bc\\u03ad\\u03bd\\u03b5\\u03c2 \\u03a0\\u03bf\\u03bb\\u03b9\\u03c4\\u03b5\\u03af\\u03b5\\u03c2 \\u0391\\u03bc\\u03b5\\u03c1\\u03b9\\u03ba\\u03ae\\u03c2",
100 "\\u0393\\u03b1\\u03bb\\u03bb\\u03af\\u03b1",
101 "\\u039a\\u03c1\\u03bf\\u03b1\\u03c4\\u03af\\u03b1",
102 "\\u0395\\u03bb\\u03bb\\u03ac\\u03b4\\u03b1",
103 "\\u039d\\u03bf\\u03c1\\u03b2\\u03b7\\u03b3\\u03af\\u03b1"
104 },
105 /* display variant (Greek) */
106 { "", "", "", "", "Nynorsk" },
107 /* display name (Greek) */
108 {
109 "\\u0391\\u03b3\\u03b3\\u03bb\\u03b9\\u03ba\\u03ac (\\u0397\\u03bd\\u03c9\\u03bc\\u03ad\\u03bd\\u03b5\\u03c2 \\u03a0\\u03bf\\u03bb\\u03b9\\u03c4\\u03b5\\u03af\\u03b5\\u03c2 \\u0391\\u03bc\\u03b5\\u03c1\\u03b9\\u03ba\\u03ae\\u03c2)",
110 "\\u0393\\u03b1\\u03bb\\u03bb\\u03b9\\u03ba\\u03ac (\\u0393\\u03b1\\u03bb\\u03bb\\u03af\\u03b1)",
111 "\\u039a\\u03c1\\u03bf\\u03b1\\u03c4\\u03b9\\u03ba\\u03ac (\\u039a\\u03c1\\u03bf\\u03b1\\u03c4\\u03af\\u03b1)",
112 "\\u03b5\\u03bb\\u03bb\\u03b7\\u03bd\\u03b9\\u03ba\\u03ac (\\u0395\\u03bb\\u03bb\\u03ac\\u03b4\\u03b1)",
113 "\\u039d\\u03bf\\u03c1\\u03b2\\u03b7\\u03b3\\u03b9\\u03ba\\u03ac (\\u039d\\u03bf\\u03c1\\u03b2\\u03b7\\u03b3\\u03af\\u03b1, Nynorsk)"
114 }
115};
116
117static UChar*** dataTable=0;
118enum {
119 ENGLISH = 0,
120 FRENCH = 1,
121 CROATIAN = 2,
122 GREEK = 3,
123 NORWEGIAN = 4
124};
125
126enum {
127 LANG = 0,
128 CTRY = 1,
129 VAR = 2,
130 NAME = 3,
131 LANG3 = 4,
132 CTRY3 = 5,
133 LCID = 6,
134 DLANG_EN = 7,
135 DCTRY_EN = 8,
136 DVAR_EN = 9,
137 DNAME_EN = 10,
138 DLANG_FR = 11,
139 DCTRY_FR = 12,
140 DVAR_FR = 13,
141 DNAME_FR = 14,
142 DLANG_HR = 15,
143 DCTRY_HR = 16,
144 DVAR_HR = 17,
145 DNAME_HR = 18,
146 DLANG_EL = 19,
147 DCTRY_EL = 20,
148 DVAR_EL = 21,
149 DNAME_EL = 22
150};
151
152void addLocaleTest(TestNode** root);
153
154void addLocaleTest(TestNode** root)
155{
156 addTest(root, &TestObsoleteNames, "tsutil/cloctst/TestObsoleteNames"); /* srl- move */
157 addTest(root, &TestBasicGetters, "tsutil/cloctst/TestBasicGetters");
158 addTest(root, &TestNullDefault, "tsutil/cloctst/TestNullDefault");
159 addTest(root, &TestPrefixes, "tsutil/cloctst/TestPrefixes");
160 addTest(root, &TestSimpleResourceInfo, "tsutil/cloctst/TestSimpleResourceInfo");
161 addTest(root, &TestDisplayNames, "tsutil/cloctst/TestDisplayNames");
162 addTest(root, &TestGetAvailableLocales, "tsutil/cloctst/TestGetAvailableLocales");
163 addTest(root, &TestDataDirectory, "tsutil/cloctst/TestDataDirectory");
164 addTest(root, &TestISOFunctions, "tsutil/cloctst/TestISOFunctions");
165 addTest(root, &TestISO3Fallback, "tsutil/cloctst/TestISO3Fallback");
166 addTest(root, &TestUninstalledISO3Names, "tsutil/cloctst/TestUninstalledISO3Names");
167 addTest(root, &TestSimpleDisplayNames, "tsutil/cloctst/TestSimpleDisplayNames");
168 addTest(root, &TestVariantParsing, "tsutil/cloctst/TestVariantParsing");
169 addTest(root, &TestLocaleStructure, "tsutil/cloctst/TestLocaleStructure");
170 addTest(root, &TestConsistentCountryInfo,"tsutil/cloctst/TestConsistentCountryInfo");
171 addTest(root, &VerifyTranslation, "tsutil/cloctst/VerifyTranslation");
172}
173
174
175/* testing uloc(), uloc_getName(), uloc_getLanguage(), uloc_getVariant(), uloc_getCountry() */
176static void TestBasicGetters() {
177 int32_t i;
178 int32_t cap;
179 UErrorCode status = U_ZERO_ERROR;
180 char *testLocale = 0;
181 char *temp = 0, *name = 0;
182 log_verbose("Testing Basic Getters\n");
183 for (i = 0; i < LOCALE_SIZE; i++) {
184 testLocale=(char*)malloc(sizeof(char) * (strlen(rawData2[NAME][i])+1));
185 strcpy(testLocale,rawData2[NAME][i]);
186
187 log_verbose("Testing %s .....\n", testLocale);
188 cap=uloc_getLanguage(testLocale, NULL, 0, &status);
189 if(status==U_BUFFER_OVERFLOW_ERROR){
190 status=U_ZERO_ERROR;
191 temp=(char*)malloc(sizeof(char) * (cap+1));
192 uloc_getLanguage(testLocale, temp, cap+1, &status);
193 }
194 if(U_FAILURE(status)){
195 log_err("ERROR: in uloc_getLanguage %s\n", myErrorName(status));
196 }
197 if (0 !=strcmp(temp,rawData2[LANG][i])) {
198 log_err(" Language code mismatch: %s versus %s\n", temp, rawData2[LANG][i]);
199 }
200
201
202 cap=uloc_getCountry(testLocale, temp, cap, &status);
203 if(status==U_BUFFER_OVERFLOW_ERROR){
204 status=U_ZERO_ERROR;
205 temp=(char*)realloc(temp, sizeof(char) * (cap+1));
206 uloc_getCountry(testLocale, temp, cap+1, &status);
207 }
208 if(U_FAILURE(status)){
209 log_err("ERROR: in uloc_getCountry %s\n", myErrorName(status));
210 }
211 if (0 != strcmp(temp, rawData2[CTRY][i])) {
212 log_err(" Country code mismatch: %s versus %s\n", temp, rawData2[CTRY][i]);
213
214 }
215
216 cap=uloc_getVariant(testLocale, temp, cap, &status);
217 if(status==U_BUFFER_OVERFLOW_ERROR){
218 status=U_ZERO_ERROR;
219 temp=(char*)realloc(temp, sizeof(char) * (cap+1));
220 uloc_getVariant(testLocale, temp, cap+1, &status);
221 }
222 if(U_FAILURE(status)){
223 log_err("ERROR: in uloc_getVariant %s\n", myErrorName(status));
224 }
225 if (0 != strcmp(temp, rawData2[VAR][i])) {
226 log_err("Variant code mismatch: %s versus %s\n", temp, rawData2[VAR][i]);
227 }
228
229 cap=uloc_getName(testLocale, NULL, 0, &status);
230 if(status==U_BUFFER_OVERFLOW_ERROR){
231 status=U_ZERO_ERROR;
232 name=(char*)malloc(sizeof(char) * (cap+1));
233 uloc_getName(testLocale, name, cap+1, &status);
234 } else if(status==U_ZERO_ERROR) {
235 log_err("ERROR: in uloc_getName(%s,NULL,0,..), expected U_BUFFER_OVERFLOW_ERROR!\n", testLocale);
236 }
237 if(U_FAILURE(status)){
238 log_err("ERROR: in uloc_getName %s\n", myErrorName(status));
239 }
240 if (0 != strcmp(name, rawData2[NAME][i])){
241 log_err(" Mismatch in getName: %s versus %s\n", name, rawData2[NAME][i]);
242 }
243
244
245 free(temp);
246 free(name);
247
248 free(testLocale);
249 }
250}
251
252static void TestNullDefault() {
253 UErrorCode status = U_ZERO_ERROR;
254 char original[ULOC_FULLNAME_CAPACITY];
255
256 uprv_strcpy(original, uloc_getDefault());
257 uloc_setDefault("qq_BLA", &status);
258 if (uprv_strcmp(uloc_getDefault(), "qq_BLA") != 0) {
259 log_err(" Mismatch in uloc_setDefault: qq_BLA versus %s\n", uloc_getDefault());
260 }
261 uloc_setDefault(NULL, &status);
262 if (uprv_strcmp(uloc_getDefault(), original) != 0) {
263 log_err(" uloc_setDefault(NULL, &status) didn't get the default locale back!\n");
264 }
265}
266/* Test the i- and x- and @ and . functionality
267*/
268
269#define PREFIXBUFSIZ 128
270
271static void TestPrefixes() {
272 int row = 0;
273 int n;
274 const char *loc;
275
276 const char *testData[][5] =
277 {
278 {"sv", "FI", "AL", "sv-fi-al", "sv_FI_AL" },
279 {"en", "GB", "", "en-gb", "en_GB" },
280 {"i-hakka", "MT", "XEMXIJA", "i-hakka_MT_XEMXIJA", "i-hakka_MT_XEMXIJA"},
281 {"i-hakka", "CN", "", "i-hakka_CN", "i-hakka_CN"},
282 {"i-hakka", "MX", "", "I-hakka_MX", "i-hakka_MX"},
283 {"x-klingon", "US", "SANJOSE", "X-KLINGON_us_SANJOSE", "x-klingon_US_SANJOSE"},
284
285 {"mr", "", "", "mr.utf8", "mr"},
286 {"de", "TV", "", "de-tv.koi8r", "de_TV"},
287 {"x-piglatin", "ML", "", "x-piglatin_ML.MBE", "x-piglatin_ML"}, /* Multibyte English */
288 {"i-cherokee","US", "", "i-Cherokee_US.utf7", "i-cherokee_US"},
289 {"x-filfli", "MT", "FILFLA", "x-filfli_MT_FILFLA.gb-18030", "x-filfli_MT_FILFLA"},
290 {"no", "NO", "NY", "no-no-ny.utf32@B", "no_NO_NY"}, /* @ ignored unless variant is empty */
291 {"no", "NO", "B", "no-no.utf32@B", "no_NO_B" },
292 {"no", "", "NY", "no__ny", "no__NY" },
293 {"no", "", "NY", "no@ny", "no__NY" },
294
295 { "","","","",""}
296 };
297
298 const char *testTitles[] = { "uloc_getLanguage()", "uloc_getCountry()", "uloc_getVariant()", "name", "uloc_getName()", "country3", "lcid" };
299
300 char buf[PREFIXBUFSIZ];
301 int32_t len;
302 UErrorCode err;
303
304
305 for(row=0;testData[row][0][0] != 0;row++) {
306 loc = testData[row][NAME];
307 log_verbose("Test #%d: %s\n", row, loc);
308
309 err = U_ZERO_ERROR;
310 len=0;
311 buf[0]=0;
312 for(n=0;n<=(NAME+1);n++) {
313 if(n==NAME) continue;
314
315 for(len=0;len<PREFIXBUFSIZ;len++) {
316 buf[len] = '%'; /* Set a tripwire.. */
317 }
318 len = 0;
319
320 switch(n) {
321 case LANG:
322 len = uloc_getLanguage(loc, buf, PREFIXBUFSIZ, &err);
323 break;
324
325 case CTRY:
326 len = uloc_getCountry(loc, buf, PREFIXBUFSIZ, &err);
327 break;
328
329 case VAR:
330 len = uloc_getVariant(loc, buf, PREFIXBUFSIZ, &err);
331 break;
332
333 case NAME+1:
334 len = uloc_getName(loc, buf, PREFIXBUFSIZ, &err);
335 break;
336
337 default:
338 strcpy(buf, "**??");
339 len=4;
340 }
341
342 if(U_FAILURE(err)) {
343 log_err("#%d: %s on %s: err %s\n",
344 row, testTitles[n], loc, u_errorName(err));
345 } else {
346 log_verbose("#%d: %s on %s: -> [%s] (length %d)\n",
347 row, testTitles[n], loc, buf, len);
348
349 if(len != (int32_t)strlen(buf)) {
350 log_err("#%d: %s on %s: -> [%s] (length returned %d, actual %d!)\n",
351 row, testTitles[n], loc, buf, len, strlen(buf)+1);
352
353 }
354
355 /* see if they smashed something */
356 if(buf[len+1] != '%') {
357 log_err("#%d: %s on %s: -> [%s] - wrote [%X] out ofbounds!\n",
358 row, testTitles[n], loc, buf, buf[len+1]);
359 }
360
361 if(strcmp(buf, testData[row][n])) {
362 log_err("#%d: %s on %s: -> [%s] (expected '%s'!)\n",
363 row, testTitles[n], loc, buf, testData[row][n]);
364
365 }
366 }
367 }
368 }
369}
370
371
372/* testing uloc_getISO3Language(), uloc_getISO3Country(), */
373static void TestSimpleResourceInfo() {
374 int32_t i;
375 char* testLocale = 0;
376 UChar* expected = 0;
377
378 const char* temp;
379 char temp2[20];
380 testLocale=(char*)malloc(sizeof(char) * 1);
381 expected=(UChar*)malloc(sizeof(UChar) * 1);
382
383setUpDataTable();
384 log_verbose("Testing getISO3Language and getISO3Country\n");
385 for (i = 0; i < LOCALE_SIZE; i++) {
386
387 testLocale=(char*)realloc(testLocale, sizeof(char) * (u_strlen(dataTable[NAME][i])+1));
388 u_austrcpy(testLocale, dataTable[NAME][i]);
389
390 log_verbose("Testing %s ......\n", testLocale);
391
392 temp=uloc_getISO3Language(testLocale);
393 expected=(UChar*)realloc(expected, sizeof(UChar) * (strlen(temp) + 1));
394 u_uastrcpy(expected,temp);
395 if (0 != u_strcmp(expected, dataTable[LANG3][i])) {
396 log_err(" ISO-3 language code mismatch: %s versus %s\n", austrdup(expected),
397 austrdup(dataTable[LANG3][i]));
398 }
399
400 temp=uloc_getISO3Country(testLocale);
401 expected=(UChar*)realloc(expected, sizeof(UChar) * (strlen(temp) + 1));
402 u_uastrcpy(expected,temp);
403 if (0 != u_strcmp(expected, dataTable[CTRY3][i])) {
404 log_err(" ISO-3 Country code mismatch: %s versus %s\n", austrdup(expected),
405 austrdup(dataTable[CTRY3][i]));
406 }
407 sprintf(temp2, "%x", uloc_getLCID(testLocale));
408 if (strcmp(temp2, rawData2[LCID][i]) != 0) {
409 log_err("LCID mismatch: %s versus %s\n", temp2 , rawData2[LCID][i]);
410 }
411
412 }
413
414 free(expected);
415 free(testLocale);
416cleanUpDataTable();
417}
418
419/*
420 * Jitterbug 2439 -- markus 20030425
421 *
422 * The lookup of display names must not fall back through the default
423 * locale because that yields useless results.
424 */
425static void TestDisplayNames()
426{
427 UChar buffer[100];
428 UErrorCode errorCode;
429 int32_t length;
430
431 log_verbose("Testing getDisplayName for different locales\n");
432
433 log_verbose(" In locale = en_US...\n");
434 doTestDisplayNames("en_US", DLANG_EN);
435 log_verbose(" In locale = fr_FR....\n");
436 doTestDisplayNames("fr_FR", DLANG_FR);
437 log_verbose(" In locale = hr_HR...\n");
438 doTestDisplayNames("hr_HR", DLANG_HR);
439 log_verbose(" In locale = gr_EL..\n");
440 doTestDisplayNames("el_GR", DLANG_EL);
441
442 /* test that the default locale has a display name for its own language */
443 errorCode=U_ZERO_ERROR;
444 length=uloc_getDisplayLanguage(NULL, NULL, buffer, LENGTHOF(buffer), &errorCode);
445 if(U_FAILURE(errorCode) || (length<=3 && buffer[0]<=0x7f)) {
446 /* check <=3 to reject getting the language code as a display name */
447 log_err("unable to get a display string for the language of the default locale - %s\n", u_errorName(errorCode));
448 }
449
450 /* test that we get the language code itself for an unknown language, and a default warning */
451 errorCode=U_ZERO_ERROR;
452 length=uloc_getDisplayLanguage("qq", "rr", buffer, LENGTHOF(buffer), &errorCode);
453 if(errorCode!=U_USING_DEFAULT_WARNING || length!=2 || buffer[0]!=0x71 || buffer[1]!=0x71) {
454 log_err("error getting the display string for an unknown language - %s\n", u_errorName(errorCode));
455 }
456}
457
458
459/* test for uloc_getAvialable() and uloc_countAvilable()*/
460static void TestGetAvailableLocales()
461{
462
463 const char *locList;
464 int32_t locCount,i;
465
466 log_verbose("Testing the no of avialable locales\n");
467 locCount=uloc_countAvailable();
468 if (locCount == 0)
469 log_data_err("countAvailable() returned an empty list!\n");
470
471 /* use something sensible w/o hardcoding the count */
472 else if(locCount < 0){
473 log_data_err("countAvailable() returned a wrong value!= %d\n", locCount);
474 }
475 else{
476 log_info("Number of locales returned = %d\n", locCount);
477 }
478 for(i=0;i<locCount;i++){
479 locList=uloc_getAvailable(i);
480
481 log_verbose(" %s\n", locList);
482 }
483}
484
485/* test for u_getDataDirectory, u_setDataDirectory, uloc_getISO3Language */
486static void TestDataDirectory()
487{
488
489 char oldDirectory[512];
490 const char *temp,*testValue1,*testValue2,*testValue3;
491 const char path[40] ="d:\\icu\\source\\test\\intltest" U_FILE_SEP_STRING; /*give the required path */
492
493 log_verbose("Testing getDataDirectory()\n");
494 temp = u_getDataDirectory();
495 strcpy(oldDirectory, temp);
496
497 testValue1=uloc_getISO3Language("en_US");
498 log_verbose("first fetch of language retrieved %s\n", testValue1);
499
500 if (0 != strcmp(testValue1,"eng")){
501 log_err("Initial check of ISO3 language failed: expected \"eng\", got %s \n", testValue1);
502 }
503
504 /*defining the path for DataDirectory */
505 log_verbose("Testing setDataDirectory\n");
506 u_setDataDirectory( path );
507 if(strcmp(path, u_getDataDirectory())==0)
508 log_verbose("setDataDirectory working fine\n");
509 else
510 log_err("Error in setDataDirectory. Directory not set correctly - came back as [%s], expected [%s]\n", u_getDataDirectory(), path);
511
512 testValue2=uloc_getISO3Language("en_US");
513 log_verbose("second fetch of language retrieved %s \n", testValue2);
514
515 u_setDataDirectory(oldDirectory);
516 testValue3=uloc_getISO3Language("en_US");
517 log_verbose("third fetch of language retrieved %s \n", testValue3);
518
519 if (0 != strcmp(testValue3,"eng")) {
520 log_err("get/setDataDirectory() failed: expected \"eng\", got \" %s \" \n", testValue3);
521 }
522}
523
524
525
526/*=========================================================== */
527
528static UChar _NUL=0;
529
530static void doTestDisplayNames(const char* displayLocale, int32_t compareIndex)
531{
532 UErrorCode status = U_ZERO_ERROR;
533 int32_t i;
534 int32_t maxresultsize;
535
536 const char *testLocale;
537
538
539 UChar *testLang = 0;
540 UChar *testCtry = 0;
541 UChar *testVar = 0;
542 UChar *testName = 0;
543
544
545 UChar* expectedLang = 0;
546 UChar* expectedCtry = 0;
547 UChar* expectedVar = 0;
548 UChar* expectedName = 0;
549
550setUpDataTable();
551
552 for(i=0;i<LOCALE_SIZE; ++i)
553 {
554 testLocale=rawData2[NAME][i];
555
556 log_verbose("Testing..... %s\n", testLocale);
557
558 maxresultsize=0;
559 maxresultsize=uloc_getDisplayLanguage(testLocale, displayLocale, NULL, maxresultsize, &status);
560 if(status==U_BUFFER_OVERFLOW_ERROR)
561 {
562 status=U_ZERO_ERROR;
563 testLang=(UChar*)malloc(sizeof(UChar) * (maxresultsize+1));
564 uloc_getDisplayLanguage(testLocale, displayLocale, testLang, maxresultsize + 1, &status);
565 }
566 else
567 {
568 testLang=&_NUL;
569 }
570 if(U_FAILURE(status)){
571 log_err("Error in getDisplayLanguage() %s\n", myErrorName(status));
572 }
573
574 maxresultsize=0;
575 maxresultsize=uloc_getDisplayCountry(testLocale, displayLocale, NULL, maxresultsize, &status);
576 if(status==U_BUFFER_OVERFLOW_ERROR)
577 {
578 status=U_ZERO_ERROR;
579 testCtry=(UChar*)malloc(sizeof(UChar) * (maxresultsize+1));
580 uloc_getDisplayCountry(testLocale, displayLocale, testCtry, maxresultsize + 1, &status);
581 }
582 else
583 {
584 testCtry=&_NUL;
585 }
586 if(U_FAILURE(status)){
587 log_err("Error in getDisplayCountry() %s\n", myErrorName(status));
588 }
589
590 maxresultsize=0;
591 maxresultsize=uloc_getDisplayVariant(testLocale, displayLocale, NULL, maxresultsize, &status);
592 if(status==U_BUFFER_OVERFLOW_ERROR)
593 {
594 status=U_ZERO_ERROR;
595 testVar=(UChar*)malloc(sizeof(UChar) * (maxresultsize+1));
596 uloc_getDisplayVariant(testLocale, displayLocale, testVar, maxresultsize + 1, &status);
597 }
598 else
599 {
600 testVar=&_NUL;
601 }
602 if(U_FAILURE(status)){
603 log_err("Error in getDisplayVariant() %s\n", myErrorName(status));
604 }
605
606 maxresultsize=0;
607 maxresultsize=uloc_getDisplayName(testLocale, displayLocale, NULL, maxresultsize, &status);
608 if(status==U_BUFFER_OVERFLOW_ERROR)
609 {
610 status=U_ZERO_ERROR;
611 testName=(UChar*)malloc(sizeof(UChar) * (maxresultsize+1));
612 uloc_getDisplayName(testLocale, displayLocale, testName, maxresultsize + 1, &status);
613 }
614 else
615 {
616 testName=&_NUL;
617 }
618 if(U_FAILURE(status)){
619 log_err("Error in getDisplayName() %s\n", myErrorName(status));
620 }
621
622 expectedLang=dataTable[compareIndex][i];
623 if(u_strlen(expectedLang)== 0)
624 expectedLang=dataTable[DLANG_EN][i];
625
626 expectedCtry=dataTable[compareIndex + 1][i];
627 if(u_strlen(expectedCtry)== 0)
628 expectedCtry=dataTable[DCTRY_EN][i];
629
630 expectedVar=dataTable[compareIndex + 2][i];
631 if(u_strlen(expectedCtry)== 0)
632 expectedVar=dataTable[DVAR_EN][i];
633
634 expectedName=dataTable[compareIndex + 3][i];
635 if(u_strlen(expectedName) == 0)
636 expectedName=dataTable[DNAME_EN][i];
637
638 if (0 !=u_strcmp(testLang,expectedLang)) {
639 log_data_err(" Display Language mismatch: got %s expected %s displayLocale=%s\n", austrdup(testLang), austrdup(expectedLang), displayLocale);
640 }
641
642 if (0 != u_strcmp(testCtry,expectedCtry)) {
643 log_data_err(" Display Country mismatch: got %s expected %s displayLocale=%s\n", austrdup(testCtry), austrdup(expectedCtry), displayLocale);
644 }
645
646 if (0 != u_strcmp(testVar,expectedVar)) {
647 log_data_err(" Display Variant mismatch: got %s expected %s displayLocale=%s\n", austrdup(testVar), austrdup(expectedVar), displayLocale);
648 }
649
650 if(0 != u_strcmp(testName, expectedName)) {
651 log_data_err(" Display Name mismatch: got %s expected %s displayLocale=%s\n", austrdup(testName), austrdup(expectedName), displayLocale);
652 }
653
654 if(testName!=&_NUL) {
655 free(testName);
656 }
657 if(testLang!=&_NUL) {
658 free(testLang);
659 }
660 if(testCtry!=&_NUL) {
661 free(testCtry);
662 }
663 if(testVar!=&_NUL) {
664 free(testVar);
665 }
666 }
667cleanUpDataTable();
668}
669
670/* test for uloc_getISOLanguages, uloc_getISOCountries */
671static void TestISOFunctions()
672{
673 const char* const* str=uloc_getISOLanguages();
674 const char* const* str1=uloc_getISOCountries();
675 const char* test;
676 int32_t count = 0;
677 UBool done = FALSE;
678 int32_t expect;
679
680 /* test getISOLanguages*/
681 /*str=uloc_getISOLanguages(); */
682 log_verbose("Testing ISO Languages: \n");
683
684 while(!done)
685 {
686 if(*(str+count++) == 0)
687 {
688 done = TRUE;
689 }
690 else
691 {
692 test = *(str+count-1);
693 if(!strcmp(test,"in"))
694 log_err("FAIL getISOLanguages() has obsolete language code %s\n", test);
695 if(!strcmp(test,"iw"))
696 log_err("FAIL getISOLanguages() has obsolete language code %s\n", test);
697 if(!strcmp(test,"ji"))
698 log_err("FAIL getISOLanguages() has obsolete language code %s\n", test);
699 if(!strcmp(test,"jw"))
700 log_err("FAIL getISOLanguages() has obsolete language code %s\n", test);
701 if(!strcmp(test,"sh"))
702 log_err("FAIL getISOLanguages() has obsolete language code %s\n", test);
703 }
704 }
705 count--;
706 expect = 450;
707
708 if(count!=expect) {
709 log_err("There is an error in getISOLanguages, got %d, expected %d\n", count, expect);
710 }
711
712 log_verbose("Testing ISO Countries");
713 count=0;
714 done=FALSE;
715 while(!done)
716 {
717 if(*(str1 + count++)==0)
718 {
719 done=TRUE;
720 }
721 else
722 {
723 test = *(str1+count-1);
724 if(!strcmp(test,"FX"))
725 log_err("FAIL getISOCountries() has obsolete country code %s\n", test);
726 if(!strcmp(test,"ZR"))
727 log_err("FAIL getISOCountries() has obsolete country code %s\n", test);
728 }
729 }
730 count--;
731 expect=239;
732 if(count!=expect)
733 {
734 log_err("There is an error in getISOCountries, got %d, expected %d \n", count, expect);
735 }
736}
737
738static void setUpDataTable()
739{
740 int32_t i,j;
741 dataTable = (UChar***)(calloc(sizeof(UChar**),LOCALE_INFO_SIZE));
742
743 for (i = 0; i < 23; i++) {
744 dataTable[i] = (UChar**)(calloc(sizeof(UChar*),LOCALE_SIZE));
745 for (j = 0; j < 5; j++){
746 dataTable[i][j] = CharsToUChars(rawData2[i][j]);
747 }
748 }
749}
750
751static void cleanUpDataTable()
752{
753 int32_t i,j;
754 if(dataTable != NULL) {
755 for (i=0; i<LOCALE_INFO_SIZE; i++) {
756 for(j = 0; j < LOCALE_SIZE; j++) {
757 free(dataTable[i][j]);
758 }
759 free(dataTable[i]);
760 }
761 free(dataTable);
762 }
763 dataTable = NULL;
764}
765
766/**
767 * @bug 4011756 4011380
768 */
769static void TestISO3Fallback()
770{
771 const char* test="xx_YY";
772
773 const char * result;
774
775 result = uloc_getISO3Language(test);
776
777 /* Conform to C API usage */
778
779 if (!result || (result[0] != 0))
780 log_err("getISO3Language() on xx_YY returned %s instead of \"\"");
781
782 result = uloc_getISO3Country(test);
783
784 if (!result || (result[0] != 0))
785 log_err("getISO3Country() on xx_YY returned %s instead of \"\"");
786}
787
788/**
789 * @bug 4118587
790 */
791static void TestSimpleDisplayNames()
792{
793 /*
794 This test is different from TestDisplayNames because TestDisplayNames checks
795 fallback behavior, combination of language and country names to form locale
796 names, and other stuff like that. This test just checks specific language
797 and country codes to make sure we have the correct names for them.
798 */
799 char languageCodes[] [4] = { "he", "id", "iu", "ug", "yi", "za" };
800 const char* languageNames [] = { "Hebrew", "Indonesian", "Inukitut", "Uighur", "Yiddish",
801 "Zhuang" };
802 UErrorCode status=U_ZERO_ERROR;
803
804 int32_t i;
805 for (i = 0; i < 6; i++) {
806 UChar *testLang=0;
807 UChar *expectedLang=0;
808 int size=0;
809 size=uloc_getDisplayLanguage(languageCodes[i], "en_US", NULL, size, &status);
810 if(status==U_BUFFER_OVERFLOW_ERROR) {
811 status=U_ZERO_ERROR;
812 testLang=(UChar*)malloc(sizeof(UChar) * (size + 1));
813 uloc_getDisplayLanguage(languageCodes[i], "en_US", testLang, size + 1, &status);
814 }
815 expectedLang=(UChar*)malloc(sizeof(UChar) * (strlen(languageNames[i])+1));
816 u_uastrcpy(expectedLang, languageNames[i]);
817 if (u_strcmp(testLang, expectedLang) != 0)
818 log_data_err("Got wrong display name for %s : Expected \"%s\", got \"%s\".\n",
819 languageCodes[i], languageNames[i], austrdup(testLang));
820 free(testLang);
821 free(expectedLang);
822 }
823
824}
825
826/**
827 * @bug 4118595
828 */
829static void TestUninstalledISO3Names()
830{
831 /* This test checks to make sure getISO3Language and getISO3Country work right
832 even for locales that are not installed. */
833 const char iso2Languages [][4] = { "am", "ba", "fy", "mr", "rn",
834 "ss", "tw", "zu" };
835 const char iso3Languages [][5] = { "amh", "bak", "fry", "mar", "run",
836 "ssw", "twi", "zul" };
837 char iso2Countries [][6] = { "am_AF", "ba_BW", "fy_KZ", "mr_MO", "rn_MN",
838 "ss_SB", "tw_TC", "zu_ZW" };
839 char iso3Countries [][4] = { "AFG", "BWA", "KAZ", "MAC", "MNG",
840 "SLB", "TCA", "ZWE" };
841 int32_t i;
842
843 for (i = 0; i < 8; i++) {
844 UErrorCode err = U_ZERO_ERROR;
845 const char *test;
846 test = uloc_getISO3Language(iso2Languages[i]);
847 if(strcmp(test, iso3Languages[i]) !=0 || U_FAILURE(err))
848 log_err("Got wrong ISO3 code for %s : Expected \"%s\", got \"%s\". %s\n",
849 iso2Languages[i], iso3Languages[i], test, myErrorName(err));
850 }
851 for (i = 0; i < 8; i++) {
852 UErrorCode err = U_ZERO_ERROR;
853 const char *test;
854 test = uloc_getISO3Country(iso2Countries[i]);
855 if(strcmp(test, iso3Countries[i]) !=0 || U_FAILURE(err))
856 log_err("Got wrong ISO3 code for %s : Expected \"%s\", got \"%s\". %s\n",
857 iso2Countries[i], iso3Countries[i], test, myErrorName(err));
858 }
859}
860
861
862static void TestVariantParsing()
863{
864 const char* en_US_custom="en_US_De Anza_Cupertino_California_United States_Earth";
865 const char* dispName="English (United States, DE ANZA_CUPERTINO_CALIFORNIA_UNITED STATES_EARTH)";
866 const char* dispVar="DE ANZA_CUPERTINO_CALIFORNIA_UNITED STATES_EARTH";
867 const char* shortVariant="fr_FR_foo";
868 const char* bogusVariant="fr_FR__foo";
869 const char* bogusVariant2="fr_FR_foo_";
870 const char* bogusVariant3="fr_FR__foo_";
871
872
873 UChar displayVar[100];
874 UChar displayName[100];
875 UErrorCode status=U_ZERO_ERROR;
876 UChar* got=0;
877 int32_t size=0;
878 size=uloc_getDisplayVariant(en_US_custom, "en_US", NULL, size, &status);
879 if(status==U_BUFFER_OVERFLOW_ERROR) {
880 status=U_ZERO_ERROR;
881 got=(UChar*)realloc(got, sizeof(UChar) * (size+1));
882 uloc_getDisplayVariant(en_US_custom, "en_US", got, size + 1, &status);
883 }
884 else {
885 log_err("FAIL: Didn't get U_BUFFER_OVERFLOW_ERROR\n");
886 }
887 u_uastrcpy(displayVar, dispVar);
888 if(u_strcmp(got,displayVar)!=0) {
889 log_err("FAIL: getDisplayVariant() Wanted %s, got %s\n", dispVar, austrdup(got));
890 }
891 size=0;
892 size=uloc_getDisplayName(en_US_custom, "en_US", NULL, size, &status);
893 if(status==U_BUFFER_OVERFLOW_ERROR) {
894 status=U_ZERO_ERROR;
895 got=(UChar*)realloc(got, sizeof(UChar) * (size+1));
896 uloc_getDisplayName(en_US_custom, "en_US", got, size + 1, &status);
897 }
898 else {
899 log_err("FAIL: Didn't get U_BUFFER_OVERFLOW_ERROR\n");
900 }
901 u_uastrcpy(displayName, dispName);
902 if(u_strcmp(got,displayName)!=0) {
903 log_err("FAIL: getDisplayName() Wanted %s, got %s\n", dispName, austrdup(got));
904 }
905
906 size=0;
907 status=U_ZERO_ERROR;
908 size=uloc_getDisplayVariant(shortVariant, NULL, NULL, size, &status);
909 if(status==U_BUFFER_OVERFLOW_ERROR) {
910 status=U_ZERO_ERROR;
911 got=(UChar*)realloc(got, sizeof(UChar) * (size+1));
912 uloc_getDisplayVariant(shortVariant, NULL, got, size + 1, &status);
913 }
914 else {
915 log_err("FAIL: Didn't get U_BUFFER_OVERFLOW_ERROR\n");
916 }
917 if(strcmp(austrdup(got),"FOO")!=0) {
918 log_err("FAIL: getDisplayVariant() Wanted: foo Got: %s\n", austrdup(got));
919 }
920 size=0;
921 status=U_ZERO_ERROR;
922 size=uloc_getDisplayVariant(bogusVariant, NULL, NULL, size, &status);
923 if(status==U_BUFFER_OVERFLOW_ERROR) {
924 status=U_ZERO_ERROR;
925 got=(UChar*)realloc(got, sizeof(UChar) * (size+1));
926 uloc_getDisplayVariant(bogusVariant, NULL, got, size + 1, &status);
927 }
928 else {
929 log_err("FAIL: Didn't get U_BUFFER_OVERFLOW_ERROR\n");
930 }
931 if(strcmp(austrdup(got),"_FOO")!=0) {
932 log_err("FAIL: getDisplayVariant() Wanted: _FOO Got: %s\n", austrdup(got));
933 }
934 size=0;
935 status=U_ZERO_ERROR;
936 size=uloc_getDisplayVariant(bogusVariant2, NULL, NULL, size, &status);
937 if(status==U_BUFFER_OVERFLOW_ERROR) {
938 status=U_ZERO_ERROR;
939 got=(UChar*)realloc(got, sizeof(UChar) * (size+1));
940 uloc_getDisplayVariant(bogusVariant2, NULL, got, size + 1, &status);
941 }
942 else {
943 log_err("FAIL: Didn't get U_BUFFER_OVERFLOW_ERROR\n");
944 }
945 if(strcmp(austrdup(got),"FOO_")!=0) {
946 log_err("FAIL: getDisplayVariant() Wanted: FOO_ Got: %s\n", austrdup(got));
947 }
948 size=0;
949 status=U_ZERO_ERROR;
950 size=uloc_getDisplayVariant(bogusVariant3, NULL, NULL, size, &status);
951 if(status==U_BUFFER_OVERFLOW_ERROR) {
952 status=U_ZERO_ERROR;
953 got=(UChar*)realloc(got, sizeof(UChar) * (size+1));
954 uloc_getDisplayVariant(bogusVariant3, NULL, got, size + 1, &status);
955 }
956 else {
957 log_err("FAIL: Didn't get U_BUFFER_OVERFLOW_ERROR\n");
958 }
959 if(strcmp(austrdup(got),"_FOO_")!=0) {
960 log_err("FAIL: getDisplayVariant() Wanted: _FOO_ Got: %s\n", austrdup(got));
961 }
962 free(got);
963}
964
965
966static void TestObsoleteNames(void)
967{
968 int32_t i;
969 UErrorCode status = U_ZERO_ERROR;
970 char buff[256];
971
972 struct
973 {
974 char locale[9];
975 char lang3[6];
976 char lang[6];
977 char ctry3[6];
978 char ctry[6];
979 } tests[] =
980 {
981 { "eng_USA", "eng", "en", "USA", "US" },
982 { "kok", "kok", "kok", "", "" },
983 { "in", "ind", "in", "", "" },
984 { "id", "ind", "id", "", "" }, /* NO aliasing */
985 { "sh", "srp", "sh", "", "" },
986 { "zz_FX", "", "zz", "FXX", "FX" },
987 { "zz_RO", "", "zz", "ROU", "RO" },
988 { "zz_TP", "", "zz", "TMP", "TP" },
989 { "zz_TL", "", "zz", "TLS", "TL" },
990 { "zz_ZR", "", "zz", "ZAR", "ZR" },
991 { "zz_FXX", "", "zz", "FXX", "FX" }, /* no aliasing. Doesn't go to PS(PSE). */
992 { "zz_ROM", "", "zz", "ROU", "RO" },
993 { "zz_ROU", "", "zz", "ROU", "RO" },
994 { "zz_ZAR", "", "zz", "ZAR", "ZR" },
995 { "zz_TMP", "", "zz", "TMP", "TP" },
996 { "zz_TLS", "", "zz", "TLS", "TL" },
997 { "mlt_PSE", "mlt", "mt", "PSE", "PS" },
998 { "iw", "heb", "iw", "", "" },
999 { "ji", "yid", "ji", "", "" },
1000 { "jw", "jaw", "jw", "", "" },
1001 { "sh", "srp", "sh", "", "" },
1002 { "", "", "", "", "" }
1003 };
1004
1005 for(i=0;tests[i].locale[0];i++)
1006 {
1007 const char *locale;
1008
1009 locale = tests[i].locale;
1010 log_verbose("** %s:\n", locale);
1011
1012 status = U_ZERO_ERROR;
1013 if(strcmp(tests[i].lang3,uloc_getISO3Language(locale)))
1014 {
1015 log_err("FAIL: uloc_getISO3Language(%s)==\t\"%s\",\t expected \"%s\"\n",
1016 locale, uloc_getISO3Language(locale), tests[i].lang3);
1017 }
1018 else
1019 {
1020 log_verbose(" uloc_getISO3Language()==\t\"%s\"\n",
1021 uloc_getISO3Language(locale) );
1022 }
1023
1024 status = U_ZERO_ERROR;
1025 uloc_getLanguage(locale, buff, 256, &status);
1026 if(U_FAILURE(status))
1027 {
1028 log_err("FAIL: error getting language from %s\n", locale);
1029 }
1030 else
1031 {
1032 if(strcmp(buff,tests[i].lang))
1033 {
1034 log_err("FAIL: uloc_getLanguage(%s)==\t\"%s\"\t expected \"%s\"\n",
1035 locale, buff, tests[i].lang);
1036 }
1037 else
1038 {
1039 log_verbose(" uloc_getLanguage(%s)==\t%s\n", locale, buff);
1040 }
1041 }
1042 if(strcmp(tests[i].lang3,uloc_getISO3Language(locale)))
1043 {
1044 log_err("FAIL: uloc_getISO3Language(%s)==\t\"%s\",\t expected \"%s\"\n",
1045 locale, uloc_getISO3Language(locale), tests[i].lang3);
1046 }
1047 else
1048 {
1049 log_verbose(" uloc_getISO3Language()==\t\"%s\"\n",
1050 uloc_getISO3Language(locale) );
1051 }
1052
1053 if(strcmp(tests[i].ctry3,uloc_getISO3Country(locale)))
1054 {
1055 log_err("FAIL: uloc_getISO3Country(%s)==\t\"%s\",\t expected \"%s\"\n",
1056 locale, uloc_getISO3Country(locale), tests[i].ctry3);
1057 }
1058 else
1059 {
1060 log_verbose(" uloc_getISO3Country()==\t\"%s\"\n",
1061 uloc_getISO3Country(locale) );
1062 }
1063
1064 status = U_ZERO_ERROR;
1065 uloc_getCountry(locale, buff, 256, &status);
1066 if(U_FAILURE(status))
1067 {
1068 log_err("FAIL: error getting country from %s\n", locale);
1069 }
1070 else
1071 {
1072 if(strcmp(buff,tests[i].ctry))
1073 {
1074 log_err("FAIL: uloc_getCountry(%s)==\t\"%s\"\t expected \"%s\"\n",
1075 locale, buff, tests[i].ctry);
1076 }
1077 else
1078 {
1079 log_verbose(" uloc_getCountry(%s)==\t%s\n", locale, buff);
1080 }
1081 }
1082 }
1083
1084#if 0
1085
1086 i = uloc_getLanguage("kok",NULL,0,&icu_err);
1087 if(U_FAILURE(icu_err))
1088 {
1089 log_err("FAIL: Got %s trying to do uloc_getLanguage(kok)\n", u_errorName(icu_err));
1090 }
1091
1092 icu_err = U_ZERO_ERROR;
1093 uloc_getLanguage("kok",r1_buff,12,&icu_err);
1094 if(U_FAILURE(icu_err))
1095 {
1096 log_err("FAIL: Got %s trying to do uloc_getLanguage(kok, buff)\n", u_errorName(icu_err));
1097 }
1098
1099 r1_addr = (char *)uloc_getISO3Language("kok");
1100
1101 icu_err = U_ZERO_ERROR;
1102 if (strcmp(r1_buff,"kok") != 0)
1103 {
1104 log_err("FAIL: uloc_getLanguage(kok)==%s not kok\n",r1_buff);
1105 line--;
1106 }
1107 r1_addr = (char *)uloc_getISO3Language("in");
1108 i = uloc_getLanguage(r1_addr,r1_buff,12,&icu_err);
1109 if (strcmp(r1_buff,"id") != 0)
1110 {
1111 printf("uloc_getLanguage error (%s)\n",r1_buff);
1112 line--;
1113 }
1114 r1_addr = (char *)uloc_getISO3Language("sh");
1115 i = uloc_getLanguage(r1_addr,r1_buff,12,&icu_err);
1116 if (strcmp(r1_buff,"sr") != 0)
1117 {
1118 printf("uloc_getLanguage error (%s)\n",r1_buff);
1119 line--;
1120 }
1121
1122 r1_addr = (char *)uloc_getISO3Country("zz_ZR");
1123 strcpy(p1_buff,"zz_");
1124 strcat(p1_buff,r1_addr);
1125 i = uloc_getCountry(p1_buff,r1_buff,12,&icu_err);
1126 if (strcmp(r1_buff,"ZR") != 0)
1127 {
1128 printf("uloc_getCountry error (%s)\n",r1_buff);
1129 line--;
1130 }
1131 r1_addr = (char *)uloc_getISO3Country("zz_FX");
1132 strcpy(p1_buff,"zz_");
1133 strcat(p1_buff,r1_addr);
1134 i = uloc_getCountry(p1_buff,r1_buff,12,&icu_err);
1135 if (strcmp(r1_buff,"FX") != 0)
1136 {
1137 printf("uloc_getCountry error (%s)\n",r1_buff);
1138 line--;
1139 }
1140
1141#endif
1142
1143}
1144
1145static void
1146TestKeyInRootRecursive(UResourceBundle *root, const char *rootName,
1147 UResourceBundle *currentBundle, const char *locale) {
1148 UErrorCode errorCode = U_ZERO_ERROR;
1149 UResourceBundle *subRootBundle = NULL, *subBundle = NULL;
1150
1151 ures_resetIterator(root);
1152 ures_resetIterator(currentBundle);
1153 while (ures_hasNext(currentBundle)) {
1154 const char *subBundleKey = NULL;
1155 const char *currentBundleKey = NULL;
1156
1157 errorCode = U_ZERO_ERROR;
1158 subBundle = ures_getNextResource(currentBundle, NULL, &errorCode);
1159 if (U_FAILURE(errorCode)) {
1160 log_err("Can't open a resource for locale %s\n", locale);
1161 continue;
1162 }
1163 subBundleKey = ures_getKey(subBundle);
1164 currentBundleKey = ures_getKey(currentBundle);
1165
1166 subRootBundle = ures_getByKey(root, subBundleKey, NULL, &errorCode);
1167 if (U_FAILURE(errorCode)) {
1168/* if (ures_hasNext(root)) {
1169 errorCode = U_ZERO_ERROR;
1170 subRootBundle = ures_getNextResource(root, NULL, &errorCode);
1171 }
1172 if (errorCode!=U_ZERO_ERROR) {
1173 if (ures_getKey(currentBundle) != 0 && strcmp(ures_getKey(currentBundle), "zoneStrings") == 0) {
1174 break;
1175 }
1176 else {*/
1177 if (subBundleKey == NULL
1178 || (strcmp(subBundleKey, "TransliterateLATIN") != 0 /* Ignore these special cases */
1179 && strcmp(subBundleKey, "BreakDictionaryData") != 0))
1180 {
1181 UBool isRoot = strcmp(rootName, "root") == 0;
1182 UBool isSpecial = FALSE;
1183 if (currentBundleKey) {
1184 isSpecial = strcmp(currentBundleKey, "Currencies") == 0
1185 || strcmp(currentBundleKey, "Languages") == 0
1186 || strcmp(currentBundleKey, "Countries") == 0;
1187 }
1188
1189 if ((isRoot && !isSpecial)
1190 || (!isRoot && isSpecial))
1191 {
1192 log_err("Can't open a resource with key \"%s\" in \"%s\" from %s for locale \"%s\"\n",
1193 subBundleKey,
1194 ures_getKey(currentBundle),
1195 rootName,
1196 locale);
1197 }
1198 }
1199 ures_close(subBundle);
1200 continue;
1201/* }
1202 }*/
1203 }
1204 if (ures_getType(subRootBundle) != ures_getType(subBundle)) {
1205 log_err("key \"%s\" in \"%s\" has a different type from root for locale \"%s\"\n"
1206 "\troot=%d, locale=%d\n",
1207 subBundleKey,
1208 ures_getKey(currentBundle),
1209 locale,
1210 ures_getType(subRootBundle),
1211 ures_getType(subBundle));
1212 continue;
1213 }
1214 else if (ures_getType(subBundle) == URES_INT_VECTOR) {
1215 int32_t minSize;
1216 int32_t subBundleSize;
1217 int32_t idx;
1218 UBool sameArray = TRUE;
1219 const int32_t *subRootBundleArr = ures_getIntVector(subRootBundle, &minSize, &errorCode);
1220 const int32_t *subBundleArr = ures_getIntVector(subBundle, &subBundleSize, &errorCode);
1221
1222 if (minSize > subBundleSize) {
1223 minSize = subBundleSize;
1224 log_err("Arrays are different size with key \"%s\" in \"%s\" from root for locale \"%s\"\n",
1225 subBundleKey,
1226 ures_getKey(currentBundle),
1227 locale);
1228 }
1229
1230 for (idx = 0; idx < minSize && sameArray; idx++) {
1231 if (subRootBundleArr[idx] != subBundleArr[idx]) {
1232 sameArray = FALSE;
1233 }
1234 if (strcmp(subBundleKey, "DateTimeElements") == 0
1235 && (subBundleArr[idx] < 1 || 7 < subBundleArr[idx]))
1236 {
1237 log_err("Value out of range with key \"%s\" at index %d in \"%s\" for locale \"%s\"\n",
1238 subBundleKey,
1239 idx,
1240 ures_getKey(currentBundle),
1241 locale);
1242 }
1243 }
1244 /* Special exception es_US and DateTimeElements */
1245 if (sameArray
1246 && !(strcmp(locale, "es_US") == 0 && strcmp(subBundleKey, "DateTimeElements") == 0))
1247 {
1248 log_err("Integer vectors are the same with key \"%s\" in \"%s\" from root for locale \"%s\"\n",
1249 subBundleKey,
1250 ures_getKey(currentBundle),
1251 locale);
1252 }
1253 }
1254 else if (ures_getType(subBundle) == URES_ARRAY) {
1255 UResourceBundle *subSubBundle = ures_getByIndex(subBundle, 0, NULL, &errorCode);
1256 UResourceBundle *subSubRootBundle = ures_getByIndex(subRootBundle, 0, NULL, &errorCode);
1257
1258 if (U_SUCCESS(errorCode)
1259 && (ures_getType(subSubBundle) == URES_ARRAY || ures_getType(subSubRootBundle) == URES_ARRAY))
1260 {
1261 /* TODO: Properly check for 2D arrays and zoneStrings */
1262 if (subBundleKey != NULL && strcmp(subBundleKey, "zoneStrings") == 0) {
1263/* int32_t minSize = ures_getSize(subBundle);
1264 int32_t idx;
1265
1266 for (idx = 0; idx < minSize; idx++) {
1267 UResourceBundle *subSubBundleAtIndex = ures_getByIndex(subBundle, idx, NULL, &errorCode);
1268 if (ures_getSize(subSubBundleAtIndex) != 6) {
1269 log_err("zoneStrings at index %d has wrong size for locale \"%s\". array size=%d\n",
1270 idx,
1271 locale,
1272 ures_getSize(subSubBundleAtIndex));
1273 }
1274 ures_close(subSubBundleAtIndex);
1275 }*/
1276 }
1277 else {
1278 /* Here is one of the recursive parts */
1279 TestKeyInRootRecursive(subRootBundle, rootName, subBundle, locale);
1280 }
1281 }
1282 else {
1283 int32_t minSize = ures_getSize(subRootBundle);
1284 int32_t idx;
1285 UBool sameArray = TRUE;
1286
1287 if (minSize > ures_getSize(subBundle)) {
1288 minSize = ures_getSize(subBundle);
1289 }
1290
1291 if ((subBundleKey == NULL
1292 || (subBundleKey != NULL && strcmp(subBundleKey, "LocaleScript") != 0))
1293 && ures_getSize(subRootBundle) != ures_getSize(subBundle))
1294 {
1295 log_err("Different size array with key \"%s\" in \"%s\" from root for locale \"%s\"\n"
1296 "\troot array size=%d, locale array size=%d\n",
1297 subBundleKey,
1298 ures_getKey(currentBundle),
1299 locale,
1300 ures_getSize(subRootBundle),
1301 ures_getSize(subBundle));
1302 }
1303
1304 for (idx = 0; idx < minSize; idx++) {
1305 int32_t rootStrLen, localeStrLen;
1306 const UChar *rootStr = ures_getStringByIndex(subRootBundle,idx,&rootStrLen,&errorCode);
1307 const UChar *localeStr = ures_getStringByIndex(subBundle,idx,&localeStrLen,&errorCode);
1308 if (rootStr && localeStr && U_SUCCESS(errorCode)) {
1309 if (u_strcmp(rootStr, localeStr) != 0) {
1310 sameArray = FALSE;
1311 }
1312 }
1313 else {
1314 log_err("Got a NULL string with key \"%s\" in \"%s\" at index %d for root or locale \"%s\"\n",
1315 subBundleKey,
1316 ures_getKey(currentBundle),
1317 idx,
1318 locale);
1319 continue;
1320 }
1321 if (localeStr[0] == (UChar)0x20) {
1322 log_err("key \"%s\" at index %d in \"%s\" starts with a space in locale \"%s\"\n",
1323 subBundleKey,
1324 idx,
1325 ures_getKey(currentBundle),
1326 locale);
1327 }
1328 else if (localeStr[localeStrLen - 1] == (UChar)0x20) {
1329 log_err("key \"%s\" at index %d in \"%s\" ends with a space in locale \"%s\"\n",
1330 subBundleKey,
1331 idx,
1332 ures_getKey(currentBundle),
1333 locale);
1334 }
1335 else if (subBundleKey != NULL
1336 && strcmp(subBundleKey, "DateTimePatterns") == 0)
1337 {
1338 int32_t quoted = 0;
1339 const UChar *localeStrItr = localeStr;
1340 while (*localeStrItr) {
1341 if (*localeStrItr == (UChar)0x27 /* ' */) {
1342 quoted++;
1343 }
1344 else if ((quoted % 2) == 0) {
1345 /* Search for unquoted characters */
1346 if (4 <= idx && idx <= 7
1347 && (*localeStrItr == (UChar)0x6B /* k */
1348 || *localeStrItr == (UChar)0x48 /* H */
1349 || *localeStrItr == (UChar)0x6D /* m */
1350 || *localeStrItr == (UChar)0x73 /* s */
1351 || *localeStrItr == (UChar)0x53 /* S */
1352 || *localeStrItr == (UChar)0x61 /* a */
1353 || *localeStrItr == (UChar)0x68 /* h */
1354 || *localeStrItr == (UChar)0x7A /* z */))
1355 {
1356 log_err("key \"%s\" at index %d has time pattern chars in date for locale \"%s\"\n",
1357 subBundleKey,
1358 idx,
1359 locale);
1360 }
1361 else if (0 <= idx && idx <= 3
1362 && (*localeStrItr == (UChar)0x47 /* G */
1363 || *localeStrItr == (UChar)0x79 /* y */
1364 || *localeStrItr == (UChar)0x4D /* M */
1365 || *localeStrItr == (UChar)0x64 /* d */
1366 || *localeStrItr == (UChar)0x45 /* E */
1367 || *localeStrItr == (UChar)0x44 /* D */
1368 || *localeStrItr == (UChar)0x46 /* F */
1369 || *localeStrItr == (UChar)0x77 /* w */
1370 || *localeStrItr == (UChar)0x57 /* W */))
1371 {
1372 log_err("key \"%s\" at index %d has date pattern chars in time for locale \"%s\"\n",
1373 subBundleKey,
1374 idx,
1375 locale);
1376 }
1377 }
1378 localeStrItr++;
1379 }
1380 }
1381 else if (idx == 4 && subBundleKey != NULL
1382 && strcmp(subBundleKey, "NumberElements") == 0
1383 && u_charDigitValue(localeStr[0]) != 0)
1384 {
1385 log_err("key \"%s\" at index %d has a non-zero based number for locale \"%s\"\n",
1386 subBundleKey,
1387 idx,
1388 locale);
1389 }
1390 }
1391 if (sameArray && strcmp(rootName, "root") == 0) {
1392 log_err("Arrays are the same with key \"%s\" in \"%s\" from root for locale \"%s\"\n",
1393 subBundleKey,
1394 ures_getKey(currentBundle),
1395 locale);
1396 }
1397 }
1398 ures_close(subSubBundle);
1399 ures_close(subSubRootBundle);
1400 }
1401 else if (ures_getType(subBundle) == URES_STRING) {
1402 int32_t len = 0;
1403 const UChar *string = ures_getString(subBundle, &len, &errorCode);
1404 if (U_FAILURE(errorCode) || string == NULL) {
1405 log_err("Can't open a string with key \"%s\" in \"%s\" for locale \"%s\"\n",
1406 subBundleKey,
1407 ures_getKey(currentBundle),
1408 locale);
1409 } else if (string[0] == (UChar)0x20) {
1410 log_err("key \"%s\" in \"%s\" starts with a space in locale \"%s\"\n",
1411 subBundleKey,
1412 ures_getKey(currentBundle),
1413 locale);
1414 } else if (string[len - 1] == (UChar)0x20) {
1415 log_err("key \"%s\" in \"%s\" ends with a space in locale \"%s\"\n",
1416 subBundleKey,
1417 ures_getKey(currentBundle),
1418 locale);
1419 } else if (strcmp(subBundleKey, "localPatternChars") == 0 && len != 20) {
1420 log_err("key \"%s\" has the wrong number of characters in locale \"%s\"\n",
1421 subBundleKey,
1422 locale);
1423 }
1424 /* No fallback was done. Check for duplicate data */
1425 /* The ures_* API does not do fallback of sub-resource bundles,
1426 So we can't do this now. */
1427 else if (strcmp(locale, "root") != 0 && errorCode == U_ZERO_ERROR) {
1428
1429 const UChar *rootString = ures_getString(subRootBundle, &len, &errorCode);
1430 if (U_FAILURE(errorCode) || rootString == NULL) {
1431 log_err("Can't open a string with key \"%s\" in \"%s\" in root\n",
1432 ures_getKey(subRootBundle),
1433 ures_getKey(currentBundle));
1434 continue;
1435 } else if (u_strcmp(string, rootString) == 0) {
1436 if (strcmp(locale, "de_CH") != 0 && strcmp(subBundleKey, "Countries") != 0) {
1437 log_err("Found duplicate data with key \"%s\" in \"%s\" in locale \"%s\"\n",
1438 ures_getKey(subRootBundle),
1439 ures_getKey(currentBundle),
1440 locale);
1441 }
1442 else {
1443 /* Ignore for now. */
1444 /* Can be fixed if fallback through de locale was done. */
1445 log_verbose("Skipping key %s in %s\n", subBundleKey, locale);
1446 }
1447 }
1448 }
1449 }
1450 else if (ures_getType(subBundle) == URES_TABLE) {
1451 /* Here is one of the recursive parts */
1452 TestKeyInRootRecursive(subRootBundle, rootName, subBundle, locale);
1453 }
1454 else if (ures_getType(subBundle) == URES_BINARY || ures_getType(subBundle) == URES_INT) {
1455 /* Can't do anything to check it */
1456 /* We'll assume it's all correct */
1457 if (strcmp(subBundleKey, "LocaleID") != 0) {
1458 log_verbose("Skipping key \"%s\" in \"%s\" for locale \"%s\"\n",
1459 subBundleKey,
1460 ures_getKey(currentBundle),
1461 locale);
1462 }
1463 /* Testing for LocaleID is done in testLCID */
1464 }
1465 else {
1466 log_err("Type %d for key \"%s\" in \"%s\" is unknown for locale \"%s\"\n",
1467 ures_getType(subBundle),
1468 subBundleKey,
1469 ures_getKey(currentBundle),
1470 locale);
1471 }
1472 ures_close(subRootBundle);
1473 ures_close(subBundle);
1474 }
1475}
1476
1477
1478#ifdef WIN32
1479
1480static void
1481testLCID(UResourceBundle *currentBundle,
1482 const char *localeName)
1483{
1484 UErrorCode status = U_ZERO_ERROR;
1485 uint32_t lcid;
1486 uint32_t expectedLCID;
1487 char lcidStringC[64] = {0};
1488 int32_t lcidStringLen = 0;
1489 const UChar *lcidString = NULL;
1490 UResourceBundle *localeID = ures_getByKey(currentBundle, "LocaleID", NULL, &status);
1491
1492 expectedLCID = ures_getInt(localeID, &status);
1493 ures_close(localeID);
1494
1495 if (U_FAILURE(status)) {
1496 log_err("ERROR: %s does not have a LocaleID (%s)\n",
1497 localeName, u_errorName(status));
1498 return;
1499 }
1500
1501 lcid = uprv_convertToLCID(localeName, &status);
1502 if (U_FAILURE(status)) {
1503 if (expectedLCID == 0) {
1504 log_verbose("INFO: %-5s does not have any LCID mapping\n",
1505 localeName);
1506 }
1507 else {
1508 log_err("ERROR: %-5s does not have an LCID mapping to 0x%.4X\n",
1509 localeName, expectedLCID);
1510 }
1511 return;
1512 }
1513
1514 status = U_ZERO_ERROR;
1515 uprv_strcpy(lcidStringC, uprv_convertToPosix(expectedLCID, &status));
1516 if (U_FAILURE(status)) {
1517 log_err("ERROR: %.4x does not have a POSIX mapping due to %s\n",
1518 expectedLCID, u_errorName(status));
1519 }
1520
1521 if(lcid != expectedLCID) {
1522 log_err("ERROR: %-5s wrongfully has 0x%.4x instead of 0x%.4x for LCID\n",
1523 localeName, expectedLCID, lcid);
1524 }
1525 if(strcmp(localeName, lcidStringC) != 0) {
1526 char langName[1024];
1527 char langLCID[1024];
1528 uloc_getLanguage(localeName, langName, sizeof(langName), &status);
1529 uloc_getLanguage(lcidStringC, langLCID, sizeof(langLCID), &status);
1530
1531 if (expectedLCID == lcid && strcmp(langName, langLCID) == 0) {
1532 log_verbose("WARNING: %-5s resolves to %s (0x%.4x)\n",
1533 localeName, lcidStringC, lcid);
1534 }
1535 else if (expectedLCID == lcid) {
1536 log_err("ERROR: %-5s has 0x%.4x and the number resolves wrongfully to %s\n",
1537 localeName, expectedLCID, lcidStringC);
1538 }
1539 else {
1540 log_err("ERROR: %-5s has 0x%.4x and the number resolves wrongfully to %s. It should be 0x%x.\n",
1541 localeName, expectedLCID, lcidStringC, lcid);
1542 }
1543 }
1544}
1545
1546#endif
1547
1548static void
1549TestLocaleStructure(void) {
1550 UResourceBundle *root, *completeLoc, *currentLocale, *subtable, *completeSubtable;
1551 int32_t locCount = uloc_countAvailable();
1552 int32_t locIndex;
1553 UErrorCode errorCode = U_ZERO_ERROR;
1554 const char *currLoc;
1555
1556 /* TODO: Compare against parent's data too. This code can't handle fallbacks that some tools do already. */
1557/* char locName[ULOC_FULLNAME_CAPACITY];
1558 char *locNamePtr;
1559
1560 for (locIndex = 0; locIndex < locCount; locIndex++) {
1561 errorCode=U_ZERO_ERROR;
1562 strcpy(locName, uloc_getAvailable(locIndex));
1563 locNamePtr = strrchr(locName, '_');
1564 if (locNamePtr) {
1565 *locNamePtr = 0;
1566 }
1567 else {
1568 strcpy(locName, "root");
1569 }
1570
1571 root = ures_openDirect(NULL, locName, &errorCode);
1572 if(U_FAILURE(errorCode)) {
1573 log_err("Can't open %s\n", locName);
1574 continue;
1575 }
1576*/
1577 if (locCount <= 1) {
1578 log_data_err("At least root needs to be installed\n");
1579 }
1580
1581 root = ures_openDirect(NULL, "root", &errorCode);
1582 if(U_FAILURE(errorCode)) {
1583 log_data_err("Can't open root\n");
1584 return;
1585 }
1586 completeLoc = ures_openDirect(NULL, "en", &errorCode);
1587 if(U_FAILURE(errorCode)) {
1588 log_data_err("Can't open en\n");
1589 return;
1590 }
1591 for (locIndex = 0; locIndex < locCount; locIndex++) {
1592 errorCode=U_ZERO_ERROR;
1593 currLoc = uloc_getAvailable(locIndex);
1594 currentLocale = ures_open(NULL, currLoc, &errorCode);
1595 if(errorCode != U_ZERO_ERROR) {
1596 if(U_SUCCESS(errorCode)) {
1597 /* It's installed, but there is no data.
1598 It's installed for the g18n white paper [grhoten] */
1599 log_err("ERROR: Locale %-5s not installed, and it should be!\n",
1600 uloc_getAvailable(locIndex));
1601 } else {
1602 log_err("%%%%%%% Unexpected error %d in %s %%%%%%%",
1603 u_errorName(errorCode),
1604 uloc_getAvailable(locIndex));
1605 }
1606 ures_close(currentLocale);
1607 continue;
1608 }
1609 ures_getStringByKey(currentLocale, "Version", NULL, &errorCode);
1610 if(errorCode != U_ZERO_ERROR) {
1611 log_err("No version information is available for locale %s, and it should be!\n",
1612 currLoc);
1613 }
1614 else if (ures_getStringByKey(currentLocale, "Version", NULL, &errorCode)[0] == (UChar)(0x78)) {
1615 log_verbose("WARNING: The locale %s is experimental! It shouldn't be listed as an installed locale.\n",
1616 currLoc);
1617 }
1618 TestKeyInRootRecursive(root, "root", currentLocale, currLoc);
1619
1620 completeSubtable = ures_getByKey(completeLoc, "Currencies", NULL, &errorCode);
1621 subtable = ures_getByKey(currentLocale, "Currencies", NULL, &errorCode);
1622 TestKeyInRootRecursive(completeSubtable, "en", subtable, currLoc);
1623
1624#ifdef WIN32
1625 testLCID(currentLocale, currLoc);
1626#endif
1627
1628 ures_close(completeSubtable);
1629 ures_close(subtable);
1630 ures_close(currentLocale);
1631 }
1632
1633 ures_close(root);
1634 ures_close(completeLoc);
1635}
1636
1637static void
1638compareArrays(const char *keyName,
1639 UResourceBundle *fromArray, const char *fromLocale,
1640 UResourceBundle *toArray, const char *toLocale,
1641 int32_t start, int32_t end)
1642{
1643 int32_t fromSize = ures_getSize(fromArray);
1644 int32_t toSize = ures_getSize(fromArray);
1645 int32_t idx;
1646 UErrorCode errorCode = U_ZERO_ERROR;
1647
1648 if (fromSize > toSize) {
1649 fromSize = toSize;
1650 log_err("Arrays are different size from \"%s\" to \"%s\"\n",
1651 fromLocale,
1652 toLocale);
1653 }
1654
1655 for (idx = start; idx <= end; idx++) {
1656 const UChar *fromBundleStr = ures_getStringByIndex(fromArray, idx, NULL, &errorCode);
1657 const UChar *toBundleStr = ures_getStringByIndex(toArray, idx, NULL, &errorCode);
1658 if (fromBundleStr && toBundleStr && u_strcmp(fromBundleStr, toBundleStr) != 0)
1659 {
1660 log_err("Difference for %s at index %d from %s= \"%s\" to %s= \"%s\"\n",
1661 keyName,
1662 idx,
1663 fromLocale,
1664 austrdup(fromBundleStr),
1665 toLocale,
1666 austrdup(toBundleStr));
1667 }
1668 }
1669}
1670
1671static void
1672compareConsistentCountryInfo(const char *fromLocale, const char *toLocale) {
1673 UErrorCode errorCode = U_ZERO_ERROR;
1674 UResourceBundle *fromDateTimeElements, *toDateTimeElements;
1675 UResourceBundle *fromArray, *toArray;
1676 UResourceBundle *fromLocaleBund = ures_open(NULL, fromLocale, &errorCode);
1677 UResourceBundle *toLocaleBund = ures_open(NULL, toLocale, &errorCode);
1678
1679 if(U_FAILURE(errorCode)) {
1680 log_err("Can't open resource bundle %s or %s - %s\n", fromLocale, toLocale, u_errorName(errorCode));
1681 return;
1682 }
1683
1684 fromDateTimeElements = ures_getByKey(fromLocaleBund, "DateTimeElements", NULL, &errorCode);
1685 toDateTimeElements = ures_getByKey(toLocaleBund, "DateTimeElements", NULL, &errorCode);
1686 if (strcmp(fromLocale, "ar_IN") != 0)
1687 {
1688 int32_t fromSize;
1689 int32_t toSize;
1690 int32_t idx;
1691 const int32_t *fromBundleArr = ures_getIntVector(fromDateTimeElements, &fromSize, &errorCode);
1692 const int32_t *toBundleArr = ures_getIntVector(toDateTimeElements, &toSize, &errorCode);
1693
1694 if (fromSize > toSize) {
1695 fromSize = toSize;
1696 log_err("Arrays are different size with key \"DateTimeElements\" from \"%s\" to \"%s\"\n",
1697 fromLocale,
1698 toLocale);
1699 }
1700
1701 for (idx = 0; idx < fromSize; idx++) {
1702 if (fromBundleArr[idx] != toBundleArr[idx]) {
1703 log_err("Difference with key \"DateTimeElements\" at index %d from \"%s\" to \"%s\"\n",
1704 idx,
1705 fromLocale,
1706 toLocale);
1707 }
1708 }
1709 }
1710 ures_close(fromDateTimeElements);
1711 ures_close(toDateTimeElements);
1712
1713 fromArray = ures_getByKey(fromLocaleBund, "CurrencyElements", NULL, &errorCode);
1714 toArray = ures_getByKey(toLocaleBund, "CurrencyElements", NULL, &errorCode);
1715 if (strcmp(fromLocale, "en_CA") != 0)
1716 {
1717 /* The first one is probably localized. */
1718 compareArrays("CurrencyElements", fromArray, fromLocale, toArray, toLocale, 1, 2);
1719 }
1720 ures_close(fromArray);
1721 ures_close(toArray);
1722
1723 fromArray = ures_getByKey(fromLocaleBund, "NumberPatterns", NULL, &errorCode);
1724 toArray = ures_getByKey(toLocaleBund, "NumberPatterns", NULL, &errorCode);
1725 if (strcmp(fromLocale, "en_CA") != 0)
1726 {
1727 compareArrays("NumberPatterns", fromArray, fromLocale, toArray, toLocale, 0, 3);
1728 }
1729 ures_close(fromArray);
1730 ures_close(toArray);
1731
1732 /* Difficult to test properly */
1733/*
1734 fromArray = ures_getByKey(fromLocaleBund, "DateTimePatterns", NULL, &errorCode);
1735 toArray = ures_getByKey(toLocaleBund, "DateTimePatterns", NULL, &errorCode);
1736 {
1737 compareArrays("DateTimePatterns", fromArray, fromLocale, toArray, toLocale);
1738 }
1739 ures_close(fromArray);
1740 ures_close(toArray);*/
1741
1742 fromArray = ures_getByKey(fromLocaleBund, "NumberElements", NULL, &errorCode);
1743 toArray = ures_getByKey(toLocaleBund, "NumberElements", NULL, &errorCode);
1744 if (strcmp(fromLocale, "en_CA") != 0)
1745 {
1746 compareArrays("NumberElements", fromArray, fromLocale, toArray, toLocale, 0, 3);
1747 /* Index 4 is a script based 0 */
1748 compareArrays("NumberElements", fromArray, fromLocale, toArray, toLocale, 5, 10);
1749 }
1750 ures_close(fromArray);
1751 ures_close(toArray);
1752
1753 ures_close(fromLocaleBund);
1754 ures_close(toLocaleBund);
1755}
1756
1757static void
1758TestConsistentCountryInfo(void) {
1759/* UResourceBundle *fromLocale, *toLocale;*/
1760 int32_t locCount = uloc_countAvailable();
1761 int32_t fromLocIndex, toLocIndex;
1762
1763 int32_t fromCountryLen, toCountryLen;
1764 char fromCountry[ULOC_FULLNAME_CAPACITY], toCountry[ULOC_FULLNAME_CAPACITY];
1765
1766 int32_t fromVariantLen, toVariantLen;
1767 char fromVariant[ULOC_FULLNAME_CAPACITY], toVariant[ULOC_FULLNAME_CAPACITY];
1768
1769 UErrorCode errorCode = U_ZERO_ERROR;
1770
1771 for (fromLocIndex = 0; fromLocIndex < locCount; fromLocIndex++) {
1772 const char *fromLocale = uloc_getAvailable(fromLocIndex);
1773
1774 errorCode=U_ZERO_ERROR;
1775 fromCountryLen = uloc_getCountry(fromLocale, fromCountry, ULOC_FULLNAME_CAPACITY, &errorCode);
1776 if (fromCountryLen <= 0) {
1777 /* Ignore countryless locales */
1778 continue;
1779 }
1780 fromVariantLen = uloc_getVariant(fromLocale, fromVariant, ULOC_FULLNAME_CAPACITY, &errorCode);
1781 if (fromVariantLen > 0) {
1782 /* Most variants are ignorable like PREEURO, or collation variants. */
1783 continue;
1784 }
1785 /* Start comparing only after the current index.
1786 Previous loop should have already compared fromLocIndex.
1787 */
1788 for (toLocIndex = fromLocIndex + 1; toLocIndex < locCount; toLocIndex++) {
1789 const char *toLocale = uloc_getAvailable(toLocIndex);
1790
1791 toCountryLen = uloc_getCountry(toLocale, toCountry, ULOC_FULLNAME_CAPACITY, &errorCode);
1792 if(U_FAILURE(errorCode)) {
1793 log_err("Unknown failure fromLocale=%s toLocale=%s errorCode=%s\n",
1794 fromLocale, toLocale, u_errorName(errorCode));
1795 continue;
1796 }
1797
1798 if (toCountryLen <= 0) {
1799 /* Ignore countryless locales */
1800 continue;
1801 }
1802 toVariantLen = uloc_getVariant(toLocale, toVariant, ULOC_FULLNAME_CAPACITY, &errorCode);
1803 if (toVariantLen > 0) {
1804 /* Most variants are ignorable like PREEURO, or collation variants. */
1805 /* They're a variant for a reason. */
1806 continue;
1807 }
1808 if (strcmp(fromCountry, toCountry) == 0) {
1809 log_verbose("comparing fromLocale=%s toLocale=%s\n",
1810 fromLocale, toLocale);
1811 compareConsistentCountryInfo(fromLocale, toLocale);
1812 }
1813 }
1814 }
1815}
1816
1817static int32_t
1818findStringSetMismatch(const UChar *string, int32_t langSize,
1819 const UChar *exemplarCharacters, int32_t exemplarLen,
1820 UBool ignoreNumbers) {
1821 UErrorCode errorCode = U_ZERO_ERROR;
1822 USet *exemplarSet = uset_openPatternOptions(exemplarCharacters, exemplarLen, USET_CASE_INSENSITIVE, &errorCode);
1823 int32_t strIdx;
1824 if (U_FAILURE(errorCode)) {
1825 log_err("error uset_openPattern returned %s\n", u_errorName(errorCode));
1826 return -1;
1827 }
1828
1829 for (strIdx = 0; strIdx < langSize; strIdx++) {
1830 if (!uset_contains(exemplarSet, string[strIdx])
1831 && string[strIdx] != 0x0020 && string[strIdx] != 0x002e && string[strIdx] != 0x002c && string[strIdx] != 0x002d && string[strIdx] != 0x0027) {
1832 if (!ignoreNumbers || (ignoreNumbers && (string[strIdx] < 0x30 || string[strIdx] > 0x39))) {
1833 return strIdx;
1834 }
1835 }
1836 }
1837 uset_close(exemplarSet);
1838 return -1;
1839}
1840
1841static void VerifyTranslation(void) {
1842 UResourceBundle *root, *currentLocale;
1843 int32_t locCount = uloc_countAvailable();
1844 int32_t locIndex;
1845 UErrorCode errorCode = U_ZERO_ERROR;
1846 int32_t exemplarLen;
1847 const UChar *exemplarCharacters;
1848 const char *currLoc;
1849 UScriptCode scripts[USCRIPT_CODE_LIMIT];
1850 int32_t numScripts;
1851 int32_t idx;
1852 int32_t end;
1853 UResourceBundle *resArray;
1854
1855 if (locCount <= 1) {
1856 log_data_err("At least root needs to be installed\n");
1857 }
1858
1859 root = ures_openDirect(NULL, "root", &errorCode);
1860 if(U_FAILURE(errorCode)) {
1861 log_data_err("Can't open root\n");
1862 return;
1863 }
1864 for (locIndex = 0; locIndex < locCount; locIndex++) {
1865 errorCode=U_ZERO_ERROR;
1866 currLoc = uloc_getAvailable(locIndex);
1867 currentLocale = ures_open(NULL, currLoc, &errorCode);
1868 if(errorCode != U_ZERO_ERROR) {
1869 if(U_SUCCESS(errorCode)) {
1870 /* It's installed, but there is no data.
1871 It's installed for the g18n white paper [grhoten] */
1872 log_err("ERROR: Locale %-5s not installed, and it should be!\n",
1873 uloc_getAvailable(locIndex));
1874 } else {
1875 log_err("%%%%%%% Unexpected error %d in %s %%%%%%%",
1876 u_errorName(errorCode),
1877 uloc_getAvailable(locIndex));
1878 }
1879 ures_close(currentLocale);
1880 continue;
1881 }
1882 exemplarCharacters = ures_getStringByKey(currentLocale, "ExemplarCharacters", &exemplarLen, &errorCode);
1883 if (U_FAILURE(errorCode)) {
1884 log_err("error ures_getStringByKey returned %s\n", u_errorName(errorCode));
1885 }
1886 else if (QUICK && exemplarLen > 2048) {
1887 log_verbose("skipping test for %s\n", currLoc);
1888 }
1889 else {
1890 UChar langBuffer[128];
1891 int32_t langSize;
1892 int32_t strIdx;
1893 langSize = uloc_getDisplayLanguage(currLoc, currLoc, langBuffer, sizeof(langBuffer)/sizeof(langBuffer[0]), &errorCode);
1894 if (U_FAILURE(errorCode)) {
1895 log_err("error uloc_getDisplayLanguage returned %s\n", u_errorName(errorCode));
1896 }
1897 else {
1898 strIdx = findStringSetMismatch(langBuffer, langSize, exemplarCharacters, exemplarLen, FALSE);
1899 if (strIdx >= 0) {
1900 log_err("getDisplayLanguage(%s) at index %d returned characters not in the exemplar characters.\n",
1901 currLoc, strIdx);
1902 }
1903 }
1904 langSize = uloc_getDisplayCountry(currLoc, currLoc, langBuffer, sizeof(langBuffer)/sizeof(langBuffer[0]), &errorCode);
1905 if (U_FAILURE(errorCode)) {
1906 log_err("error uloc_getDisplayCountry returned %s\n", u_errorName(errorCode));
1907 }
1908 else {
1909 strIdx = findStringSetMismatch(langBuffer, langSize, exemplarCharacters, exemplarLen, FALSE);
1910 if (strIdx >= 0) {
1911 log_err("getDisplayCountry(%s) at index %d returned characters not in the exemplar characters.\n",
1912 currLoc, strIdx);
1913 }
1914 }
1915
1916 resArray = ures_getByKey(currentLocale, "DayNames", NULL, &errorCode);
1917 if (U_FAILURE(errorCode)) {
1918 log_err("error ures_getByKey returned %s\n", u_errorName(errorCode));
1919 }
1920 if (QUICK) {
1921 end = 1;
1922 }
1923 else {
1924 end = ures_getSize(resArray);
1925 }
1926
1927
1928 for (idx = 0; idx < end; idx++) {
1929 const UChar *fromBundleStr = ures_getStringByIndex(resArray, idx, &langSize, &errorCode);
1930 if (U_FAILURE(errorCode)) {
1931 log_err("error ures_getStringByIndex(%d) returned %s\n", idx, u_errorName(errorCode));
1932 continue;
1933 }
1934 strIdx = findStringSetMismatch(fromBundleStr, langSize, exemplarCharacters, exemplarLen, TRUE);
1935 if (strIdx >= 0) {
1936 log_err("getDayNames(%s, %d) at index %d returned characters not in the exemplar characters.\n",
1937 currLoc, idx, strIdx);
1938 }
1939 }
1940 ures_close(resArray);
1941
1942 resArray = ures_getByKey(currentLocale, "MonthNames", NULL, &errorCode);
1943 if (U_FAILURE(errorCode)) {
1944 log_err("error ures_getByKey returned %s\n", u_errorName(errorCode));
1945 }
1946 if (QUICK) {
1947 end = 1;
1948 }
1949 else {
1950 end = ures_getSize(resArray);
1951 }
1952
1953 for (idx = 0; idx < end; idx++) {
1954 const UChar *fromBundleStr = ures_getStringByIndex(resArray, idx, &langSize, &errorCode);
1955 if (U_FAILURE(errorCode)) {
1956 log_err("error ures_getStringByIndex(%d) returned %s\n", idx, u_errorName(errorCode));
1957 continue;
1958 }
1959 strIdx = findStringSetMismatch(fromBundleStr, langSize, exemplarCharacters, exemplarLen, TRUE);
1960 if (strIdx >= 0) {
1961 log_err("getMonthNames(%s, %d) at index %d returned characters not in the exemplar characters.\n",
1962 currLoc, idx, strIdx);
1963 }
1964 }
1965 ures_close(resArray);
1966
1967 errorCode = U_ZERO_ERROR;
1968 numScripts = uscript_getCode(currLoc, scripts, sizeof(scripts)/sizeof(scripts[0]), &errorCode);
1969 if (numScripts == 0) {
1970 log_err("uscript_getCode(%s) doesn't work.\n", currLoc);
1971 }
1972 /* TODO: test that the scripts are a superset of exemplar characters. */
1973 }
1974 ures_close(currentLocale);
1975 }
1976
1977 ures_close(root);
1978}