1
/********************************************************************
3
* Copyright (c) 1997-2001, International Business Machines Corporation and
4
* others. All Rights Reserved.
5
********************************************************************/
6
/********************************************************************************
10
* Modification History:
12
* Madhu Katragadda Ported for C API
13
*********************************************************************************
18
#include "unicode/utypes.h"
19
#include "unicode/putil.h"
21
#include "unicode/uloc.h"
22
#include "unicode/uchar.h"
23
#include "unicode/ustring.h"
27
#include "unicode/ures.h"
29
/* Get the private functions. This is a hack! [grhoten] */
33
void PrintDataTable();
35
/*---------------------------------------------------
37
--------------------------------------------------- */
39
#define LOCALE_INFO_SIZE 23
41
static const char* rawData2[LOCALE_INFO_SIZE][LOCALE_SIZE] = {
43
{ "en", "fr", "hr", "el", "no" },
45
{ "US", "FR", "HR", "GR", "NO" },
47
{ "", "", "", "", "NY" },
49
{ "en_US", "fr_FR", "hr_HR", "el_GR", "no_NO_NY" },
51
{ "eng", "fra", "hrv", "ell", "nor" },
53
{ "USA", "FRA", "HRV", "GRC", "NOR" },
54
/* LCID (not currently public) */
55
{ "409", "40c", "41a", "408", "814" },
57
/* display langage (English) */
58
{ "English", "French", "Croatian", "Greek", "Norwegian" },
59
/* display country (English) */
60
{ "United States", "France", "Croatia", "Greece", "Norway" },
61
/* display variant (English) */
62
{ "", "", "", "", "Nynorsk" },
63
/* display name (English) */
64
{ "English (United States)", "French (France)", "Croatian (Croatia)", "Greek (Greece)", "Norwegian (Norway, Nynorsk)" },
66
/* display langage (French) */
67
{ "anglais", "fran\\u00E7ais", "croate", "grec", "norv\\u00E9gien" },
68
/* display country (French) */
69
{ "\\u00C9tats-Unis", "France", "Croatie", "Gr\\u00E8ce", "Norv\\u00E8ge" },
70
/* display variant (French) */
71
{ "", "", "", "", "Nynorsk" },
72
/* display name (French) */
73
{ "anglais (\\u00C9tats-Unis)", "fran\\u00E7ais (France)", "croate (Croatie)", "grec (Gr\\u00E8ce)", "norv\\u00E9gien (Norv\\u00E8ge, Nynorsk)" },
75
/* display langage (Croatian) */
76
{ "", "", "hrvatski", "", "" },
77
/* display country (Croatian) */
78
{ "", "", "Hrvatska", "", "" },
79
/* display variant (Croatian) */
80
{ "", "", "", "", "" },
81
/* display name (Croatian) */
82
{ "", "", "hrvatski (Hrvatska)", "", "" },
84
/* display langage (Greek) */
85
{ "\\u0391\\u03b3\\u03b3\\u03bb\\u03b9\\u03ba\\u03ac", "\\u0393\\u03b1\\u03bb\\u03bb\\u03b9\\u03ba\\u03ac", "\\u039a\\u03c1\\u03bf\\u03b1\\u03c4\\u03b9\\u03ba\\u03ac", "\\u03b5\\u03bb\\u03bb\\u03b7\\u03bd\\u03b9\\u03ba\\u03ac", "\\u039d\\u03bf\\u03c1\\u03b2\\u03b7\\u03b3\\u03b9\\u03ba\\u03ac" },
86
/* display country (Greek) */
87
{ "\\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", "\\u0393\\u03b1\\u03bb\\u03bb\\u03af\\u03b1", "\\u039a\\u03c1\\u03bf\\u03b1\\u03c4\\u03af\\u03b1", "\\u0395\\u03bb\\u03bb\\u03ac\\u03b4\\u03b1", "\\u039d\\u03bf\\u03c1\\u03b2\\u03b7\\u03b3\\u03af\\u03b1" },
88
/* display variant (Greek) */
89
{ "", "", "", "", "" },
90
/* display name (Greek) */
91
{ "\\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)", "\\u0393\\u03b1\\u03bb\\u03bb\\u03b9\\u03ba\\u03ac (\\u0393\\u03b1\\u03bb\\u03bb\\u03af\\u03b1)", "\\u039a\\u03c1\\u03bf\\u03b1\\u03c4\\u03b9\\u03ba\\u03ac (\\u039a\\u03c1\\u03bf\\u03b1\\u03c4\\u03af\\u03b1)", "\\u03b5\\u03bb\\u03bb\\u03b7\\u03bd\\u03b9\\u03ba\\u03ac (\\u0395\\u03bb\\u03bb\\u03ac\\u03b4\\u03b1)", "" }
94
static UChar*** dataTable=0;
130
void addLocaleTest(TestNode** root);
132
void addLocaleTest(TestNode** root)
134
addTest(root, &TestObsoleteNames, "tsutil/cloctst/TestObsoleteNames"); /* srl- move */
135
addTest(root, &TestBasicGetters, "tsutil/cloctst/TestBasicGetters");
136
addTest(root, &TestPrefixes, "tsutil/cloctst/TestPrefixes");
137
addTest(root, &TestSimpleResourceInfo, "tsutil/cloctst/TestSimpleResourceInfo");
138
addTest(root, &TestDisplayNames, "tsutil/cloctst/TestDisplayNames");
139
addTest(root, &TestGetAvailableLocales, "tsutil/cloctst/TestGetAvailableLocales");
140
addTest(root, &TestDataDirectory, "tsutil/cloctst/TestDataDirectory");
141
addTest(root, &TestISOFunctions, "tsutil/cloctst/TestISOFunctions");
142
addTest(root, &TestISO3Fallback, "tsutil/cloctst/TestISO3Fallback");
143
addTest(root, &TestUninstalledISO3Names, "tsutil/cloctst/TestUninstalledISO3Names");
144
addTest(root, &TestSimpleDisplayNames, "tsutil/cloctst/TestSimpleDisplayNames");
145
addTest(root, &TestVariantParsing, "tsutil/cloctst/TestVariantParsing");
146
addTest(root, &TestLocaleStructure, "tsutil/cloctst/TestLocaleStructure");
147
addTest(root, &TestConsistentCountryInfo,"tsutil/cloctst/TestConsistentCountryInfo");
151
/* testing uloc(), uloc_getName(), uloc_getLanguage(), uloc_getVariant(), uloc_getCountry() */
152
static void TestBasicGetters() {
155
UErrorCode status = U_ZERO_ERROR;
156
char *testLocale = 0;
157
char *temp = 0, *name = 0;
158
log_verbose("Testing Basic Getters\n");
159
for (i = 0; i <= MAX_LOCALES; i++) {
160
testLocale=(char*)malloc(sizeof(char) * (strlen(rawData2[NAME][i])+1));
161
strcpy(testLocale,rawData2[NAME][i]);
163
log_verbose("Testing %s .....\n", testLocale);
164
cap=uloc_getLanguage(testLocale, NULL, 0, &status);
165
if(status==U_BUFFER_OVERFLOW_ERROR){
167
temp=(char*)malloc(sizeof(char) * (cap+1));
168
uloc_getLanguage(testLocale, temp, cap+1, &status);
170
if(U_FAILURE(status)){
171
log_err("ERROR: in uloc_getLanguage %s\n", myErrorName(status));
173
if (0 !=strcmp(temp,rawData2[LANG][i])) {
174
log_err(" Language code mismatch: %s versus %s\n", temp, rawData2[LANG][i]);
178
cap=uloc_getCountry(testLocale, temp, cap, &status);
179
if(status==U_BUFFER_OVERFLOW_ERROR){
181
temp=(char*)realloc(temp, sizeof(char) * (cap+1));
182
uloc_getCountry(testLocale, temp, cap+1, &status);
184
if(U_FAILURE(status)){
185
log_err("ERROR: in uloc_getCountry %s\n", myErrorName(status));
187
if (0 != strcmp(temp, rawData2[CTRY][i])) {
188
log_err(" Country code mismatch: %s versus %s\n", temp, rawData2[CTRY][i]);
192
cap=uloc_getVariant(testLocale, temp, cap, &status);
193
if(status==U_BUFFER_OVERFLOW_ERROR){
195
temp=(char*)realloc(temp, sizeof(char) * (cap+1));
196
uloc_getVariant(testLocale, temp, cap+1, &status);
198
if(U_FAILURE(status)){
199
log_err("ERROR: in uloc_getVariant %s\n", myErrorName(status));
201
if (0 != strcmp(temp, rawData2[VAR][i])) {
202
log_err("Variant code mismatch: %s versus %s\n", temp, rawData2[VAR][i]);
205
cap=uloc_getName(testLocale, NULL, 0, &status);
206
if(status==U_BUFFER_OVERFLOW_ERROR){
208
name=(char*)malloc(sizeof(char) * (cap+1));
209
uloc_getName(testLocale, name, cap+1, &status);
210
} else if(status==U_ZERO_ERROR) {
211
log_err("ERROR: in uloc_getName(%s,NULL,0,..), expected U_BUFFER_OVERFLOW_ERROR!\n", testLocale);
213
if(U_FAILURE(status)){
214
log_err("ERROR: in uloc_getName %s\n", myErrorName(status));
216
if (0 != strcmp(name, rawData2[NAME][i])){
217
log_err(" Mismatch in getName: %s versus %s\n", name, rawData2[NAME][i]);
228
/* Test the i- and x- and @ and . functionality
231
#define PREFIXBUFSIZ 128
233
static void TestPrefixes() {
238
const char *testData[][5] =
240
{"sv", "FI", "AL", "sv-fi-al", "sv_FI_AL" },
241
{"en", "GB", "", "en-gb", "en_GB" },
242
{"i-hakka", "MT", "XEMXIJA", "i-hakka_MT_XEMXIJA", "i-hakka_MT_XEMXIJA"},
243
{"i-hakka", "CN", "", "i-hakka_CN", "i-hakka_CN"},
244
{"i-hakka", "MX", "", "I-hakka_MX", "i-hakka_MX"},
245
{"x-klingon", "US", "SANJOSE", "X-KLINGON_us_SANJOSE", "x-klingon_US_SANJOSE"},
247
{"mr", "", "", "mr.utf8", "mr"},
248
{"de", "TV", "", "de-tv.koi8r", "de_TV"},
249
{"x-piglatin", "ML", "", "x-piglatin_ML.MBE", "x-piglatin_ML"}, /* Multibyte English */
250
{"i-cherokee","US", "", "i-Cherokee_US.utf7", "i-cherokee_US"},
251
{"x-filfli", "MT", "FILFLA", "x-filfli_MT_FILFLA.gb-18030", "x-filfli_MT_FILFLA"},
252
{"no", "NO", "NY", "no-no-ny.utf32@B", "no_NO_NY"}, /* @ ignored unless variant is empty */
253
{"no", "NO", "B", "no-no.utf32@B", "no_NO_B" },
254
{"no", "", "NY", "no__ny", "no__NY" },
255
{"no", "", "NY", "no@ny", "no__NY" },
260
const char *testTitles[] = { "uloc_getLanguage()", "uloc_getCountry()", "uloc_getVariant()", "name", "uloc_getName()", "country3", "lcid" };
262
char buf[PREFIXBUFSIZ];
267
for(row=0;testData[row][0][0] != 0;row++) {
268
loc = testData[row][NAME];
269
log_verbose("Test #%d: %s\n", row, loc);
274
for(n=0;n<=(NAME+1);n++) {
275
if(n==NAME) continue;
277
for(len=0;len<PREFIXBUFSIZ;len++) {
278
buf[len] = '%'; /* Set a tripwire.. */
284
len = uloc_getLanguage(loc, buf, PREFIXBUFSIZ, &err);
288
len = uloc_getCountry(loc, buf, PREFIXBUFSIZ, &err);
292
len = uloc_getVariant(loc, buf, PREFIXBUFSIZ, &err);
296
len = uloc_getName(loc, buf, PREFIXBUFSIZ, &err);
305
log_err("#%d: %s on %s: err %s\n",
306
row, testTitles[n], loc, u_errorName(err));
308
log_verbose("#%d: %s on %s: -> [%s] (length %d)\n",
309
row, testTitles[n], loc, buf, len);
311
if(len != (int32_t)strlen(buf)) {
312
log_err("#%d: %s on %s: -> [%s] (length returned %d, actual %d!)\n",
313
row, testTitles[n], loc, buf, len, strlen(buf)+1);
317
/* see if they smashed something */
318
if(buf[len+1] != '%') {
319
log_err("#%d: %s on %s: -> [%s] - wrote [%X] out ofbounds!\n",
320
row, testTitles[n], loc, buf, buf[len+1]);
323
if(strcmp(buf, testData[row][n])) {
324
log_err("#%d: %s on %s: -> [%s] (expected '%s'!)\n",
325
row, testTitles[n], loc, buf, testData[row][n]);
334
/* testing uloc_getISO3Language(), uloc_getISO3Country(), */
335
static void TestSimpleResourceInfo() {
337
char* testLocale = 0;
342
testLocale=(char*)malloc(sizeof(char) * 1);
343
expected=(UChar*)malloc(sizeof(UChar) * 1);
346
log_verbose("Testing getISO3Language and getISO3Country\n");
347
for (i = 0; i <= MAX_LOCALES; i++) {
349
testLocale=(char*)realloc(testLocale, sizeof(char) * (u_strlen(dataTable[NAME][i])+1));
350
u_austrcpy(testLocale, dataTable[NAME][i]);
352
log_verbose("Testing %s ......\n", testLocale);
354
temp=uloc_getISO3Language(testLocale);
355
expected=(UChar*)realloc(expected, sizeof(UChar) * (strlen(temp) + 1));
356
u_uastrcpy(expected,temp);
357
if (0 != u_strcmp(expected, dataTable[LANG3][i])) {
358
log_err(" ISO-3 language code mismatch: %s versus %s\n", austrdup(expected),
359
austrdup(dataTable[LANG3][i]));
362
temp=uloc_getISO3Country(testLocale);
363
expected=(UChar*)realloc(expected, sizeof(UChar) * (strlen(temp) + 1));
364
u_uastrcpy(expected,temp);
365
if (0 != u_strcmp(expected, dataTable[CTRY3][i])) {
366
log_err(" ISO-3 Country code mismatch: %s versus %s\n", austrdup(expected),
367
austrdup(dataTable[CTRY3][i]));
369
sprintf(temp2, "%x", uloc_getLCID(testLocale));
370
if (strcmp(temp2, rawData2[LCID][i]) != 0) {
371
log_err("LCID mismatch: %s versus %s\n", temp2 , rawData2[LCID][i]);
381
static void TestDisplayNames()
384
Can't just save a pointer to the default locale.
385
Although the pointer won't change, the contents will, so the
386
restore at the end doesn't actually restore the original.
388
const char *saveDefault;
391
UErrorCode err = U_ZERO_ERROR;
394
saveDefault = uloc_getDefault();
395
defaultLocale = (char*) malloc(strlen(saveDefault) + 1);
396
if(defaultLocale == 0) {
397
log_err("out of memory");
400
strcpy(defaultLocale, saveDefault);
402
uloc_setDefault("en_US", &err);
403
if (U_FAILURE(err)) {
404
log_err("uloc_setDefault returned error code ");
409
log_verbose("Testing getDisplayName for different locales\n");
410
log_verbose("With default = en_US...\n");
412
log_verbose(" In default locale...\n");
413
doTestDisplayNames(" ", DLANG_EN, FALSE);
414
log_verbose(" In locale = en_US...\n");
415
doTestDisplayNames("en_US", DLANG_EN, FALSE);
416
log_verbose(" In locale = fr_FR....\n");
417
doTestDisplayNames("fr_FR", DLANG_FR, FALSE);
418
log_verbose(" In locale = hr_HR...\n");
419
doTestDisplayNames("hr_HR", DLANG_HR, FALSE);
420
log_verbose(" In locale = gr_EL..\n");
421
doTestDisplayNames("el_GR", DLANG_EL, FALSE);
423
uloc_setDefault("fr_FR", &err);
424
if (U_FAILURE(err)) {
425
log_err("Locale::setDefault returned error code %s\n", myErrorName(err));
429
log_verbose("With default = fr_FR...\n");
431
log_verbose(" In default locale...\n");
432
doTestDisplayNames(" ", DLANG_FR, TRUE);
433
log_verbose(" In locale = en_US...\n");
434
doTestDisplayNames("en_US", DLANG_EN, TRUE);
435
log_verbose(" In locale = fr_FR....\n");
436
doTestDisplayNames("fr_FR", DLANG_FR, TRUE);
437
log_verbose(" In locale = hr_HR...\n");
438
doTestDisplayNames("hr_HR", DLANG_HR, TRUE);
439
log_verbose(" In locale = el_GR...\n");
440
doTestDisplayNames("el_GR", DLANG_EL, TRUE);
442
uloc_setDefault(defaultLocale, &err);
443
if (U_FAILURE(err)) {
444
log_err("Locale::setDefault returned error code %s\n", myErrorName(err));
453
/* test for uloc_getAvialable() and uloc_countAvilable()*/
454
static void TestGetAvailableLocales()
460
log_verbose("Testing the no of avialable locales\n");
461
locCount=uloc_countAvailable();
463
log_err("countAvailable() returned an empty list!\n");
465
/* use something sensible w/o hardcoding the count */
466
else if(locCount < 0){
467
log_err("countAvailable() returned a wrong value!= %d\n", locCount);
470
log_info("Number of locales returned = %d\n", locCount);
472
for(i=0;i<locCount;i++){
473
locList=uloc_getAvailable(i);
475
log_verbose(" %s\n", locList);
479
/* test for u_getDataDirectory, u_setDataDirectory, uloc_getISO3Language */
480
static void TestDataDirectory()
483
char oldDirectory[512];
484
const char *temp,*testValue1,*testValue2,*testValue3;
485
const char path[40] ="d:\\icu\\source\\test\\intltest" U_FILE_SEP_STRING; /*give the required path */
487
log_verbose("Testing getDataDirectory()\n");
488
temp = u_getDataDirectory();
489
strcpy(oldDirectory, temp);
491
testValue1=uloc_getISO3Language("en_US");
492
log_verbose("first fetch of language retrieved %s\n", testValue1);
494
if (0 != strcmp(testValue1,"eng")){
495
log_err("Initial check of ISO3 language failed: expected \"eng\", got %s \n", testValue1);
498
/*defining the path for DataDirectory */
499
log_verbose("Testing setDataDirectory\n");
500
u_setDataDirectory( path );
501
if(strcmp(path, u_getDataDirectory())==0)
502
log_verbose("setDataDirectory working fine\n");
504
log_err("Error in setDataDirectory. Directory not set correctly - came back as [%s], expected [%s]\n", u_getDataDirectory(), path);
506
testValue2=uloc_getISO3Language("en_US");
507
log_verbose("second fetch of language retrieved %s \n", testValue2);
509
u_setDataDirectory(oldDirectory);
510
testValue3=uloc_getISO3Language("en_US");
511
log_verbose("third fetch of language retrieved %s \n", testValue3);
513
if (0 != strcmp(testValue3,"eng")) {
514
log_err("get/setDataDirectory() failed: expected \"eng\", got \" %s \" \n", testValue3);
520
/*=========================================================== */
524
static void doTestDisplayNames(const char* inLocale,
525
int32_t compareIndex,
526
int32_t defaultIsFrench)
528
UErrorCode status = U_ZERO_ERROR;
530
int32_t maxresultsize;
541
UChar* expectedLang = 0;
542
UChar* expectedCtry = 0;
543
UChar* expectedVar = 0;
544
UChar* expectedName = 0;
546
const char* defaultDefaultLocale=" ";
551
uloc_getLanguage(uloc_getDefault(), temp, 5, &status);
552
if(U_FAILURE(status)){
553
log_err("ERROR: in getDefault %s \n", myErrorName(status));
555
if (defaultIsFrench && 0 != strcmp(temp, "fr")) {
556
log_err("Default locale should be French, but it's really %s\n", temp);
558
else if (!defaultIsFrench && 0 != strcmp(temp, "en")){
559
log_err("Default locale should be English, but it's really %s\n", temp);
562
testLocale = (char*)malloc(sizeof(char) * 1);
565
for(i=0;i<MAX_LOCALES; ++i)
567
testLocale=(char*)realloc(testLocale, sizeof(char) * (u_strlen(dataTable[NAME][i])+1));
568
u_austrcpy(testLocale,dataTable[NAME][i]);
570
log_verbose("Testing..... %s\n", testLocale);
572
if (strcmp(inLocale, defaultDefaultLocale)==0) {
574
maxresultsize=uloc_getDisplayLanguage(testLocale, NULL, NULL, maxresultsize, &status);
575
if(status==U_BUFFER_OVERFLOW_ERROR)
578
testLang=(UChar*)malloc(sizeof(UChar) * (maxresultsize + 1));
579
uloc_getDisplayLanguage(testLocale, NULL, testLang, maxresultsize + 1, &status);
586
if(U_FAILURE(status)){
587
log_err("Error in getDisplayLanguage() %s\n", myErrorName(status));
590
maxresultsize=uloc_getDisplayCountry(testLocale, NULL, NULL, maxresultsize, &status);
591
if(status==U_BUFFER_OVERFLOW_ERROR)
594
testCtry=(UChar*)malloc(sizeof(UChar) * (maxresultsize + 1));
595
uloc_getDisplayCountry(testLocale, NULL, testCtry, maxresultsize + 1, &status);
601
if(U_FAILURE(status)){
602
log_err("Error in getDisplayCountry() %s\n", myErrorName(status));
606
maxresultsize=uloc_getDisplayVariant(testLocale, NULL, NULL, maxresultsize, &status);
607
if(status==U_BUFFER_OVERFLOW_ERROR)
610
testVar=(UChar*)malloc(sizeof(UChar) * (maxresultsize+1));
611
uloc_getDisplayVariant(testLocale, NULL, testVar, maxresultsize + 1, &status);
617
if(U_FAILURE(status)){
618
log_err("Error in getDisplayVariant() %s\n", myErrorName(status));
621
maxresultsize=uloc_getDisplayName(testLocale, NULL, NULL, maxresultsize, &status);
622
if(status==U_BUFFER_OVERFLOW_ERROR)
625
testName=(UChar*)malloc(sizeof(UChar) * (maxresultsize+1));
626
uloc_getDisplayName(testLocale, NULL, testName, maxresultsize + 1, &status);
632
if(U_FAILURE(status)){
633
log_err("Error in getDisplayName() %s\n", myErrorName(status));
640
maxresultsize=uloc_getDisplayLanguage(testLocale, inLocale, NULL, maxresultsize, &status);
641
if(status==U_BUFFER_OVERFLOW_ERROR)
644
testLang=(UChar*)malloc(sizeof(UChar) * (maxresultsize+1));
645
uloc_getDisplayLanguage(testLocale, inLocale, testLang, maxresultsize + 1, &status);
651
if(U_FAILURE(status)){
652
log_err("Error in getDisplayLanguage() %s\n", myErrorName(status));
656
maxresultsize=uloc_getDisplayCountry(testLocale, inLocale, NULL, maxresultsize, &status);
657
if(status==U_BUFFER_OVERFLOW_ERROR)
660
testCtry=(UChar*)malloc(sizeof(UChar) * (maxresultsize+1));
661
uloc_getDisplayCountry(testLocale, inLocale, testCtry, maxresultsize + 1, &status);
667
if(U_FAILURE(status)){
668
log_err("Error in getDisplayCountry() %s\n", myErrorName(status));
672
maxresultsize=uloc_getDisplayVariant(testLocale, inLocale, NULL, maxresultsize, &status);
673
if(status==U_BUFFER_OVERFLOW_ERROR)
676
testVar=(UChar*)malloc(sizeof(UChar) * (maxresultsize+1));
677
uloc_getDisplayVariant(testLocale, inLocale, testVar, maxresultsize + 1, &status);
683
if(U_FAILURE(status)){
684
log_err("Error in getDisplayVariant() %s\n", myErrorName(status));
688
maxresultsize=uloc_getDisplayName(testLocale, inLocale, NULL, maxresultsize, &status);
689
if(status==U_BUFFER_OVERFLOW_ERROR)
692
testName=(UChar*)malloc(sizeof(UChar) * (maxresultsize+1));
693
uloc_getDisplayName(testLocale, inLocale, testName, maxresultsize + 1, &status);
699
if(U_FAILURE(status)){
700
log_err("Error in getDisplayName() %s\n", myErrorName(status));
705
expectedLang=dataTable[compareIndex][i];
706
if(u_strlen(expectedLang) == 0 && defaultIsFrench)
707
expectedLang=dataTable[DLANG_FR][i];
708
if(u_strlen(expectedLang)== 0)
709
expectedLang=dataTable[DLANG_EN][i];
712
expectedCtry=dataTable[compareIndex + 1][i];
713
if(u_strlen(expectedCtry) == 0 && defaultIsFrench)
714
expectedCtry=dataTable[DCTRY_FR][i];
715
if(u_strlen(expectedCtry)== 0)
716
expectedCtry=dataTable[DCTRY_EN][i];
718
expectedVar=dataTable[compareIndex + 2][i];
719
if(u_strlen(expectedVar) == 0 && defaultIsFrench)
720
expectedVar=dataTable[DVAR_FR][i];
721
if(u_strlen(expectedCtry)== 0)
722
expectedVar=dataTable[DVAR_EN][i];
725
expectedName=dataTable[compareIndex + 3][i];
726
if(u_strlen(expectedName) ==0 && defaultIsFrench)
727
expectedName=dataTable[DNAME_FR][i];
728
if(u_strlen(expectedName) == 0)
729
expectedName=dataTable[DNAME_EN][i];
732
if (0 !=u_strcmp(testLang,expectedLang)) {
733
log_err(" Display Language mismatch: %s versus %s inLocale=%s\n", austrdup(testLang), austrdup(expectedLang), inLocale);
736
if (0 != u_strcmp(testCtry,expectedCtry)) {
737
log_err(" Display Country mismatch: %s versus %s inLocale=%s\n", austrdup(testCtry), austrdup(expectedCtry), inLocale);
740
if (0 != u_strcmp(testVar,expectedVar)) {
741
log_err(" Display Variant mismatch: %s versus %s inLocale=%s\n", austrdup(testVar), austrdup(expectedVar), inLocale);
744
if(0 != u_strcmp(testName, expectedName)) {
745
log_err(" Display Name mismatch: %s versus %s inLocale=%s\n", austrdup(testName), austrdup(expectedName), inLocale);
748
if(testName!=&_NUL) {
751
if(testLang!=&_NUL) {
754
if(testCtry!=&_NUL) {
765
/* test for uloc_getISOLanguages, uloc_getISOCountries */
766
static void TestISOFunctions()
768
const char* const* str=uloc_getISOLanguages();
769
const char* const* str1=uloc_getISOCountries();
775
/* test getISOLanguages*/
776
/*str=uloc_getISOLanguages(); */
777
log_verbose("Testing ISO Languages: \n");
781
if(*(str+count++) == 0)
787
test = *(str+count-1);
788
if(!strcmp(test,"in")) log_err("FAIL getISOLanguages() has obsolete language code %s\n", test);
789
if(!strcmp(test,"iw")) log_err("FAIL getISOLanguages() has obsolete language code %s\n", test);
790
if(!strcmp(test,"ji")) log_err("FAIL getISOLanguages() has obsolete language code %s\n", test);
791
if(!strcmp(test,"jw")) log_err("FAIL getISOLanguages() has obsolete language code %s\n", test);
792
if(!strcmp(test,"sh")) log_err("FAIL getISOLanguages() has obsolete language code %s\n", test);
799
log_err("There is an error in getISOLanguages, got %d, expected %d\n", count, expect);
802
log_verbose("Testing ISO Countries");
807
if(*(str1 + count++)==0)
813
test = *(str1+count-1);
814
if(!strcmp(test,"FX")) log_err("FAIL getISOCountries() has obsolete country code %s\n", test);
815
if(!strcmp(test,"ZR")) log_err("FAIL getISOCountries() has obsolete country code %s\n", test);
822
log_err("There is an error in getISOCountries, got %d, expected %d \n", count, expect);
826
static void setUpDataTable()
829
dataTable = (UChar***)(calloc(sizeof(UChar**),LOCALE_INFO_SIZE));
831
for (i = 0; i < 23; i++) {
832
dataTable[i] = (UChar**)(calloc(sizeof(UChar*),LOCALE_SIZE));
833
for (j = 0; j < 5; j++){
834
dataTable[i][j] = CharsToUChars(rawData2[i][j]);
839
static void cleanUpDataTable()
842
if(dataTable != NULL) {
843
for (i=0; i<LOCALE_INFO_SIZE; i++) {
844
for(j = 0; j < LOCALE_SIZE; j++) {
845
free(dataTable[i][j]);
855
* @bug 4011756 4011380
857
static void TestISO3Fallback()
859
const char* test="xx_YY";
863
result = uloc_getISO3Language(test);
865
/* Conform to C API usage */
867
if (!result || (result[0] != 0))
868
log_err("getISO3Language() on xx_YY returned %s instead of \"\"");
870
result = uloc_getISO3Country(test);
872
if (!result || (result[0] != 0))
873
log_err("getISO3Country() on xx_YY returned %s instead of \"\"");
879
static void TestSimpleDisplayNames()
882
This test is different from TestDisplayNames because TestDisplayNames checks
883
fallback behavior, combination of language and country names to form locale
884
names, and other stuff like that. This test just checks specific language
885
and country codes to make sure we have the correct names for them.
887
char languageCodes[] [4] = { "he", "id", "iu", "ug", "yi", "za" };
888
const char* languageNames [] = { "Hebrew", "Indonesian", "Inukitut", "Uighur", "Yiddish",
890
UErrorCode status=U_ZERO_ERROR;
893
for (i = 0; i < 6; i++) {
895
UChar *expectedLang=0;
897
size=uloc_getDisplayLanguage(languageCodes[i], "en_US", NULL, size, &status);
898
if(status==U_BUFFER_OVERFLOW_ERROR) {
900
testLang=(UChar*)malloc(sizeof(UChar) * (size + 1));
901
uloc_getDisplayLanguage(languageCodes[i], "en_US", testLang, size + 1, &status);
903
expectedLang=(UChar*)malloc(sizeof(UChar) * (strlen(languageNames[i])+1));
904
u_uastrcpy(expectedLang, languageNames[i]);
905
if (u_strcmp(testLang, expectedLang) != 0)
906
log_err("Got wrong display name for %s : Expected \"%s\", got \"%s\".\n",
907
languageCodes[i], languageNames[i], austrdup(testLang));
917
static void TestUninstalledISO3Names()
919
/* This test checks to make sure getISO3Language and getISO3Country work right
920
even for locales that are not installed. */
921
const char iso2Languages [][4] = { "am", "ba", "fy", "mr", "rn",
923
const char iso3Languages [][5] = { "amh", "bak", "fry", "mar", "run",
924
"ssw", "twi", "zul" };
925
char iso2Countries [][6] = { "am_AF", "ba_BW", "fy_KZ", "mr_MO", "rn_MN",
926
"ss_SB", "tw_TC", "zu_ZW" };
927
char iso3Countries [][4] = { "AFG", "BWA", "KAZ", "MAC", "MNG",
928
"SLB", "TCA", "ZWE" };
931
for (i = 0; i < 8; i++) {
932
UErrorCode err = U_ZERO_ERROR;
934
test = uloc_getISO3Language(iso2Languages[i]);
935
if(strcmp(test, iso3Languages[i]) !=0 || U_FAILURE(err))
936
log_err("Got wrong ISO3 code for %s : Expected \"%s\", got \"%s\". %s\n",
937
iso2Languages[i], iso3Languages[i], test, myErrorName(err));
939
for (i = 0; i < 8; i++) {
940
UErrorCode err = U_ZERO_ERROR;
942
test = uloc_getISO3Country(iso2Countries[i]);
943
if(strcmp(test, iso3Countries[i]) !=0 || U_FAILURE(err))
944
log_err("Got wrong ISO3 code for %s : Expected \"%s\", got \"%s\". %s\n",
945
iso2Countries[i], iso3Countries[i], test, myErrorName(err));
950
static void TestVariantParsing()
952
const char* en_US_custom="en_US_De Anza_Cupertino_California_United States_Earth";
953
const char* dispName="English (United States, DE ANZA_CUPERTINO_CALIFORNIA_UNITED STATES_EARTH)";
954
const char* dispVar="DE ANZA_CUPERTINO_CALIFORNIA_UNITED STATES_EARTH";
955
const char* shortVariant="fr_FR_foo";
956
const char* bogusVariant="fr_FR__foo";
957
const char* bogusVariant2="fr_FR_foo_";
958
const char* bogusVariant3="fr_FR__foo_";
961
UChar displayVar[100];
962
UChar displayName[100];
963
UErrorCode status=U_ZERO_ERROR;
966
size=uloc_getDisplayVariant(en_US_custom, "en_US", NULL, size, &status);
967
if(status==U_BUFFER_OVERFLOW_ERROR) {
969
got=(UChar*)realloc(got, sizeof(UChar) * (size+1));
970
uloc_getDisplayVariant(en_US_custom, "en_US", got, size + 1, &status);
973
log_err("FAIL: Didn't get U_BUFFER_OVERFLOW_ERROR\n");
975
u_uastrcpy(displayVar, dispVar);
976
if(u_strcmp(got,displayVar)!=0) {
977
log_err("FAIL: getDisplayVariant() Wanted %s, got %s\n", dispVar, austrdup(got));
980
size=uloc_getDisplayName(en_US_custom, "en_US", NULL, size, &status);
981
if(status==U_BUFFER_OVERFLOW_ERROR) {
983
got=(UChar*)realloc(got, sizeof(UChar) * (size+1));
984
uloc_getDisplayName(en_US_custom, "en_US", got, size + 1, &status);
987
log_err("FAIL: Didn't get U_BUFFER_OVERFLOW_ERROR\n");
989
u_uastrcpy(displayName, dispName);
990
if(u_strcmp(got,displayName)!=0) {
991
log_err("FAIL: getDisplayName() Wanted %s, got %s\n", dispName, austrdup(got));
996
size=uloc_getDisplayVariant(shortVariant, NULL, NULL, size, &status);
997
if(status==U_BUFFER_OVERFLOW_ERROR) {
999
got=(UChar*)realloc(got, sizeof(UChar) * (size+1));
1000
uloc_getDisplayVariant(shortVariant, NULL, got, size + 1, &status);
1003
log_err("FAIL: Didn't get U_BUFFER_OVERFLOW_ERROR\n");
1005
if(strcmp(austrdup(got),"FOO")!=0) {
1006
log_err("FAIL: getDisplayVariant() Wanted: foo Got: %s\n", austrdup(got));
1009
status=U_ZERO_ERROR;
1010
size=uloc_getDisplayVariant(bogusVariant, NULL, NULL, size, &status);
1011
if(status==U_BUFFER_OVERFLOW_ERROR) {
1012
status=U_ZERO_ERROR;
1013
got=(UChar*)realloc(got, sizeof(UChar) * (size+1));
1014
uloc_getDisplayVariant(bogusVariant, NULL, got, size + 1, &status);
1017
log_err("FAIL: Didn't get U_BUFFER_OVERFLOW_ERROR\n");
1019
if(strcmp(austrdup(got),"_FOO")!=0) {
1020
log_err("FAIL: getDisplayVariant() Wanted: _FOO Got: %s\n", austrdup(got));
1023
status=U_ZERO_ERROR;
1024
size=uloc_getDisplayVariant(bogusVariant2, NULL, NULL, size, &status);
1025
if(status==U_BUFFER_OVERFLOW_ERROR) {
1026
status=U_ZERO_ERROR;
1027
got=(UChar*)realloc(got, sizeof(UChar) * (size+1));
1028
uloc_getDisplayVariant(bogusVariant2, NULL, got, size + 1, &status);
1031
log_err("FAIL: Didn't get U_BUFFER_OVERFLOW_ERROR\n");
1033
if(strcmp(austrdup(got),"FOO_")!=0) {
1034
log_err("FAIL: getDisplayVariant() Wanted: FOO_ Got: %s\n", austrdup(got));
1037
status=U_ZERO_ERROR;
1038
size=uloc_getDisplayVariant(bogusVariant3, NULL, NULL, size, &status);
1039
if(status==U_BUFFER_OVERFLOW_ERROR) {
1040
status=U_ZERO_ERROR;
1041
got=(UChar*)realloc(got, sizeof(UChar) * (size+1));
1042
uloc_getDisplayVariant(bogusVariant3, NULL, got, size + 1, &status);
1045
log_err("FAIL: Didn't get U_BUFFER_OVERFLOW_ERROR\n");
1047
if(strcmp(austrdup(got),"_FOO_")!=0) {
1048
log_err("FAIL: getDisplayVariant() Wanted: _FOO_ Got: %s\n", austrdup(got));
1054
static void TestObsoleteNames(void)
1057
UErrorCode status = U_ZERO_ERROR;
1069
{ "eng_USA", "eng", "en", "USA", "US" },
1070
{ "kok", "kok", "kok", "", "" },
1071
{ "in", "ind", "in", "", "" },
1072
{ "id", "ind", "id", "", "" }, /* NO aliasing */
1073
{ "sh", "srp", "sh", "", "" },
1074
{ "zz_FX", "", "zz", "FXX", "FX" },
1075
{ "zz_RO", "", "zz", "ROU", "RO" },
1076
{ "zz_ZR", "", "zz", "ZAR", "ZR" },
1077
{ "zz_FXX", "", "zz", "FXX", "FX" }, /* no aliasing. Doesn't go to PS(PSE). */
1078
{ "zz_ROM", "", "zz", "ROU", "RO" },
1079
{ "zz_ROU", "", "zz", "ROU", "RO" },
1080
{ "zz_ZAR", "", "zz", "ZAR", "ZR" },
1081
{ "mlt_PSE", "mlt", "mt", "PSE", "PS" },
1082
{ "iw", "heb", "iw", "", "" },
1083
{ "ji", "yid", "ji", "", "" },
1084
{ "jw", "jaw", "jw", "", "" },
1085
{ "sh", "srp", "sh", "", "" },
1086
{ "", "", "", "", "" }
1089
for(i=0;tests[i].locale[0];i++)
1093
locale = tests[i].locale;
1094
log_verbose("** %s:\n", locale);
1096
status = U_ZERO_ERROR;
1097
if(strcmp(tests[i].lang3,uloc_getISO3Language(locale)))
1099
log_err("FAIL: uloc_getISO3Language(%s)==\t\"%s\",\t expected \"%s\"\n",
1100
locale, uloc_getISO3Language(locale), tests[i].lang3);
1104
log_verbose(" uloc_getISO3Language()==\t\"%s\"\n",
1105
uloc_getISO3Language(locale) );
1108
status = U_ZERO_ERROR;
1109
uloc_getLanguage(locale, buff, 256, &status);
1110
if(U_FAILURE(status))
1112
log_err("FAIL: error getting language from %s\n", locale);
1116
if(strcmp(buff,tests[i].lang))
1118
log_err("FAIL: uloc_getLanguage(%s)==\t\"%s\"\t expected \"%s\"\n",
1119
locale, buff, tests[i].lang);
1123
log_verbose(" uloc_getLanguage(%s)==\t%s\n", locale, buff);
1126
if(strcmp(tests[i].lang3,uloc_getISO3Language(locale)))
1128
log_err("FAIL: uloc_getISO3Language(%s)==\t\"%s\",\t expected \"%s\"\n",
1129
locale, uloc_getISO3Language(locale), tests[i].lang3);
1133
log_verbose(" uloc_getISO3Language()==\t\"%s\"\n",
1134
uloc_getISO3Language(locale) );
1137
if(strcmp(tests[i].ctry3,uloc_getISO3Country(locale)))
1139
log_err("FAIL: uloc_getISO3Country(%s)==\t\"%s\",\t expected \"%s\"\n",
1140
locale, uloc_getISO3Country(locale), tests[i].ctry3);
1144
log_verbose(" uloc_getISO3Country()==\t\"%s\"\n",
1145
uloc_getISO3Country(locale) );
1148
status = U_ZERO_ERROR;
1149
uloc_getCountry(locale, buff, 256, &status);
1150
if(U_FAILURE(status))
1152
log_err("FAIL: error getting country from %s\n", locale);
1156
if(strcmp(buff,tests[i].ctry))
1158
log_err("FAIL: uloc_getCountry(%s)==\t\"%s\"\t expected \"%s\"\n",
1159
locale, buff, tests[i].ctry);
1163
log_verbose(" uloc_getCountry(%s)==\t%s\n", locale, buff);
1170
i = uloc_getLanguage("kok",NULL,0,&icu_err);
1171
if(U_FAILURE(icu_err))
1173
log_err("FAIL: Got %s trying to do uloc_getLanguage(kok)\n", u_errorName(icu_err));
1176
icu_err = U_ZERO_ERROR;
1177
uloc_getLanguage("kok",r1_buff,12,&icu_err);
1178
if(U_FAILURE(icu_err))
1180
log_err("FAIL: Got %s trying to do uloc_getLanguage(kok, buff)\n", u_errorName(icu_err));
1183
r1_addr = (char *)uloc_getISO3Language("kok");
1185
icu_err = U_ZERO_ERROR;
1186
if (strcmp(r1_buff,"kok") != 0)
1188
log_err("FAIL: uloc_getLanguage(kok)==%s not kok\n",r1_buff);
1191
r1_addr = (char *)uloc_getISO3Language("in");
1192
i = uloc_getLanguage(r1_addr,r1_buff,12,&icu_err);
1193
if (strcmp(r1_buff,"id") != 0)
1195
printf("uloc_getLanguage error (%s)\n",r1_buff);
1198
r1_addr = (char *)uloc_getISO3Language("sh");
1199
i = uloc_getLanguage(r1_addr,r1_buff,12,&icu_err);
1200
if (strcmp(r1_buff,"sr") != 0)
1202
printf("uloc_getLanguage error (%s)\n",r1_buff);
1206
r1_addr = (char *)uloc_getISO3Country("zz_ZR");
1207
strcpy(p1_buff,"zz_");
1208
strcat(p1_buff,r1_addr);
1209
i = uloc_getCountry(p1_buff,r1_buff,12,&icu_err);
1210
if (strcmp(r1_buff,"ZR") != 0)
1212
printf("uloc_getCountry error (%s)\n",r1_buff);
1215
r1_addr = (char *)uloc_getISO3Country("zz_FX");
1216
strcpy(p1_buff,"zz_");
1217
strcat(p1_buff,r1_addr);
1218
i = uloc_getCountry(p1_buff,r1_buff,12,&icu_err);
1219
if (strcmp(r1_buff,"FX") != 0)
1221
printf("uloc_getCountry error (%s)\n",r1_buff);
1230
TestKeyInRootRecursive(UResourceBundle *root, UResourceBundle *currentBundle, const char *locale) {
1231
UErrorCode errorCode = U_ZERO_ERROR;
1232
UResourceBundle *subRootBundle = NULL, *subBundle = NULL;
1234
ures_resetIterator(root);
1235
ures_resetIterator(currentBundle);
1236
while (ures_hasNext(currentBundle)) {
1237
const char *subBundleKey = NULL;
1239
errorCode = U_ZERO_ERROR;
1240
subBundle = ures_getNextResource(currentBundle, NULL, &errorCode);
1241
if (U_FAILURE(errorCode)) {
1242
log_err("Can't open a resource for locale %s\n", locale);
1245
subBundleKey = ures_getKey(subBundle);
1247
subRootBundle = ures_getByKey(root, subBundleKey, NULL, &errorCode);
1248
if (U_FAILURE(errorCode)) {
1249
/* if (ures_hasNext(root)) {
1250
errorCode = U_ZERO_ERROR;
1251
subRootBundle = ures_getNextResource(root, NULL, &errorCode);
1253
if (errorCode!=U_ZERO_ERROR) {
1254
if (ures_getKey(currentBundle) != 0 && strcmp(ures_getKey(currentBundle), "zoneStrings") == 0) {
1258
if (subBundleKey == NULL
1259
|| (strcmp(subBundleKey, "TransliterateLATIN") != 0 /* Ignore these special cases */
1260
&& strcmp(subBundleKey, "BreakDictionaryData") != 0))
1262
log_err("Can't open a resource with key \"%s\" in \"%s\" from root for locale \"%s\"\n",
1264
ures_getKey(currentBundle),
1267
ures_close(subBundle);
1272
if (ures_getType(subRootBundle) != ures_getType(subBundle)) {
1273
log_err("key \"%s\" in \"%s\" has a different type from root for locale \"%s\"\n"
1274
"\troot=%d, locale=%d\n",
1276
ures_getKey(currentBundle),
1278
ures_getType(subRootBundle),
1279
ures_getType(subBundle));
1282
else if (ures_getType(subBundle) == RES_INT_VECTOR) {
1284
int32_t subBundleSize;
1286
UBool sameArray = TRUE;
1287
const int32_t *subRootBundleArr = ures_getIntVector(subRootBundle, &minSize, &errorCode);
1288
const int32_t *subBundleArr = ures_getIntVector(subBundle, &subBundleSize, &errorCode);
1290
if (minSize > subBundleSize) {
1291
minSize = subBundleSize;
1292
log_err("Arrays are different size with key \"%s\" in \"%s\" from root for locale \"%s\"\n",
1294
ures_getKey(currentBundle),
1298
for (idx = 0; idx < minSize && sameArray; idx++) {
1299
if (subRootBundleArr[idx] != subBundleArr[idx]) {
1302
if (strcmp(subBundleKey, "DateTimeElements") == 0
1303
&& (subBundleArr[idx] < 1 || 7 < subBundleArr[idx]))
1305
log_err("Value out of range with key \"%s\" at index %d in \"%s\" for locale \"%s\"\n",
1308
ures_getKey(currentBundle),
1312
/* Special exception es_US and DateTimeElements */
1314
&& !(strcmp(locale, "es_US") == 0 && strcmp(subBundleKey, "DateTimeElements") == 0))
1316
log_err("Arrays are the same with key \"%s\" in \"%s\" from root for locale \"%s\"\n",
1318
ures_getKey(currentBundle),
1322
else if (ures_getType(subBundle) == RES_ARRAY) {
1323
UResourceBundle *subSubBundle = ures_getByIndex(subBundle, 0, NULL, &errorCode);
1324
UResourceBundle *subSubRootBundle = ures_getByIndex(subRootBundle, 0, NULL, &errorCode);
1326
if (U_SUCCESS(errorCode)
1327
&& (ures_getType(subSubBundle) == RES_ARRAY || ures_getType(subSubRootBundle) == RES_ARRAY))
1329
/* TODO: Properly check for 2D arrays and zoneStrings */
1330
if (subBundleKey != NULL && strcmp(subBundleKey, "zoneStrings") == 0) {
1331
/* int32_t minSize = ures_getSize(subBundle);
1334
for (idx = 0; idx < minSize; idx++) {
1335
UResourceBundle *subSubBundleAtIndex = ures_getByIndex(subBundle, idx, NULL, &errorCode);
1336
if (ures_getSize(subSubBundleAtIndex) != 6) {
1337
log_err("zoneStrings at index %d has wrong size for locale \"%s\". array size=%d\n",
1340
ures_getSize(subSubBundleAtIndex));
1342
ures_close(subSubBundleAtIndex);
1346
/* Here is one of the recursive parts */
1347
TestKeyInRootRecursive(subRootBundle, subBundle, locale);
1351
int32_t minSize = ures_getSize(subRootBundle);
1353
UBool sameArray = TRUE;
1355
if (minSize > ures_getSize(subBundle)) {
1356
minSize = ures_getSize(subBundle);
1359
if ((subBundleKey == NULL
1360
|| (subBundleKey != NULL && strcmp(subBundleKey, "LocaleScript") != 0))
1361
&& ures_getSize(subRootBundle) != ures_getSize(subBundle))
1363
log_err("Different size array with key \"%s\" in \"%s\" from root for locale \"%s\"\n"
1364
"\troot array size=%d, locale array size=%d\n",
1366
ures_getKey(currentBundle),
1368
ures_getSize(subRootBundle),
1369
ures_getSize(subBundle));
1372
for (idx = 0; idx < minSize; idx++) {
1373
int32_t rootStrLen, localeStrLen;
1374
const UChar *rootStr = ures_getStringByIndex(subRootBundle,idx,&rootStrLen,&errorCode);
1375
const UChar *localeStr = ures_getStringByIndex(subBundle,idx,&localeStrLen,&errorCode);
1376
if (rootStr && localeStr && U_SUCCESS(errorCode)) {
1377
if (u_strcmp(rootStr, localeStr) != 0) {
1382
log_err("Got a NULL string with key \"%s\" in \"%s\" at index %d for root or locale \"%s\"\n",
1384
ures_getKey(currentBundle),
1389
if (localeStr[0] == (UChar)0x20) {
1390
log_err("key \"%s\" at index %d in \"%s\" starts with a space in locale \"%s\"\n",
1393
ures_getKey(currentBundle),
1396
else if (localeStr[localeStrLen - 1] == (UChar)0x20) {
1397
log_err("key \"%s\" at index %d in \"%s\" ends with a space in locale \"%s\"\n",
1400
ures_getKey(currentBundle),
1403
else if (subBundleKey != NULL
1404
&& strcmp(subBundleKey, "DateTimePatterns") == 0)
1407
const UChar *localeStrItr = localeStr;
1408
while (*localeStrItr) {
1409
if (*localeStrItr == (UChar)0x27 /* ' */) {
1412
else if ((quoted % 2) == 0) {
1413
/* Search for unquoted characters */
1414
if (4 <= idx && idx <= 7
1415
&& (*localeStrItr == (UChar)0x6B /* k */
1416
|| *localeStrItr == (UChar)0x48 /* H */
1417
|| *localeStrItr == (UChar)0x6D /* m */
1418
|| *localeStrItr == (UChar)0x73 /* s */
1419
|| *localeStrItr == (UChar)0x53 /* S */
1420
|| *localeStrItr == (UChar)0x61 /* a */
1421
|| *localeStrItr == (UChar)0x68 /* h */
1422
|| *localeStrItr == (UChar)0x7A /* z */))
1424
log_err("key \"%s\" at index %d has time pattern chars in date for locale \"%s\"\n",
1429
else if (0 <= idx && idx <= 3
1430
&& (*localeStrItr == (UChar)0x47 /* G */
1431
|| *localeStrItr == (UChar)0x79 /* y */
1432
|| *localeStrItr == (UChar)0x4D /* M */
1433
|| *localeStrItr == (UChar)0x64 /* d */
1434
|| *localeStrItr == (UChar)0x45 /* E */
1435
|| *localeStrItr == (UChar)0x44 /* D */
1436
|| *localeStrItr == (UChar)0x46 /* F */
1437
|| *localeStrItr == (UChar)0x77 /* w */
1438
|| *localeStrItr == (UChar)0x57 /* W */))
1440
log_err("key \"%s\" at index %d has date pattern chars in time for locale \"%s\"\n",
1449
else if (idx == 4 && subBundleKey != NULL
1450
&& strcmp(subBundleKey, "NumberElements") == 0
1451
&& u_charDigitValue(localeStr[0]) != 0)
1453
log_err("key \"%s\" at index %d has a non-zero based number for locale \"%s\"\n",
1460
log_err("Arrays are the same with key \"%s\" in \"%s\" from root for locale \"%s\"\n",
1462
ures_getKey(currentBundle),
1466
ures_close(subSubBundle);
1467
ures_close(subSubRootBundle);
1469
else if (ures_getType(subBundle) == RES_STRING) {
1471
const UChar *string = ures_getString(subBundle, &len, &errorCode);
1472
if (U_FAILURE(errorCode) || string == NULL) {
1473
log_err("Can't open a string with key \"%s\" in \"%s\" for locale \"%s\"\n",
1475
ures_getKey(currentBundle),
1477
} else if (string[0] == (UChar)0x20) {
1478
log_err("key \"%s\" in \"%s\" starts with a space in locale \"%s\"\n",
1480
ures_getKey(currentBundle),
1482
} else if (string[len - 1] == (UChar)0x20) {
1483
log_err("key \"%s\" in \"%s\" ends with a space in locale \"%s\"\n",
1485
ures_getKey(currentBundle),
1487
} else if (strcmp(subBundleKey, "localPatternChars") == 0 && len != 20) {
1488
log_err("key \"%s\" has the wrong number of characters in locale \"%s\"\n",
1492
/* No fallback was done. Check for duplicate data */
1493
/* The ures_* API does not do fallback of sub-resource bundles,
1494
So we can't do this now. */
1495
else if (strcmp(locale, "root") != 0 && errorCode == U_ZERO_ERROR) {
1497
const UChar *rootString = ures_getString(subRootBundle, &len, &errorCode);
1498
if (U_FAILURE(errorCode) || rootString == NULL) {
1499
log_err("Can't open a string with key \"%s\" in \"%s\" in root\n",
1500
ures_getKey(subRootBundle),
1501
ures_getKey(currentBundle));
1503
} else if (u_strcmp(string, rootString) == 0) {
1504
if (strcmp(locale, "de_CH") != 0 && strcmp(subBundleKey, "Countries") != 0) {
1505
log_err("Found duplicate data with key \"%s\" in \"%s\" in locale \"%s\"\n",
1506
ures_getKey(subRootBundle),
1507
ures_getKey(currentBundle),
1511
/* Ignore for now. */
1512
/* Can be fixed if fallback through de locale was done. */
1513
log_verbose("Skipping key %s in %s\n", subBundleKey, locale);
1518
else if (ures_getType(subBundle) == RES_TABLE) {
1519
/* Here is one of the recursive parts */
1520
TestKeyInRootRecursive(subRootBundle, subBundle, locale);
1522
else if (ures_getType(subBundle) == RES_BINARY || ures_getType(subBundle) == RES_INT) {
1523
/* Can't do anything to check it */
1524
/* We'll assume it's all correct */
1525
log_verbose("Skipping key \"%s\" in \"%s\" for locale \"%s\"\n",
1527
ures_getKey(currentBundle),
1531
log_err("Type %d for key \"%s\" in \"%s\" is unknown for locale \"%s\"\n",
1532
ures_getType(subBundle),
1534
ures_getKey(currentBundle),
1537
ures_close(subRootBundle);
1538
ures_close(subBundle);
1546
testLCID(UResourceBundle *currentBundle,
1547
const char *localeName)
1549
UErrorCode status = U_ZERO_ERROR;
1551
uint32_t expectedLCID;
1552
char lcidStringC[64] = {0};
1553
int32_t lcidStringLen = 0;
1554
const UChar *lcidString = NULL;
1555
UResourceBundle *localeID = ures_getByKey(currentBundle, "LocaleID", NULL, &status);
1557
expectedLCID = ures_getInt(localeID, &status);
1558
ures_close(localeID);
1560
if (U_FAILURE(status)) {
1561
log_err("ERROR: %s does not have a LocaleID (%s)\n",
1562
localeName, u_errorName(status));
1566
lcid = T_convertToLCID(localeName, &status);
1567
if (U_FAILURE(status)) {
1568
if (expectedLCID == 0) {
1569
log_verbose("INFO: %-5s does not have any LCID mapping\n",
1573
log_err("ERROR: %-5s does not have an LCID mapping to 0x%.4X\n",
1574
localeName, expectedLCID);
1579
status = U_ZERO_ERROR;
1580
uprv_strcpy(lcidStringC, T_convertToPosix(expectedLCID, &status));
1581
if (U_FAILURE(status)) {
1582
log_err("ERROR: %.4x does not have a POSIX mapping due to %s\n",
1583
expectedLCID, u_errorName(status));
1586
if(lcid != expectedLCID) {
1587
log_err("ERROR: %-5s wrongfully has 0x%.4x instead of 0x%.4x for LCID\n",
1588
localeName, expectedLCID, lcid);
1590
if(strcmp(localeName, lcidStringC) != 0) {
1591
char langName[1024];
1592
char langLCID[1024];
1593
uloc_getLanguage(localeName, langName, sizeof(langName), &status);
1594
uloc_getLanguage(lcidStringC, langLCID, sizeof(langLCID), &status);
1596
if (expectedLCID == lcid && strcmp(langName, langLCID) == 0) {
1597
log_verbose("WARNING: %-5s resolves to %s (0x%.4x)\n",
1598
localeName, lcidStringC, lcid);
1600
else if (expectedLCID == lcid) {
1601
log_err("ERROR: %-5s has 0x%.4x and the number resolves wrongfully to %s\n",
1602
localeName, expectedLCID, lcidStringC);
1605
log_err("ERROR: %-5s has 0x%.4x and the number resolves wrongfully to %s. It should be 0x%x.\n",
1606
localeName, expectedLCID, lcidStringC, lcid);
1614
TestLocaleStructure(void) {
1615
UResourceBundle *root, *currentLocale;
1616
int32_t locCount = uloc_countAvailable();
1618
UErrorCode errorCode = U_ZERO_ERROR;
1620
/* TODO: Compare against parent's data too. This code can't handle fallbacks that some tools do already. */
1621
/* char locName[ULOC_FULLNAME_CAPACITY];
1624
for (locIndex = 0; locIndex < locCount; locIndex++) {
1625
errorCode=U_ZERO_ERROR;
1626
strcpy(locName, uloc_getAvailable(locIndex));
1627
locNamePtr = strrchr(locName, '_');
1632
strcpy(locName, "root");
1635
root = ures_openDirect(NULL, locName, &errorCode);
1636
if(U_FAILURE(errorCode)) {
1637
log_err("Can't open %s\n", locName);
1641
root = ures_openDirect(NULL, "root", &errorCode);
1642
if(U_FAILURE(errorCode)) {
1643
log_err("Can't open root\n");
1646
for (locIndex = 0; locIndex < locCount; locIndex++) {
1647
errorCode=U_ZERO_ERROR;
1648
currentLocale = ures_open(NULL, uloc_getAvailable(locIndex), &errorCode);
1649
if(errorCode != U_ZERO_ERROR) {
1650
if(U_SUCCESS(errorCode)) {
1651
if (strcmp(uloc_getAvailable(locIndex),"sv_FI_AL") != 0) {
1652
/* It's installed, but there is no data.
1653
It's installed for the g18n white paper [grhoten] */
1654
log_err("ERROR: Locale %-5s not installed, and it should be!\n",
1655
uloc_getAvailable(locIndex));
1658
log_err("%%%%%%% Unexpected error %d in %s %%%%%%%",
1659
u_errorName(errorCode),
1660
uloc_getAvailable(locIndex));
1662
ures_close(currentLocale);
1665
ures_getStringByKey(currentLocale, "Version", NULL, &errorCode);
1666
if(errorCode != U_ZERO_ERROR) {
1667
log_err("No version information is available for locale %s, and it should be!\n",
1668
uloc_getAvailable(locIndex));
1670
else if (ures_getStringByKey(currentLocale, "Version", NULL, &errorCode)[0] == (UChar)(0x78)) {
1671
log_err("The locale %s is experimental! It shouldn't be listed as an installed locale.\n",
1672
uloc_getAvailable(locIndex));
1674
TestKeyInRootRecursive(root, currentLocale, uloc_getAvailable(locIndex));
1676
testLCID(currentLocale, uloc_getAvailable(locIndex));
1678
ures_close(currentLocale);
1685
compareArrays(const char *keyName,
1686
UResourceBundle *fromArray, const char *fromLocale,
1687
UResourceBundle *toArray, const char *toLocale,
1688
int32_t start, int32_t end)
1690
int32_t fromSize = ures_getSize(fromArray);
1691
int32_t toSize = ures_getSize(fromArray);
1693
UErrorCode errorCode = U_ZERO_ERROR;
1695
if (fromSize > toSize) {
1697
log_err("Arrays are different size from \"%s\" to \"%s\"\n",
1702
for (idx = start; idx <= end; idx++) {
1703
const UChar *fromBundleStr = ures_getStringByIndex(fromArray, idx, NULL, &errorCode);
1704
const UChar *toBundleStr = ures_getStringByIndex(toArray, idx, NULL, &errorCode);
1705
if (fromBundleStr && toBundleStr && u_strcmp(fromBundleStr, toBundleStr) != 0)
1707
log_err("Difference for %s at index %d from %s= \"%s\" to %s= \"%s\"\n",
1711
austrdup(fromBundleStr),
1713
austrdup(toBundleStr));
1719
compareConsistentCountryInfo(const char *fromLocale, const char *toLocale) {
1720
UErrorCode errorCode = U_ZERO_ERROR;
1721
UResourceBundle *fromDateTimeElements, *toDateTimeElements;
1722
UResourceBundle *fromArray, *toArray;
1723
UResourceBundle *fromLocaleBund = ures_open(NULL, fromLocale, &errorCode);
1724
UResourceBundle *toLocaleBund = ures_open(NULL, toLocale, &errorCode);
1726
if(U_FAILURE(errorCode)) {
1727
log_err("Can't open resource bundle %s or %s\n", fromLocale, toLocale);
1731
fromDateTimeElements = ures_getByKey(fromLocaleBund, "DateTimeElements", NULL, &errorCode);
1732
toDateTimeElements = ures_getByKey(toLocaleBund, "DateTimeElements", NULL, &errorCode);
1733
if (strcmp(fromLocale, "ar_IN") != 0)
1738
const int32_t *fromBundleArr = ures_getIntVector(fromDateTimeElements, &fromSize, &errorCode);
1739
const int32_t *toBundleArr = ures_getIntVector(toDateTimeElements, &toSize, &errorCode);
1741
if (fromSize > toSize) {
1743
log_err("Arrays are different size with key \"DateTimeElements\" from \"%s\" to \"%s\"\n",
1748
for (idx = 0; idx < fromSize; idx++) {
1749
if (fromBundleArr[idx] != toBundleArr[idx]) {
1750
log_err("Difference with key \"DateTimeElements\" at index %d from \"%s\" to \"%s\"\n",
1757
ures_close(fromDateTimeElements);
1758
ures_close(toDateTimeElements);
1760
fromArray = ures_getByKey(fromLocaleBund, "CurrencyElements", NULL, &errorCode);
1761
toArray = ures_getByKey(toLocaleBund, "CurrencyElements", NULL, &errorCode);
1762
if (strcmp(fromLocale, "en_CA") != 0)
1764
/* The first one is probably localized. */
1765
compareArrays("CurrencyElements", fromArray, fromLocale, toArray, toLocale, 1, 2);
1767
ures_close(fromArray);
1768
ures_close(toArray);
1770
fromArray = ures_getByKey(fromLocaleBund, "NumberPatterns", NULL, &errorCode);
1771
toArray = ures_getByKey(toLocaleBund, "NumberPatterns", NULL, &errorCode);
1772
if (strcmp(fromLocale, "en_CA") != 0)
1774
compareArrays("NumberPatterns", fromArray, fromLocale, toArray, toLocale, 0, 3);
1776
ures_close(fromArray);
1777
ures_close(toArray);
1779
/* Difficult to test properly */
1781
fromArray = ures_getByKey(fromLocaleBund, "DateTimePatterns", NULL, &errorCode);
1782
toArray = ures_getByKey(toLocaleBund, "DateTimePatterns", NULL, &errorCode);
1784
compareArrays("DateTimePatterns", fromArray, fromLocale, toArray, toLocale);
1786
ures_close(fromArray);
1787
ures_close(toArray);*/
1789
fromArray = ures_getByKey(fromLocaleBund, "NumberElements", NULL, &errorCode);
1790
toArray = ures_getByKey(toLocaleBund, "NumberElements", NULL, &errorCode);
1791
if (strcmp(fromLocale, "en_CA") != 0)
1793
compareArrays("NumberElements", fromArray, fromLocale, toArray, toLocale, 0, 3);
1794
/* Index 4 is a script based 0 */
1795
compareArrays("NumberElements", fromArray, fromLocale, toArray, toLocale, 5, 10);
1797
ures_close(fromArray);
1798
ures_close(toArray);
1800
ures_close(fromLocaleBund);
1801
ures_close(toLocaleBund);
1805
TestConsistentCountryInfo(void) {
1806
/* UResourceBundle *fromLocale, *toLocale;*/
1807
int32_t locCount = uloc_countAvailable();
1808
int32_t fromLocIndex, toLocIndex;
1810
int32_t fromCountryLen, toCountryLen;
1811
char fromCountry[ULOC_FULLNAME_CAPACITY], toCountry[ULOC_FULLNAME_CAPACITY];
1813
int32_t fromVariantLen, toVariantLen;
1814
char fromVariant[ULOC_FULLNAME_CAPACITY], toVariant[ULOC_FULLNAME_CAPACITY];
1816
UErrorCode errorCode = U_ZERO_ERROR;
1818
for (fromLocIndex = 0; fromLocIndex < locCount; fromLocIndex++) {
1819
const char *fromLocale = uloc_getAvailable(fromLocIndex);
1821
errorCode=U_ZERO_ERROR;
1822
fromCountryLen = uloc_getCountry(fromLocale, fromCountry, ULOC_FULLNAME_CAPACITY, &errorCode);
1823
if (fromCountryLen <= 0) {
1824
/* Ignore countryless locales */
1827
fromVariantLen = uloc_getVariant(fromLocale, fromVariant, ULOC_FULLNAME_CAPACITY, &errorCode);
1828
if (fromVariantLen > 0) {
1829
/* Most variants are ignorable like PREEURO, or collation variants. */
1832
/* Start comparing only after the current index.
1833
Previous loop should have already compared fromLocIndex.
1835
for (toLocIndex = fromLocIndex + 1; toLocIndex < locCount; toLocIndex++) {
1836
const char *toLocale = uloc_getAvailable(toLocIndex);
1838
toCountryLen = uloc_getCountry(toLocale, toCountry, ULOC_FULLNAME_CAPACITY, &errorCode);
1839
if(U_FAILURE(errorCode)) {
1840
log_err("Unknown failure fromLocale=%s toLocale=%s errorCode=%s\n",
1841
fromLocale, toLocale, u_errorName(errorCode));
1845
if (toCountryLen <= 0) {
1846
/* Ignore countryless locales */
1849
toVariantLen = uloc_getVariant(toLocale, toVariant, ULOC_FULLNAME_CAPACITY, &errorCode);
1850
if (toVariantLen > 0) {
1851
/* Most variants are ignorable like PREEURO, or collation variants. */
1852
/* They're a variant for a reason. */
1855
if (strcmp(fromCountry, toCountry) == 0) {
1856
log_verbose("comparing fromLocale=%s toLocale=%s\n",
1857
fromLocale, toLocale);
1858
compareConsistentCountryInfo(fromLocale, toLocale);