#include "cloctst.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "cintltst.h"
#include "cmemory.h"
#include "cstring.h"
#include "uparse.h"
#include "uresimp.h"
#include "cmemory.h"
#include "unicode/putil.h"
#include "unicode/ubrk.h"
#include "unicode/uchar.h"
#include "unicode/ucol.h"
#include "unicode/udat.h"
#include "unicode/uloc.h"
#include "unicode/umsg.h"
#include "unicode/ures.h"
#include "unicode/uset.h"
#include "unicode/ustring.h"
#include "unicode/utypes.h"
#include "unicode/ulocdata.h"
#include "unicode/uldnames.h"
#include "unicode/parseerr.h"
#include "udbgutil.h"
#include "unicode/ualoc.h"
static void TestNullDefault(void);
static void TestNonexistentLanguageExemplars(void);
static void TestLocDataErrorCodeChaining(void);
static void TestLocDataWithRgTag(void);
static void TestLanguageExemplarsFallbacks(void);
static void TestDisplayNameBrackets(void);
static void TestUnicodeDefines(void);
static void TestIsRightToLeft(void);
static void TestBadLocaleIDs(void);
static void TestUldnNameVariants(void);
static void TestGetLanguagesForRegion(void);
static void TestGetAppleParent(void);
static void TestAppleLocalizationsToUse(void);
void PrintDataTable();
#define LOCALE_SIZE 9
#define LOCALE_INFO_SIZE 28
static const char* const rawData2[LOCALE_INFO_SIZE][LOCALE_SIZE] = {
{ "en", "fr", "ca", "el", "no", "zh", "de", "es", "ja" },
{ "", "", "", "", "", "", "", "", "" },
{ "US", "FR", "ES", "GR", "NO", "CN", "DE", "", "JP" },
{ "", "", "", "", "NY", "", "", "", "" },
{ "en_US", "fr_FR", "ca_ES",
"el_GR", "no_NO_NY", "zh_Hans_CN",
"de_DE@collation=phonebook", "es@collation=traditional", "ja_JP@calendar=japanese" },
{ "eng", "fra", "cat", "ell", "nor", "zho", "deu", "spa", "jpn" },
{ "USA", "FRA", "ESP", "GRC", "NOR", "CHN", "DEU", "", "JPN" },
{ "409", "40c", "403", "408", "814", "804", "10407", "40a", "411" },
{ "English", "French", "Catalan", "Greek", "Norwegian", "Chinese", "German", "Spanish", "Japanese" },
{ "", "", "", "", "", "Simplified Han", "", "", "" },
{ "United States", "France", "Spain", "Greece", "Norway", "China", "Germany", "", "Japan" },
{ "", "", "", "", "NY", "", "", "", "" },
{ "English (United States)", "French (France)", "Catalan (Spain)",
"Greek (Greece)", "Norwegian (Norway, NY)", "Chinese (Simplified, China)",
"German (Germany, Sort Order=Phonebook Sort Order)", "Spanish (Sort Order=Traditional Sort Order)", "Japanese (Japan, Calendar=Japanese Calendar)" },
{ "anglais", "fran\\u00E7ais", "catalan", "grec", "norv\\u00E9gien", "chinois", "allemand", "espagnol", "japonais" },
{ "", "", "", "", "", "sinogrammes simplifi\\u00e9s", "", "", "" },
{ "\\u00C9tats-Unis", "France", "Espagne", "Gr\\u00E8ce", "Norv\\u00E8ge", "Chine", "Allemagne", "", "Japon" },
{ "", "", "", "", "NY", "", "", "", "" },
{ "anglais (\\u00C9tats-Unis)", "fran\\u00E7ais (France)", "catalan (Espagne)",
"grec (Gr\\u00E8ce)", "norv\\u00E9gien (Norv\\u00E8ge, NY)", "chinois (simplifi\\u00e9, Chine)",
"allemand (Allemagne, ordre de tri=ordre de l\\u2019annuaire)", "espagnol (ordre de tri=ordre traditionnel)", "japonais (Japon, calendrier=calendrier japonais)" },
{ "angl\\u00E8s", "franc\\u00E8s", "catal\\u00E0", "grec", "noruec", "xin\\u00E8s", "alemany", "espanyol", "japon\\u00E8s" },
{ "", "", "", "", "", "han simplificat", "", "", "" },
{ "Estats Units", "Fran\\u00E7a", "Espanya", "Gr\\u00E8cia", "Noruega", "Xina", "Alemanya", "", "Jap\\u00F3" },
{ "", "", "", "", "NY", "", "", "", "" },
{ "angl\\u00E8s (Estats Units)", "franc\\u00E8s (Fran\\u00E7a)", "catal\\u00E0 (Espanya)",
"grec (Gr\\u00E8cia)", "noruec (Noruega, NY)", "xin\\u00E8s (simplificat, Xina)",
"alemany (Alemanya, ordenaci\\u00F3=ordre de la guia telef\\u00F2nica)", "espanyol (ordenaci\\u00F3=ordre tradicional)", "japon\\u00E8s (Jap\\u00F3, calendari=calendari japon\\u00e8s)" },
{
"\\u0391\\u03b3\\u03b3\\u03bb\\u03b9\\u03ba\\u03ac",
"\\u0393\\u03b1\\u03bb\\u03bb\\u03b9\\u03ba\\u03ac",
"\\u039a\\u03b1\\u03c4\\u03b1\\u03bb\\u03b1\\u03bd\\u03b9\\u03ba\\u03ac",
"\\u0395\\u03bb\\u03bb\\u03b7\\u03bd\\u03b9\\u03ba\\u03ac",
"\\u039d\\u03bf\\u03c1\\u03b2\\u03b7\\u03b3\\u03b9\\u03ba\\u03ac",
"\\u039A\\u03B9\\u03BD\\u03B5\\u03B6\\u03B9\\u03BA\\u03AC",
"\\u0393\\u03B5\\u03C1\\u03BC\\u03B1\\u03BD\\u03B9\\u03BA\\u03AC",
"\\u0399\\u03C3\\u03C0\\u03B1\\u03BD\\u03B9\\u03BA\\u03AC",
"\\u0399\\u03B1\\u03C0\\u03C9\\u03BD\\u03B9\\u03BA\\u03AC"
},
{ "", "", "", "", "", "\\u0391\\u03c0\\u03bb\\u03bf\\u03c0\\u03bf\\u03b9\\u03b7\\u03bc\\u03ad\\u03bd\\u03bf \\u03a7\\u03b1\\u03bd", "", "", "" },
{
"\\u0397\\u03BD\\u03C9\\u03BC\\u03AD\\u03BD\\u03B5\\u03C2 \\u03A0\\u03BF\\u03BB\\u03B9\\u03C4\\u03B5\\u03AF\\u03B5\\u03C2",
"\\u0393\\u03b1\\u03bb\\u03bb\\u03af\\u03b1",
"\\u0399\\u03c3\\u03c0\\u03b1\\u03bd\\u03af\\u03b1",
"\\u0395\\u03bb\\u03bb\\u03ac\\u03b4\\u03b1",
"\\u039d\\u03bf\\u03c1\\u03b2\\u03b7\\u03b3\\u03af\\u03b1",
"\\u039A\\u03AF\\u03BD\\u03B1",
"\\u0393\\u03B5\\u03C1\\u03BC\\u03B1\\u03BD\\u03AF\\u03B1",
"",
"\\u0399\\u03B1\\u03C0\\u03C9\\u03BD\\u03AF\\u03B1"
},
{ "", "", "", "", "NY", "", "", "", "" },
{
"\\u0391\\u03b3\\u03b3\\u03bb\\u03b9\\u03ba\\u03ac (\\u0397\\u03BD\\u03C9\\u03BC\\u03AD\\u03BD\\u03B5\\u03C2 \\u03A0\\u03BF\\u03BB\\u03B9\\u03C4\\u03B5\\u03AF\\u03B5\\u03C2)",
"\\u0393\\u03b1\\u03bb\\u03bb\\u03b9\\u03ba\\u03ac (\\u0393\\u03b1\\u03bb\\u03bb\\u03af\\u03b1)",
"\\u039a\\u03b1\\u03c4\\u03b1\\u03bb\\u03b1\\u03bd\\u03b9\\u03ba\\u03ac (\\u0399\\u03c3\\u03c0\\u03b1\\u03bd\\u03af\\u03b1)",
"\\u0395\\u03bb\\u03bb\\u03b7\\u03bd\\u03b9\\u03ba\\u03ac (\\u0395\\u03bb\\u03bb\\u03ac\\u03b4\\u03b1)",
"\\u039d\\u03bf\\u03c1\\u03b2\\u03b7\\u03b3\\u03b9\\u03ba\\u03ac (\\u039d\\u03bf\\u03c1\\u03b2\\u03b7\\u03b3\\u03af\\u03b1, NY)",
"\\u039A\\u03B9\\u03BD\\u03B5\\u03B6\\u03B9\\u03BA\\u03AC (\\u0391\\u03c0\\u03bb\\u03bf\\u03c0\\u03bf\\u03b9\\u03b7\\u03bc\\u03ad\\u03bd\\u03b1, \\u039A\\u03AF\\u03BD\\u03B1)",
"\\u0393\\u03b5\\u03c1\\u03bc\\u03b1\\u03bd\\u03b9\\u03ba\\u03ac (\\u0393\\u03b5\\u03c1\\u03bc\\u03b1\\u03bd\\u03af\\u03b1, \\u03a3\\u03b5\\u03b9\\u03c1\\u03ac \\u03c4\\u03b1\\u03be\\u03b9\\u03bd\\u03cc\\u03bc\\u03b7\\u03c3\\u03b7\\u03c2=\\u03a3\\u03b5\\u03b9\\u03c1\\u03ac \\u03c4\\u03b1\\u03be\\u03b9\\u03bd\\u03cc\\u03bc\\u03b7\\u03c3\\u03b7\\u03c2 \\u03c4\\u03b7\\u03bb\\u03b5\\u03c6\\u03c9\\u03bd\\u03b9\\u03ba\\u03bf\\u03cd \\u03ba\\u03b1\\u03c4\\u03b1\\u03bb\\u03cc\\u03b3\\u03bf\\u03c5)",
"\\u0399\\u03c3\\u03c0\\u03b1\\u03bd\\u03b9\\u03ba\\u03ac (\\u03a3\\u03b5\\u03b9\\u03c1\\u03ac \\u03c4\\u03b1\\u03be\\u03b9\\u03bd\\u03cc\\u03bc\\u03b7\\u03c3\\u03b7\\u03c2=\\u03a0\\u03b1\\u03c1\\u03b1\\u03b4\\u03bf\\u03c3\\u03b9\\u03b1\\u03ba\\u03ae \\u03c3\\u03b5\\u03b9\\u03c1\\u03ac \\u03c4\\u03b1\\u03be\\u03b9\\u03bd\\u03cc\\u03bc\\u03b7\\u03c3\\u03b7\\u03c2)",
"\\u0399\\u03b1\\u03c0\\u03c9\\u03bd\\u03b9\\u03ba\\u03ac (\\u0399\\u03b1\\u03c0\\u03c9\\u03bd\\u03af\\u03b1, \\u0397\\u03bc\\u03b5\\u03c1\\u03bf\\u03bb\\u03cc\\u03b3\\u03b9\\u03bf=\\u0399\\u03b1\\u03c0\\u03c9\\u03bd\\u03b9\\u03ba\\u03cc \\u03b7\\u03bc\\u03b5\\u03c1\\u03bf\\u03bb\\u03cc\\u03b3\\u03b9\\u03bf)"
}
};
static UChar*** dataTable=0;
enum {
ENGLISH = 0,
FRENCH = 1,
CATALAN = 2,
GREEK = 3,
NORWEGIAN = 4
};
enum {
LANG = 0,
SCRIPT = 1,
CTRY = 2,
VAR = 3,
NAME = 4,
LANG3 = 5,
CTRY3 = 6,
LCID = 7,
DLANG_EN = 8,
DSCRIPT_EN = 9,
DCTRY_EN = 10,
DVAR_EN = 11,
DNAME_EN = 12,
DLANG_FR = 13,
DSCRIPT_FR = 14,
DCTRY_FR = 15,
DVAR_FR = 16,
DNAME_FR = 17,
DLANG_CA = 18,
DSCRIPT_CA = 19,
DCTRY_CA = 20,
DVAR_CA = 21,
DNAME_CA = 22,
DLANG_EL = 23,
DSCRIPT_EL = 24,
DCTRY_EL = 25,
DVAR_EL = 26,
DNAME_EL = 27
};
#define TESTCASE(name) addTest(root, &name, "tsutil/cloctst/" #name)
void addLocaleTest(TestNode** root);
void addLocaleTest(TestNode** root)
{
TESTCASE(TestObsoleteNames);
TESTCASE(TestBasicGetters);
TESTCASE(TestNullDefault);
TESTCASE(TestPrefixes);
TESTCASE(TestSimpleResourceInfo);
TESTCASE(TestDisplayNames);
TESTCASE(TestGetAvailableLocales);
TESTCASE(TestDataDirectory);
#if !UCONFIG_NO_FILE_IO && !UCONFIG_NO_LEGACY_CONVERSION
TESTCASE(TestISOFunctions);
#endif
TESTCASE(TestISO3Fallback);
TESTCASE(TestUninstalledISO3Names);
TESTCASE(TestSimpleDisplayNames);
TESTCASE(TestVariantParsing);
TESTCASE(TestKeywordVariants);
TESTCASE(TestKeywordVariantParsing);
TESTCASE(TestCanonicalization);
TESTCASE(TestKeywordSet);
TESTCASE(TestKeywordSetError);
TESTCASE(TestDisplayKeywords);
TESTCASE(TestDisplayKeywordValues);
TESTCASE(TestGetBaseName);
#if !UCONFIG_NO_FILE_IO
TESTCASE(TestGetLocale);
#endif
TESTCASE(TestDisplayNameWarning);
TESTCASE(TestNonexistentLanguageExemplars);
TESTCASE(TestLocDataErrorCodeChaining);
TESTCASE(TestLocDataWithRgTag);
TESTCASE(TestLanguageExemplarsFallbacks);
TESTCASE(TestCalendar);
TESTCASE(TestDateFormat);
TESTCASE(TestCollation);
TESTCASE(TestULocale);
TESTCASE(TestUResourceBundle);
TESTCASE(TestDisplayName);
TESTCASE(TestAcceptLanguage);
TESTCASE(TestGetLocaleForLCID);
TESTCASE(TestOrientation);
TESTCASE(TestLikelySubtags);
TESTCASE(TestToLanguageTag);
TESTCASE(TestForLanguageTag);
TESTCASE(TestTrailingNull);
TESTCASE(TestUnicodeDefines);
TESTCASE(TestEnglishExemplarCharacters);
TESTCASE(TestDisplayNameBrackets);
TESTCASE(TestIsRightToLeft);
TESTCASE(TestToUnicodeLocaleKey);
TESTCASE(TestToLegacyKey);
TESTCASE(TestToUnicodeLocaleType);
TESTCASE(TestToLegacyType);
TESTCASE(TestBadLocaleIDs);
TESTCASE(TestUldnNameVariants);
TESTCASE(TestGetLanguagesForRegion);
TESTCASE(TestGetAppleParent);
TESTCASE(TestAppleLocalizationsToUse);
}
static void TestBasicGetters() {
int32_t i;
int32_t cap;
UErrorCode status = U_ZERO_ERROR;
char *testLocale = 0;
char *temp = 0, *name = 0;
log_verbose("Testing Basic Getters\n");
for (i = 0; i < LOCALE_SIZE; i++) {
testLocale=(char*)malloc(sizeof(char) * (strlen(rawData2[NAME][i])+1));
strcpy(testLocale,rawData2[NAME][i]);
log_verbose("Testing %s .....\n", testLocale);
cap=uloc_getLanguage(testLocale, NULL, 0, &status);
if(status==U_BUFFER_OVERFLOW_ERROR){
status=U_ZERO_ERROR;
temp=(char*)malloc(sizeof(char) * (cap+1));
uloc_getLanguage(testLocale, temp, cap+1, &status);
}
if(U_FAILURE(status)){
log_err("ERROR: in uloc_getLanguage %s\n", myErrorName(status));
}
if (0 !=strcmp(temp,rawData2[LANG][i])) {
log_err(" Language code mismatch: %s versus %s\n", temp, rawData2[LANG][i]);
}
cap=uloc_getCountry(testLocale, temp, cap, &status);
if(status==U_BUFFER_OVERFLOW_ERROR){
status=U_ZERO_ERROR;
temp=(char*)realloc(temp, sizeof(char) * (cap+1));
uloc_getCountry(testLocale, temp, cap+1, &status);
}
if(U_FAILURE(status)){
log_err("ERROR: in uloc_getCountry %s\n", myErrorName(status));
}
if (0 != strcmp(temp, rawData2[CTRY][i])) {
log_err(" Country code mismatch: %s versus %s\n", temp, rawData2[CTRY][i]);
}
cap=uloc_getVariant(testLocale, temp, cap, &status);
if(status==U_BUFFER_OVERFLOW_ERROR){
status=U_ZERO_ERROR;
temp=(char*)realloc(temp, sizeof(char) * (cap+1));
uloc_getVariant(testLocale, temp, cap+1, &status);
}
if(U_FAILURE(status)){
log_err("ERROR: in uloc_getVariant %s\n", myErrorName(status));
}
if (0 != strcmp(temp, rawData2[VAR][i])) {
log_err("Variant code mismatch: %s versus %s\n", temp, rawData2[VAR][i]);
}
cap=uloc_getName(testLocale, NULL, 0, &status);
if(status==U_BUFFER_OVERFLOW_ERROR){
status=U_ZERO_ERROR;
name=(char*)malloc(sizeof(char) * (cap+1));
uloc_getName(testLocale, name, cap+1, &status);
} else if(status==U_ZERO_ERROR) {
log_err("ERROR: in uloc_getName(%s,NULL,0,..), expected U_BUFFER_OVERFLOW_ERROR!\n", testLocale);
}
if(U_FAILURE(status)){
log_err("ERROR: in uloc_getName %s\n", myErrorName(status));
}
if (0 != strcmp(name, rawData2[NAME][i])){
log_err(" Mismatch in getName: %s versus %s\n", name, rawData2[NAME][i]);
}
free(temp);
free(name);
free(testLocale);
}
}
static void TestNullDefault() {
UErrorCode status = U_ZERO_ERROR;
char original[ULOC_FULLNAME_CAPACITY];
uprv_strcpy(original, uloc_getDefault());
uloc_setDefault("qq_BLA", &status);
if (uprv_strcmp(uloc_getDefault(), "qq_BLA") != 0) {
log_err(" Mismatch in uloc_setDefault: qq_BLA versus %s\n", uloc_getDefault());
}
uloc_setDefault(NULL, &status);
if (uprv_strcmp(uloc_getDefault(), original) != 0) {
log_err(" uloc_setDefault(NULL, &status) didn't get the default locale back!\n");
}
{
const char *n_en_US;
const char *n_fr_FR;
const char *n2_en_US;
status = U_ZERO_ERROR;
uloc_setDefault("en_US", &status);
n_en_US = uloc_getDefault();
if (strcmp(n_en_US, "en_US") != 0) {
log_err("Wrong result from uloc_getDefault(). Expected \"en_US\", got \"%s\"\n", n_en_US);
}
uloc_setDefault("fr_FR", &status);
n_fr_FR = uloc_getDefault();
if (strcmp(n_en_US, "en_US") != 0) {
log_err("uloc_setDefault altered previously default string."
"Expected \"en_US\", got \"%s\"\n", n_en_US);
}
if (strcmp(n_fr_FR, "fr_FR") != 0) {
log_err("Wrong result from uloc_getDefault(). Expected \"fr_FR\", got %s\n", n_fr_FR);
}
uloc_setDefault("en_US", &status);
n2_en_US = uloc_getDefault();
if (strcmp(n2_en_US, "en_US") != 0) {
log_err("Wrong result from uloc_getDefault(). Expected \"en_US\", got \"%s\"\n", n_en_US);
}
if (n2_en_US != n_en_US) {
log_err("Default locale cache failed to reuse en_US locale.\n");
}
if (U_FAILURE(status)) {
log_err("Failure returned from uloc_setDefault - \"%s\"\n", u_errorName(status));
}
}
}
#define PREFIXBUFSIZ 128
static void TestPrefixes() {
int row = 0;
int n;
const char *loc, *expected;
static const char * const testData[][7] =
{
{"sv", "", "FI", "AL", "sv-fi-al", "sv_FI_AL", NULL},
{"en", "", "GB", "", "en-gb", "en_GB", NULL},
{"i-hakka", "", "MT", "XEMXIJA", "i-hakka_MT_XEMXIJA", "i-hakka_MT_XEMXIJA", NULL},
{"i-hakka", "", "CN", "", "i-hakka_CN", "i-hakka_CN", NULL},
{"i-hakka", "", "MX", "", "I-hakka_MX", "i-hakka_MX", NULL},
{"x-klingon", "", "US", "SANJOSE", "X-KLINGON_us_SANJOSE", "x-klingon_US_SANJOSE", NULL},
{"zh", "Hans", "", "PINYIN", "zh-Hans-pinyin", "zh_Hans__PINYIN", "zh_Hans@collation=pinyin"},
{"hy", "", "", "AREVMDA", "hy_AREVMDA", "hy__AREVMDA", NULL},
{"de", "", "", "1901", "de-1901", "de__1901", NULL},
{"mr", "", "", "", "mr.utf8", "mr.utf8", "mr"},
{"de", "", "TV", "", "de-tv.koi8r", "de_TV.koi8r", "de_TV"},
{"x-piglatin", "", "ML", "", "x-piglatin_ML.MBE", "x-piglatin_ML.MBE", "x-piglatin_ML"},
{"i-cherokee", "","US", "", "i-Cherokee_US.utf7", "i-cherokee_US.utf7", "i-cherokee_US"},
{"x-filfli", "", "MT", "FILFLA", "x-filfli_MT_FILFLA.gb-18030", "x-filfli_MT_FILFLA.gb-18030", "x-filfli_MT_FILFLA"},
{"no", "", "NO", "NY", "no-no-ny.utf32@B", "no_NO_NY.utf32@B", "no_NO_NY_B"},
{"no", "", "NO", "", "no-no.utf32@B", "no_NO.utf32@B", "no_NO_B"},
{"no", "", "", "NY", "no__ny", "no__NY", NULL},
{"no", "", "", "", "no@ny", "no@ny", "no__NY"},
{"el", "Latn", "", "", "el-latn", "el_Latn", NULL},
{"en", "Cyrl", "RU", "", "en-cyrl-ru", "en_Cyrl_RU", NULL},
{"zh", "Hant", "TW", "STROKE", "zh-hant_TW_STROKE", "zh_Hant_TW_STROKE", "zh_Hant_TW@collation=stroke"},
{"qq", "Qqqq", "QQ", "QQ", "qq_Qqqq_QQ_QQ", "qq_Qqqq_QQ_QQ", NULL},
{"qq", "Qqqq", "", "QQ", "qq_Qqqq__QQ", "qq_Qqqq__QQ", NULL},
{"ab", "Cdef", "GH", "IJ", "ab_cdef_gh_ij", "ab_Cdef_GH_IJ", NULL},
{NULL,NULL,NULL,NULL,NULL,NULL,NULL}
};
static const char * const testTitles[] = {
"uloc_getLanguage()",
"uloc_getScript()",
"uloc_getCountry()",
"uloc_getVariant()",
"name",
"uloc_getName()",
"uloc_canonicalize()"
};
char buf[PREFIXBUFSIZ];
int32_t len;
UErrorCode err;
for(row=0;testData[row][0] != NULL;row++) {
loc = testData[row][NAME];
log_verbose("Test #%d: %s\n", row, loc);
err = U_ZERO_ERROR;
len=0;
buf[0]=0;
for(n=0;n<=(NAME+2);n++) {
if(n==NAME) continue;
for(len=0;len<PREFIXBUFSIZ;len++) {
buf[len] = '%';
}
len = 0;
switch(n) {
case LANG:
len = uloc_getLanguage(loc, buf, PREFIXBUFSIZ, &err);
break;
case SCRIPT:
len = uloc_getScript(loc, buf, PREFIXBUFSIZ, &err);
break;
case CTRY:
len = uloc_getCountry(loc, buf, PREFIXBUFSIZ, &err);
break;
case VAR:
len = uloc_getVariant(loc, buf, PREFIXBUFSIZ, &err);
break;
case NAME+1:
len = uloc_getName(loc, buf, PREFIXBUFSIZ, &err);
break;
case NAME+2:
len = uloc_canonicalize(loc, buf, PREFIXBUFSIZ, &err);
break;
default:
strcpy(buf, "**??");
len=4;
}
if(U_FAILURE(err)) {
log_err("#%d: %s on %s: err %s\n",
row, testTitles[n], loc, u_errorName(err));
} else {
log_verbose("#%d: %s on %s: -> [%s] (length %d)\n",
row, testTitles[n], loc, buf, len);
if(len != (int32_t)strlen(buf)) {
log_err("#%d: %s on %s: -> [%s] (length returned %d, actual %d!)\n",
row, testTitles[n], loc, buf, len, strlen(buf)+1);
}
if(buf[len+1] != '%') {
log_err("#%d: %s on %s: -> [%s] - wrote [%X] out ofbounds!\n",
row, testTitles[n], loc, buf, buf[len+1]);
}
expected = testData[row][n];
if (expected == NULL && n == (NAME+2)) {
expected = testData[row][NAME+1];
}
if(strcmp(buf, expected)) {
log_err("#%d: %s on %s: -> [%s] (expected '%s'!)\n",
row, testTitles[n], loc, buf, expected);
}
}
}
}
}
static void TestSimpleResourceInfo() {
int32_t i;
char* testLocale = 0;
UChar* expected = 0;
const char* temp;
char temp2[20];
testLocale=(char*)malloc(sizeof(char) * 1);
expected=(UChar*)malloc(sizeof(UChar) * 1);
setUpDataTable();
log_verbose("Testing getISO3Language and getISO3Country\n");
for (i = 0; i < LOCALE_SIZE; i++) {
testLocale=(char*)realloc(testLocale, sizeof(char) * (u_strlen(dataTable[NAME][i])+1));
u_austrcpy(testLocale, dataTable[NAME][i]);
log_verbose("Testing %s ......\n", testLocale);
temp=uloc_getISO3Language(testLocale);
expected=(UChar*)realloc(expected, sizeof(UChar) * (strlen(temp) + 1));
u_uastrcpy(expected,temp);
if (0 != u_strcmp(expected, dataTable[LANG3][i])) {
log_err(" ISO-3 language code mismatch: %s versus %s\n", austrdup(expected),
austrdup(dataTable[LANG3][i]));
}
temp=uloc_getISO3Country(testLocale);
expected=(UChar*)realloc(expected, sizeof(UChar) * (strlen(temp) + 1));
u_uastrcpy(expected,temp);
if (0 != u_strcmp(expected, dataTable[CTRY3][i])) {
log_err(" ISO-3 Country code mismatch: %s versus %s\n", austrdup(expected),
austrdup(dataTable[CTRY3][i]));
}
sprintf(temp2, "%x", (int)uloc_getLCID(testLocale));
if (strcmp(temp2, rawData2[LCID][i]) != 0) {
log_err("LCID mismatch: %s versus %s\n", temp2 , rawData2[LCID][i]);
}
}
free(expected);
free(testLocale);
cleanUpDataTable();
}
static int32_t UCharsToEscapedAscii(const UChar* utext, int32_t len, char* resultChars, int32_t buflen) {
static const struct {
char escapedChar;
UChar sourceVal;
} ESCAPE_MAP[] = {
{'a', 0x07},
{'b', 0x08},
{'e', 0x1b},
{'f', 0x0c},
{'n', 0x0a},
{'r', 0x0d},
{'t', 0x09},
{'v', 0x0b}
};
static const int32_t ESCAPE_MAP_LENGTH = UPRV_LENGTHOF(ESCAPE_MAP);
static const char HEX_DIGITS[] = {
'0', '1', '2', '3', '4', '5', '6', '7',
'8', '9', 'a', 'b', 'c', 'd', 'e', 'f'
};
int32_t i, j;
int32_t resultLen = 0;
const int32_t limit = len<0 ? buflen : len;
const int32_t escapeLimit1 = buflen-2;
const int32_t escapeLimit2 = buflen-6;
UChar uc;
if(utext==NULL || resultChars==NULL || buflen<0) {
return -1;
}
for(i=0;i<limit && resultLen<buflen;++i) {
uc=utext[i];
if(len<0 && uc==0) {
break;
}
if(uc<0x20) {
for(j=0;j<ESCAPE_MAP_LENGTH && uc!=ESCAPE_MAP[j].sourceVal;j++) {
}
if(j<ESCAPE_MAP_LENGTH) {
if(resultLen>escapeLimit1) {
break;
}
resultChars[resultLen++]='\\';
resultChars[resultLen++]=ESCAPE_MAP[j].escapedChar;
continue;
}
} else if(uc<0x7f) {
u_austrncpy(resultChars + resultLen, &uc, 1);
resultLen++;
continue;
}
if(resultLen>escapeLimit2) {
break;
}
resultChars[resultLen++]='\\';
resultChars[resultLen++]='u';
resultChars[resultLen++]=HEX_DIGITS[(uc>>12)&0xff];
resultChars[resultLen++]=HEX_DIGITS[(uc>>8)&0xff];
resultChars[resultLen++]=HEX_DIGITS[(uc>>4)&0xff];
resultChars[resultLen++]=HEX_DIGITS[uc&0xff];
}
if(resultLen<buflen) {
resultChars[resultLen] = 0;
}
return resultLen;
}
static void TestDisplayNames()
{
UChar buffer[100];
UErrorCode errorCode=U_ZERO_ERROR;
int32_t length;
log_verbose("Testing getDisplayName for different locales\n");
log_verbose(" In locale = en_US...\n");
doTestDisplayNames("en_US", DLANG_EN);
log_verbose(" In locale = fr_FR....\n");
doTestDisplayNames("fr_FR", DLANG_FR);
log_verbose(" In locale = ca_ES...\n");
doTestDisplayNames("ca_ES", DLANG_CA);
log_verbose(" In locale = gr_EL..\n");
doTestDisplayNames("el_GR", DLANG_EL);
errorCode=U_ZERO_ERROR;
length=uloc_getDisplayLanguage(NULL, NULL, buffer, UPRV_LENGTHOF(buffer), &errorCode);
if(U_FAILURE(errorCode) || (length<=3 && buffer[0]<=0x7f)) {
log_data_err("unable to get a display string for the language of the default locale - %s (Are you missing data?)\n", u_errorName(errorCode));
}
errorCode=U_ZERO_ERROR;
length=uloc_getDisplayLanguage("qq", "rr", buffer, UPRV_LENGTHOF(buffer), &errorCode);
if(errorCode!=U_USING_DEFAULT_WARNING || length!=2 || buffer[0]!=0x71 || buffer[1]!=0x71) {
log_err("error getting the display string for an unknown language - %s\n", u_errorName(errorCode));
}
errorCode=U_ZERO_ERROR;
length=uloc_getDisplayName("qq_US_POSIX", "en_US", buffer, UPRV_LENGTHOF(buffer), &errorCode);
if(errorCode!=U_USING_DEFAULT_WARNING) {
log_err("error getting the display name for a locale with an unknown language - %s\n", u_errorName(errorCode));
}
{
int32_t i;
static const char *aLocale = "es@collation=traditional;calendar=japanese";
static const char *testL[] = { "en_US",
"fr_FR",
"ca_ES",
"el_GR" };
static const char *expect[] = { "Spanish (Calendar=Japanese Calendar, Sort Order=Traditional Sort Order)",
"espagnol (calendrier=calendrier japonais, ordre de tri=ordre traditionnel)",
"espanyol (calendari=calendari japon\\u00e8s, ordenaci\\u00f3=ordre tradicional)",
"\\u0399\\u03c3\\u03c0\\u03b1\\u03bd\\u03b9\\u03ba\\u03ac (\\u0397\\u03bc\\u03b5\\u03c1\\u03bf\\u03bb\\u03cc\\u03b3\\u03b9\\u03bf=\\u0399\\u03b1\\u03c0\\u03c9\\u03bd\\u03b9\\u03ba\\u03cc \\u03b7\\u03bc\\u03b5\\u03c1\\u03bf\\u03bb\\u03cc\\u03b3\\u03b9\\u03bf, \\u03a3\\u03b5\\u03b9\\u03c1\\u03ac \\u03c4\\u03b1\\u03be\\u03b9\\u03bd\\u03cc\\u03bc\\u03b7\\u03c3\\u03b7\\u03c2=\\u03a0\\u03b1\\u03c1\\u03b1\\u03b4\\u03bf\\u03c3\\u03b9\\u03b1\\u03ba\\u03ae \\u03c3\\u03b5\\u03b9\\u03c1\\u03ac \\u03c4\\u03b1\\u03be\\u03b9\\u03bd\\u03cc\\u03bc\\u03b7\\u03c3\\u03b7\\u03c2)" };
UChar *expectBuffer;
for(i=0;i<UPRV_LENGTHOF(testL);i++) {
errorCode = U_ZERO_ERROR;
uloc_getDisplayName(aLocale, testL[i], buffer, UPRV_LENGTHOF(buffer), &errorCode);
if(U_FAILURE(errorCode)) {
log_err("FAIL in uloc_getDisplayName(%s,%s,..) -> %s\n", aLocale, testL[i], u_errorName(errorCode));
} else {
expectBuffer = CharsToUChars(expect[i]);
if(u_strcmp(buffer,expectBuffer)) {
log_data_err("FAIL in uloc_getDisplayName(%s,%s,..) expected '%s' got '%s' (Are you missing data?)\n", aLocale, testL[i], expect[i], austrdup(buffer));
} else {
log_verbose("pass in uloc_getDisplayName(%s,%s,..) got '%s'\n", aLocale, testL[i], expect[i]);
}
free(expectBuffer);
}
}
}
{
int32_t i;
static const char *locale="az_Cyrl";
static const char *displayLocale="ja";
static const char *expectedChars =
"\\u30a2\\u30bc\\u30eb\\u30d0\\u30a4\\u30b8\\u30e3\\u30f3\\u8a9e "
"(\\u30ad\\u30ea\\u30eb\\u6587\\u5b57)";
UErrorCode ec=U_ZERO_ERROR;
UChar result[256];
int32_t len;
int32_t preflightLen=uloc_getDisplayName(locale, displayLocale, NULL, 0, &ec);
if(ec==U_BUFFER_OVERFLOW_ERROR) {
ec=U_ZERO_ERROR;
}
len=uloc_getDisplayName(locale, displayLocale, result, UPRV_LENGTHOF(result), &ec);
if(U_FAILURE(ec)) {
log_err("uloc_getDisplayName(%s, %s...) returned error: %s",
locale, displayLocale, u_errorName(ec));
} else {
UChar *expected=CharsToUChars(expectedChars);
int32_t expectedLen=u_strlen(expected);
if(len!=expectedLen) {
log_data_err("uloc_getDisplayName(%s, %s...) returned string of length %d, expected length %d",
locale, displayLocale, len, expectedLen);
} else if(preflightLen!=expectedLen) {
log_err("uloc_getDisplayName(%s, %s...) returned preflight length %d, expected length %d",
locale, displayLocale, preflightLen, expectedLen);
} else if(u_strncmp(result, expected, len)) {
int32_t cap=len*6+1;
char* resultChars=(char*)malloc(cap);
int32_t resultCharsLen=UCharsToEscapedAscii(result, len, resultChars, cap);
if(resultCharsLen<0 || resultCharsLen<cap-1) {
log_err("uloc_getDisplayName(%s, %s...) mismatch", locale, displayLocale);
} else {
log_err("uloc_getDisplayName(%s, %s...) returned '%s' but expected '%s'",
locale, displayLocale, resultChars, expectedChars);
}
free(resultChars);
resultChars=NULL;
} else {
for(i=len+1;i>=0;--i) {
len=uloc_getDisplayName(locale, displayLocale, result, i, &ec);
if(ec==U_BUFFER_OVERFLOW_ERROR) {
ec=U_ZERO_ERROR;
}
if(U_FAILURE(ec)) {
log_err("using buffer of length %d returned error %s", i, u_errorName(ec));
break;
}
if(len!=expectedLen) {
log_err("with buffer of length %d, expected length %d but got %d", i, expectedLen, len);
break;
}
}
}
free(expected);
}
}
}
static void TestGetAvailableLocales()
{
const char *locList;
int32_t locCount,i;
log_verbose("Testing the no of avialable locales\n");
locCount=uloc_countAvailable();
if (locCount == 0)
log_data_err("countAvailable() returned an empty list!\n");
else if(locCount < 0){
log_data_err("countAvailable() returned a wrong value!= %d\n", locCount);
}
else{
log_info("Number of locales returned = %d\n", locCount);
}
for(i=0;i<locCount;i++){
locList=uloc_getAvailable(i);
log_verbose(" %s\n", locList);
}
}
static void TestDataDirectory()
{
char oldDirectory[512];
const char *temp,*testValue1,*testValue2,*testValue3;
const char path[40] ="d:\\icu\\source\\test\\intltest" U_FILE_SEP_STRING;
log_verbose("Testing getDataDirectory()\n");
temp = u_getDataDirectory();
strcpy(oldDirectory, temp);
testValue1=uloc_getISO3Language("en_US");
log_verbose("first fetch of language retrieved %s\n", testValue1);
if (0 != strcmp(testValue1,"eng")){
log_err("Initial check of ISO3 language failed: expected \"eng\", got %s \n", testValue1);
}
log_verbose("Testing setDataDirectory\n");
u_setDataDirectory( path );
if(strcmp(path, u_getDataDirectory())==0)
log_verbose("setDataDirectory working fine\n");
else
log_err("Error in setDataDirectory. Directory not set correctly - came back as [%s], expected [%s]\n", u_getDataDirectory(), path);
testValue2=uloc_getISO3Language("en_US");
log_verbose("second fetch of language retrieved %s \n", testValue2);
u_setDataDirectory(oldDirectory);
testValue3=uloc_getISO3Language("en_US");
log_verbose("third fetch of language retrieved %s \n", testValue3);
if (0 != strcmp(testValue3,"eng")) {
log_err("get/setDataDirectory() failed: expected \"eng\", got \" %s \" \n", testValue3);
}
}
static UChar _NUL=0;
static void doTestDisplayNames(const char* displayLocale, int32_t compareIndex)
{
UErrorCode status = U_ZERO_ERROR;
int32_t i;
int32_t maxresultsize;
const char *testLocale;
UChar *testLang = 0;
UChar *testScript = 0;
UChar *testCtry = 0;
UChar *testVar = 0;
UChar *testName = 0;
UChar* expectedLang = 0;
UChar* expectedScript = 0;
UChar* expectedCtry = 0;
UChar* expectedVar = 0;
UChar* expectedName = 0;
setUpDataTable();
for(i=0;i<LOCALE_SIZE; ++i)
{
testLocale=rawData2[NAME][i];
log_verbose("Testing..... %s\n", testLocale);
maxresultsize=0;
maxresultsize=uloc_getDisplayLanguage(testLocale, displayLocale, NULL, maxresultsize, &status);
if(status==U_BUFFER_OVERFLOW_ERROR)
{
status=U_ZERO_ERROR;
testLang=(UChar*)malloc(sizeof(UChar) * (maxresultsize+1));
uloc_getDisplayLanguage(testLocale, displayLocale, testLang, maxresultsize + 1, &status);
}
else
{
testLang=&_NUL;
}
if(U_FAILURE(status)){
log_err("Error in getDisplayLanguage() %s\n", myErrorName(status));
}
maxresultsize=0;
maxresultsize=uloc_getDisplayScript(testLocale, displayLocale, NULL, maxresultsize, &status);
if(status==U_BUFFER_OVERFLOW_ERROR)
{
status=U_ZERO_ERROR;
testScript=(UChar*)malloc(sizeof(UChar) * (maxresultsize+1));
uloc_getDisplayScript(testLocale, displayLocale, testScript, maxresultsize + 1, &status);
}
else
{
testScript=&_NUL;
}
if(U_FAILURE(status)){
log_err("Error in getDisplayScript() %s\n", myErrorName(status));
}
maxresultsize=0;
maxresultsize=uloc_getDisplayCountry(testLocale, displayLocale, NULL, maxresultsize, &status);
if(status==U_BUFFER_OVERFLOW_ERROR)
{
status=U_ZERO_ERROR;
testCtry=(UChar*)malloc(sizeof(UChar) * (maxresultsize+1));
uloc_getDisplayCountry(testLocale, displayLocale, testCtry, maxresultsize + 1, &status);
}
else
{
testCtry=&_NUL;
}
if(U_FAILURE(status)){
log_err("Error in getDisplayCountry() %s\n", myErrorName(status));
}
maxresultsize=0;
maxresultsize=uloc_getDisplayVariant(testLocale, displayLocale, NULL, maxresultsize, &status);
if(status==U_BUFFER_OVERFLOW_ERROR)
{
status=U_ZERO_ERROR;
testVar=(UChar*)malloc(sizeof(UChar) * (maxresultsize+1));
uloc_getDisplayVariant(testLocale, displayLocale, testVar, maxresultsize + 1, &status);
}
else
{
testVar=&_NUL;
}
if(U_FAILURE(status)){
log_err("Error in getDisplayVariant() %s\n", myErrorName(status));
}
maxresultsize=0;
maxresultsize=uloc_getDisplayName(testLocale, displayLocale, NULL, maxresultsize, &status);
if(status==U_BUFFER_OVERFLOW_ERROR)
{
status=U_ZERO_ERROR;
testName=(UChar*)malloc(sizeof(UChar) * (maxresultsize+1));
uloc_getDisplayName(testLocale, displayLocale, testName, maxresultsize + 1, &status);
}
else
{
testName=&_NUL;
}
if(U_FAILURE(status)){
log_err("Error in getDisplayName() %s\n", myErrorName(status));
}
expectedLang=dataTable[compareIndex][i];
if(u_strlen(expectedLang)== 0)
expectedLang=dataTable[DLANG_EN][i];
expectedScript=dataTable[compareIndex + 1][i];
if(u_strlen(expectedScript)== 0)
expectedScript=dataTable[DSCRIPT_EN][i];
expectedCtry=dataTable[compareIndex + 2][i];
if(u_strlen(expectedCtry)== 0)
expectedCtry=dataTable[DCTRY_EN][i];
expectedVar=dataTable[compareIndex + 3][i];
if(u_strlen(expectedVar)== 0)
expectedVar=dataTable[DVAR_EN][i];
expectedName=dataTable[compareIndex + 4][i];
if(u_strlen(expectedName) == 0)
expectedName=dataTable[DNAME_EN][i];
if (0 !=u_strcmp(testLang,expectedLang)) {
log_data_err(" Display Language mismatch: got %s expected %s displayLocale=%s (Are you missing data?)\n", austrdup(testLang), austrdup(expectedLang), displayLocale);
}
if (0 != u_strcmp(testScript,expectedScript)) {
log_data_err(" Display Script mismatch: got %s expected %s displayLocale=%s (Are you missing data?)\n", austrdup(testScript), austrdup(expectedScript), displayLocale);
}
if (0 != u_strcmp(testCtry,expectedCtry)) {
log_data_err(" Display Country mismatch: got %s expected %s displayLocale=%s (Are you missing data?)\n", austrdup(testCtry), austrdup(expectedCtry), displayLocale);
}
if (0 != u_strcmp(testVar,expectedVar)) {
log_data_err(" Display Variant mismatch: got %s expected %s displayLocale=%s (Are you missing data?)\n", austrdup(testVar), austrdup(expectedVar), displayLocale);
}
if(0 != u_strcmp(testName, expectedName)) {
log_data_err(" Display Name mismatch: got %s expected %s displayLocale=%s (Are you missing data?)\n", austrdup(testName), austrdup(expectedName), displayLocale);
}
if(testName!=&_NUL) {
free(testName);
}
if(testLang!=&_NUL) {
free(testLang);
}
if(testScript!=&_NUL) {
free(testScript);
}
if(testCtry!=&_NUL) {
free(testCtry);
}
if(testVar!=&_NUL) {
free(testVar);
}
}
cleanUpDataTable();
}
typedef struct {
const char * displayLocale;
const char * namedRegion;
const char * namedLocale;
const char * regionName;
const char * ulocLocaleName;
const char * uldnLocaleName;
} DisplayNameBracketsItem;
static const DisplayNameBracketsItem displayNameBracketsItems[] = {
{ "en", "CC", "en_CC", "Cocos (Keeling) Islands", "English (Cocos [Keeling] Islands)", "English (Cocos [Keeling] Islands)" },
{ "en", "MM", "my_MM", "Myanmar (Burma)", "Burmese (Myanmar [Burma])", "Burmese (Myanmar)" },
{ "en", "MM", "my_Mymr_MM", "Myanmar (Burma)", "Burmese (Myanmar, Myanmar [Burma])", "Burmese (Myanmar, Myanmar)" },
{ "zh", "CC", "en_CC", "\\u79D1\\u79D1\\u65AF\\uFF08\\u57FA\\u6797\\uFF09\\u7FA4\\u5C9B",
"\\u82F1\\u6587\\uFF08\\u79D1\\u79D1\\u65AF\\uFF3B\\u57FA\\u6797\\uFF3D\\u7FA4\\u5C9B\\uFF09",
"\\u82F1\\u6587\\uFF08\\u79D1\\u79D1\\u65AF\\uFF3B\\u57FA\\u6797\\uFF3D\\u7FA4\\u5C9B\\uFF09" },
{ "zh", "CG", "fr_CG", "\\u521A\\u679C\\uFF08\\u5E03\\uFF09",
"\\u6CD5\\u6587\\uFF08\\u521A\\u679C\\uFF3B\\u5E03\\uFF3D\\uFF09",
"\\u6CD5\\u6587\\uFF08\\u521A\\u679C\\uFF3B\\u5E03\\uFF3D\\uFF09" },
{ NULL, NULL, NULL, NULL, NULL, NULL }
};
enum { kDisplayNameBracketsMax = 128 };
static void TestDisplayNameBrackets()
{
const DisplayNameBracketsItem * itemPtr = displayNameBracketsItems;
for (; itemPtr->displayLocale != NULL; itemPtr++) {
ULocaleDisplayNames * uldn;
UErrorCode status;
UChar expectRegionName[kDisplayNameBracketsMax];
UChar expectUlocLocaleName[kDisplayNameBracketsMax];
UChar expectUldnLocaleName[kDisplayNameBracketsMax];
UChar getName[kDisplayNameBracketsMax];
int32_t ulen;
(void) u_unescape(itemPtr->regionName, expectRegionName, kDisplayNameBracketsMax);
(void) u_unescape(itemPtr->ulocLocaleName, expectUlocLocaleName, kDisplayNameBracketsMax);
(void) u_unescape(itemPtr->uldnLocaleName, expectUldnLocaleName, kDisplayNameBracketsMax);
status = U_ZERO_ERROR;
ulen = uloc_getDisplayCountry(itemPtr->namedLocale, itemPtr->displayLocale, getName, kDisplayNameBracketsMax, &status);
if ( U_FAILURE(status) || u_strcmp(getName, expectRegionName) != 0 ) {
log_data_err("uloc_getDisplayCountry for displayLocale %s and namedLocale %s returns unexpected name or status %s\n", itemPtr->displayLocale, itemPtr->namedLocale, myErrorName(status));
}
status = U_ZERO_ERROR;
ulen = uloc_getDisplayName(itemPtr->namedLocale, itemPtr->displayLocale, getName, kDisplayNameBracketsMax, &status);
if ( U_FAILURE(status) || u_strcmp(getName, expectUlocLocaleName) != 0 ) {
log_data_err("uloc_getDisplayName for displayLocale %s and namedLocale %s returns unexpected name or status %s\n", itemPtr->displayLocale, itemPtr->namedLocale, myErrorName(status));
}
if ( U_FAILURE(status) ) {
log_data_err("uloc_getDisplayName for displayLocale %s and namedLocale %-10s returns unexpected status %s\n", itemPtr->displayLocale, itemPtr->namedLocale, myErrorName(status));
} else if ( u_strcmp(getName, expectUlocLocaleName) != 0 ) {
char bbuf[128];
u_strToUTF8(bbuf, 128, NULL, getName, ulen, &status);
log_data_err("uloc_getDisplayName for displayLocale %s and namedLocale %-10s returns unexpected name (len %d): \"%s\"\n", itemPtr->displayLocale, itemPtr->namedLocale, ulen, bbuf);
}
#if !UCONFIG_NO_FORMATTING
status = U_ZERO_ERROR;
uldn = uldn_open(itemPtr->displayLocale, ULDN_STANDARD_NAMES, &status);
if (U_SUCCESS(status)) {
status = U_ZERO_ERROR;
ulen = uldn_regionDisplayName(uldn, itemPtr->namedRegion, getName, kDisplayNameBracketsMax, &status);
if ( U_FAILURE(status) || u_strcmp(getName, expectRegionName) != 0 ) {
log_data_err("uldn_regionDisplayName for displayLocale %s and namedRegion %s returns unexpected name or status %s\n", itemPtr->displayLocale, itemPtr->namedRegion, myErrorName(status));
}
status = U_ZERO_ERROR;
ulen = uldn_localeDisplayName(uldn, itemPtr->namedLocale, getName, kDisplayNameBracketsMax, &status);
if ( U_FAILURE(status) ) {
log_data_err("uldn_localeDisplayName for displayLocale %s and namedLocale %-10s returns unexpected status %s\n", itemPtr->displayLocale, itemPtr->namedLocale, myErrorName(status));
} else if ( u_strcmp(getName, expectUldnLocaleName) != 0 ) {
char bbuf[128];
u_strToUTF8(bbuf, 128, NULL, getName, ulen, &status);
log_data_err("uldn_localeDisplayName for displayLocale %s and namedLocale %-10s returns unexpected name (len %d): \"%s\"\n", itemPtr->displayLocale, itemPtr->namedLocale, ulen, bbuf);
}
uldn_close(uldn);
} else {
log_data_err("uldn_open fails for displayLocale %s, status=%s\n", itemPtr->displayLocale, u_errorName(status));
}
#endif
(void)ulen;
}
}
#if !UCONFIG_NO_FILE_IO && !UCONFIG_NO_LEGACY_CONVERSION
static void TestISOFunctions()
{
const char* const* str=uloc_getISOLanguages();
const char* const* str1=uloc_getISOCountries();
const char* test;
const char *key = NULL;
int32_t count = 0, skipped = 0;
int32_t expect;
UResourceBundle *res;
UResourceBundle *subRes;
UErrorCode status = U_ZERO_ERROR;
log_verbose("Testing ISO Languages: \n");
res = ures_openDirect(loadTestData(&status), "structLocale", &status);
subRes = ures_getByKey(res, "Languages", NULL, &status);
if (U_FAILURE(status)) {
log_data_err("There is an error in structLocale's ures_getByKey(\"Languages\"), status=%s\n", u_errorName(status));
return;
}
expect = ures_getSize(subRes);
for(count = 0; *(str+count) != 0; count++)
{
key = NULL;
test = *(str+count);
status = U_ZERO_ERROR;
do {
skipped += (key != NULL);
ures_getNextString(subRes, NULL, &key, &status);
}
while (key != NULL && strchr(key, '_'));
if(key == NULL)
break;
if(strcmp(key,"root") == 0 || strcmp(key,"Fallback") == 0 || strcmp(key,"sh") == 0) {
ures_getNextString(subRes, NULL, &key, &status);
skipped++;
}
#if U_CHARSET_FAMILY==U_ASCII_FAMILY
if(strcmp(test,key)) {
log_err("FAIL Language diff at offset %d, \"%s\" != \"%s\"\n", count, test, key);
}
#endif
if(!strcmp(test,"in"))
log_err("FAIL getISOLanguages() has obsolete language code %s\n", test);
if(!strcmp(test,"iw"))
log_err("FAIL getISOLanguages() has obsolete language code %s\n", test);
if(!strcmp(test,"ji"))
log_err("FAIL getISOLanguages() has obsolete language code %s\n", test);
if(!strcmp(test,"jw"))
log_err("FAIL getISOLanguages() has obsolete language code %s\n", test);
if(!strcmp(test,"sh"))
log_err("FAIL getISOLanguages() has obsolete language code %s\n", test);
}
expect -= skipped;
if(count!=expect) {
log_err("There is an error in getISOLanguages, got %d, expected %d (as per structLocale)\n", count, expect);
}
subRes = ures_getByKey(res, "Countries", subRes, &status);
log_verbose("Testing ISO Countries");
skipped = 0;
expect = ures_getSize(subRes) - 1;
for(count = 0; *(str1+count) != 0; count++)
{
key = NULL;
test = *(str1+count);
do {
skipped += (key != NULL);
ures_getNextString(subRes, NULL, &key, &status);
}
while (key != NULL && strlen(key) != 2);
if(key == NULL)
break;
while(strcmp(key,"QO") == 0 || strcmp(key,"QU") == 0 || strcmp(key,"CS") == 0) {
ures_getNextString(subRes, NULL, &key, &status);
skipped++;
}
#if U_CHARSET_FAMILY==U_ASCII_FAMILY
if(strcmp(test,key)) {
log_err("FAIL Country diff at offset %d, \"%s\" != \"%s\"\n", count, test, key);
}
#endif
if(!strcmp(test,"FX"))
log_err("FAIL getISOCountries() has obsolete country code %s\n", test);
if(!strcmp(test,"YU"))
log_err("FAIL getISOCountries() has obsolete country code %s\n", test);
if(!strcmp(test,"ZR"))
log_err("FAIL getISOCountries() has obsolete country code %s\n", test);
}
ures_getNextString(subRes, NULL, &key, &status);
if (strcmp(key, "ZZ") != 0) {
log_err("ZZ was expected to be the last entry in structLocale, but got %s\n", key);
}
#if U_CHARSET_FAMILY==U_EBCDIC_FAMILY
key = NULL;
do {
skipped += (key != NULL);
ures_getNextString(subRes, NULL, &key, &status);
}
while (U_SUCCESS(status) && key != NULL && strlen(key) != 2);
#endif
expect -= skipped;
if(count!=expect)
{
log_err("There is an error in getISOCountries, got %d, expected %d \n", count, expect);
}
ures_close(subRes);
ures_close(res);
}
#endif
static void setUpDataTable()
{
int32_t i,j;
dataTable = (UChar***)(calloc(sizeof(UChar**),LOCALE_INFO_SIZE));
for (i = 0; i < LOCALE_INFO_SIZE; i++) {
dataTable[i] = (UChar**)(calloc(sizeof(UChar*),LOCALE_SIZE));
for (j = 0; j < LOCALE_SIZE; j++){
dataTable[i][j] = CharsToUChars(rawData2[i][j]);
}
}
}
static void cleanUpDataTable()
{
int32_t i,j;
if(dataTable != NULL) {
for (i=0; i<LOCALE_INFO_SIZE; i++) {
for(j = 0; j < LOCALE_SIZE; j++) {
free(dataTable[i][j]);
}
free(dataTable[i]);
}
free(dataTable);
}
dataTable = NULL;
}
static void TestISO3Fallback()
{
const char* test="xx_YY";
const char * result;
result = uloc_getISO3Language(test);
if (!result || (result[0] != 0))
log_err("getISO3Language() on xx_YY returned %s instead of \"\"");
result = uloc_getISO3Country(test);
if (!result || (result[0] != 0))
log_err("getISO3Country() on xx_YY returned %s instead of \"\"");
}
static void TestSimpleDisplayNames()
{
char languageCodes[] [4] = { "he", "id", "iu", "ug", "yi", "za", "419" };
const char* languageNames [] = { "Hebrew", "Indonesian", "Inuktitut", "Uyghur", "Yiddish",
"Zhuang", "419" };
const char* inLocale [] = { "en_US", "zh_Hant"};
UErrorCode status=U_ZERO_ERROR;
int32_t i;
int32_t localeIndex = 0;
for (i = 0; i < 7; i++) {
UChar *testLang=0;
UChar *expectedLang=0;
int size=0;
if (i == 6) {
localeIndex = 1;
}
size=uloc_getDisplayLanguage(languageCodes[i], inLocale[localeIndex], NULL, size, &status);
if(status==U_BUFFER_OVERFLOW_ERROR) {
status=U_ZERO_ERROR;
testLang=(UChar*)malloc(sizeof(UChar) * (size + 1));
uloc_getDisplayLanguage(languageCodes[i], inLocale[localeIndex], testLang, size + 1, &status);
}
expectedLang=(UChar*)malloc(sizeof(UChar) * (strlen(languageNames[i])+1));
u_uastrcpy(expectedLang, languageNames[i]);
if (u_strcmp(testLang, expectedLang) != 0)
log_data_err("Got wrong display name for %s : Expected \"%s\", got \"%s\".\n",
languageCodes[i], languageNames[i], austrdup(testLang));
free(testLang);
free(expectedLang);
}
}
static void TestUninstalledISO3Names()
{
static const char iso2Languages [][4] = { "am", "ba", "fy", "mr", "rn",
"ss", "tw", "zu" };
static const char iso3Languages [][5] = { "amh", "bak", "fry", "mar", "run",
"ssw", "twi", "zul" };
static const char iso2Countries [][6] = { "am_AF", "ba_BW", "fy_KZ", "mr_MO", "rn_MN",
"ss_SB", "tw_TC", "zu_ZW" };
static const char iso3Countries [][4] = { "AFG", "BWA", "KAZ", "MAC", "MNG",
"SLB", "TCA", "ZWE" };
int32_t i;
for (i = 0; i < 8; i++) {
UErrorCode err = U_ZERO_ERROR;
const char *test;
test = uloc_getISO3Language(iso2Languages[i]);
if(strcmp(test, iso3Languages[i]) !=0 || U_FAILURE(err))
log_err("Got wrong ISO3 code for %s : Expected \"%s\", got \"%s\". %s\n",
iso2Languages[i], iso3Languages[i], test, myErrorName(err));
}
for (i = 0; i < 8; i++) {
UErrorCode err = U_ZERO_ERROR;
const char *test;
test = uloc_getISO3Country(iso2Countries[i]);
if(strcmp(test, iso3Countries[i]) !=0 || U_FAILURE(err))
log_err("Got wrong ISO3 code for %s : Expected \"%s\", got \"%s\". %s\n",
iso2Countries[i], iso3Countries[i], test, myErrorName(err));
}
}
static void TestVariantParsing()
{
static const char* en_US_custom="en_US_De Anza_Cupertino_California_United States_Earth";
static const char* dispName="English (United States, DE ANZA_CUPERTINO_CALIFORNIA_UNITED STATES_EARTH)";
static const char* dispVar="DE ANZA_CUPERTINO_CALIFORNIA_UNITED STATES_EARTH";
static const char* shortVariant="fr_FR_foo";
static const char* bogusVariant="fr_FR__foo";
static const char* bogusVariant2="fr_FR_foo_";
static const char* bogusVariant3="fr_FR__foo_";
UChar displayVar[100];
UChar displayName[100];
UErrorCode status=U_ZERO_ERROR;
UChar* got=0;
int32_t size=0;
size=uloc_getDisplayVariant(en_US_custom, "en_US", NULL, size, &status);
if(status==U_BUFFER_OVERFLOW_ERROR) {
status=U_ZERO_ERROR;
got=(UChar*)realloc(got, sizeof(UChar) * (size+1));
uloc_getDisplayVariant(en_US_custom, "en_US", got, size + 1, &status);
}
else {
log_err("FAIL: Didn't get U_BUFFER_OVERFLOW_ERROR\n");
}
u_uastrcpy(displayVar, dispVar);
if(u_strcmp(got,displayVar)!=0) {
log_err("FAIL: getDisplayVariant() Wanted %s, got %s\n", dispVar, austrdup(got));
}
size=0;
size=uloc_getDisplayName(en_US_custom, "en_US", NULL, size, &status);
if(status==U_BUFFER_OVERFLOW_ERROR) {
status=U_ZERO_ERROR;
got=(UChar*)realloc(got, sizeof(UChar) * (size+1));
uloc_getDisplayName(en_US_custom, "en_US", got, size + 1, &status);
}
else {
log_err("FAIL: Didn't get U_BUFFER_OVERFLOW_ERROR\n");
}
u_uastrcpy(displayName, dispName);
if(u_strcmp(got,displayName)!=0) {
if (status == U_USING_DEFAULT_WARNING) {
log_data_err("FAIL: getDisplayName() got %s. Perhaps you are missing data?\n", u_errorName(status));
} else {
log_err("FAIL: getDisplayName() Wanted %s, got %s\n", dispName, austrdup(got));
}
}
size=0;
status=U_ZERO_ERROR;
size=uloc_getDisplayVariant(shortVariant, NULL, NULL, size, &status);
if(status==U_BUFFER_OVERFLOW_ERROR) {
status=U_ZERO_ERROR;
got=(UChar*)realloc(got, sizeof(UChar) * (size+1));
uloc_getDisplayVariant(shortVariant, NULL, got, size + 1, &status);
}
else {
log_err("FAIL: Didn't get U_BUFFER_OVERFLOW_ERROR\n");
}
if(strcmp(austrdup(got),"FOO")!=0) {
log_err("FAIL: getDisplayVariant() Wanted: foo Got: %s\n", austrdup(got));
}
size=0;
status=U_ZERO_ERROR;
size=uloc_getDisplayVariant(bogusVariant, NULL, NULL, size, &status);
if(status==U_BUFFER_OVERFLOW_ERROR) {
status=U_ZERO_ERROR;
got=(UChar*)realloc(got, sizeof(UChar) * (size+1));
uloc_getDisplayVariant(bogusVariant, NULL, got, size + 1, &status);
}
else {
log_err("FAIL: Didn't get U_BUFFER_OVERFLOW_ERROR\n");
}
if(strcmp(austrdup(got),"_FOO")!=0) {
log_err("FAIL: getDisplayVariant() Wanted: _FOO Got: %s\n", austrdup(got));
}
size=0;
status=U_ZERO_ERROR;
size=uloc_getDisplayVariant(bogusVariant2, NULL, NULL, size, &status);
if(status==U_BUFFER_OVERFLOW_ERROR) {
status=U_ZERO_ERROR;
got=(UChar*)realloc(got, sizeof(UChar) * (size+1));
uloc_getDisplayVariant(bogusVariant2, NULL, got, size + 1, &status);
}
else {
log_err("FAIL: Didn't get U_BUFFER_OVERFLOW_ERROR\n");
}
if(strcmp(austrdup(got),"FOO_")!=0) {
log_err("FAIL: getDisplayVariant() Wanted: FOO_ Got: %s\n", austrdup(got));
}
size=0;
status=U_ZERO_ERROR;
size=uloc_getDisplayVariant(bogusVariant3, NULL, NULL, size, &status);
if(status==U_BUFFER_OVERFLOW_ERROR) {
status=U_ZERO_ERROR;
got=(UChar*)realloc(got, sizeof(UChar) * (size+1));
uloc_getDisplayVariant(bogusVariant3, NULL, got, size + 1, &status);
}
else {
log_err("FAIL: Didn't get U_BUFFER_OVERFLOW_ERROR\n");
}
if(strcmp(austrdup(got),"_FOO_")!=0) {
log_err("FAIL: getDisplayVariant() Wanted: _FOO_ Got: %s\n", austrdup(got));
}
free(got);
}
static void TestObsoleteNames(void)
{
int32_t i;
UErrorCode status = U_ZERO_ERROR;
char buff[256];
static const struct
{
char locale[9];
char lang3[4];
char lang[4];
char ctry3[4];
char ctry[4];
} tests[] =
{
{ "eng_USA", "eng", "en", "USA", "US" },
{ "kok", "kok", "kok", "", "" },
{ "in", "ind", "in", "", "" },
{ "id", "ind", "id", "", "" },
{ "sh", "srp", "sh", "", "" },
{ "zz_CS", "", "zz", "SCG", "CS" },
{ "zz_FX", "", "zz", "FXX", "FX" },
{ "zz_RO", "", "zz", "ROU", "RO" },
{ "zz_TP", "", "zz", "TMP", "TP" },
{ "zz_TL", "", "zz", "TLS", "TL" },
{ "zz_ZR", "", "zz", "ZAR", "ZR" },
{ "zz_FXX", "", "zz", "FXX", "FX" },
{ "zz_ROM", "", "zz", "ROU", "RO" },
{ "zz_ROU", "", "zz", "ROU", "RO" },
{ "zz_ZAR", "", "zz", "ZAR", "ZR" },
{ "zz_TMP", "", "zz", "TMP", "TP" },
{ "zz_TLS", "", "zz", "TLS", "TL" },
{ "zz_YUG", "", "zz", "YUG", "YU" },
{ "mlt_PSE", "mlt", "mt", "PSE", "PS" },
{ "iw", "heb", "iw", "", "" },
{ "ji", "yid", "ji", "", "" },
{ "jw", "jaw", "jw", "", "" },
{ "sh", "srp", "sh", "", "" },
{ "", "", "", "", "" }
};
for(i=0;tests[i].locale[0];i++)
{
const char *locale;
locale = tests[i].locale;
log_verbose("** %s:\n", locale);
status = U_ZERO_ERROR;
if(strcmp(tests[i].lang3,uloc_getISO3Language(locale)))
{
log_err("FAIL: uloc_getISO3Language(%s)==\t\"%s\",\t expected \"%s\"\n",
locale, uloc_getISO3Language(locale), tests[i].lang3);
}
else
{
log_verbose(" uloc_getISO3Language()==\t\"%s\"\n",
uloc_getISO3Language(locale) );
}
status = U_ZERO_ERROR;
uloc_getLanguage(locale, buff, 256, &status);
if(U_FAILURE(status))
{
log_err("FAIL: error getting language from %s\n", locale);
}
else
{
if(strcmp(buff,tests[i].lang))
{
log_err("FAIL: uloc_getLanguage(%s)==\t\"%s\"\t expected \"%s\"\n",
locale, buff, tests[i].lang);
}
else
{
log_verbose(" uloc_getLanguage(%s)==\t%s\n", locale, buff);
}
}
if(strcmp(tests[i].lang3,uloc_getISO3Language(locale)))
{
log_err("FAIL: uloc_getISO3Language(%s)==\t\"%s\",\t expected \"%s\"\n",
locale, uloc_getISO3Language(locale), tests[i].lang3);
}
else
{
log_verbose(" uloc_getISO3Language()==\t\"%s\"\n",
uloc_getISO3Language(locale) );
}
if(strcmp(tests[i].ctry3,uloc_getISO3Country(locale)))
{
log_err("FAIL: uloc_getISO3Country(%s)==\t\"%s\",\t expected \"%s\"\n",
locale, uloc_getISO3Country(locale), tests[i].ctry3);
}
else
{
log_verbose(" uloc_getISO3Country()==\t\"%s\"\n",
uloc_getISO3Country(locale) );
}
status = U_ZERO_ERROR;
uloc_getCountry(locale, buff, 256, &status);
if(U_FAILURE(status))
{
log_err("FAIL: error getting country from %s\n", locale);
}
else
{
if(strcmp(buff,tests[i].ctry))
{
log_err("FAIL: uloc_getCountry(%s)==\t\"%s\"\t expected \"%s\"\n",
locale, buff, tests[i].ctry);
}
else
{
log_verbose(" uloc_getCountry(%s)==\t%s\n", locale, buff);
}
}
}
if (uloc_getLCID("iw_IL") != uloc_getLCID("he_IL")) {
log_err("he,iw LCID mismatch: %X versus %X\n", uloc_getLCID("iw_IL"), uloc_getLCID("he_IL"));
}
if (uloc_getLCID("iw") != uloc_getLCID("he")) {
log_err("he,iw LCID mismatch: %X versus %X\n", uloc_getLCID("iw"), uloc_getLCID("he"));
}
#if 0
i = uloc_getLanguage("kok",NULL,0,&icu_err);
if(U_FAILURE(icu_err))
{
log_err("FAIL: Got %s trying to do uloc_getLanguage(kok)\n", u_errorName(icu_err));
}
icu_err = U_ZERO_ERROR;
uloc_getLanguage("kok",r1_buff,12,&icu_err);
if(U_FAILURE(icu_err))
{
log_err("FAIL: Got %s trying to do uloc_getLanguage(kok, buff)\n", u_errorName(icu_err));
}
r1_addr = (char *)uloc_getISO3Language("kok");
icu_err = U_ZERO_ERROR;
if (strcmp(r1_buff,"kok") != 0)
{
log_err("FAIL: uloc_getLanguage(kok)==%s not kok\n",r1_buff);
line--;
}
r1_addr = (char *)uloc_getISO3Language("in");
i = uloc_getLanguage(r1_addr,r1_buff,12,&icu_err);
if (strcmp(r1_buff,"id") != 0)
{
printf("uloc_getLanguage error (%s)\n",r1_buff);
line--;
}
r1_addr = (char *)uloc_getISO3Language("sh");
i = uloc_getLanguage(r1_addr,r1_buff,12,&icu_err);
if (strcmp(r1_buff,"sr") != 0)
{
printf("uloc_getLanguage error (%s)\n",r1_buff);
line--;
}
r1_addr = (char *)uloc_getISO3Country("zz_ZR");
strcpy(p1_buff,"zz_");
strcat(p1_buff,r1_addr);
i = uloc_getCountry(p1_buff,r1_buff,12,&icu_err);
if (strcmp(r1_buff,"ZR") != 0)
{
printf("uloc_getCountry error (%s)\n",r1_buff);
line--;
}
r1_addr = (char *)uloc_getISO3Country("zz_FX");
strcpy(p1_buff,"zz_");
strcat(p1_buff,r1_addr);
i = uloc_getCountry(p1_buff,r1_buff,12,&icu_err);
if (strcmp(r1_buff,"FX") != 0)
{
printf("uloc_getCountry error (%s)\n",r1_buff);
line--;
}
#endif
}
static void TestKeywordVariants(void)
{
static const struct {
const char *localeID;
const char *expectedLocaleID;
const char *expectedLocaleIDNoKeywords;
const char *expectedCanonicalID;
const char *expectedKeywords[10];
int32_t numKeywords;
UErrorCode expectedStatus;
} testCases[] = {
{
"de_DE@ currency = euro; C o ll A t i o n = Phonebook ; C alen dar = buddhist ",
"de_DE@calendar=buddhist;collation=Phonebook;currency=euro",
"de_DE",
"de_DE@calendar=buddhist;collation=Phonebook;currency=euro",
{"calendar", "collation", "currency"},
3,
U_ZERO_ERROR
},
{
"de_DE@euro",
"de_DE@euro",
"de_DE@euro",
"de_DE@currency=EUR",
{"","","","","","",""},
0,
U_INVALID_FORMAT_ERROR
},
{
"de_DE@euro;collation=phonebook",
"de_DE",
"de_DE",
"de_DE",
{"","","","","","",""},
0,
U_INVALID_FORMAT_ERROR
},
{
"de_DE@collation=",
0,
"de_DE",
0,
{"","","","","","",""},
0,
U_INVALID_FORMAT_ERROR
}
};
UErrorCode status = U_ZERO_ERROR;
int32_t i = 0, j = 0;
int32_t resultLen = 0;
char buffer[256];
UEnumeration *keywords;
int32_t keyCount = 0;
const char *keyword = NULL;
int32_t keywordLen = 0;
for(i = 0; i < UPRV_LENGTHOF(testCases); i++) {
status = U_ZERO_ERROR;
*buffer = 0;
keywords = uloc_openKeywords(testCases[i].localeID, &status);
if(status != testCases[i].expectedStatus) {
log_err("Expected to uloc_openKeywords(\"%s\") => status %s. Got %s instead\n",
testCases[i].localeID,
u_errorName(testCases[i].expectedStatus), u_errorName(status));
}
status = U_ZERO_ERROR;
if(keywords) {
if((keyCount = uenum_count(keywords, &status)) != testCases[i].numKeywords) {
log_err("Expected to get %i keywords, got %i\n", testCases[i].numKeywords, keyCount);
}
if(keyCount) {
j = 0;
while((keyword = uenum_next(keywords, &keywordLen, &status))) {
if(strcmp(keyword, testCases[i].expectedKeywords[j]) != 0) {
log_err("Expected to get keyword value %s, got %s\n", testCases[i].expectedKeywords[j], keyword);
}
j++;
}
j = 0;
uenum_reset(keywords, &status);
while((keyword = uenum_next(keywords, &keywordLen, &status))) {
if(strcmp(keyword, testCases[i].expectedKeywords[j]) != 0) {
log_err("Expected to get keyword value %s, got %s\n", testCases[i].expectedKeywords[j], keyword);
}
j++;
}
}
uenum_close(keywords);
}
status = U_ZERO_ERROR;
resultLen = uloc_getName(testCases[i].localeID, buffer, 256, &status);
if (U_SUCCESS(status)) {
if (testCases[i].expectedLocaleID == 0) {
log_err("Expected uloc_getName(\"%s\") to fail; got \"%s\"\n",
testCases[i].localeID, buffer);
} else if (uprv_strcmp(testCases[i].expectedLocaleID, buffer) != 0) {
log_err("Expected uloc_getName(\"%s\") => \"%s\"; got \"%s\"\n",
testCases[i].localeID, testCases[i].expectedLocaleID, buffer);
}
} else {
if (testCases[i].expectedLocaleID != 0) {
log_err("Expected uloc_getName(\"%s\") => \"%s\"; but returned error: %s\n",
testCases[i].localeID, testCases[i].expectedLocaleID, buffer, u_errorName(status));
}
}
status = U_ZERO_ERROR;
resultLen = uloc_getBaseName(testCases[i].localeID, buffer, 256, &status);
if (U_SUCCESS(status)) {
if (testCases[i].expectedLocaleIDNoKeywords == 0) {
log_err("Expected uloc_getBaseName(\"%s\") to fail; got \"%s\"\n",
testCases[i].localeID, buffer);
} else if (uprv_strcmp(testCases[i].expectedLocaleIDNoKeywords, buffer) != 0) {
log_err("Expected uloc_getBaseName(\"%s\") => \"%s\"; got \"%s\"\n",
testCases[i].localeID, testCases[i].expectedLocaleIDNoKeywords, buffer);
}
} else {
if (testCases[i].expectedLocaleIDNoKeywords != 0) {
log_err("Expected uloc_getBaseName(\"%s\") => \"%s\"; but returned error: %s\n",
testCases[i].localeID, testCases[i].expectedLocaleIDNoKeywords, buffer, u_errorName(status));
}
}
status = U_ZERO_ERROR;
resultLen = uloc_canonicalize(testCases[i].localeID, buffer, 256, &status);
if (U_SUCCESS(status)) {
if (testCases[i].expectedCanonicalID == 0) {
log_err("Expected uloc_canonicalize(\"%s\") to fail; got \"%s\"\n",
testCases[i].localeID, buffer);
} else if (uprv_strcmp(testCases[i].expectedCanonicalID, buffer) != 0) {
log_err("Expected uloc_canonicalize(\"%s\") => \"%s\"; got \"%s\"\n",
testCases[i].localeID, testCases[i].expectedCanonicalID, buffer);
}
} else {
if (testCases[i].expectedCanonicalID != 0) {
log_err("Expected uloc_canonicalize(\"%s\") => \"%s\"; but returned error: %s\n",
testCases[i].localeID, testCases[i].expectedCanonicalID, buffer, u_errorName(status));
}
}
}
}
static void TestKeywordVariantParsing(void)
{
static const struct {
const char *localeID;
const char *keyword;
const char *expectedValue;
} testCases[] = {
{ "de_DE@ C o ll A t i o n = Phonebook ", "c o ll a t i o n", NULL },
{ "de_DE", "collation", ""},
{ "de_DE@collation=PHONEBOOK", "collation", "PHONEBOOK" },
{ "de_DE@currency = euro; CoLLaTion = PHONEBOOk", "collatiON", "PHONEBOOk" },
};
UErrorCode status;
int32_t i = 0;
int32_t resultLen = 0;
char buffer[256];
for(i = 0; i < UPRV_LENGTHOF(testCases); i++) {
*buffer = 0;
status = U_ZERO_ERROR;
resultLen = uloc_getKeywordValue(testCases[i].localeID, testCases[i].keyword, buffer, 256, &status);
(void)resultLen;
if (testCases[i].expectedValue) {
if (U_FAILURE(status)) {
log_err("Expected to extract \"%s\" from \"%s\" for keyword \"%s\". Instead got status %s\n",
testCases[i].expectedValue, testCases[i].localeID, testCases[i].keyword, u_errorName(status));
} else if (uprv_strcmp(testCases[i].expectedValue, buffer) != 0) {
log_err("Expected to extract \"%s\" from \"%s\" for keyword \"%s\". Instead got \"%s\"\n",
testCases[i].expectedValue, testCases[i].localeID, testCases[i].keyword, buffer);
}
} else if (U_SUCCESS(status)) {
log_err("Expected failure but got success from \"%s\" for keyword \"%s\". Got \"%s\"\n",
testCases[i].localeID, testCases[i].keyword, buffer);
}
}
}
static const struct {
const char *l;
const char *k;
const char *v;
const char *x;
} kwSetTestCases[] = {
#if 1
{ "en_US", "calendar", "japanese", "en_US@calendar=japanese" },
{ "en_US@", "calendar", "japanese", "en_US@calendar=japanese" },
{ "en_US@calendar=islamic", "calendar", "japanese", "en_US@calendar=japanese" },
{ "en_US@calendar=slovakian", "calendar", "gregorian", "en_US@calendar=gregorian" },
{ "en_US@calendar=gregorian", "calendar", "japanese", "en_US@calendar=japanese" },
{ "de", "Currency", "CHF", "de@currency=CHF" },
{ "de", "Currency", "CHF", "de@currency=CHF" },
{ "en_US@collation=phonebook", "calendar", "japanese", "en_US@calendar=japanese;collation=phonebook" },
{ "en_US@calendar=japanese", "collation", "phonebook", "en_US@calendar=japanese;collation=phonebook" },
{ "de@collation=phonebook", "Currency", "CHF", "de@collation=phonebook;currency=CHF" },
{ "en_US@calendar=gregorian;collation=phonebook", "calendar", "japanese", "en_US@calendar=japanese;collation=phonebook" },
{ "en_US@calendar=slovakian;collation=phonebook", "calendar", "gregorian", "en_US@calendar=gregorian;collation=phonebook" },
{ "en_US@calendar=slovakian;collation=videobook", "collation", "phonebook", "en_US@calendar=slovakian;collation=phonebook" },
{ "en_US@calendar=islamic;collation=phonebook", "calendar", "japanese", "en_US@calendar=japanese;collation=phonebook" },
{ "de@collation=phonebook", "Currency", "CHF", "de@collation=phonebook;currency=CHF" },
#endif
#if 1
{ "mt@a=0;b=1;c=2;d=3", "c","j", "mt@a=0;b=1;c=j;d=3" },
{ "mt@a=0;b=1;c=2;d=3", "x","j", "mt@a=0;b=1;c=2;d=3;x=j" },
{ "mt@a=0;b=1;c=2;d=3", "a","f", "mt@a=f;b=1;c=2;d=3" },
{ "mt@a=0;aa=1;aaa=3", "a","x", "mt@a=x;aa=1;aaa=3" },
{ "mt@a=0;aa=1;aaa=3", "aa","x", "mt@a=0;aa=x;aaa=3" },
{ "mt@a=0;aa=1;aaa=3", "aaa","x", "mt@a=0;aa=1;aaa=x" },
{ "mt@a=0;aa=1;aaa=3", "a","yy", "mt@a=yy;aa=1;aaa=3" },
{ "mt@a=0;aa=1;aaa=3", "aa","yy", "mt@a=0;aa=yy;aaa=3" },
{ "mt@a=0;aa=1;aaa=3", "aaa","yy", "mt@a=0;aa=1;aaa=yy" },
#endif
#if 1
{ "de@collation=phonebook;currency=CHF", "currency", "", "de@collation=phonebook" },
{ "de@collation=phonebook;currency=CHF", "currency", NULL, "de@collation=phonebook" },
{ "de@collation=phonebook;currency=CHF", "collation", "", "de@currency=CHF" },
{ "de@collation=phonebook;currency=CHF", "collation", NULL, "de@currency=CHF" },
{ "de@collation=phonebook;currency=CHF", "calendar", NULL, "de@collation=phonebook;currency=CHF" },
{ "de@collation=phonebook", "collation", NULL, "de" },
#endif
{ "de@collation=phonebook", "Currency", "CHF", "de@collation=phonebook;currency=CHF" },
{ "en_US@ calendar = islamic", "calendar", "japanese", "en_US@calendar=japanese" },
{ "en_US@ calendar = gregorian ; collation = phonebook", "calendar", "japanese", "en_US@calendar=japanese;collation=phonebook" },
{ "en_US@ calendar = islamic", "currency", "CHF", "en_US@calendar=islamic;currency=CHF" },
{ "en_US@ currency = CHF", "calendar", "japanese", "en_US@calendar=japanese;currency=CHF" },
{ "en_US@calendar=gregorian;", "calendar", "japanese", NULL },
{ "en_US@calendar=gregorian;=", "calendar", "japanese", NULL },
{ "en_US@calendar=gregorian;currency=", "calendar", "japanese", NULL },
{ "en_US@=", "calendar", "japanese", NULL },
{ "en_US@=;", "calendar", "japanese", NULL },
{ "en_US@= ", "calendar", "japanese", NULL },
{ "en_US@ =", "calendar", "japanese", NULL },
{ "en_US@ = ", "calendar", "japanese", NULL },
{ "en_US@=;calendar=gregorian", "calendar", "japanese", NULL },
{ "en_US@= calen dar = gregorian", "calendar", "japanese", NULL },
{ "en_US@= calendar = greg orian", "calendar", "japanese", NULL },
{ "en_US@=;cal...endar=gregorian", "calendar", "japanese", NULL },
{ "en_US@=;calendar=greg...orian", "calendar", "japanese", NULL },
{ "en_US@calendar=gregorian", "cale ndar", "japanese", NULL },
{ "en_US@calendar=gregorian", "calendar", "japa..nese", NULL },
{ "en_US@=", "calendar", NULL, NULL },
{ "en_US@=;", "calendar", NULL, NULL },
{ "en_US@= ", "calendar", NULL, NULL },
{ "en_US@ =", "calendar", NULL, NULL },
{ "en_US@ = ", "calendar", NULL, NULL },
{ "en_US@=;calendar=gregorian", "calendar", NULL, NULL },
{ "en_US@= calen dar = gregorian", "calendar", NULL, NULL },
{ "en_US@= calendar = greg orian", "calendar", NULL, NULL },
{ "en_US@=;cal...endar=gregorian", "calendar", NULL, NULL },
{ "en_US@=;calendar=greg...orian", "calendar", NULL, NULL },
{ "en_US@calendar=gregorian", "cale ndar", NULL, NULL },
};
static void TestKeywordSet(void)
{
int32_t i = 0;
int32_t resultLen = 0;
char buffer[1024];
char cbuffer[1024];
for(i = 0; i < UPRV_LENGTHOF(kwSetTestCases); i++) {
UErrorCode status = U_ZERO_ERROR;
memset(buffer,'%',1023);
strcpy(buffer, kwSetTestCases[i].l);
if (kwSetTestCases[i].x != NULL) {
uloc_canonicalize(kwSetTestCases[i].l, cbuffer, 1023, &status);
if(strcmp(buffer,cbuffer)) {
log_verbose("note: [%d] wasn't canonical, should be: '%s' not '%s'. Won't check for canonicity in output.\n", i, cbuffer, buffer);
}
uloc_canonicalize(kwSetTestCases[i].x, cbuffer, 1023, &status);
if(strcmp(kwSetTestCases[i].x,cbuffer)) {
log_err("%s:%d: ERROR: kwSetTestCases[%d].x = '%s', should be %s (must be canonical)\n", __FILE__, __LINE__, i, kwSetTestCases[i].x, cbuffer);
}
status = U_ZERO_ERROR;
resultLen = uloc_setKeywordValue(kwSetTestCases[i].k, kwSetTestCases[i].v, buffer, 1023, &status);
if(U_FAILURE(status)) {
log_err("Err on test case %d for setKeywordValue: got error %s\n", i, u_errorName(status));
} else if(strcmp(buffer,kwSetTestCases[i].x) || ((int32_t)strlen(buffer)!=resultLen)) {
log_err("FAIL: #%d setKeywordValue: %s + [%s=%s] -> %s (%d) expected %s (%d)\n", i, kwSetTestCases[i].l, kwSetTestCases[i].k,
kwSetTestCases[i].v, buffer, resultLen, kwSetTestCases[i].x, strlen(buffer));
} else {
log_verbose("pass: #%d: %s + [%s=%s] -> %s\n", i, kwSetTestCases[i].l, kwSetTestCases[i].k, kwSetTestCases[i].v,buffer);
}
if (kwSetTestCases[i].v != NULL && kwSetTestCases[i].v[0] != 0) {
status = U_ZERO_ERROR;
resultLen = uloc_getKeywordValue(kwSetTestCases[i].x, kwSetTestCases[i].k, buffer, 1023, &status);
if(U_FAILURE(status)) {
log_err("Err on test case %d for getKeywordValue: got error %s\n", i, u_errorName(status));
} else if (resultLen != uprv_strlen(kwSetTestCases[i].v) || uprv_strcmp(buffer, kwSetTestCases[i].v) != 0) {
log_err("FAIL: #%d getKeywordValue: got %s (%d) expected %s (%d)\n", i, buffer, resultLen,
kwSetTestCases[i].v, uprv_strlen(kwSetTestCases[i].v));
}
}
} else {
status = U_ZERO_ERROR;
resultLen = uloc_setKeywordValue(kwSetTestCases[i].k, kwSetTestCases[i].v, buffer, 1023, &status);
if(U_SUCCESS(status)) {
log_err("Err on test case %d for setKeywordValue: expected to fail but succeeded, got %s (%d)\n", i, buffer, resultLen);
}
if (kwSetTestCases[i].v == NULL) {
status = U_ZERO_ERROR;
strcpy(cbuffer, kwSetTestCases[i].l);
resultLen = uloc_getKeywordValue(cbuffer, kwSetTestCases[i].k, buffer, 1023, &status);
if(U_SUCCESS(status)) {
log_err("Err on test case %d for getKeywordValue: expected to fail but succeeded\n", i);
}
}
}
}
}
static void TestKeywordSetError(void)
{
char buffer[1024];
UErrorCode status;
int32_t res;
int32_t i;
int32_t blen;
blen=0;
i=0;
memset(buffer,'%',1023);
status = U_ZERO_ERROR;
res = uloc_setKeywordValue(kwSetTestCases[i].k, kwSetTestCases[i].v, buffer, blen, &status);
if(status != U_ILLEGAL_ARGUMENT_ERROR) {
log_err("expected illegal err got %s\n", u_errorName(status));
return;
}
if(buffer[blen]!='%') {
log_err("Buffer byte %d was modified: now %c\n", blen, buffer[blen]);
return;
}
log_verbose("0-buffer modify OK\n");
for(i=0;i<=2;i++) {
blen=(int32_t)strlen(kwSetTestCases[i].l)+1;
memset(buffer,'%',1023);
strcpy(buffer,kwSetTestCases[i].l);
status = U_ZERO_ERROR;
res = uloc_setKeywordValue(kwSetTestCases[i].k, kwSetTestCases[i].v, buffer, blen, &status);
if(status != U_BUFFER_OVERFLOW_ERROR) {
log_err("expected buffer overflow on buffer %d got %s, len %d (%s + [%s=%s])\n", blen, u_errorName(status), res, kwSetTestCases[i].l, kwSetTestCases[i].k, kwSetTestCases[i].v);
return;
}
if(res!=(int32_t)strlen(kwSetTestCases[i].x)) {
log_err("expected result %d got %d\n", strlen(kwSetTestCases[i].x), res);
return;
}
if(buffer[blen]!='%') {
log_err("Buffer byte %d was modified: now %c\n", blen, buffer[blen]);
return;
}
log_verbose("1/%d-buffer modify OK\n",i);
}
for(i=3;i<=4;i++) {
blen=(int32_t)strlen(kwSetTestCases[i].l)+1;
memset(buffer,'%',1023);
strcpy(buffer,kwSetTestCases[i].l);
status = U_ZERO_ERROR;
res = uloc_setKeywordValue(kwSetTestCases[i].k, kwSetTestCases[i].v, buffer, blen, &status);
if(status != U_ZERO_ERROR) {
log_err("expected zero error got %s\n", u_errorName(status));
return;
}
if(buffer[blen+1]!='%') {
log_err("Buffer byte %d was modified: now %c\n", blen+1, buffer[blen+1]);
return;
}
if(res!=(int32_t)strlen(kwSetTestCases[i].x)) {
log_err("expected result %d got %d\n", strlen(kwSetTestCases[i].x), res);
return;
}
if(strcmp(buffer,kwSetTestCases[i].x) || ((int32_t)strlen(buffer)!=res)) {
log_err("FAIL: #%d: %s + [%s=%s] -> %s (%d) expected %s (%d)\n", i, kwSetTestCases[i].l, kwSetTestCases[i].k,
kwSetTestCases[i].v, buffer, res, kwSetTestCases[i].x, strlen(buffer));
} else {
log_verbose("pass: #%d: %s + [%s=%s] -> %s\n", i, kwSetTestCases[i].l, kwSetTestCases[i].k, kwSetTestCases[i].v,
buffer);
}
log_verbose("2/%d-buffer modify OK\n",i);
}
}
static int32_t _canonicalize(int32_t selector,
const char* localeID,
char* result,
int32_t resultCapacity,
UErrorCode* ec) {
switch (selector) {
case 0:
return uloc_getName(localeID, result, resultCapacity, ec);
case 1:
return uloc_canonicalize(localeID, result, resultCapacity, ec);
default:
return -1;
}
}
static void TestCanonicalization(void)
{
static const struct {
const char *localeID;
const char *getNameID;
const char *canonicalID;
} testCases[] = {
{ "ca_ES_PREEURO-with-extra-stuff-that really doesn't make any sense-unless-you're trying to increase code coverage",
"ca_ES_PREEURO_WITH_EXTRA_STUFF_THAT REALLY DOESN'T MAKE ANY SENSE_UNLESS_YOU'RE TRYING TO INCREASE CODE COVERAGE",
"ca_ES_PREEURO_WITH_EXTRA_STUFF_THAT REALLY DOESN'T MAKE ANY SENSE_UNLESS_YOU'RE TRYING TO INCREASE CODE COVERAGE"},
{ "ca_ES_PREEURO", "ca_ES_PREEURO", "ca_ES@currency=ESP" },
{ "de_AT_PREEURO", "de_AT_PREEURO", "de_AT@currency=ATS" },
{ "de_DE_PREEURO", "de_DE_PREEURO", "de_DE@currency=DEM" },
{ "de_LU_PREEURO", "de_LU_PREEURO", "de_LU@currency=LUF" },
{ "el_GR_PREEURO", "el_GR_PREEURO", "el_GR@currency=GRD" },
{ "en_BE_PREEURO", "en_BE_PREEURO", "en_BE@currency=BEF" },
{ "en_IE_PREEURO", "en_IE_PREEURO", "en_IE@currency=IEP" },
{ "es_ES_PREEURO", "es_ES_PREEURO", "es_ES@currency=ESP" },
{ "eu_ES_PREEURO", "eu_ES_PREEURO", "eu_ES@currency=ESP" },
{ "fi_FI_PREEURO", "fi_FI_PREEURO", "fi_FI@currency=FIM" },
{ "fr_BE_PREEURO", "fr_BE_PREEURO", "fr_BE@currency=BEF" },
{ "fr_FR_PREEURO", "fr_FR_PREEURO", "fr_FR@currency=FRF" },
{ "fr_LU_PREEURO", "fr_LU_PREEURO", "fr_LU@currency=LUF" },
{ "ga_IE_PREEURO", "ga_IE_PREEURO", "ga_IE@currency=IEP" },
{ "gl_ES_PREEURO", "gl_ES_PREEURO", "gl_ES@currency=ESP" },
{ "it_IT_PREEURO", "it_IT_PREEURO", "it_IT@currency=ITL" },
{ "nl_BE_PREEURO", "nl_BE_PREEURO", "nl_BE@currency=BEF" },
{ "nl_NL_PREEURO", "nl_NL_PREEURO", "nl_NL@currency=NLG" },
{ "pt_PT_PREEURO", "pt_PT_PREEURO", "pt_PT@currency=PTE" },
{ "de__PHONEBOOK", "de__PHONEBOOK", "de@collation=phonebook" },
{ "en_GB_EURO", "en_GB_EURO", "en_GB@currency=EUR" },
{ "en_GB@EURO", "en_GB@EURO", "en_GB@currency=EUR" },
{ "es__TRADITIONAL", "es__TRADITIONAL", "es@collation=traditional" },
{ "hi__DIRECT", "hi__DIRECT", "hi@collation=direct" },
{ "ja_JP_TRADITIONAL", "ja_JP_TRADITIONAL", "ja_JP@calendar=japanese" },
{ "th_TH_TRADITIONAL", "th_TH_TRADITIONAL", "th_TH@calendar=buddhist" },
{ "zh_TW_STROKE", "zh_TW_STROKE", "zh_TW@collation=stroke" },
{ "zh__PINYIN", "zh__PINYIN", "zh@collation=pinyin" },
{ "zh@collation=pinyin", "zh@collation=pinyin", "zh@collation=pinyin" },
{ "zh_CN@collation=pinyin", "zh_CN@collation=pinyin", "zh_CN@collation=pinyin" },
{ "zh_CN_STROKE", "zh_CN_STROKE", "zh_CN@collation=stroke" },
{ "zh_CN_CA@collation=pinyin", "zh_CN_CA@collation=pinyin", "zh_CN_CA@collation=pinyin" },
{ "en_US_POSIX", "en_US_POSIX", "en_US_POSIX" },
{ "hy_AM_REVISED", "hy_AM_REVISED", "hy_AM_REVISED" },
{ "no_NO_NY", "no_NO_NY", "no_NO_NY" },
{ "no@ny", "no@ny", "no__NY" },
{ "no-no.utf32@B", "no_NO.utf32@B", "no_NO_B" },
{ "qz-qz@Euro", "qz_QZ@Euro", "qz_QZ@currency=EUR" },
{ "en-BOONT", "en__BOONT", "en__BOONT" },
{ "de-1901", "de__1901", "de__1901" },
{ "de-1906", "de__1906", "de__1906" },
{ "sr-SP-Cyrl", "sr_SP_CYRL", "sr_Cyrl_RS" },
{ "sr-SP-Latn", "sr_SP_LATN", "sr_Latn_RS" },
{ "sr_YU_CYRILLIC", "sr_YU_CYRILLIC", "sr_Cyrl_RS" },
{ "uz-UZ-Cyrl", "uz_UZ_CYRL", "uz_Cyrl_UZ" },
{ "uz-UZ-Latn", "uz_UZ_LATN", "uz_Latn_UZ" },
{ "zh-CHS", "zh_CHS", "zh_Hans" },
{ "zh-CHT", "zh_CHT", "zh_Hant" },
{ "mr.utf8", "mr.utf8", "mr" },
{ "de-tv.koi8r", "de_TV.koi8r", "de_TV" },
{ "x-piglatin_ML.MBE", "x-piglatin_ML.MBE", "x-piglatin_ML" },
{ "i-cherokee_US.utf7", "i-cherokee_US.utf7", "i-cherokee_US" },
{ "x-filfli_MT_FILFLA.gb-18030", "x-filfli_MT_FILFLA.gb-18030", "x-filfli_MT_FILFLA" },
{ "no-no-ny.utf8@B", "no_NO_NY.utf8@B", "no_NO_NY_B" },
{ "en_Hant_IL_VALLEY_GIRL@ currency = EUR; calendar = Japanese ;", "en_Hant_IL_VALLEY_GIRL@calendar=Japanese;currency=EUR", "en_Hant_IL_VALLEY_GIRL@calendar=Japanese;currency=EUR" },
{ "en_Hant_IL_VALLEY_GIRL@calendar=Japanese;currency=EUR", "en_Hant_IL_VALLEY_GIRL@calendar=Japanese;currency=EUR", "en_Hant_IL_VALLEY_GIRL@calendar=Japanese;currency=EUR" },
{ "es_ES_PREEURO@CALendar=Japanese", "es_ES_PREEURO@calendar=Japanese", "es_ES@calendar=Japanese;currency=ESP" },
{ "es_ES_EURO@SHOUT=zipeedeedoodah", "es_ES_EURO@shout=zipeedeedoodah", "es_ES@currency=EUR;shout=zipeedeedoodah" },
{ "es_ES_PREEURO@currency=EUR", "es_ES_PREEURO@currency=EUR", "es_ES@currency=EUR" },
{ "es_ES_EURO@currency=ESP", "es_ES_EURO@currency=ESP", "es_ES@currency=ESP" },
{ "no-Hant-GB_NY@currency=$$$", "no_Hant_GB_NY@currency=$$$", "no_Hant_GB_NY@currency=$$$" },
{ "root@kw=foo", "root@kw=foo", "root@kw=foo" },
{ "@calendar=gregorian", "@calendar=gregorian", "@calendar=gregorian" },
{ "ja_JP@calendar=Japanese", "ja_JP@calendar=Japanese", "ja_JP@calendar=Japanese" },
{ "ja_JP", "ja_JP", "ja_JP" },
{ "i-default", "en@x=i-default", "en@x=i-default" }
};
static const char* label[] = { "getName", "canonicalize" };
UErrorCode status = U_ZERO_ERROR;
int32_t i, j, resultLen = 0, origResultLen;
char buffer[256];
for (i=0; i < UPRV_LENGTHOF(testCases); i++) {
for (j=0; j<2; ++j) {
const char* expected = (j==0) ? testCases[i].getNameID : testCases[i].canonicalID;
*buffer = 0;
status = U_ZERO_ERROR;
if (expected == NULL) {
expected = uloc_getDefault();
}
origResultLen = _canonicalize(j, testCases[i].localeID, NULL, 0, &status);
if (status != U_BUFFER_OVERFLOW_ERROR) {
log_err("FAIL: uloc_%s(%s) => %s, expected U_BUFFER_OVERFLOW_ERROR\n",
label[j], testCases[i].localeID, u_errorName(status));
continue;
}
status = U_ZERO_ERROR;
resultLen = _canonicalize(j, testCases[i].localeID, buffer, sizeof(buffer), &status);
if (U_FAILURE(status)) {
log_err("FAIL: uloc_%s(%s) => %s, expected U_ZERO_ERROR\n",
label[j], testCases[i].localeID, u_errorName(status));
continue;
}
if(uprv_strcmp(expected, buffer) != 0) {
log_err("FAIL: uloc_%s(%s) => \"%s\", expected \"%s\"\n",
label[j], testCases[i].localeID, buffer, expected);
} else {
log_verbose("Ok: uloc_%s(%s) => \"%s\"\n",
label[j], testCases[i].localeID, buffer);
}
if (resultLen != (int32_t)strlen(buffer)) {
log_err("FAIL: uloc_%s(%s) => len %d, expected len %d\n",
label[j], testCases[i].localeID, resultLen, strlen(buffer));
}
if (origResultLen != resultLen) {
log_err("FAIL: uloc_%s(%s) => preflight len %d != actual len %d\n",
label[j], testCases[i].localeID, origResultLen, resultLen);
}
}
}
}
static void TestDisplayKeywords(void)
{
int32_t i;
static const struct {
const char *localeID;
const char *displayLocale;
UChar displayKeyword[200];
} testCases[] = {
{ "ca_ES@currency=ESP", "de_AT",
{0x0057, 0x00e4, 0x0068, 0x0072, 0x0075, 0x006e, 0x0067, 0x0000},
},
{ "ja_JP@calendar=japanese", "de",
{ 0x004b, 0x0061, 0x006c, 0x0065, 0x006e, 0x0064, 0x0065, 0x0072, 0x0000}
},
{ "de_DE@collation=traditional", "de_DE",
{0x0053, 0x006f, 0x0072, 0x0074, 0x0069, 0x0065, 0x0072, 0x0075, 0x006e, 0x0067, 0x0000}
},
};
for(i = 0; i < UPRV_LENGTHOF(testCases); i++) {
UErrorCode status = U_ZERO_ERROR;
const char* keyword =NULL;
int32_t keywordLen = 0;
int32_t keywordCount = 0;
UChar *displayKeyword=NULL;
int32_t displayKeywordLen = 0;
UEnumeration* keywordEnum = uloc_openKeywords(testCases[i].localeID, &status);
for(keywordCount = uenum_count(keywordEnum, &status); keywordCount > 0 ; keywordCount--){
if(U_FAILURE(status)){
log_err("uloc_getKeywords failed for locale id: %s with error : %s \n", testCases[i].localeID, u_errorName(status));
break;
}
keyword = uenum_next(keywordEnum, &keywordLen, &status);
displayKeywordLen = uloc_getDisplayKeyword(keyword, testCases[i].displayLocale, displayKeyword, displayKeywordLen, &status);
if(status==U_BUFFER_OVERFLOW_ERROR){
status = U_ZERO_ERROR;
displayKeywordLen++;
displayKeyword = (UChar*) malloc(displayKeywordLen * U_SIZEOF_UCHAR);
displayKeywordLen = uloc_getDisplayKeyword(keyword, testCases[i].displayLocale, displayKeyword, displayKeywordLen, &status);
if(U_FAILURE(status)){
log_err("uloc_getDisplayKeyword filed for keyword : %s in locale id: %s for display locale: %s \n", testCases[i].localeID, keyword, testCases[i].displayLocale, u_errorName(status));
break;
}
if(u_strncmp(displayKeyword, testCases[i].displayKeyword, displayKeywordLen)!=0){
if (status == U_USING_DEFAULT_WARNING) {
log_data_err("uloc_getDisplayKeyword did not get the expected value for keyword : %s in locale id: %s for display locale: %s . Got error: %s. Perhaps you are missing data?\n", testCases[i].localeID, keyword, testCases[i].displayLocale, u_errorName(status));
} else {
log_err("uloc_getDisplayKeyword did not get the expected value for keyword : %s in locale id: %s for display locale: %s \n", testCases[i].localeID, keyword, testCases[i].displayLocale);
}
break;
}
}else{
log_err("uloc_getDisplayKeyword did not return the expected error. Error: %s\n", u_errorName(status));
}
free(displayKeyword);
}
uenum_close(keywordEnum);
}
}
static void TestDisplayKeywordValues(void){
int32_t i;
static const struct {
const char *localeID;
const char *displayLocale;
UChar displayKeywordValue[500];
} testCases[] = {
{ "ca_ES@currency=ESP", "de_AT",
{0x0053, 0x0070, 0x0061, 0x006e, 0x0069, 0x0073, 0x0063, 0x0068, 0x0065, 0x0020, 0x0050, 0x0065, 0x0073, 0x0065, 0x0074, 0x0061, 0x0000}
},
{ "de_AT@currency=ATS", "fr_FR",
{0x0073, 0x0063, 0x0068, 0x0069, 0x006c, 0x006c, 0x0069, 0x006e, 0x0067, 0x0020, 0x0061, 0x0075, 0x0074, 0x0072, 0x0069, 0x0063, 0x0068, 0x0069, 0x0065, 0x006e, 0x0000}
},
{ "de_DE@currency=DEM", "it",
{0x006d, 0x0061, 0x0072, 0x0063, 0x006f, 0x0020, 0x0074, 0x0065, 0x0064, 0x0065, 0x0073, 0x0063, 0x006f, 0x0000}
},
{ "el_GR@currency=GRD", "en",
{0x0047, 0x0072, 0x0065, 0x0065, 0x006b, 0x0020, 0x0044, 0x0072, 0x0061, 0x0063, 0x0068, 0x006d, 0x0061, 0x0000}
},
{ "eu_ES@currency=ESP", "it_IT",
{0x0070, 0x0065, 0x0073, 0x0065, 0x0074, 0x0061, 0x0020, 0x0073, 0x0070, 0x0061, 0x0067, 0x006e, 0x006f, 0x006c, 0x0061, 0x0000}
},
{ "de@collation=phonebook", "es",
{0x006F, 0x0072, 0x0064, 0x0065, 0x006E, 0x0020, 0x0064, 0x0065, 0x0020, 0x006C, 0x0069, 0x0073, 0x0074, 0x00ED, 0x006E, 0x0020, 0x0074, 0x0065, 0x006C, 0x0065, 0x0066, 0x00F3, 0x006E, 0x0069, 0x0063, 0x006F, 0x0000}
},
{ "de_DE@collation=phonebook", "es",
{0x006F, 0x0072, 0x0064, 0x0065, 0x006E, 0x0020, 0x0064, 0x0065, 0x0020, 0x006C, 0x0069, 0x0073, 0x0074, 0x00ED, 0x006E, 0x0020, 0x0074, 0x0065, 0x006C, 0x0065, 0x0066, 0x00F3, 0x006E, 0x0069, 0x0063, 0x006F, 0x0000}
},
{ "es_ES@collation=traditional","de",
{0x0054, 0x0072, 0x0061, 0x0064, 0x0069, 0x0074, 0x0069, 0x006f, 0x006e, 0x0065, 0x006c, 0x006c, 0x0065, 0x0020, 0x0053, 0x006f, 0x0072, 0x0074, 0x0069, 0x0065, 0x0072, 0x0072, 0x0065, 0x0067, 0x0065, 0x006c, 0x006e, 0x0000}
},
{ "ja_JP@calendar=japanese", "de",
{0x004a, 0x0061, 0x0070, 0x0061, 0x006e, 0x0069, 0x0073, 0x0063, 0x0068, 0x0065, 0x0072, 0x0020, 0x004b, 0x0061, 0x006c, 0x0065, 0x006e, 0x0064, 0x0065, 0x0072, 0x0000}
},
};
for(i = 0; i < UPRV_LENGTHOF(testCases); i++) {
UErrorCode status = U_ZERO_ERROR;
const char* keyword =NULL;
int32_t keywordLen = 0;
int32_t keywordCount = 0;
UChar *displayKeywordValue = NULL;
int32_t displayKeywordValueLen = 0;
UEnumeration* keywordEnum = uloc_openKeywords(testCases[i].localeID, &status);
for(keywordCount = uenum_count(keywordEnum, &status); keywordCount > 0 ; keywordCount--){
if(U_FAILURE(status)){
log_err("uloc_getKeywords failed for locale id: %s in display locale: % with error : %s \n", testCases[i].localeID, testCases[i].displayLocale, u_errorName(status));
break;
}
keyword = uenum_next(keywordEnum, &keywordLen, &status);
displayKeywordValueLen = uloc_getDisplayKeywordValue(testCases[i].localeID, keyword, testCases[i].displayLocale, displayKeywordValue, displayKeywordValueLen, &status);
if(status==U_BUFFER_OVERFLOW_ERROR){
status = U_ZERO_ERROR;
displayKeywordValueLen++;
displayKeywordValue = (UChar*)malloc(displayKeywordValueLen * U_SIZEOF_UCHAR);
displayKeywordValueLen = uloc_getDisplayKeywordValue(testCases[i].localeID, keyword, testCases[i].displayLocale, displayKeywordValue, displayKeywordValueLen, &status);
if(U_FAILURE(status)){
log_err("uloc_getDisplayKeywordValue failed for keyword : %s in locale id: %s for display locale: %s with error : %s \n", testCases[i].localeID, keyword, testCases[i].displayLocale, u_errorName(status));
break;
}
if(u_strncmp(displayKeywordValue, testCases[i].displayKeywordValue, displayKeywordValueLen)!=0){
if (status == U_USING_DEFAULT_WARNING) {
log_data_err("uloc_getDisplayKeywordValue did not return the expected value keyword : %s in locale id: %s for display locale: %s with error : %s Perhaps you are missing data\n", testCases[i].localeID, keyword, testCases[i].displayLocale, u_errorName(status));
} else {
log_err("uloc_getDisplayKeywordValue did not return the expected value keyword : %s in locale id: %s for display locale: %s with error : %s \n", testCases[i].localeID, keyword, testCases[i].displayLocale, u_errorName(status));
}
break;
}
}else{
log_err("uloc_getDisplayKeywordValue did not return the expected error. Error: %s\n", u_errorName(status));
}
free(displayKeywordValue);
}
uenum_close(keywordEnum);
}
{
UErrorCode status = U_ZERO_ERROR;
const char* keyword =NULL;
int32_t keywordLen = 0;
int32_t keywordCount = 0;
const char* localeID = "es@collation=phonebook;calendar=buddhist;currency=DEM";
const char* displayLocale = "de";
static const UChar expected[][50] = {
{0x0042, 0x0075, 0x0064, 0x0064, 0x0068, 0x0069, 0x0073, 0x0074, 0x0069, 0x0073, 0x0063, 0x0068, 0x0065, 0x0072, 0x0020, 0x004b, 0x0061, 0x006c, 0x0065, 0x006e, 0x0064, 0x0065, 0x0072, 0x0000},
{0x0054, 0x0065, 0x006c, 0x0065, 0x0066, 0x006f, 0x006e, 0x0062, 0x0075, 0x0063, 0x0068, 0x002d, 0x0053, 0x006f, 0x0072, 0x0074, 0x0069, 0x0065, 0x0072, 0x0075, 0x006e, 0x0067, 0x0000},
{0x0044, 0x0065, 0x0075, 0x0074, 0x0073, 0x0063, 0x0068, 0x0065, 0x0020, 0x004d, 0x0061, 0x0072, 0x006b, 0x0000},
};
UEnumeration* keywordEnum = uloc_openKeywords(localeID, &status);
for(keywordCount = 0; keywordCount < uenum_count(keywordEnum, &status) ; keywordCount++){
UChar *displayKeywordValue = NULL;
int32_t displayKeywordValueLen = 0;
if(U_FAILURE(status)){
log_err("uloc_getKeywords failed for locale id: %s in display locale: % with error : %s \n", localeID, displayLocale, u_errorName(status));
break;
}
keyword = uenum_next(keywordEnum, &keywordLen, &status);
displayKeywordValueLen = uloc_getDisplayKeywordValue(localeID, keyword, displayLocale, displayKeywordValue, displayKeywordValueLen, &status);
if(status==U_BUFFER_OVERFLOW_ERROR){
status = U_ZERO_ERROR;
displayKeywordValueLen++;
displayKeywordValue = (UChar*)malloc(displayKeywordValueLen * U_SIZEOF_UCHAR);
displayKeywordValueLen = uloc_getDisplayKeywordValue(localeID, keyword, displayLocale, displayKeywordValue, displayKeywordValueLen, &status);
if(U_FAILURE(status)){
log_err("uloc_getDisplayKeywordValue failed for keyword : %s in locale id: %s for display locale: %s with error : %s \n", localeID, keyword, displayLocale, u_errorName(status));
break;
}
if(u_strncmp(displayKeywordValue, expected[keywordCount], displayKeywordValueLen)!=0){
if (status == U_USING_DEFAULT_WARNING) {
log_data_err("uloc_getDisplayKeywordValue did not return the expected value keyword : %s in locale id: %s for display locale: %s got error: %s. Perhaps you are missing data?\n", localeID, keyword, displayLocale, u_errorName(status));
} else {
log_err("uloc_getDisplayKeywordValue did not return the expected value keyword : %s in locale id: %s for display locale: %s \n", localeID, keyword, displayLocale);
}
break;
}
}else{
log_err("uloc_getDisplayKeywordValue did not return the expected error. Error: %s\n", u_errorName(status));
}
free(displayKeywordValue);
}
uenum_close(keywordEnum);
}
{
UErrorCode status = U_ZERO_ERROR;
const char* localeID = "es";
const char* displayLocale = "de";
UChar *displayKeywordValue = NULL;
int32_t displayKeywordValueLen = 0;
displayKeywordValueLen = uloc_getDisplayKeywordValue(localeID, "calendar", displayLocale, displayKeywordValue, displayKeywordValueLen, &status);
if(U_FAILURE(status)) {
log_err("uloc_getDisplaykeywordValue returned error status %s\n", u_errorName(status));
} else if(displayKeywordValueLen != 0) {
log_err("uloc_getDisplaykeywordValue returned %d should be 0 \n", displayKeywordValueLen);
}
}
}
static void TestGetBaseName(void) {
static const struct {
const char *localeID;
const char *baseName;
} testCases[] = {
{ "de_DE@ C o ll A t i o n = Phonebook ", "de_DE" },
{ "de@currency = euro; CoLLaTion = PHONEBOOk", "de" },
{ "ja@calendar = buddhist", "ja" }
};
int32_t i = 0, baseNameLen = 0;
char baseName[256];
UErrorCode status = U_ZERO_ERROR;
for(i = 0; i < UPRV_LENGTHOF(testCases); i++) {
baseNameLen = uloc_getBaseName(testCases[i].localeID, baseName, 256, &status);
(void)baseNameLen;
if(strcmp(testCases[i].baseName, baseName)) {
log_err("For locale \"%s\" expected baseName \"%s\", but got \"%s\"\n",
testCases[i].localeID, testCases[i].baseName, baseName);
return;
}
}
}
static void TestTrailingNull(void) {
const char* localeId = "zh_Hans";
UChar buffer[128];
int32_t len;
UErrorCode status = U_ZERO_ERROR;
int i;
len = uloc_getDisplayName(localeId, localeId, buffer, 128, &status);
if (len > 128) {
log_err("buffer too small");
return;
}
for (i = 0; i < len; ++i) {
if (buffer[i] == 0) {
log_err("name contained null");
return;
}
}
}
static void TestDisplayNameWarning(void) {
UChar name[256];
int32_t size;
UErrorCode status = U_ZERO_ERROR;
size = uloc_getDisplayLanguage("qqq", "kl", name, UPRV_LENGTHOF(name), &status);
(void)size;
if (status != U_USING_DEFAULT_WARNING) {
log_err("For language \"qqq\" in locale \"kl\", expecting U_USING_DEFAULT_WARNING, but got %s\n",
u_errorName(status));
}
}
static UBool _loccmp(const char* string, const char* prefix) {
int32_t slen = (int32_t)uprv_strlen(string),
plen = (int32_t)uprv_strlen(prefix);
int32_t c = uprv_strncmp(string, prefix, plen);
if (uprv_strcmp(prefix, "root") == 0) {
return (uprv_strcmp(string, "root") == 0) ? 0 : 1;
}
if (c) return -1;
if (slen == plen) return 0;
if (string[plen] == '_') return 1;
return -2;
}
static void _checklocs(const char* label,
const char* req,
const char* valid,
const char* actual) {
if (_loccmp(req, valid) > 0 &&
_loccmp(valid, actual) >= 0) {
log_verbose("%s; req=%s, valid=%s, actual=%s\n",
label, req, valid, actual);
} else {
log_err("FAIL: %s; req=%s, valid=%s, actual=%s\n",
label, req, valid, actual);
}
}
static void TestGetLocale(void) {
UErrorCode ec = U_ZERO_ERROR;
UParseError pe;
UChar EMPTY[1] = {0};
#if !UCONFIG_NO_FORMATTING
{
UDateFormat *obj;
const char *req = "en_US_REDWOODSHORES", *valid, *actual;
obj = udat_open(UDAT_DEFAULT, UDAT_DEFAULT,
req,
NULL, 0,
NULL, 0, &ec);
if (U_FAILURE(ec)) {
log_data_err("udat_open failed.Error %s\n", u_errorName(ec));
return;
}
valid = udat_getLocaleByType(obj, ULOC_VALID_LOCALE, &ec);
actual = udat_getLocaleByType(obj, ULOC_ACTUAL_LOCALE, &ec);
if (U_FAILURE(ec)) {
log_err("udat_getLocaleByType() failed\n");
return;
}
_checklocs("udat", req, valid, actual);
udat_close(obj);
}
#endif
#if !UCONFIG_NO_FORMATTING
{
UCalendar *obj;
const char *req = "fr_FR_PROVENCAL", *valid, *actual;
obj = ucal_open(NULL, 0,
req,
UCAL_GREGORIAN,
&ec);
if (U_FAILURE(ec)) {
log_err("ucal_open failed with error: %s\n", u_errorName(ec));
return;
}
valid = ucal_getLocaleByType(obj, ULOC_VALID_LOCALE, &ec);
actual = ucal_getLocaleByType(obj, ULOC_ACTUAL_LOCALE, &ec);
if (U_FAILURE(ec)) {
log_err("ucal_getLocaleByType() failed\n");
return;
}
_checklocs("ucal", req, valid, actual);
ucal_close(obj);
}
#endif
#if !UCONFIG_NO_FORMATTING
{
UNumberFormat *obj;
const char *req = "zh_Hant_TW_TAINAN", *valid, *actual;
obj = unum_open(UNUM_DECIMAL,
NULL, 0,
req,
&pe, &ec);
if (U_FAILURE(ec)) {
log_err("unum_open failed\n");
return;
}
valid = unum_getLocaleByType(obj, ULOC_VALID_LOCALE, &ec);
actual = unum_getLocaleByType(obj, ULOC_ACTUAL_LOCALE, &ec);
if (U_FAILURE(ec)) {
log_err("unum_getLocaleByType() failed\n");
return;
}
_checklocs("unum", req, valid, actual);
unum_close(obj);
}
#endif
#if 0
#if !UCONFIG_NO_FORMATTING
{
UMessageFormat *obj;
const char *req = "ja_JP_TAKAYAMA", *valid, *actual;
UBool test;
obj = umsg_open(EMPTY, 0,
req,
&pe, &ec);
if (U_FAILURE(ec)) {
log_err("umsg_open failed\n");
return;
}
valid = umsg_getLocaleByType(obj, ULOC_VALID_LOCALE, &ec);
actual = umsg_getLocaleByType(obj, ULOC_ACTUAL_LOCALE, &ec);
if (U_FAILURE(ec)) {
log_err("umsg_getLocaleByType() failed\n");
return;
}
test = (_cmpversion("3.2") <= 0) ?
(_loccmp(req, valid) >= 0) :
(_loccmp(req, valid) > 0);
if (test &&
_loccmp(valid, actual) >= 0) {
log_verbose("umsg; req=%s, valid=%s, actual=%s\n", req, valid, actual);
} else {
log_err("FAIL: umsg; req=%s, valid=%s, actual=%s\n", req, valid, actual);
}
umsg_close(obj);
}
#endif
#endif
#if !UCONFIG_NO_BREAK_ITERATION
{
UBreakIterator *obj;
const char *req = "ar_KW_ABDALI", *valid, *actual;
obj = ubrk_open(UBRK_WORD,
req,
EMPTY,
0,
&ec);
if (U_FAILURE(ec)) {
log_err("ubrk_open failed. Error: %s \n", u_errorName(ec));
return;
}
valid = ubrk_getLocaleByType(obj, ULOC_VALID_LOCALE, &ec);
actual = ubrk_getLocaleByType(obj, ULOC_ACTUAL_LOCALE, &ec);
if (U_FAILURE(ec)) {
log_err("ubrk_getLocaleByType() failed\n");
return;
}
_checklocs("ubrk", req, valid, actual);
ubrk_close(obj);
}
#endif
#if !UCONFIG_NO_COLLATION
{
UCollator *obj;
const char *req = "es_AR_BUENOSAIRES", *valid, *actual;
obj = ucol_open(req, &ec);
if (U_FAILURE(ec)) {
log_err("ucol_open failed - %s\n", u_errorName(ec));
return;
}
valid = ucol_getLocaleByType(obj, ULOC_VALID_LOCALE, &ec);
actual = ucol_getLocaleByType(obj, ULOC_ACTUAL_LOCALE, &ec);
if (U_FAILURE(ec)) {
log_err("ucol_getLocaleByType() failed\n");
return;
}
_checklocs("ucol", req, valid, actual);
ucol_close(obj);
}
#endif
}
static void TestEnglishExemplarCharacters(void) {
UErrorCode status = U_ZERO_ERROR;
int i;
USet *exSet = NULL;
UChar testChars[] = {
0x61,
0xE1,
0x41,
0x2D
};
ULocaleData *uld = ulocdata_open("en", &status);
if (U_FAILURE(status)) {
log_data_err("ulocdata_open() failed : %s - (Are you missing data?)\n", u_errorName(status));
return;
}
for (i = 0; i < ULOCDATA_ES_COUNT; i++) {
exSet = ulocdata_getExemplarSet(uld, exSet, 0, (ULocaleDataExemplarSetType)i, &status);
if (U_FAILURE(status)) {
log_err_status(status, "ulocdata_getExemplarSet() for type %d failed\n", i);
status = U_ZERO_ERROR;
continue;
}
if (!uset_contains(exSet, (UChar32)testChars[i])) {
log_err("Character U+%04X is not included in exemplar type %d\n", testChars[i], i);
}
}
uset_close(exSet);
ulocdata_close(uld);
}
static void TestNonexistentLanguageExemplars(void) {
UErrorCode ec = U_ZERO_ERROR;
ULocaleData *uld = ulocdata_open("qqq",&ec);
if (ec != U_USING_DEFAULT_WARNING) {
log_err_status(ec, "Exemplar set for \"qqq\", expecting U_USING_DEFAULT_WARNING, but got %s\n",
u_errorName(ec));
}
uset_close(ulocdata_getExemplarSet(uld, NULL, 0, ULOCDATA_ES_STANDARD, &ec));
ulocdata_close(uld);
}
static void TestLocDataErrorCodeChaining(void) {
UErrorCode ec = U_USELESS_COLLATOR_ERROR;
ulocdata_open(NULL, &ec);
ulocdata_getExemplarSet(NULL, NULL, 0, ULOCDATA_ES_STANDARD, &ec);
ulocdata_getDelimiter(NULL, ULOCDATA_DELIMITER_COUNT, NULL, -1, &ec);
ulocdata_getMeasurementSystem(NULL, &ec);
ulocdata_getPaperSize(NULL, NULL, NULL, &ec);
if (ec != U_USELESS_COLLATOR_ERROR) {
log_err("ulocdata API changed the error code to %s\n", u_errorName(ec));
}
}
typedef struct {
const char* locale;
UMeasurementSystem measureSys;
} LocToMeasureSys;
static const LocToMeasureSys locToMeasures[] = {
{ "fr_FR", UMS_SI },
{ "en", UMS_US },
{ "en_GB", UMS_UK },
{ "fr_FR@rg=GBZZZZ", UMS_UK },
{ "en@rg=frzzzz", UMS_SI },
{ "en_GB@rg=USZZZZ", UMS_US },
{ NULL, (UMeasurementSystem)0 }
};
static void TestLocDataWithRgTag(void) {
const LocToMeasureSys* locToMeasurePtr = locToMeasures;
for (; locToMeasurePtr->locale != NULL; locToMeasurePtr++) {
UErrorCode status = U_ZERO_ERROR;
UMeasurementSystem measureSys = ulocdata_getMeasurementSystem(locToMeasurePtr->locale, &status);
if (U_FAILURE(status)) {
log_data_err("ulocdata_getMeasurementSystem(\"%s\", ...) failed: %s - Are you missing data?\n",
locToMeasurePtr->locale, u_errorName(status));
} else if (measureSys != locToMeasurePtr->measureSys) {
log_err("ulocdata_getMeasurementSystem(\"%s\", ...), expected %d, got %d\n",
locToMeasurePtr->locale, (int) locToMeasurePtr->measureSys, (int)measureSys);
}
}
}
static void TestLanguageExemplarsFallbacks(void) {
UErrorCode ec = U_ZERO_ERROR;
ULocaleData *uld = ulocdata_open("en_US",&ec);
uset_close(ulocdata_getExemplarSet(uld, NULL, 0, ULOCDATA_ES_STANDARD, &ec));
if (ec != U_USING_FALLBACK_WARNING) {
log_err_status(ec, "Exemplar set for \"en_US\", expecting U_USING_FALLBACK_WARNING, but got %s\n",
u_errorName(ec));
}
ulocdata_close(uld);
ec = U_ZERO_ERROR;
uld = ulocdata_open("en",&ec);
uset_close(ulocdata_getExemplarSet(uld, NULL, 0, ULOCDATA_ES_STANDARD, &ec));
if (ec != U_ZERO_ERROR) {
log_err_status(ec, "Exemplar set for \"en\", expecting U_ZERO_ERROR, but got %s\n",
u_errorName(ec));
}
ulocdata_close(uld);
}
static const char *acceptResult(UAcceptResult uar) {
return udbg_enumName(UDBG_UAcceptResult, uar);
}
static void TestAcceptLanguage(void) {
UErrorCode status = U_ZERO_ERROR;
UAcceptResult outResult;
UEnumeration *available;
char tmp[200];
int i;
int32_t rc = 0;
struct {
int32_t httpSet;
const char *icuSet;
const char *expect;
UAcceptResult res;
UErrorCode expectStatus;
} tests[] = {
{ 0, NULL, "mt_MT", ULOC_ACCEPT_VALID, U_ZERO_ERROR},
{ 1, NULL, "en", ULOC_ACCEPT_VALID, U_ZERO_ERROR},
{ 2, NULL, "en", ULOC_ACCEPT_FALLBACK, U_ZERO_ERROR},
{ 3, NULL, "", ULOC_ACCEPT_FAILED, U_ZERO_ERROR},
{ 4, NULL, "es", ULOC_ACCEPT_VALID, U_ZERO_ERROR},
{ 5, NULL, "en", ULOC_ACCEPT_VALID, U_ZERO_ERROR},
{ 6, NULL, "ja", ULOC_ACCEPT_FALLBACK, U_ZERO_ERROR},
{ 7, NULL, "zh", ULOC_ACCEPT_FALLBACK, U_ZERO_ERROR},
{ 8, NULL, "", ULOC_ACCEPT_FAILED, U_ZERO_ERROR },
{ 9, NULL, "", ULOC_ACCEPT_FAILED, U_ZERO_ERROR },
{10, NULL, "", ULOC_ACCEPT_FAILED, U_BUFFER_OVERFLOW_ERROR },
{11, NULL, "", ULOC_ACCEPT_FAILED, U_BUFFER_OVERFLOW_ERROR },
};
const int32_t numTests = UPRV_LENGTHOF(tests);
static const char *http[] = {
"mt-mt, ja;q=0.76, en-us;q=0.95, en;q=0.92, en-gb;q=0.89, fr;q=0.87, iu-ca;q=0.84, iu;q=0.82, ja-jp;q=0.79, mt;q=0.97, de-de;q=0.74, de;q=0.71, es;q=0.68, it-it;q=0.66, it;q=0.63, vi-vn;q=0.61, vi;q=0.58, nl-nl;q=0.55, nl;q=0.53, th-th-traditional;q=.01",
"ja;q=0.5, en;q=0.8, tlh",
"en-wf, de-lx;q=0.8",
"mga-ie;q=0.9, tlh",
"xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, "
"xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, "
"xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, "
"xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, "
"xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, "
"xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, "
"xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, xx-yy;q=.1, "
"es",
"zh-xx;q=0.9, en;q=0.6",
"ja-JA",
"zh-xx;q=0.9",
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB", "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABC", "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", };
for(i=0;i<numTests;i++) {
outResult = -3;
status=U_ZERO_ERROR;
log_verbose("test #%d: http[%s], ICU[%s], expect %s, %s\n",
i, http[tests[i].httpSet], tests[i].icuSet, tests[i].expect, acceptResult(tests[i].res));
available = ures_openAvailableLocales(tests[i].icuSet, &status);
tmp[0]=0;
rc = uloc_acceptLanguageFromHTTP(tmp, 199, &outResult, http[tests[i].httpSet], available, &status);
(void)rc;
uenum_close(available);
log_verbose(" got %s, %s [%s]\n", tmp[0]?tmp:"(EMPTY)", acceptResult(outResult), u_errorName(status));
if(status != tests[i].expectStatus) {
log_err_status(status, "FAIL: expected status %s but got %s\n", u_errorName(tests[i].expectStatus), u_errorName(status));
} else if(U_SUCCESS(tests[i].expectStatus)) {
if(outResult != tests[i].res) {
log_err_status(status, "FAIL: #%d: expected outResult of %s but got %s\n", i,
acceptResult( tests[i].res),
acceptResult( outResult));
log_info("test #%d: http[%s], ICU[%s], expect %s, %s\n",
i, http[tests[i].httpSet], tests[i].icuSet, tests[i].expect,acceptResult(tests[i].res));
}
if((outResult>0)&&uprv_strcmp(tmp, tests[i].expect)) {
log_err_status(status, "FAIL: #%d: expected %s but got %s\n", i, tests[i].expect, tmp);
log_info("test #%d: http[%s], ICU[%s], expect %s, %s\n",
i, http[tests[i].httpSet], tests[i].icuSet, tests[i].expect, acceptResult(tests[i].res));
}
}
}
}
static const char* LOCALE_ALIAS[][2] = {
{"in", "id"},
{"in_ID", "id_ID"},
{"iw", "he"},
{"iw_IL", "he_IL"},
{"ji", "yi"},
{"en_BU", "en_MM"},
{"en_DY", "en_BJ"},
{"en_HV", "en_BF"},
{"en_NH", "en_VU"},
{"en_RH", "en_ZW"},
{"en_TP", "en_TL"},
{"en_ZR", "en_CD"}
};
static UBool isLocaleAvailable(UResourceBundle* resIndex, const char* loc){
UErrorCode status = U_ZERO_ERROR;
int32_t len = 0;
ures_getStringByKey(resIndex, loc,&len, &status);
if(U_FAILURE(status)){
return FALSE;
}
return TRUE;
}
static void TestCalendar() {
#if !UCONFIG_NO_FORMATTING
int i;
UErrorCode status = U_ZERO_ERROR;
UResourceBundle *resIndex = ures_open(NULL,"res_index", &status);
if(U_FAILURE(status)){
log_err_status(status, "Could not open res_index.res. Exiting. Error: %s\n", u_errorName(status));
return;
}
for (i=0; i<UPRV_LENGTHOF(LOCALE_ALIAS); i++) {
const char* oldLoc = LOCALE_ALIAS[i][0];
const char* newLoc = LOCALE_ALIAS[i][1];
UCalendar* c1 = NULL;
UCalendar* c2 = NULL;
const char* l1 = ucal_getLocaleByType(c1, ULOC_VALID_LOCALE, &status);
const char* l2 = ucal_getLocaleByType(c2, ULOC_VALID_LOCALE, &status);
if(!isLocaleAvailable(resIndex, newLoc)){
continue;
}
c1 = ucal_open(NULL, -1, oldLoc, UCAL_GREGORIAN, &status);
c2 = ucal_open(NULL, -1, newLoc, UCAL_GREGORIAN, &status);
if (strcmp(newLoc,l1)!=0 || strcmp(l1,l2)!=0 || status!=U_ZERO_ERROR) {
log_err("The locales are not equal!.Old: %s, New: %s \n", oldLoc, newLoc);
}
log_verbose("ucal_getLocaleByType old:%s new:%s\n", l1, l2);
ucal_close(c1);
ucal_close(c2);
}
ures_close(resIndex);
#endif
}
static void TestDateFormat() {
#if !UCONFIG_NO_FORMATTING
int i;
UErrorCode status = U_ZERO_ERROR;
UResourceBundle *resIndex = ures_open(NULL,"res_index", &status);
if(U_FAILURE(status)){
log_err_status(status, "Could not open res_index.res. Exiting. Error: %s\n", u_errorName(status));
return;
}
for (i=0; i<UPRV_LENGTHOF(LOCALE_ALIAS); i++) {
const char* oldLoc = LOCALE_ALIAS[i][0];
const char* newLoc = LOCALE_ALIAS[i][1];
UDateFormat* df1 = NULL;
UDateFormat* df2 = NULL;
const char* l1 = NULL;
const char* l2 = NULL;
if(!isLocaleAvailable(resIndex, newLoc)){
continue;
}
df1 = udat_open(UDAT_FULL, UDAT_FULL,oldLoc, NULL, 0, NULL, -1, &status);
df2 = udat_open(UDAT_FULL, UDAT_FULL,newLoc, NULL, 0, NULL, -1, &status);
if(U_FAILURE(status)){
log_err("Creation of date format failed %s\n", u_errorName(status));
return;
}
l1 = udat_getLocaleByType(df1, ULOC_VALID_LOCALE, &status);
l2 = udat_getLocaleByType(df2, ULOC_VALID_LOCALE, &status);
if(U_FAILURE(status)){
log_err("Fetching the locale by type failed. %s\n", u_errorName(status));
}
if (strcmp(newLoc,l1)!=0 || strcmp(l1,l2)!=0) {
log_err("The locales are not equal!.Old: %s, New: %s \n", oldLoc, newLoc);
}
log_verbose("udat_getLocaleByType old:%s new:%s\n", l1, l2);
udat_close(df1);
udat_close(df2);
}
ures_close(resIndex);
#endif
}
static void TestCollation() {
#if !UCONFIG_NO_COLLATION
int i;
UErrorCode status = U_ZERO_ERROR;
UResourceBundle *resIndex = ures_open(NULL,"res_index", &status);
if(U_FAILURE(status)){
log_err_status(status, "Could not open res_index.res. Exiting. Error: %s\n", u_errorName(status));
return;
}
for (i=0; i<UPRV_LENGTHOF(LOCALE_ALIAS); i++) {
const char* oldLoc = LOCALE_ALIAS[i][0];
const char* newLoc = LOCALE_ALIAS[i][1];
UCollator* c1 = NULL;
UCollator* c2 = NULL;
const char* l1 = NULL;
const char* l2 = NULL;
status = U_ZERO_ERROR;
if(!isLocaleAvailable(resIndex, newLoc)){
continue;
}
if(U_FAILURE(status)){
log_err("Creation of collators failed %s\n", u_errorName(status));
return;
}
c1 = ucol_open(oldLoc, &status);
c2 = ucol_open(newLoc, &status);
l1 = ucol_getLocaleByType(c1, ULOC_VALID_LOCALE, &status);
l2 = ucol_getLocaleByType(c2, ULOC_VALID_LOCALE, &status);
if(U_FAILURE(status)){
log_err("Fetching the locale names failed failed %s\n", u_errorName(status));
}
if (strcmp(newLoc,l1)!=0 || strcmp(l1,l2)!=0) {
log_err("The locales are not equal!.Old: %s, New: %s \n", oldLoc, newLoc);
}
log_verbose("ucol_getLocaleByType old:%s new:%s\n", l1, l2);
ucol_close(c1);
ucol_close(c2);
}
ures_close(resIndex);
#endif
}
typedef struct OrientationStructTag {
const char* localeId;
ULayoutType character;
ULayoutType line;
} OrientationStruct;
static const char* ULayoutTypeToString(ULayoutType type)
{
switch(type)
{
case ULOC_LAYOUT_LTR:
return "ULOC_LAYOUT_LTR";
break;
case ULOC_LAYOUT_RTL:
return "ULOC_LAYOUT_RTL";
break;
case ULOC_LAYOUT_TTB:
return "ULOC_LAYOUT_TTB";
break;
case ULOC_LAYOUT_BTT:
return "ULOC_LAYOUT_BTT";
break;
case ULOC_LAYOUT_UNKNOWN:
break;
}
return "Unknown enum value for ULayoutType!";
}
static void TestOrientation()
{
static const OrientationStruct toTest [] = {
{ "ar", ULOC_LAYOUT_RTL, ULOC_LAYOUT_TTB },
{ "aR", ULOC_LAYOUT_RTL, ULOC_LAYOUT_TTB },
{ "ar_Arab", ULOC_LAYOUT_RTL, ULOC_LAYOUT_TTB },
{ "fa", ULOC_LAYOUT_RTL, ULOC_LAYOUT_TTB },
{ "Fa", ULOC_LAYOUT_RTL, ULOC_LAYOUT_TTB },
{ "he", ULOC_LAYOUT_RTL, ULOC_LAYOUT_TTB },
{ "ps", ULOC_LAYOUT_RTL, ULOC_LAYOUT_TTB },
{ "ur", ULOC_LAYOUT_RTL, ULOC_LAYOUT_TTB },
{ "UR", ULOC_LAYOUT_RTL, ULOC_LAYOUT_TTB },
{ "en", ULOC_LAYOUT_LTR, ULOC_LAYOUT_TTB }
};
size_t i = 0;
for (; i < UPRV_LENGTHOF(toTest); ++i) {
UErrorCode statusCO = U_ZERO_ERROR;
UErrorCode statusLO = U_ZERO_ERROR;
const char* const localeId = toTest[i].localeId;
const ULayoutType co = uloc_getCharacterOrientation(localeId, &statusCO);
const ULayoutType expectedCO = toTest[i].character;
const ULayoutType lo = uloc_getLineOrientation(localeId, &statusLO);
const ULayoutType expectedLO = toTest[i].line;
if (U_FAILURE(statusCO)) {
log_err_status(statusCO,
" unexpected failure for uloc_getCharacterOrientation(), with localId \"%s\" and status %s\n",
localeId,
u_errorName(statusCO));
}
else if (co != expectedCO) {
log_err(
" unexpected result for uloc_getCharacterOrientation(), with localeId \"%s\". Expected %s but got result %s\n",
localeId,
ULayoutTypeToString(expectedCO),
ULayoutTypeToString(co));
}
if (U_FAILURE(statusLO)) {
log_err_status(statusLO,
" unexpected failure for uloc_getLineOrientation(), with localId \"%s\" and status %s\n",
localeId,
u_errorName(statusLO));
}
else if (lo != expectedLO) {
log_err(
" unexpected result for uloc_getLineOrientation(), with localeId \"%s\". Expected %s but got result %s\n",
localeId,
ULayoutTypeToString(expectedLO),
ULayoutTypeToString(lo));
}
}
}
static void TestULocale() {
int i;
UErrorCode status = U_ZERO_ERROR;
UResourceBundle *resIndex = ures_open(NULL,"res_index", &status);
if(U_FAILURE(status)){
log_err_status(status, "Could not open res_index.res. Exiting. Error: %s\n", u_errorName(status));
return;
}
for (i=0; i<UPRV_LENGTHOF(LOCALE_ALIAS); i++) {
const char* oldLoc = LOCALE_ALIAS[i][0];
const char* newLoc = LOCALE_ALIAS[i][1];
UChar name1[256], name2[256];
char names1[256], names2[256];
int32_t capacity = 256;
status = U_ZERO_ERROR;
if(!isLocaleAvailable(resIndex, newLoc)){
continue;
}
uloc_getDisplayName(oldLoc, ULOC_US, name1, capacity, &status);
if(U_FAILURE(status)){
log_err("uloc_getDisplayName(%s) failed %s\n", oldLoc, u_errorName(status));
}
uloc_getDisplayName(newLoc, ULOC_US, name2, capacity, &status);
if(U_FAILURE(status)){
log_err("uloc_getDisplayName(%s) failed %s\n", newLoc, u_errorName(status));
}
if (u_strcmp(name1, name2)!=0) {
log_err("The locales are not equal!.Old: %s, New: %s \n", oldLoc, newLoc);
}
u_austrcpy(names1, name1);
u_austrcpy(names2, name2);
log_verbose("uloc_getDisplayName old:%s new:%s\n", names1, names2);
}
ures_close(resIndex);
}
static void TestUResourceBundle() {
const char* us1;
const char* us2;
UResourceBundle* rb1 = NULL;
UResourceBundle* rb2 = NULL;
UErrorCode status = U_ZERO_ERROR;
int i;
UResourceBundle *resIndex = NULL;
if(U_FAILURE(status)){
log_err("Could not open res_index.res. Exiting. Error: %s\n", u_errorName(status));
return;
}
resIndex = ures_open(NULL,"res_index", &status);
for (i=0; i<UPRV_LENGTHOF(LOCALE_ALIAS); i++) {
const char* oldLoc = LOCALE_ALIAS[i][0];
const char* newLoc = LOCALE_ALIAS[i][1];
if(!isLocaleAvailable(resIndex, newLoc)){
continue;
}
rb1 = ures_open(NULL, oldLoc, &status);
if (U_FAILURE(status)) {
log_err("ures_open(%s) failed %s\n", oldLoc, u_errorName(status));
}
us1 = ures_getLocaleByType(rb1, ULOC_ACTUAL_LOCALE, &status);
status = U_ZERO_ERROR;
rb2 = ures_open(NULL, newLoc, &status);
if (U_FAILURE(status)) {
log_err("ures_open(%s) failed %s\n", oldLoc, u_errorName(status));
}
us2 = ures_getLocaleByType(rb2, ULOC_ACTUAL_LOCALE, &status);
if (strcmp(us1,newLoc)!=0 || strcmp(us1,us2)!=0 ) {
log_err("The locales are not equal!.Old: %s, New: %s \n", oldLoc, newLoc);
}
log_verbose("ures_getStringByKey old:%s new:%s\n", us1, us2);
ures_close(rb1);
rb1 = NULL;
ures_close(rb2);
rb2 = NULL;
}
ures_close(resIndex);
}
static void TestDisplayName() {
UChar oldCountry[256] = {'\0'};
UChar newCountry[256] = {'\0'};
UChar oldLang[256] = {'\0'};
UChar newLang[256] = {'\0'};
char country[256] ={'\0'};
char language[256] ={'\0'};
int32_t capacity = 256;
int i =0;
int j=0;
for (i=0; i<UPRV_LENGTHOF(LOCALE_ALIAS); i++) {
const char* oldLoc = LOCALE_ALIAS[i][0];
const char* newLoc = LOCALE_ALIAS[i][1];
UErrorCode status = U_ZERO_ERROR;
int32_t available = uloc_countAvailable();
for(j=0; j<available; j++){
const char* dispLoc = uloc_getAvailable(j);
int32_t oldCountryLen = uloc_getDisplayCountry(oldLoc,dispLoc, oldCountry, capacity, &status);
int32_t newCountryLen = uloc_getDisplayCountry(newLoc, dispLoc, newCountry, capacity, &status);
int32_t oldLangLen = uloc_getDisplayLanguage(oldLoc, dispLoc, oldLang, capacity, &status);
int32_t newLangLen = uloc_getDisplayLanguage(newLoc, dispLoc, newLang, capacity, &status );
int32_t countryLen = uloc_getCountry(newLoc, country, capacity, &status);
int32_t langLen = uloc_getLanguage(newLoc, language, capacity, &status);
if(countryLen != newCountryLen ){
if(u_strncmp(oldCountry,newCountry,oldCountryLen)!=0){
log_err("uloc_getDisplayCountry() failed for %s in display locale %s \n", oldLoc, dispLoc);
}
}
if(langLen!=newLangLen){
if(u_strncmp(oldLang,newLang,oldLangLen)){
log_err("uloc_getDisplayLanguage() failed for %s in display locale %s \n", oldLoc, dispLoc); }
}
}
}
}
static void TestGetLocaleForLCID() {
int32_t i, length, lengthPre;
const char* testLocale = 0;
UErrorCode status = U_ZERO_ERROR;
char temp2[40], temp3[40];
uint32_t lcid;
lcid = uloc_getLCID("en_US");
if (lcid != 0x0409) {
log_err(" uloc_getLCID(\"en_US\") = %d, expected 0x0409\n", lcid);
}
lengthPre = uloc_getLocaleForLCID(lcid, temp2, 4, &status);
if (status != U_BUFFER_OVERFLOW_ERROR) {
log_err(" unexpected result from uloc_getLocaleForLCID with small buffer: %s\n", u_errorName(status));
}
else {
status = U_ZERO_ERROR;
}
length = uloc_getLocaleForLCID(lcid, temp2, UPRV_LENGTHOF(temp2), &status);
if (U_FAILURE(status)) {
log_err(" unexpected result from uloc_getLocaleForLCID(0x0409): %s\n", u_errorName(status));
status = U_ZERO_ERROR;
}
if (length != lengthPre) {
log_err(" uloc_getLocaleForLCID(0x0409): returned length %d does not match preflight length %d\n", length, lengthPre);
}
length = uloc_getLocaleForLCID(0x12345, temp2, UPRV_LENGTHOF(temp2), &status);
if (U_SUCCESS(status)) {
log_err(" unexpected result from uloc_getLocaleForLCID(0x12345): %s, status %s\n", temp2, u_errorName(status));
}
status = U_ZERO_ERROR;
log_verbose("Testing getLocaleForLCID vs. locale data\n");
for (i = 0; i < LOCALE_SIZE; i++) {
testLocale=rawData2[NAME][i];
log_verbose("Testing %s ......\n", testLocale);
sscanf(rawData2[LCID][i], "%x", &lcid);
length = uloc_getLocaleForLCID(lcid, temp2, UPRV_LENGTHOF(temp2), &status);
if (U_FAILURE(status)) {
log_err(" unexpected failure of uloc_getLocaleForLCID(%#04x), status %s\n", lcid, u_errorName(status));
status = U_ZERO_ERROR;
continue;
}
if (length != uprv_strlen(temp2)) {
log_err(" returned length %d not correct for uloc_getLocaleForLCID(%#04x), expected %d\n", length, lcid, uprv_strlen(temp2));
}
length = uloc_getLanguage(temp2, temp3, UPRV_LENGTHOF(temp3), &status);
if (U_FAILURE(status)) {
log_err(" couldn't get language in uloc_getLocaleForLCID(%#04x) = %s, status %s\n", lcid, temp2, u_errorName(status));
status = U_ZERO_ERROR;
}
else if (uprv_strcmp(temp3, rawData2[LANG][i]) && !(uprv_strcmp(temp3, "nn") == 0 && uprv_strcmp(rawData2[VAR][i], "NY") == 0)) {
log_err(" language doesn't match expected %s in in uloc_getLocaleForLCID(%#04x) = %s\n", rawData2[LANG][i], lcid, temp2);
}
length = uloc_getScript(temp2, temp3, UPRV_LENGTHOF(temp3), &status);
if (U_FAILURE(status)) {
log_err(" couldn't get script in uloc_getLocaleForLCID(%#04x) = %s, status %s\n", lcid, temp2, u_errorName(status));
status = U_ZERO_ERROR;
}
else if (uprv_strcmp(temp3, rawData2[SCRIPT][i])) {
log_err(" script doesn't match expected %s in in uloc_getLocaleForLCID(%#04x) = %s\n", rawData2[SCRIPT][i], lcid, temp2);
}
length = uloc_getCountry(temp2, temp3, UPRV_LENGTHOF(temp3), &status);
if (U_FAILURE(status)) {
log_err(" couldn't get country in uloc_getLocaleForLCID(%#04x) = %s, status %s\n", lcid, temp2, u_errorName(status));
status = U_ZERO_ERROR;
}
else if (uprv_strlen(rawData2[CTRY][i]) && uprv_strcmp(temp3, rawData2[CTRY][i])) {
log_err(" country doesn't match expected %s in in uloc_getLocaleForLCID(%#04x) = %s\n", rawData2[CTRY][i], lcid, temp2);
}
}
}
const char* const basic_maximize_data[][2] = {
{
"zu_Zzzz_Zz",
"zu_Latn_ZA",
}, {
"ZU_Zz",
"zu_Latn_ZA"
}, {
"zu_LATN",
"zu_Latn_ZA"
}, {
"en_Zz",
"en_Latn_US"
}, {
"en_us",
"en_Latn_US"
}, {
"en_Kore",
"en_Kore_US"
}, {
"en_Kore_Zz",
"en_Kore_US"
}, {
"en_Kore_ZA",
"en_Kore_ZA"
}, {
"en_Kore_ZA_POSIX",
"en_Kore_ZA_POSIX"
}, {
"en_Gujr",
"en_Gujr_US"
}, {
"en_ZA",
"en_Latn_ZA"
}, {
"en_Gujr_Zz",
"en_Gujr_US"
}, {
"en_Gujr_ZA",
"en_Gujr_ZA"
}, {
"en_Gujr_ZA_POSIX",
"en_Gujr_ZA_POSIX"
}, {
"en_US_POSIX_1901",
"en_Latn_US_POSIX_1901"
}, {
"en_Latn__POSIX_1901",
"en_Latn_US_POSIX_1901"
}, {
"en__POSIX_1901",
"en_Latn_US_POSIX_1901"
}, {
"de__POSIX_1901",
"de_Latn_DE_POSIX_1901"
}, {
"en_US_BOSTON",
"en_Latn_US_BOSTON"
}, {
"th@calendar=buddhist",
"th_Thai_TH@calendar=buddhist"
}, {
"ar_ZZ",
"ar_Arab_EG"
}, {
"zh",
"zh_Hans_CN"
}, {
"zh_TW",
"zh_Hant_TW"
}, {
"zh_HK",
"zh_Hant_HK"
}, {
"zh_Hant",
"zh_Hant_TW"
}, {
"zh_Zzzz_CN",
"zh_Hans_CN"
}, {
"und_US",
"en_Latn_US"
}, {
"und_HK",
"zh_Hant_HK"
}, {
"zzz",
""
}, {
"de_u_co_phonebk",
"de_Latn_DE_U_CO_PHONEBK"
}, {
"de_Latn_u_co_phonebk",
"de_Latn_DE_U_CO_PHONEBK"
}, {
"de_Latn_DE_u_co_phonebk",
"de_Latn_DE_U_CO_PHONEBK"
}, {
"_Arab@em=emoji",
"ar_Arab_EG@em=emoji"
}, {
"_Latn@em=emoji",
"en_Latn_US@em=emoji"
}, {
"_Latn_DE@em=emoji",
"de_Latn_DE@em=emoji"
}, {
"_Zzzz_DE@em=emoji",
"de_Latn_DE@em=emoji"
}, {
"_DE@em=emoji",
"de_Latn_DE@em=emoji"
}
};
const char* const basic_minimize_data[][2] = {
{
"en_Latn_US",
"en"
}, {
"en_Latn_US_POSIX_1901",
"en__POSIX_1901"
}, {
"EN_Latn_US_POSIX_1901",
"en__POSIX_1901"
}, {
"en_Zzzz_US_POSIX_1901",
"en__POSIX_1901"
}, {
"de_Latn_DE_POSIX_1901",
"de__POSIX_1901"
}, {
"und",
""
}, {
"en_Latn_US@calendar=gregorian",
"en@calendar=gregorian"
}
};
const char* const full_data[][3] = {
{
"aa",
"aa_Latn_ET",
"aa"
}, {
"af",
"af_Latn_ZA",
"af"
}, {
"ak",
"ak_Latn_GH",
"ak"
}, {
"am",
"am_Ethi_ET",
"am"
}, {
"ar",
"ar_Arab_EG",
"ar"
}, {
"as",
"as_Beng_IN",
"as"
}, {
"az",
"az_Latn_AZ",
"az"
}, {
"be",
"be_Cyrl_BY",
"be"
}, {
"bg",
"bg_Cyrl_BG",
"bg"
}, {
"bn",
"bn_Beng_BD",
"bn"
}, {
"bo",
"bo_Tibt_CN",
"bo"
}, {
"bs",
"bs_Latn_BA",
"bs"
}, {
"ca",
"ca_Latn_ES",
"ca"
}, {
"ch",
"ch_Latn_GU",
"ch"
}, {
"chk",
"chk_Latn_FM",
"chk"
}, {
"cs",
"cs_Latn_CZ",
"cs"
}, {
"cy",
"cy_Latn_GB",
"cy"
}, {
"da",
"da_Latn_DK",
"da"
}, {
"de",
"de_Latn_DE",
"de"
}, {
"dv",
"dv_Thaa_MV",
"dv"
}, {
"dz",
"dz_Tibt_BT",
"dz"
}, {
"ee",
"ee_Latn_GH",
"ee"
}, {
"el",
"el_Grek_GR",
"el"
}, {
"en",
"en_Latn_US",
"en"
}, {
"es",
"es_Latn_ES",
"es"
}, {
"et",
"et_Latn_EE",
"et"
}, {
"eu",
"eu_Latn_ES",
"eu"
}, {
"fa",
"fa_Arab_IR",
"fa"
}, {
"fi",
"fi_Latn_FI",
"fi"
}, {
"fil",
"fil_Latn_PH",
"fil"
}, {
"fo",
"fo_Latn_FO",
"fo"
}, {
"fr",
"fr_Latn_FR",
"fr"
}, {
"fur",
"fur_Latn_IT",
"fur"
}, {
"ga",
"ga_Latn_IE",
"ga"
}, {
"gaa",
"gaa_Latn_GH",
"gaa"
}, {
"gl",
"gl_Latn_ES",
"gl"
}, {
"gn",
"gn_Latn_PY",
"gn"
}, {
"gu",
"gu_Gujr_IN",
"gu"
}, {
"ha",
"ha_Latn_NG",
"ha"
}, {
"haw",
"haw_Latn_US",
"haw"
}, {
"he",
"he_Hebr_IL",
"he"
}, {
"hi",
"hi_Deva_IN",
"hi"
}, {
"hr",
"hr_Latn_HR",
"hr"
}, {
"ht",
"ht_Latn_HT",
"ht"
}, {
"hu",
"hu_Latn_HU",
"hu"
}, {
"hy",
"hy_Armn_AM",
"hy"
}, {
"id",
"id_Latn_ID",
"id"
}, {
"ig",
"ig_Latn_NG",
"ig"
}, {
"ii",
"ii_Yiii_CN",
"ii"
}, {
"is",
"is_Latn_IS",
"is"
}, {
"it",
"it_Latn_IT",
"it"
}, {
"ja",
"ja_Jpan_JP",
"ja"
}, {
"ka",
"ka_Geor_GE",
"ka"
}, {
"kaj",
"kaj_Latn_NG",
"kaj"
}, {
"kam",
"kam_Latn_KE",
"kam"
}, {
"kk",
"kk_Cyrl_KZ",
"kk"
}, {
"kl",
"kl_Latn_GL",
"kl"
}, {
"km",
"km_Khmr_KH",
"km"
}, {
"kn",
"kn_Knda_IN",
"kn"
}, {
"ko",
"ko_Kore_KR",
"ko"
}, {
"kok",
"kok_Deva_IN",
"kok"
}, {
"kpe",
"kpe_Latn_LR",
"kpe"
}, {
"ku",
"ku_Latn_TR",
"ku"
}, {
"ky",
"ky_Cyrl_KG",
"ky"
}, {
"la",
"la_Latn_VA",
"la"
}, {
"ln",
"ln_Latn_CD",
"ln"
}, {
"lo",
"lo_Laoo_LA",
"lo"
}, {
"lt",
"lt_Latn_LT",
"lt"
}, {
"lv",
"lv_Latn_LV",
"lv"
}, {
"mg",
"mg_Latn_MG",
"mg"
}, {
"mh",
"mh_Latn_MH",
"mh"
}, {
"mk",
"mk_Cyrl_MK",
"mk"
}, {
"ml",
"ml_Mlym_IN",
"ml"
}, {
"mn",
"mn_Cyrl_MN",
"mn"
}, {
"mr",
"mr_Deva_IN",
"mr"
}, {
"ms",
"ms_Latn_MY",
"ms"
}, {
"mt",
"mt_Latn_MT",
"mt"
}, {
"my",
"my_Mymr_MM",
"my"
}, {
"na",
"na_Latn_NR",
"na"
}, {
"ne",
"ne_Deva_NP",
"ne"
}, {
"niu",
"niu_Latn_NU",
"niu"
}, {
"nl",
"nl_Latn_NL",
"nl"
}, {
"nn",
"nn_Latn_NO",
"nn"
}, {
"nr",
"nr_Latn_ZA",
"nr"
}, {
"nso",
"nso_Latn_ZA",
"nso"
}, {
"ny",
"ny_Latn_MW",
"ny"
}, {
"om",
"om_Latn_ET",
"om"
}, {
"or",
"or_Orya_IN",
"or"
}, {
"pa",
"pa_Guru_IN",
"pa"
}, {
"pa_Arab",
"pa_Arab_PK",
"pa_PK"
}, {
"pa_PK",
"pa_Arab_PK",
"pa_PK"
}, {
"pap",
"pap_Latn_AW",
"pap"
}, {
"pau",
"pau_Latn_PW",
"pau"
}, {
"pl",
"pl_Latn_PL",
"pl"
}, {
"ps",
"ps_Arab_AF",
"ps"
}, {
"pt",
"pt_Latn_BR",
"pt"
}, {
"rn",
"rn_Latn_BI",
"rn"
}, {
"ro",
"ro_Latn_RO",
"ro"
}, {
"ru",
"ru_Cyrl_RU",
"ru"
}, {
"rw",
"rw_Latn_RW",
"rw"
}, {
"sa",
"sa_Deva_IN",
"sa"
}, {
"se",
"se_Latn_NO",
"se"
}, {
"sg",
"sg_Latn_CF",
"sg"
}, {
"si",
"si_Sinh_LK",
"si"
}, {
"sid",
"sid_Latn_ET",
"sid"
}, {
"sk",
"sk_Latn_SK",
"sk"
}, {
"sl",
"sl_Latn_SI",
"sl"
}, {
"sm",
"sm_Latn_WS",
"sm"
}, {
"so",
"so_Latn_SO",
"so"
}, {
"sq",
"sq_Latn_AL",
"sq"
}, {
"sr",
"sr_Cyrl_RS",
"sr"
}, {
"ss",
"ss_Latn_ZA",
"ss"
}, {
"st",
"st_Latn_ZA",
"st"
}, {
"sv",
"sv_Latn_SE",
"sv"
}, {
"sw",
"sw_Latn_TZ",
"sw"
}, {
"ta",
"ta_Taml_IN",
"ta"
}, {
"te",
"te_Telu_IN",
"te"
}, {
"tet",
"tet_Latn_TL",
"tet"
}, {
"tg",
"tg_Cyrl_TJ",
"tg"
}, {
"th",
"th_Thai_TH",
"th"
}, {
"ti",
"ti_Ethi_ET",
"ti"
}, {
"tig",
"tig_Ethi_ER",
"tig"
}, {
"tk",
"tk_Latn_TM",
"tk"
}, {
"tkl",
"tkl_Latn_TK",
"tkl"
}, {
"tn",
"tn_Latn_ZA",
"tn"
}, {
"to",
"to_Latn_TO",
"to"
}, {
"tpi",
"tpi_Latn_PG",
"tpi"
}, {
"tr",
"tr_Latn_TR",
"tr"
}, {
"ts",
"ts_Latn_ZA",
"ts"
}, {
"tt",
"tt_Cyrl_RU",
"tt"
}, {
"tvl",
"tvl_Latn_TV",
"tvl"
}, {
"ty",
"ty_Latn_PF",
"ty"
}, {
"uk",
"uk_Cyrl_UA",
"uk"
}, {
"und",
"en_Latn_US",
"en"
}, {
"und_AD",
"ca_Latn_AD",
"ca_AD"
}, {
"und_AE",
"ar_Arab_AE",
"ar_AE"
}, {
"und_AF",
"fa_Arab_AF",
"fa_AF"
}, {
"und_AL",
"sq_Latn_AL",
"sq"
}, {
"und_AM",
"hy_Armn_AM",
"hy"
}, {
"und_AO",
"pt_Latn_AO",
"pt_AO"
}, {
"und_AR",
"es_Latn_AR",
"es_AR"
}, {
"und_AS",
"sm_Latn_AS",
"sm_AS"
}, {
"und_AT",
"de_Latn_AT",
"de_AT"
}, {
"und_AW",
"nl_Latn_AW",
"nl_AW"
}, {
"und_AX",
"sv_Latn_AX",
"sv_AX"
}, {
"und_AZ",
"az_Latn_AZ",
"az"
}, {
"und_Arab",
"ar_Arab_EG",
"ar"
}, {
"und_Arab_IN",
"ur_Arab_IN",
"ur_IN"
}, {
"und_Arab_PK",
"ur_Arab_PK",
"ur"
}, {
"und_Arab_SN",
"ar_Arab_SN",
"ar_SN"
}, {
"und_Armn",
"hy_Armn_AM",
"hy"
}, {
"und_BA",
"bs_Latn_BA",
"bs"
}, {
"und_BD",
"bn_Beng_BD",
"bn"
}, {
"und_BE",
"nl_Latn_BE",
"nl_BE"
}, {
"und_BF",
"fr_Latn_BF",
"fr_BF"
}, {
"und_BG",
"bg_Cyrl_BG",
"bg"
}, {
"und_BH",
"ar_Arab_BH",
"ar_BH"
}, {
"und_BI",
"rn_Latn_BI",
"rn"
}, {
"und_BJ",
"fr_Latn_BJ",
"fr_BJ"
}, {
"und_BN",
"ms_Latn_BN",
"ms_BN"
}, {
"und_BO",
"es_Latn_BO",
"es_BO"
}, {
"und_BR",
"pt_Latn_BR",
"pt"
}, {
"und_BT",
"dz_Tibt_BT",
"dz"
}, {
"und_BY",
"be_Cyrl_BY",
"be"
}, {
"und_Beng",
"bn_Beng_BD",
"bn"
}, {
"und_Beng_IN",
"bn_Beng_IN",
"bn_IN"
}, {
"und_CD",
"sw_Latn_CD",
"sw_CD"
}, {
"und_CF",
"fr_Latn_CF",
"fr_CF"
}, {
"und_CG",
"fr_Latn_CG",
"fr_CG"
}, {
"und_CH",
"de_Latn_CH",
"de_CH"
}, {
"und_CI",
"fr_Latn_CI",
"fr_CI"
}, {
"und_CL",
"es_Latn_CL",
"es_CL"
}, {
"und_CM",
"fr_Latn_CM",
"fr_CM"
}, {
"und_CN",
"zh_Hans_CN",
"zh"
}, {
"und_CO",
"es_Latn_CO",
"es_CO"
}, {
"und_CR",
"es_Latn_CR",
"es_CR"
}, {
"und_CU",
"es_Latn_CU",
"es_CU"
}, {
"und_CV",
"pt_Latn_CV",
"pt_CV"
}, {
"und_CY",
"el_Grek_CY",
"el_CY"
}, {
"und_CZ",
"cs_Latn_CZ",
"cs"
}, {
"und_Cher",
"chr_Cher_US",
"chr"
}, {
"und_Cyrl",
"ru_Cyrl_RU",
"ru"
}, {
"und_Cyrl_KZ",
"ru_Cyrl_KZ",
"ru_KZ"
}, {
"und_DE",
"de_Latn_DE",
"de"
}, {
"und_DJ",
"aa_Latn_DJ",
"aa_DJ"
}, {
"und_DK",
"da_Latn_DK",
"da"
}, {
"und_DO",
"es_Latn_DO",
"es_DO"
}, {
"und_DZ",
"ar_Arab_DZ",
"ar_DZ"
}, {
"und_Deva",
"hi_Deva_IN",
"hi"
}, {
"und_EC",
"es_Latn_EC",
"es_EC"
}, {
"und_EE",
"et_Latn_EE",
"et"
}, {
"und_EG",
"ar_Arab_EG",
"ar"
}, {
"und_EH",
"ar_Arab_EH",
"ar_EH"
}, {
"und_ER",
"ti_Ethi_ER",
"ti_ER"
}, {
"und_ES",
"es_Latn_ES",
"es"
}, {
"und_ET",
"am_Ethi_ET",
"am"
}, {
"und_Ethi",
"am_Ethi_ET",
"am"
}, {
"und_Ethi_ER",
"am_Ethi_ER",
"am_ER"
}, {
"und_FI",
"fi_Latn_FI",
"fi"
}, {
"und_FM",
"en_Latn_FM",
"en_FM"
}, {
"und_FO",
"fo_Latn_FO",
"fo"
}, {
"und_FR",
"fr_Latn_FR",
"fr"
}, {
"und_GA",
"fr_Latn_GA",
"fr_GA"
}, {
"und_GE",
"ka_Geor_GE",
"ka"
}, {
"und_GF",
"fr_Latn_GF",
"fr_GF"
}, {
"und_GL",
"kl_Latn_GL",
"kl"
}, {
"und_GN",
"fr_Latn_GN",
"fr_GN"
}, {
"und_GP",
"fr_Latn_GP",
"fr_GP"
}, {
"und_GQ",
"es_Latn_GQ",
"es_GQ"
}, {
"und_GR",
"el_Grek_GR",
"el"
}, {
"und_GT",
"es_Latn_GT",
"es_GT"
}, {
"und_GU",
"en_Latn_GU",
"en_GU"
}, {
"und_GW",
"pt_Latn_GW",
"pt_GW"
}, {
"und_Geor",
"ka_Geor_GE",
"ka"
}, {
"und_Grek",
"el_Grek_GR",
"el"
}, {
"und_Gujr",
"gu_Gujr_IN",
"gu"
}, {
"und_Guru",
"pa_Guru_IN",
"pa"
}, {
"und_HK",
"zh_Hant_HK",
"zh_HK"
}, {
"und_HN",
"es_Latn_HN",
"es_HN"
}, {
"und_HR",
"hr_Latn_HR",
"hr"
}, {
"und_HT",
"ht_Latn_HT",
"ht"
}, {
"und_HU",
"hu_Latn_HU",
"hu"
}, {
"und_Hani",
"zh_Hani_CN",
"zh_Hani"
}, {
"und_Hans",
"zh_Hans_CN",
"zh"
}, {
"und_Hant",
"zh_Hant_TW",
"zh_TW"
}, {
"und_Hebr",
"he_Hebr_IL",
"he"
}, {
"und_IL",
"he_Hebr_IL",
"he"
}, {
"und_IN",
"hi_Deva_IN",
"hi"
}, {
"und_IQ",
"ar_Arab_IQ",
"ar_IQ"
}, {
"und_IR",
"fa_Arab_IR",
"fa"
}, {
"und_IS",
"is_Latn_IS",
"is"
}, {
"und_IT",
"it_Latn_IT",
"it"
}, {
"und_JO",
"ar_Arab_JO",
"ar_JO"
}, {
"und_JP",
"ja_Jpan_JP",
"ja"
}, {
"und_Jpan",
"ja_Jpan_JP",
"ja"
}, {
"und_KG",
"ky_Cyrl_KG",
"ky"
}, {
"und_KH",
"km_Khmr_KH",
"km"
}, {
"und_KM",
"ar_Arab_KM",
"ar_KM"
}, {
"und_KP",
"ko_Kore_KP",
"ko_KP"
}, {
"und_KR",
"ko_Kore_KR",
"ko"
}, {
"und_KW",
"ar_Arab_KW",
"ar_KW"
}, {
"und_KZ",
"ru_Cyrl_KZ",
"ru_KZ"
}, {
"und_Khmr",
"km_Khmr_KH",
"km"
}, {
"und_Knda",
"kn_Knda_IN",
"kn"
}, {
"und_Kore",
"ko_Kore_KR",
"ko"
}, {
"und_LA",
"lo_Laoo_LA",
"lo"
}, {
"und_LB",
"ar_Arab_LB",
"ar_LB"
}, {
"und_LI",
"de_Latn_LI",
"de_LI"
}, {
"und_LK",
"si_Sinh_LK",
"si"
}, {
"und_LS",
"st_Latn_LS",
"st_LS"
}, {
"und_LT",
"lt_Latn_LT",
"lt"
}, {
"und_LU",
"fr_Latn_LU",
"fr_LU"
}, {
"und_LV",
"lv_Latn_LV",
"lv"
}, {
"und_LY",
"ar_Arab_LY",
"ar_LY"
}, {
"und_Laoo",
"lo_Laoo_LA",
"lo"
}, {
"und_Latn_ES",
"es_Latn_ES",
"es"
}, {
"und_Latn_ET",
"en_Latn_ET",
"en_ET"
}, {
"und_Latn_GB",
"en_Latn_GB",
"en_GB"
}, {
"und_Latn_GH",
"ak_Latn_GH",
"ak"
}, {
"und_Latn_ID",
"id_Latn_ID",
"id"
}, {
"und_Latn_IT",
"it_Latn_IT",
"it"
}, {
"und_Latn_NG",
"en_Latn_NG",
"en_NG"
}, {
"und_Latn_TR",
"tr_Latn_TR",
"tr"
}, {
"und_Latn_ZA",
"en_Latn_ZA",
"en_ZA"
}, {
"und_MA",
"ar_Arab_MA",
"ar_MA"
}, {
"und_MC",
"fr_Latn_MC",
"fr_MC"
}, {
"und_MD",
"ro_Latn_MD",
"ro_MD"
}, {
"und_ME",
"sr_Latn_ME",
"sr_ME"
}, {
"und_MG",
"mg_Latn_MG",
"mg"
}, {
"und_MH",
"en_Latn_MH",
"en_MH"
}, {
"und_MK",
"mk_Cyrl_MK",
"mk"
}, {
"und_ML",
"bm_Latn_ML",
"bm"
}, {
"und_MM",
"my_Mymr_MM",
"my"
}, {
"und_MN",
"mn_Cyrl_MN",
"mn"
}, {
"und_MO",
"zh_Hant_MO",
"zh_MO"
}, {
"und_MQ",
"fr_Latn_MQ",
"fr_MQ"
}, {
"und_MR",
"ar_Arab_MR",
"ar_MR"
}, {
"und_MT",
"mt_Latn_MT",
"mt"
}, {
"und_MV",
"dv_Thaa_MV",
"dv"
}, {
"und_MW",
"en_Latn_MW",
"en_MW"
}, {
"und_MX",
"es_Latn_MX",
"es_MX"
}, {
"und_MY",
"ms_Latn_MY",
"ms"
}, {
"und_MZ",
"pt_Latn_MZ",
"pt_MZ"
}, {
"und_Mlym",
"ml_Mlym_IN",
"ml"
}, {
"und_Mymr",
"my_Mymr_MM",
"my"
}, {
"und_NC",
"fr_Latn_NC",
"fr_NC"
}, {
"und_NE",
"ha_Latn_NE",
"ha_NE"
}, {
"und_NG",
"en_Latn_NG",
"en_NG"
}, {
"und_NI",
"es_Latn_NI",
"es_NI"
}, {
"und_NL",
"nl_Latn_NL",
"nl"
}, {
"und_NO",
"nb_Latn_NO",
"nb"
}, {
"und_NP",
"ne_Deva_NP",
"ne"
}, {
"und_NR",
"en_Latn_NR",
"en_NR"
}, {
"und_NU",
"en_Latn_NU",
"en_NU"
}, {
"und_OM",
"ar_Arab_OM",
"ar_OM"
}, {
"und_Orya",
"or_Orya_IN",
"or"
}, {
"und_PA",
"es_Latn_PA",
"es_PA"
}, {
"und_PE",
"es_Latn_PE",
"es_PE"
}, {
"und_PF",
"fr_Latn_PF",
"fr_PF"
}, {
"und_PG",
"tpi_Latn_PG",
"tpi"
}, {
"und_PH",
"fil_Latn_PH",
"fil"
}, {
"und_PL",
"pl_Latn_PL",
"pl"
}, {
"und_PM",
"fr_Latn_PM",
"fr_PM"
}, {
"und_PR",
"es_Latn_PR",
"es_PR"
}, {
"und_PS",
"ar_Arab_PS",
"ar_PS"
}, {
"und_PT",
"pt_Latn_PT",
"pt_PT"
}, {
"und_PW",
"pau_Latn_PW",
"pau"
}, {
"und_PY",
"gn_Latn_PY",
"gn"
}, {
"und_QA",
"ar_Arab_QA",
"ar_QA"
}, {
"und_RE",
"fr_Latn_RE",
"fr_RE"
}, {
"und_RO",
"ro_Latn_RO",
"ro"
}, {
"und_RS",
"sr_Cyrl_RS",
"sr"
}, {
"und_RU",
"ru_Cyrl_RU",
"ru"
}, {
"und_RW",
"rw_Latn_RW",
"rw"
}, {
"und_SA",
"ar_Arab_SA",
"ar_SA"
}, {
"und_SD",
"ar_Arab_SD",
"ar_SD"
}, {
"und_SE",
"sv_Latn_SE",
"sv"
}, {
"und_SG",
"en_Latn_SG",
"en_SG"
}, {
"und_SI",
"sl_Latn_SI",
"sl"
}, {
"und_SJ",
"nb_Latn_SJ",
"nb_SJ"
}, {
"und_SK",
"sk_Latn_SK",
"sk"
}, {
"und_SM",
"it_Latn_SM",
"it_SM"
}, {
"und_SN",
"fr_Latn_SN",
"fr_SN"
}, {
"und_SO",
"so_Latn_SO",
"so"
}, {
"und_SR",
"nl_Latn_SR",
"nl_SR"
}, {
"und_ST",
"pt_Latn_ST",
"pt_ST"
}, {
"und_SV",
"es_Latn_SV",
"es_SV"
}, {
"und_SY",
"ar_Arab_SY",
"ar_SY"
}, {
"und_Sinh",
"si_Sinh_LK",
"si"
}, {
"und_TD",
"fr_Latn_TD",
"fr_TD"
}, {
"und_TG",
"fr_Latn_TG",
"fr_TG"
}, {
"und_TH",
"th_Thai_TH",
"th"
}, {
"und_TJ",
"tg_Cyrl_TJ",
"tg"
}, {
"und_TK",
"tkl_Latn_TK",
"tkl"
}, {
"und_TL",
"pt_Latn_TL",
"pt_TL"
}, {
"und_TM",
"tk_Latn_TM",
"tk"
}, {
"und_TN",
"ar_Arab_TN",
"ar_TN"
}, {
"und_TO",
"to_Latn_TO",
"to"
}, {
"und_TR",
"tr_Latn_TR",
"tr"
}, {
"und_TV",
"tvl_Latn_TV",
"tvl"
}, {
"und_TW",
"zh_Hant_TW",
"zh_TW"
}, {
"und_Taml",
"ta_Taml_IN",
"ta"
}, {
"und_Telu",
"te_Telu_IN",
"te"
}, {
"und_Thaa",
"dv_Thaa_MV",
"dv"
}, {
"und_Thai",
"th_Thai_TH",
"th"
}, {
"und_Tibt",
"bo_Tibt_CN",
"bo"
}, {
"und_UA",
"uk_Cyrl_UA",
"uk"
}, {
"und_UY",
"es_Latn_UY",
"es_UY"
}, {
"und_UZ",
"uz_Latn_UZ",
"uz"
}, {
"und_VA",
"it_Latn_VA",
"it_VA"
}, {
"und_VE",
"es_Latn_VE",
"es_VE"
}, {
"und_VN",
"vi_Latn_VN",
"vi"
}, {
"und_VU",
"bi_Latn_VU",
"bi"
}, {
"und_WF",
"fr_Latn_WF",
"fr_WF"
}, {
"und_WS",
"sm_Latn_WS",
"sm"
}, {
"und_YE",
"ar_Arab_YE",
"ar_YE"
}, {
"und_YT",
"fr_Latn_YT",
"fr_YT"
}, {
"und_Yiii",
"ii_Yiii_CN",
"ii"
}, {
"ur",
"ur_Arab_PK",
"ur"
}, {
"uz",
"uz_Latn_UZ",
"uz"
}, {
"uz_AF",
"uz_Arab_AF",
"uz_AF"
}, {
"uz_Arab",
"uz_Arab_AF",
"uz_AF"
}, {
"ve",
"ve_Latn_ZA",
"ve"
}, {
"vi",
"vi_Latn_VN",
"vi"
}, {
"wal",
"wal_Ethi_ET",
"wal"
}, {
"wo",
"wo_Latn_SN",
"wo"
}, {
"xh",
"xh_Latn_ZA",
"xh"
}, {
"yo",
"yo_Latn_NG",
"yo"
}, {
"zh",
"zh_Hans_CN",
"zh"
}, {
"zh_HK",
"zh_Hant_HK",
"zh_HK"
}, {
"zh_Hani",
"zh_Hani_CN",
"zh_Hani",
}, {
"zh_Hant",
"zh_Hant_TW",
"zh_TW"
}, {
"zh_MO",
"zh_Hant_MO",
"zh_MO"
}, {
"zh_TW",
"zh_Hant_TW",
"zh_TW"
}, {
"zu",
"zu_Latn_ZA",
"zu"
}, {
"und",
"en_Latn_US",
"en"
}, {
"und_ZZ",
"en_Latn_US",
"en"
}, {
"und_CN",
"zh_Hans_CN",
"zh"
}, {
"und_TW",
"zh_Hant_TW",
"zh_TW"
}, {
"und_HK",
"zh_Hant_HK",
"zh_HK"
}, {
"und_AQ",
"und_Latn_AQ",
"und_AQ"
}, {
"und_Zzzz",
"en_Latn_US",
"en"
}, {
"und_Zzzz_ZZ",
"en_Latn_US",
"en"
}, {
"und_Zzzz_CN",
"zh_Hans_CN",
"zh"
}, {
"und_Zzzz_TW",
"zh_Hant_TW",
"zh_TW"
}, {
"und_Zzzz_HK",
"zh_Hant_HK",
"zh_HK"
}, {
"und_Zzzz_AQ",
"und_Latn_AQ",
"und_AQ"
}, {
"und_Latn",
"en_Latn_US",
"en"
}, {
"und_Latn_ZZ",
"en_Latn_US",
"en"
}, {
"und_Latn_CN",
"za_Latn_CN",
"za"
}, {
"und_Latn_TW",
"trv_Latn_TW",
"trv"
}, {
"und_Latn_HK",
"zh_Latn_HK",
"zh_Latn_HK"
}, {
"und_Latn_AQ",
"und_Latn_AQ",
"und_AQ"
}, {
"und_Hans",
"zh_Hans_CN",
"zh"
}, {
"und_Hans_ZZ",
"zh_Hans_CN",
"zh"
}, {
"und_Hans_CN",
"zh_Hans_CN",
"zh"
}, {
"und_Hans_TW",
"zh_Hans_TW",
"zh_Hans_TW"
}, {
"und_Hans_HK",
"zh_Hans_HK",
"zh_Hans_HK"
}, {
"und_Hans_AQ",
"zh_Hans_AQ",
"zh_AQ"
}, {
"und_Hant",
"zh_Hant_TW",
"zh_TW"
}, {
"und_Hant_ZZ",
"zh_Hant_TW",
"zh_TW"
}, {
"und_Hant_CN",
"zh_Hant_CN",
"zh_Hant_CN"
}, {
"und_Hant_TW",
"zh_Hant_TW",
"zh_TW"
}, {
"und_Hant_HK",
"zh_Hant_HK",
"zh_HK"
}, {
"und_Hant_AQ",
"zh_Hant_AQ",
"zh_Hant_AQ"
}, {
"und_Moon",
"en_Moon_US",
"en_Moon"
}, {
"und_Moon_ZZ",
"en_Moon_US",
"en_Moon"
}, {
"und_Moon_CN",
"zh_Moon_CN",
"zh_Moon"
}, {
"und_Moon_TW",
"zh_Moon_TW",
"zh_Moon_TW"
}, {
"und_Moon_HK",
"zh_Moon_HK",
"zh_Moon_HK"
}, {
"und_Moon_AQ",
"und_Moon_AQ",
"und_Moon_AQ"
}, {
"es",
"es_Latn_ES",
"es"
}, {
"es_ZZ",
"es_Latn_ES",
"es"
}, {
"es_CN",
"es_Latn_CN",
"es_CN"
}, {
"es_TW",
"es_Latn_TW",
"es_TW"
}, {
"es_HK",
"es_Latn_HK",
"es_HK"
}, {
"es_AQ",
"es_Latn_AQ",
"es_AQ"
}, {
"es_Zzzz",
"es_Latn_ES",
"es"
}, {
"es_Zzzz_ZZ",
"es_Latn_ES",
"es"
}, {
"es_Zzzz_CN",
"es_Latn_CN",
"es_CN"
}, {
"es_Zzzz_TW",
"es_Latn_TW",
"es_TW"
}, {
"es_Zzzz_HK",
"es_Latn_HK",
"es_HK"
}, {
"es_Zzzz_AQ",
"es_Latn_AQ",
"es_AQ"
}, {
"es_Latn",
"es_Latn_ES",
"es"
}, {
"es_Latn_ZZ",
"es_Latn_ES",
"es"
}, {
"es_Latn_CN",
"es_Latn_CN",
"es_CN"
}, {
"es_Latn_TW",
"es_Latn_TW",
"es_TW"
}, {
"es_Latn_HK",
"es_Latn_HK",
"es_HK"
}, {
"es_Latn_AQ",
"es_Latn_AQ",
"es_AQ"
}, {
"es_Hans",
"es_Hans_ES",
"es_Hans"
}, {
"es_Hans_ZZ",
"es_Hans_ES",
"es_Hans"
}, {
"es_Hans_CN",
"es_Hans_CN",
"es_Hans_CN"
}, {
"es_Hans_TW",
"es_Hans_TW",
"es_Hans_TW"
}, {
"es_Hans_HK",
"es_Hans_HK",
"es_Hans_HK"
}, {
"es_Hans_AQ",
"es_Hans_AQ",
"es_Hans_AQ"
}, {
"es_Hant",
"es_Hant_ES",
"es_Hant"
}, {
"es_Hant_ZZ",
"es_Hant_ES",
"es_Hant"
}, {
"es_Hant_CN",
"es_Hant_CN",
"es_Hant_CN"
}, {
"es_Hant_TW",
"es_Hant_TW",
"es_Hant_TW"
}, {
"es_Hant_HK",
"es_Hant_HK",
"es_Hant_HK"
}, {
"es_Hant_AQ",
"es_Hant_AQ",
"es_Hant_AQ"
}, {
"es_Moon",
"es_Moon_ES",
"es_Moon"
}, {
"es_Moon_ZZ",
"es_Moon_ES",
"es_Moon"
}, {
"es_Moon_CN",
"es_Moon_CN",
"es_Moon_CN"
}, {
"es_Moon_TW",
"es_Moon_TW",
"es_Moon_TW"
}, {
"es_Moon_HK",
"es_Moon_HK",
"es_Moon_HK"
}, {
"es_Moon_AQ",
"es_Moon_AQ",
"es_Moon_AQ"
}, {
"zh",
"zh_Hans_CN",
"zh"
}, {
"zh_ZZ",
"zh_Hans_CN",
"zh"
}, {
"zh_CN",
"zh_Hans_CN",
"zh"
}, {
"zh_TW",
"zh_Hant_TW",
"zh_TW"
}, {
"zh_HK",
"zh_Hant_HK",
"zh_HK"
}, {
"zh_AQ",
"zh_Hans_AQ",
"zh_AQ"
}, {
"zh_MY",
"zh_Hans_MY",
"zh_MY"
}, {
"zh_Zzzz",
"zh_Hans_CN",
"zh"
}, {
"zh_Zzzz_ZZ",
"zh_Hans_CN",
"zh"
}, {
"zh_Zzzz_CN",
"zh_Hans_CN",
"zh"
}, {
"zh_Zzzz_TW",
"zh_Hant_TW",
"zh_TW"
}, {
"zh_Zzzz_HK",
"zh_Hant_HK",
"zh_HK"
}, {
"zh_Zzzz_AQ",
"zh_Hans_AQ",
"zh_AQ"
}, {
"zh_Latn",
"zh_Latn_CN",
"zh_Latn"
}, {
"zh_Latn_ZZ",
"zh_Latn_CN",
"zh_Latn"
}, {
"zh_Latn_CN",
"zh_Latn_CN",
"zh_Latn"
}, {
"zh_Latn_TW",
"zh_Latn_TW",
"zh_Latn_TW"
}, {
"zh_Latn_HK",
"zh_Latn_HK",
"zh_Latn_HK"
}, {
"zh_Latn_AQ",
"zh_Latn_AQ",
"zh_Latn_AQ"
}, {
"zh_Hans",
"zh_Hans_CN",
"zh"
}, {
"zh_Hans_ZZ",
"zh_Hans_CN",
"zh"
}, {
"zh_Hans_TW",
"zh_Hans_TW",
"zh_Hans_TW"
}, {
"zh_Hans_HK",
"zh_Hans_HK",
"zh_Hans_HK"
}, {
"zh_Hans_AQ",
"zh_Hans_AQ",
"zh_AQ"
}, {
"zh_Hant",
"zh_Hant_TW",
"zh_TW"
}, {
"zh_Hant_ZZ",
"zh_Hant_TW",
"zh_TW"
}, {
"zh_Hant_CN",
"zh_Hant_CN",
"zh_Hant_CN"
}, {
"zh_Hant_AQ",
"zh_Hant_AQ",
"zh_Hant_AQ"
}, {
"zh_Moon",
"zh_Moon_CN",
"zh_Moon"
}, {
"zh_Moon_ZZ",
"zh_Moon_CN",
"zh_Moon"
}, {
"zh_Moon_CN",
"zh_Moon_CN",
"zh_Moon"
}, {
"zh_Moon_TW",
"zh_Moon_TW",
"zh_Moon_TW"
}, {
"zh_Moon_HK",
"zh_Moon_HK",
"zh_Moon_HK"
}, {
"zh_Moon_AQ",
"zh_Moon_AQ",
"zh_Moon_AQ"
}, {
"art",
"",
""
}, {
"art_ZZ",
"",
""
}, {
"art_CN",
"",
""
}, {
"art_TW",
"",
""
}, {
"art_HK",
"",
""
}, {
"art_AQ",
"",
""
}, {
"art_Zzzz",
"",
""
}, {
"art_Zzzz_ZZ",
"",
""
}, {
"art_Zzzz_CN",
"",
""
}, {
"art_Zzzz_TW",
"",
""
}, {
"art_Zzzz_HK",
"",
""
}, {
"art_Zzzz_AQ",
"",
""
}, {
"art_Latn",
"",
""
}, {
"art_Latn_ZZ",
"",
""
}, {
"art_Latn_CN",
"",
""
}, {
"art_Latn_TW",
"",
""
}, {
"art_Latn_HK",
"",
""
}, {
"art_Latn_AQ",
"",
""
}, {
"art_Hans",
"",
""
}, {
"art_Hans_ZZ",
"",
""
}, {
"art_Hans_CN",
"",
""
}, {
"art_Hans_TW",
"",
""
}, {
"art_Hans_HK",
"",
""
}, {
"art_Hans_AQ",
"",
""
}, {
"art_Hant",
"",
""
}, {
"art_Hant_ZZ",
"",
""
}, {
"art_Hant_CN",
"",
""
}, {
"art_Hant_TW",
"",
""
}, {
"art_Hant_HK",
"",
""
}, {
"art_Hant_AQ",
"",
""
}, {
"art_Moon",
"",
""
}, {
"art_Moon_ZZ",
"",
""
}, {
"art_Moon_CN",
"",
""
}, {
"art_Moon_TW",
"",
""
}, {
"art_Moon_HK",
"",
""
}, {
"art_Moon_AQ",
"",
""
}, {
"de@collation=phonebook",
"de_Latn_DE@collation=phonebook",
"de@collation=phonebook"
}
};
typedef struct errorDataTag {
const char* tag;
const char* expected;
UErrorCode uerror;
int32_t bufferSize;
} errorData;
const errorData maximizeErrors[] = {
{
"enfueiujhytdf",
NULL,
U_ILLEGAL_ARGUMENT_ERROR,
-1
},
{
"en_THUJIOGIURJHGJFURYHFJGURYYYHHGJURHG",
NULL,
U_ILLEGAL_ARGUMENT_ERROR,
-1
},
{
"en_THUJIOGIURJHGJFURYHFJGURYYYHHGJURHG",
NULL,
U_ILLEGAL_ARGUMENT_ERROR,
-1
},
{
"en_Latn_US_POSIX@currency=EURO",
"en_Latn_US_POSIX@currency=EURO",
U_BUFFER_OVERFLOW_ERROR,
29
},
{
"en_Latn_US_POSIX@currency=EURO",
"en_Latn_US_POSIX@currency=EURO",
U_STRING_NOT_TERMINATED_WARNING,
30
}
};
const errorData minimizeErrors[] = {
{
"enfueiujhytdf",
NULL,
U_ILLEGAL_ARGUMENT_ERROR,
-1
},
{
"en_THUJIOGIURJHGJFURYHFJGURYYYHHGJURHG",
NULL,
U_ILLEGAL_ARGUMENT_ERROR,
-1
},
{
"en_Latn_US_POSIX@currency=EURO",
"en__POSIX@currency=EURO",
U_BUFFER_OVERFLOW_ERROR,
22
},
{
"en_Latn_US_POSIX@currency=EURO",
"en__POSIX@currency=EURO",
U_STRING_NOT_TERMINATED_WARNING,
23
}
};
static int32_t getExpectedReturnValue(const errorData* data)
{
if (data->uerror == U_BUFFER_OVERFLOW_ERROR ||
data->uerror == U_STRING_NOT_TERMINATED_WARNING)
{
return strlen(data->expected);
}
else
{
return -1;
}
}
static int32_t getBufferSize(const errorData* data, int32_t actualSize)
{
if (data->expected == NULL)
{
return actualSize;
}
else if (data->bufferSize < 0)
{
return strlen(data->expected) + 1;
}
else
{
return data->bufferSize;
}
}
static void TestLikelySubtags()
{
char buffer[ULOC_FULLNAME_CAPACITY + ULOC_KEYWORD_AND_VALUES_CAPACITY + 1];
int32_t i = 0;
for (; i < UPRV_LENGTHOF(basic_maximize_data); ++i)
{
UErrorCode status = U_ZERO_ERROR;
const char* const minimal = basic_maximize_data[i][0];
const char* const maximal = basic_maximize_data[i][1];
uloc_addLikelySubtags(
minimal,
buffer,
sizeof(buffer),
&status);
if (U_FAILURE(status)) {
log_err_status(status, " unexpected failure of uloc_addLikelySubtags(), minimal \"%s\" status %s\n", minimal, u_errorName(status));
status = U_ZERO_ERROR;
}
else if (uprv_strlen(maximal) == 0) {
if (uprv_stricmp(minimal, buffer) != 0) {
log_err(" unexpected maximal value \"%s\" in uloc_addLikelySubtags(), minimal \"%s\" = \"%s\"\n", maximal, minimal, buffer);
}
}
else if (uprv_stricmp(maximal, buffer) != 0) {
log_err(" maximal doesn't match expected %s in uloc_addLikelySubtags(), minimal \"%s\" = %s\n", maximal, minimal, buffer);
}
}
for (i = 0; i < UPRV_LENGTHOF(basic_minimize_data); ++i) {
UErrorCode status = U_ZERO_ERROR;
const char* const maximal = basic_minimize_data[i][0];
const char* const minimal = basic_minimize_data[i][1];
uloc_minimizeSubtags(
maximal,
buffer,
sizeof(buffer),
&status);
if (U_FAILURE(status)) {
log_err_status(status, " unexpected failure of uloc_MinimizeSubtags(), maximal \"%s\" status %s\n", maximal, u_errorName(status));
status = U_ZERO_ERROR;
}
else if (uprv_strlen(minimal) == 0) {
if (uprv_stricmp(maximal, buffer) != 0) {
log_err(" unexpected minimal value \"%s\" in uloc_minimizeSubtags(), maximal \"%s\" = \"%s\"\n", minimal, maximal, buffer);
}
}
else if (uprv_stricmp(minimal, buffer) != 0) {
log_err(" minimal doesn't match expected %s in uloc_MinimizeSubtags(), maximal \"%s\" = %s\n", minimal, maximal, buffer);
}
}
for (i = 0; i < UPRV_LENGTHOF(full_data); ++i) {
UErrorCode status = U_ZERO_ERROR;
const char* const minimal = full_data[i][0];
const char* const maximal = full_data[i][1];
uloc_addLikelySubtags(
minimal,
buffer,
sizeof(buffer),
&status);
if (U_FAILURE(status)) {
log_err_status(status, " unexpected failure of uloc_addLikelySubtags(), minimal \"%s\" status \"%s\"\n", minimal, u_errorName(status));
status = U_ZERO_ERROR;
}
else if (uprv_strlen(maximal) == 0) {
if (uprv_stricmp(minimal, buffer) != 0) {
log_err(" unexpected maximal value \"%s\" in uloc_addLikelySubtags(), minimal \"%s\" = \"%s\"\n", maximal, minimal, buffer);
}
}
else if (uprv_stricmp(maximal, buffer) != 0) {
log_err(" maximal doesn't match expected \"%s\" in uloc_addLikelySubtags(), minimal \"%s\" = \"%s\"\n", maximal, minimal, buffer);
}
}
for (i = 0; i < UPRV_LENGTHOF(full_data); ++i) {
UErrorCode status = U_ZERO_ERROR;
const char* const maximal = full_data[i][1];
const char* const minimal = full_data[i][2];
if (strlen(maximal) > 0) {
uloc_minimizeSubtags(
maximal,
buffer,
sizeof(buffer),
&status);
if (U_FAILURE(status)) {
log_err_status(status, " unexpected failure of uloc_minimizeSubtags(), maximal \"%s\" status %s\n", maximal, u_errorName(status));
status = U_ZERO_ERROR;
}
else if (uprv_strlen(minimal) == 0) {
if (uprv_stricmp(maximal, buffer) != 0) {
log_err(" unexpected minimal value \"%s\" in uloc_minimizeSubtags(), maximal \"%s\" = \"%s\"\n", minimal, maximal, buffer);
}
}
else if (uprv_stricmp(minimal, buffer) != 0) {
log_err(" minimal doesn't match expected %s in uloc_MinimizeSubtags(), maximal \"%s\" = %s\n", minimal, maximal, buffer);
}
}
}
for (i = 0; i < UPRV_LENGTHOF(maximizeErrors); ++i) {
UErrorCode status = U_ZERO_ERROR;
const char* const minimal = maximizeErrors[i].tag;
const char* const maximal = maximizeErrors[i].expected;
const UErrorCode expectedStatus = maximizeErrors[i].uerror;
const int32_t expectedLength = getExpectedReturnValue(&maximizeErrors[i]);
const int32_t bufferSize = getBufferSize(&maximizeErrors[i], sizeof(buffer));
const int32_t length =
uloc_addLikelySubtags(
minimal,
buffer,
bufferSize,
&status);
if (status == U_ZERO_ERROR) {
log_err(" unexpected U_ZERO_ERROR for uloc_addLikelySubtags(), minimal \"%s\" expected status %s\n", minimal, u_errorName(expectedStatus));
status = U_ZERO_ERROR;
}
else if (status != expectedStatus) {
log_err_status(status, " unexpected status for uloc_addLikelySubtags(), minimal \"%s\" expected status %s, but got %s\n", minimal, u_errorName(expectedStatus), u_errorName(status));
}
else if (length != expectedLength) {
log_err(" unexpected length for uloc_addLikelySubtags(), minimal \"%s\" expected length %d, but got %d\n", minimal, expectedLength, length);
}
else if (status == U_BUFFER_OVERFLOW_ERROR || status == U_STRING_NOT_TERMINATED_WARNING) {
if (uprv_strnicmp(maximal, buffer, bufferSize) != 0) {
log_err(" maximal doesn't match expected %s in uloc_addLikelySubtags(), minimal \"%s\" = %*s\n",
maximal, minimal, (int)sizeof(buffer), buffer);
}
}
}
for (i = 0; i < UPRV_LENGTHOF(minimizeErrors); ++i) {
UErrorCode status = U_ZERO_ERROR;
const char* const maximal = minimizeErrors[i].tag;
const char* const minimal = minimizeErrors[i].expected;
const UErrorCode expectedStatus = minimizeErrors[i].uerror;
const int32_t expectedLength = getExpectedReturnValue(&minimizeErrors[i]);
const int32_t bufferSize = getBufferSize(&minimizeErrors[i], sizeof(buffer));
const int32_t length =
uloc_minimizeSubtags(
maximal,
buffer,
bufferSize,
&status);
if (status == U_ZERO_ERROR) {
log_err(" unexpected U_ZERO_ERROR for uloc_minimizeSubtags(), maximal \"%s\" expected status %s\n", maximal, u_errorName(expectedStatus));
status = U_ZERO_ERROR;
}
else if (status != expectedStatus) {
log_err_status(status, " unexpected status for uloc_minimizeSubtags(), maximal \"%s\" expected status %s, but got %s\n", maximal, u_errorName(expectedStatus), u_errorName(status));
}
else if (length != expectedLength) {
log_err(" unexpected length for uloc_minimizeSubtags(), maximal \"%s\" expected length %d, but got %d\n", maximal, expectedLength, length);
}
else if (status == U_BUFFER_OVERFLOW_ERROR || status == U_STRING_NOT_TERMINATED_WARNING) {
if (uprv_strnicmp(minimal, buffer, bufferSize) != 0) {
log_err(" minimal doesn't match expected \"%s\" in uloc_minimizeSubtags(), minimal \"%s\" = \"%*s\"\n",
minimal, maximal, (int)sizeof(buffer), buffer);
}
}
}
}
const char* const locale_to_langtag[][3] = {
{"", "und", "und"},
{"en", "en", "en"},
{"en_US", "en-US", "en-US"},
{"iw_IL", "he-IL", "he-IL"},
{"sr_Latn_SR", "sr-Latn-SR", "sr-Latn-SR"},
{"en__POSIX", "en-u-va-posix", "en-u-va-posix"},
{"en_POSIX", "en-u-va-posix", "en-u-va-posix"},
{"en_US_POSIX_VAR", "en-US-posix-x-lvariant-var", NULL},
{"en_US_VAR_POSIX", "en-US-x-lvariant-var-posix", NULL},
{"en_US_POSIX@va=posix2", "en-US-u-va-posix2", "en-US-u-va-posix2"},
{"en_US_POSIX@ca=japanese", "en-US-u-ca-japanese-va-posix", "en-US-u-ca-japanese-va-posix"},
{"und_555", "und-555", "und-555"},
{"123", "und", NULL},
{"%$#&", "und", NULL},
{"_Latn", "und-Latn", "und-Latn"},
{"_DE", "und-DE", "und-DE"},
{"und_FR", "und-FR", "und-FR"},
{"th_TH_TH", "th-TH-x-lvariant-th", NULL},
{"bogus", "bogus", "bogus"},
{"foooobarrr", "und", NULL},
{"az_AZ_CYRL", "az-Cyrl-AZ", "az-Cyrl-AZ"},
{"aa_BB_CYRL", "aa-BB-x-lvariant-cyrl", NULL},
{"en_US_1234", "en-US-1234", "en-US-1234"},
{"en_US_VARIANTA_VARIANTB", "en-US-varianta-variantb", "en-US-varianta-variantb"},
{"ja__9876_5432", "ja-9876-5432", "ja-9876-5432"},
{"zh_Hant__VAR", "zh-Hant-x-lvariant-var", NULL},
{"es__BADVARIANT_GOODVAR", "es-goodvar", NULL},
{"en@calendar=gregorian", "en-u-ca-gregory", "en-u-ca-gregory"},
{"de@collation=phonebook;calendar=gregorian", "de-u-ca-gregory-co-phonebk", "de-u-ca-gregory-co-phonebk"},
{"th@numbers=thai;z=extz;x=priv-use;a=exta", "th-a-exta-u-nu-thai-z-extz-x-priv-use", "th-a-exta-u-nu-thai-z-extz-x-priv-use"},
{"en@timezone=America/New_York;calendar=japanese", "en-u-ca-japanese-tz-usnyc", "en-u-ca-japanese-tz-usnyc"},
{"en@timezone=US/Eastern", "en-u-tz-usnyc", "en-u-tz-usnyc"},
{"en@x=x-y-z;a=a-b-c", "en-x-x-y-z", NULL},
{"it@collation=badcollationtype;colStrength=identical;cu=usd-eur", "it-u-cu-usd-eur-ks-identic", NULL},
{"en_US_POSIX", "en-US-u-va-posix", "en-US-u-va-posix"},
{"en_US_POSIX@calendar=japanese;currency=EUR","en-US-u-ca-japanese-cu-eur-va-posix", "en-US-u-ca-japanese-cu-eur-va-posix"},
{"@x=elmer", "x-elmer", "x-elmer"},
{"en@x=elmer", "en-x-elmer", "en-x-elmer"},
{"@x=elmer;a=exta", "und-a-exta-x-elmer", "und-a-exta-x-elmer"},
{"en_US@attribute=attr1-attr2;calendar=gregorian", "en-US-u-attr1-attr2-ca-gregory", "en-US-u-attr1-attr2-ca-gregory"},
{"en@a=bar;attribute=baz", "en-a-bar-u-baz", "en-a-bar-u-baz"},
{"en@a=bar;attribute=baz;x=u-foo", "en-a-bar-u-baz-x-u-foo", "en-a-bar-u-baz-x-u-foo"},
{"en@attribute=baz", "en-u-baz", "en-u-baz"},
{"en@attribute=baz;calendar=islamic-civil", "en-u-baz-ca-islamic-civil", "en-u-baz-ca-islamic-civil"},
{"en@a=bar;calendar=islamic-civil;x=u-foo", "en-a-bar-u-ca-islamic-civil-x-u-foo", "en-a-bar-u-ca-islamic-civil-x-u-foo"},
{"en@a=bar;attribute=baz;calendar=islamic-civil;x=u-foo", "en-a-bar-u-baz-ca-islamic-civil-x-u-foo", "en-a-bar-u-baz-ca-islamic-civil-x-u-foo"},
{NULL, NULL, NULL}
};
static void TestToLanguageTag(void) {
char langtag[256];
int32_t i;
UErrorCode status;
int32_t len;
const char *inloc;
const char *expected;
for (i = 0; locale_to_langtag[i][0] != NULL; i++) {
inloc = locale_to_langtag[i][0];
status = U_ZERO_ERROR;
langtag[0] = 0;
expected = locale_to_langtag[i][1];
len = uloc_toLanguageTag(inloc, langtag, sizeof(langtag), FALSE, &status);
(void)len;
if (U_FAILURE(status)) {
if (expected != NULL) {
log_err("Error returned by uloc_toLanguageTag for locale id [%s] - error: %s\n",
inloc, u_errorName(status));
}
} else {
if (expected == NULL) {
log_err("Error should be returned by uloc_toLanguageTag for locale id [%s], but [%s] is returned without errors\n",
inloc, langtag);
} else if (uprv_strcmp(langtag, expected) != 0) {
log_data_err("uloc_toLanguageTag returned language tag [%s] for input locale [%s] - expected: [%s]. Are you missing data?\n",
langtag, inloc, expected);
}
}
status = U_ZERO_ERROR;
langtag[0] = 0;
expected = locale_to_langtag[i][2];
len = uloc_toLanguageTag(inloc, langtag, sizeof(langtag), TRUE, &status);
if (U_FAILURE(status)) {
if (expected != NULL) {
log_data_err("Error returned by uloc_toLanguageTag {strict} for locale id [%s] - error: %s Are you missing data?\n",
inloc, u_errorName(status));
}
} else {
if (expected == NULL) {
log_err("Error should be returned by uloc_toLanguageTag {strict} for locale id [%s], but [%s] is returned without errors\n",
inloc, langtag);
} else if (uprv_strcmp(langtag, expected) != 0) {
log_err("uloc_toLanguageTag {strict} returned language tag [%s] for input locale [%s] - expected: [%s]\n",
langtag, inloc, expected);
}
}
}
}
#define FULL_LENGTH -1
static const struct {
const char *bcpID;
const char *locID;
int32_t len;
} langtag_to_locale[] = {
{"en", "en", FULL_LENGTH},
{"en-us", "en_US", FULL_LENGTH},
{"und-US", "_US", FULL_LENGTH},
{"und-latn", "_Latn", FULL_LENGTH},
{"en-US-posix", "en_US_POSIX", FULL_LENGTH},
{"de-de_euro", "de", 2},
{"kok-IN", "kok_IN", FULL_LENGTH},
{"123", "", 0},
{"en_us", "", 0},
{"en-latn-x", "en_Latn", 7},
{"art-lojban", "jbo", FULL_LENGTH},
{"zh-hakka", "hak", FULL_LENGTH},
{"zh-cmn-CH", "cmn_CH", FULL_LENGTH},
{"xxx-yy", "xxx_YY", FULL_LENGTH},
{"fr-234", "fr_234", FULL_LENGTH},
{"i-default", "en@x=i-default", FULL_LENGTH},
{"i-test", "", 0},
{"ja-jp-jp", "ja_JP", 5},
{"bogus", "bogus", FULL_LENGTH},
{"boguslang", "", 0},
{"EN-lATN-us", "en_Latn_US", FULL_LENGTH},
{"und-variant-1234", "__VARIANT_1234", FULL_LENGTH},
{"und-varzero-var1-vartwo", "__VARZERO", 11},
{"en-u-ca-gregory", "en@calendar=gregorian", FULL_LENGTH},
{"en-U-cu-USD", "en@currency=usd", FULL_LENGTH},
{"en-US-u-va-posix", "en_US_POSIX", FULL_LENGTH},
{"en-us-u-ca-gregory-va-posix", "en_US_POSIX@calendar=gregorian", FULL_LENGTH},
{"en-us-posix-u-va-posix", "en_US_POSIX@va=posix", FULL_LENGTH},
{"en-us-u-va-posix2", "en_US@va=posix2", FULL_LENGTH},
{"en-us-vari1-u-va-posix", "en_US_VARI1@va=posix", FULL_LENGTH},
{"ar-x-1-2-3", "ar@x=1-2-3", FULL_LENGTH},
{"fr-u-nu-latn-cu-eur", "fr@currency=eur;numbers=latn", FULL_LENGTH},
{"de-k-kext-u-co-phonebk-nu-latn", "de@collation=phonebook;k=kext;numbers=latn", FULL_LENGTH},
{"ja-u-cu-jpy-ca-jp", "ja@calendar=yes;currency=jpy;jp=yes", FULL_LENGTH},
{"en-us-u-tz-usnyc", "en_US@timezone=America/New_York", FULL_LENGTH},
{"und-a-abc-def", "und@a=abc-def", FULL_LENGTH},
{"zh-u-ca-chinese-x-u-ca-chinese", "zh@calendar=chinese;x=u-ca-chinese", FULL_LENGTH},
{"x-elmer", "@x=elmer", FULL_LENGTH},
{"en-US-u-attr1-attr2-ca-gregory", "en_US@attribute=attr1-attr2;calendar=gregorian", FULL_LENGTH},
{"sr-u-kn", "sr@colnumeric=yes", FULL_LENGTH},
{"de-u-kn-co-phonebk", "de@collation=phonebook;colnumeric=yes", FULL_LENGTH},
{"en-u-attr2-attr1-kn-kb", "en@attribute=attr1-attr2;colbackwards=yes;colnumeric=yes", FULL_LENGTH},
{"ja-u-ijkl-efgh-abcd-ca-japanese-xx-yyy-zzz-kn", "ja@attribute=abcd-efgh-ijkl;calendar=japanese;colnumeric=yes;xx=yyy-zzz", FULL_LENGTH},
{"de-u-xc-xphonebk-co-phonebk-ca-buddhist-mo-very-lo-extensi-xd-that-de-should-vc-probably-xz-killthebuffer",
"de@calendar=buddhist;collation=phonebook;de=should;lo=extensi;mo=very;vc=probably;xc=xphonebk;xd=that;xz=yes", 91},
{"en-a-bar-u-baz", "en@a=bar;attribute=baz", FULL_LENGTH},
{"en-a-bar-u-baz-x-u-foo", "en@a=bar;attribute=baz;x=u-foo", FULL_LENGTH},
{"en-u-baz", "en@attribute=baz", FULL_LENGTH},
{"en-u-baz-ca-islamic-civil", "en@attribute=baz;calendar=islamic-civil", FULL_LENGTH},
{"en-a-bar-u-ca-islamic-civil-x-u-foo", "en@a=bar;calendar=islamic-civil;x=u-foo", FULL_LENGTH},
{"en-a-bar-u-baz-ca-islamic-civil-x-u-foo", "en@a=bar;attribute=baz;calendar=islamic-civil;x=u-foo", FULL_LENGTH},
{"und-Arab-u-em-emoji", "_Arab@em=emoji", FULL_LENGTH},
{"und-Latn-u-em-emoji", "_Latn@em=emoji", FULL_LENGTH},
{"und-Latn-DE-u-em-emoji", "_Latn_DE@em=emoji", FULL_LENGTH},
{"und-Zzzz-DE-u-em-emoji", "_Zzzz_DE@em=emoji", FULL_LENGTH},
{"und-DE-u-em-emoji", "_DE@em=emoji", FULL_LENGTH},
{NULL, NULL, 0}
};
static void TestForLanguageTag(void) {
char locale[256];
int32_t i;
UErrorCode status;
int32_t parsedLen;
int32_t expParsedLen;
for (i = 0; langtag_to_locale[i].bcpID != NULL; i++) {
status = U_ZERO_ERROR;
locale[0] = 0;
expParsedLen = langtag_to_locale[i].len;
if (expParsedLen == FULL_LENGTH) {
expParsedLen = uprv_strlen(langtag_to_locale[i].bcpID);
}
uloc_forLanguageTag(langtag_to_locale[i].bcpID, locale, sizeof(locale), &parsedLen, &status);
if (U_FAILURE(status)) {
log_err_status(status, "Error returned by uloc_forLanguageTag for language tag [%s] - error: %s\n",
langtag_to_locale[i].bcpID, u_errorName(status));
} else {
if (uprv_strcmp(langtag_to_locale[i].locID, locale) != 0) {
log_data_err("uloc_forLanguageTag returned locale [%s] for input language tag [%s] - expected: [%s]\n",
locale, langtag_to_locale[i].bcpID, langtag_to_locale[i].locID);
}
if (parsedLen != expParsedLen) {
log_err("uloc_forLanguageTag parsed length of %d for input language tag [%s] - expected parsed length: %d\n",
parsedLen, langtag_to_locale[i].bcpID, expParsedLen);
}
}
}
}
static void TestToUnicodeLocaleKey(void)
{
static const char* DATA[][2] = {
{"calendar", "ca"},
{"CALEndar", "ca"},
{"ca", "ca"},
{"kv", "kv"},
{"foo", NULL},
{"ZZ", "$IN"},
{NULL, NULL}
};
int32_t i;
for (i = 0; DATA[i][0] != NULL; i++) {
const char* keyword = DATA[i][0];
const char* expected = DATA[i][1];
const char* bcpKey = NULL;
bcpKey = uloc_toUnicodeLocaleKey(keyword);
if (expected == NULL) {
if (bcpKey != NULL) {
log_err("toUnicodeLocaleKey: keyword=%s => %s, expected=NULL\n", keyword, bcpKey);
}
} else if (bcpKey == NULL) {
log_data_err("toUnicodeLocaleKey: keyword=%s => NULL, expected=%s\n", keyword, expected);
} else if (uprv_strcmp(expected, "$IN") == 0) {
if (bcpKey != keyword) {
log_err("toUnicodeLocaleKey: keyword=%s => %s, expected=%s(input pointer)\n", keyword, bcpKey, keyword);
}
} else if (uprv_strcmp(bcpKey, expected) != 0) {
log_err("toUnicodeLocaleKey: keyword=%s => %s, expected=%s\n", keyword, bcpKey, expected);
}
}
}
static void TestToLegacyKey(void)
{
static const char* DATA[][2] = {
{"kb", "colbackwards"},
{"kB", "colbackwards"},
{"Collation", "collation"},
{"kv", "kv"},
{"foo", "$IN"},
{"ZZ", "$IN"},
{"e=mc2", NULL},
{NULL, NULL}
};
int32_t i;
for (i = 0; DATA[i][0] != NULL; i++) {
const char* keyword = DATA[i][0];
const char* expected = DATA[i][1];
const char* legacyKey = NULL;
legacyKey = uloc_toLegacyKey(keyword);
if (expected == NULL) {
if (legacyKey != NULL) {
log_err("toLegacyKey: keyword=%s => %s, expected=NULL\n", keyword, legacyKey);
}
} else if (legacyKey == NULL) {
log_err("toLegacyKey: keyword=%s => NULL, expected=%s\n", keyword, expected);
} else if (uprv_strcmp(expected, "$IN") == 0) {
if (legacyKey != keyword) {
log_err("toLegacyKey: keyword=%s => %s, expected=%s(input pointer)\n", keyword, legacyKey, keyword);
}
} else if (uprv_strcmp(legacyKey, expected) != 0) {
log_data_err("toUnicodeLocaleKey: keyword=%s, %s, expected=%s\n", keyword, legacyKey, expected);
}
}
}
static void TestToUnicodeLocaleType(void)
{
static const char* DATA[][3] = {
{"tz", "Asia/Kolkata", "inccu"},
{"calendar", "gregorian", "gregory"},
{"ca", "gregorian", "gregory"},
{"ca", "Gregorian", "gregory"},
{"ca", "buddhist", "buddhist"},
{"Calendar", "Japanese", "japanese"},
{"calendar", "Islamic-Civil", "islamic-civil"},
{"calendar", "islamicc", "islamic-civil"},
{"colalternate", "NON-IGNORABLE", "noignore"},
{"colcaselevel", "yes", "true"},
{"rg", "GBzzzz", "$IN"},
{"tz", "america/new_york", "usnyc"},
{"tz", "Asia/Kolkata", "inccu"},
{"timezone", "navajo", "usden"},
{"ca", "aaaa", "$IN"},
{"ca", "gregory-japanese-islamic", "$IN"},
{"zz", "gregorian", NULL},
{"co", "foo-", NULL},
{"variableTop", "00A0", "$IN"},
{"variableTop", "wxyz", "$IN"},
{"kr", "space-punct", "space-punct"},
{"kr", "digit-spacepunct", NULL},
{NULL, NULL, NULL}
};
int32_t i;
for (i = 0; DATA[i][0] != NULL; i++) {
const char* keyword = DATA[i][0];
const char* value = DATA[i][1];
const char* expected = DATA[i][2];
const char* bcpType = NULL;
bcpType = uloc_toUnicodeLocaleType(keyword, value);
if (expected == NULL) {
if (bcpType != NULL) {
log_err("toUnicodeLocaleType: keyword=%s, value=%s => %s, expected=NULL\n", keyword, value, bcpType);
}
} else if (bcpType == NULL) {
log_data_err("toUnicodeLocaleType: keyword=%s, value=%s => NULL, expected=%s\n", keyword, value, expected);
} else if (uprv_strcmp(expected, "$IN") == 0) {
if (bcpType != value) {
log_err("toUnicodeLocaleType: keyword=%s, value=%s => %s, expected=%s(input pointer)\n", keyword, value, bcpType, value);
}
} else if (uprv_strcmp(bcpType, expected) != 0) {
log_data_err("toUnicodeLocaleType: keyword=%s, value=%s => %s, expected=%s\n", keyword, value, bcpType, expected);
}
}
}
static void TestToLegacyType(void)
{
static const char* DATA[][3] = {
{"calendar", "gregory", "gregorian"},
{"ca", "gregory", "gregorian"},
{"ca", "Gregory", "gregorian"},
{"ca", "buddhist", "buddhist"},
{"Calendar", "Japanese", "japanese"},
{"calendar", "Islamic-Civil", "islamic-civil"},
{"calendar", "islamicc", "islamic-civil"},
{"colalternate", "noignore", "non-ignorable"},
{"colcaselevel", "true", "yes"},
{"rg", "gbzzzz", "gbzzzz"},
{"tz", "usnyc", "America/New_York"},
{"tz", "inccu", "Asia/Calcutta"},
{"timezone", "usden", "America/Denver"},
{"timezone", "usnavajo", "America/Denver"},
{"colstrength", "quarternary", "quaternary"},
{"ca", "aaaa", "$IN"},
{"calendar", "gregory-japanese-islamic", "$IN"},
{"zz", "gregorian", "$IN"},
{"ca", "gregorian-calendar", "$IN"},
{"co", "e=mc2", NULL},
{"variableTop", "00A0", "$IN"},
{"variableTop", "wxyz", "$IN"},
{"kr", "space-punct", "space-punct"},
{"kr", "digit-spacepunct", "digit-spacepunct"},
{NULL, NULL, NULL}
};
int32_t i;
for (i = 0; DATA[i][0] != NULL; i++) {
const char* keyword = DATA[i][0];
const char* value = DATA[i][1];
const char* expected = DATA[i][2];
const char* legacyType = NULL;
legacyType = uloc_toLegacyType(keyword, value);
if (expected == NULL) {
if (legacyType != NULL) {
log_err("toLegacyType: keyword=%s, value=%s => %s, expected=NULL\n", keyword, value, legacyType);
}
} else if (legacyType == NULL) {
log_err("toLegacyType: keyword=%s, value=%s => NULL, expected=%s\n", keyword, value, expected);
} else if (uprv_strcmp(expected, "$IN") == 0) {
if (legacyType != value) {
log_err("toLegacyType: keyword=%s, value=%s => %s, expected=%s(input pointer)\n", keyword, value, legacyType, value);
}
} else if (uprv_strcmp(legacyType, expected) != 0) {
log_data_err("toLegacyType: keyword=%s, value=%s => %s, expected=%s\n", keyword, value, legacyType, expected);
} else {
log_verbose("toLegacyType: keyword=%s, value=%s => %s\n", keyword, value, legacyType);
}
}
}
static void test_unicode_define(const char *namech, char ch, const char *nameu, UChar uch)
{
UChar asUch[1];
asUch[0]=0;
log_verbose("Testing whether %s[\\x%02x,'%c'] == %s[U+%04X]\n", namech, ch,(int)ch, nameu, (int) uch);
u_charsToUChars(&ch, asUch, 1);
if(asUch[0] != uch) {
log_err("FAIL: %s[\\x%02x,'%c'] maps to U+%04X, but %s = U+%04X\n", namech, ch, (int)ch, (int)asUch[0], nameu, (int)uch);
} else {
log_verbose(" .. OK, == U+%04X\n", (int)asUch[0]);
}
}
#define TEST_UNICODE_DEFINE(x,y) test_unicode_define(#x, (char)(x), #y, (UChar)(y))
static void TestUnicodeDefines(void) {
TEST_UNICODE_DEFINE(ULOC_KEYWORD_SEPARATOR, ULOC_KEYWORD_SEPARATOR_UNICODE);
TEST_UNICODE_DEFINE(ULOC_KEYWORD_ASSIGN, ULOC_KEYWORD_ASSIGN_UNICODE);
TEST_UNICODE_DEFINE(ULOC_KEYWORD_ITEM_SEPARATOR, ULOC_KEYWORD_ITEM_SEPARATOR_UNICODE);
}
static void TestIsRightToLeft() {
if(uloc_isRightToLeft("root") || !uloc_isRightToLeft("EN-HEBR")) {
log_err("uloc_isRightToLeft() failed");
}
}
typedef struct {
const char * badLocaleID;
const char * displayLocale;
const char * expectedName;
UErrorCode expectedStatus;
} BadLocaleItem;
static const BadLocaleItem badLocaleItems[] = {
{ "-9223372036854775808", "en", "9223372036854775808", U_USING_DEFAULT_WARNING },
{ NULL, NULL, NULL, U_ZERO_ERROR }
};
enum { kUBufDispNameMax = 128, kBBufDispNameMax = 256 };
static void TestBadLocaleIDs() {
const BadLocaleItem* itemPtr;
for (itemPtr = badLocaleItems; itemPtr->badLocaleID != NULL; itemPtr++) {
UChar ubufExpect[kUBufDispNameMax], ubufGet[kUBufDispNameMax];
UErrorCode status = U_ZERO_ERROR;
int32_t ulenExpect = u_unescape(itemPtr->expectedName, ubufExpect, kUBufDispNameMax);
int32_t ulenGet = uloc_getDisplayName(itemPtr->badLocaleID, itemPtr->displayLocale, ubufGet, kUBufDispNameMax, &status);
if (status != itemPtr->expectedStatus ||
(U_SUCCESS(status) && (ulenGet != ulenExpect || u_strncmp(ubufGet, ubufExpect, ulenExpect) != 0))) {
char bbufExpect[kBBufDispNameMax], bbufGet[kBBufDispNameMax];
u_austrncpy(bbufExpect, ubufExpect, ulenExpect);
u_austrncpy(bbufGet, ubufGet, ulenGet);
log_err("FAIL: For localeID %s, displayLocale %s, calling uloc_getDisplayName:\n"
" expected status %-26s, name (len %2d): %s\n"
" got status %-26s, name (len %2d): %s\n",
itemPtr->badLocaleID, itemPtr->displayLocale,
u_errorName(itemPtr->expectedStatus), ulenExpect, bbufExpect,
u_errorName(status), ulenGet, bbufGet );
}
}
}
typedef enum UldnNameType {
TEST_ULDN_LOCALE,
TEST_ULDN_LANGUAGE,
TEST_ULDN_SCRIPT,
TEST_ULDN_REGION,
} UldnNameType;
typedef struct {
const char * localeToName; UldnNameType nameType;
const char * expectResult;
} UldnItem;
typedef struct {
const char * displayLocale;
const UDisplayContext * displayOptions; const UldnItem * testItems;
int32_t countItems;
} UldnLocAndOpts;
static const UDisplayContext optStdMidLong[3] = {UDISPCTX_STANDARD_NAMES, UDISPCTX_CAPITALIZATION_FOR_MIDDLE_OF_SENTENCE, UDISPCTX_LENGTH_FULL};
static const UDisplayContext optStdMidShrt[3] = {UDISPCTX_STANDARD_NAMES, UDISPCTX_CAPITALIZATION_FOR_MIDDLE_OF_SENTENCE, UDISPCTX_LENGTH_SHORT};
static const UDisplayContext optDiaMidLong[3] = {UDISPCTX_DIALECT_NAMES, UDISPCTX_CAPITALIZATION_FOR_MIDDLE_OF_SENTENCE, UDISPCTX_LENGTH_FULL};
static const UDisplayContext optDiaMidShrt[3] = {UDISPCTX_DIALECT_NAMES, UDISPCTX_CAPITALIZATION_FOR_MIDDLE_OF_SENTENCE, UDISPCTX_LENGTH_SHORT};
static const UDisplayContext optStdBegLong[3] = {UDISPCTX_STANDARD_NAMES, UDISPCTX_CAPITALIZATION_FOR_BEGINNING_OF_SENTENCE, UDISPCTX_LENGTH_FULL};
static const UDisplayContext optStdBegShrt[3] = {UDISPCTX_STANDARD_NAMES, UDISPCTX_CAPITALIZATION_FOR_BEGINNING_OF_SENTENCE, UDISPCTX_LENGTH_SHORT};
static const UDisplayContext optDiaBegLong[3] = {UDISPCTX_DIALECT_NAMES, UDISPCTX_CAPITALIZATION_FOR_BEGINNING_OF_SENTENCE, UDISPCTX_LENGTH_FULL};
static const UDisplayContext optDiaBegShrt[3] = {UDISPCTX_DIALECT_NAMES, UDISPCTX_CAPITALIZATION_FOR_BEGINNING_OF_SENTENCE, UDISPCTX_LENGTH_SHORT};
static const UDisplayContext optStdLstLong[3] = {UDISPCTX_STANDARD_NAMES, UDISPCTX_CAPITALIZATION_FOR_UI_LIST_OR_MENU, UDISPCTX_LENGTH_FULL};
static const UDisplayContext optStdLstShrt[3] = {UDISPCTX_STANDARD_NAMES, UDISPCTX_CAPITALIZATION_FOR_UI_LIST_OR_MENU, UDISPCTX_LENGTH_SHORT};
static const UDisplayContext optDiaLstLong[3] = {UDISPCTX_DIALECT_NAMES, UDISPCTX_CAPITALIZATION_FOR_UI_LIST_OR_MENU, UDISPCTX_LENGTH_FULL};
static const UDisplayContext optDiaLstShrt[3] = {UDISPCTX_DIALECT_NAMES, UDISPCTX_CAPITALIZATION_FOR_UI_LIST_OR_MENU, UDISPCTX_LENGTH_SHORT};
static const UldnItem en_StdMidLong[] = {
{ "en_US", TEST_ULDN_LOCALE, "English (US)" },
{ "en_US_POSIX", TEST_ULDN_LOCALE, "English (US, Computer)" },
{ "en_US@calendar=chinese", TEST_ULDN_LOCALE, "English (US, Chinese Calendar)" },
{ "en_CA", TEST_ULDN_LOCALE, "English (Canada)" },
{ "pt", TEST_ULDN_LOCALE, "Portuguese" },
{ "pt_BR", TEST_ULDN_LOCALE, "Portuguese (Brazil)" },
{ "pt_PT", TEST_ULDN_LOCALE, "Portuguese (Portugal)" },
{ "zh_Hans", TEST_ULDN_LOCALE, "Chinese (Simplified)" },
{ "zh_Hant_HK", TEST_ULDN_LOCALE, "Chinese (Traditional, Hong Kong)" },
{ "zh_HK", TEST_ULDN_LOCALE, "Chinese (Hong Kong)" },
{ "Latn", TEST_ULDN_SCRIPT, "Latin" },
{ "Hans", TEST_ULDN_SCRIPT, "Simplified Han" },
{ "Hant", TEST_ULDN_SCRIPT, "Traditional Han" },
{ "US", TEST_ULDN_REGION, "United States" },
{ "CA", TEST_ULDN_REGION, "Canada" },
{ "GB", TEST_ULDN_REGION, "United Kingdom" },
{ "HK", TEST_ULDN_REGION, "Hong Kong (China)" },
};
static const UldnItem en_StdMidShrt[] = {
{ "en_US", TEST_ULDN_LOCALE, "English (US)" },
{ "en_US_POSIX", TEST_ULDN_LOCALE, "English (US, Computer)" },
{ "en_US@calendar=chinese", TEST_ULDN_LOCALE, "English (US, Calendar: chinese)" },
{ "en_CA", TEST_ULDN_LOCALE, "English (Canada)" },
{ "pt", TEST_ULDN_LOCALE, "Portuguese" },
{ "pt_BR", TEST_ULDN_LOCALE, "Portuguese (Brazil)" },
{ "pt_PT", TEST_ULDN_LOCALE, "Portuguese (Portugal)" },
{ "zh_Hans", TEST_ULDN_LOCALE, "Chinese (Simplified)" },
{ "zh_Hant_HK", TEST_ULDN_LOCALE, "Chinese (Traditional, Hong Kong)" },
{ "zh_HK", TEST_ULDN_LOCALE, "Chinese (Hong Kong)" },
{ "Latn", TEST_ULDN_SCRIPT, "Latin" },
{ "Hans", TEST_ULDN_SCRIPT, "Simplified Han" },
{ "Hant", TEST_ULDN_SCRIPT, "Traditional Han" },
{ "US", TEST_ULDN_REGION, "US" },
{ "CA", TEST_ULDN_REGION, "Canada" },
{ "GB", TEST_ULDN_REGION, "UK" },
{ "HK", TEST_ULDN_REGION, "Hong Kong" },
};
static const UldnItem en_DiaMidLong[] = {
{ "en_US", TEST_ULDN_LOCALE, "American English" },
{ "en_US_POSIX", TEST_ULDN_LOCALE, "American English (Computer)" },
{ "en_US@calendar=chinese", TEST_ULDN_LOCALE, "American English (Chinese Calendar)" },
{ "en_CA", TEST_ULDN_LOCALE, "Canadian English" },
{ "pt", TEST_ULDN_LOCALE, "Portuguese" },
{ "pt_BR", TEST_ULDN_LOCALE, "Brazilian Portuguese" },
{ "pt_PT", TEST_ULDN_LOCALE, "European Portuguese" },
{ "zh_Hans", TEST_ULDN_LOCALE, "Simplified Chinese" },
{ "zh_Hant_HK", TEST_ULDN_LOCALE, "Traditional Chinese (Hong Kong)" },
{ "zh_HK", TEST_ULDN_LOCALE, "Chinese (Hong Kong)" },
{ "Latn", TEST_ULDN_SCRIPT, "Latin" },
{ "Hans", TEST_ULDN_SCRIPT, "Simplified Han" },
{ "Hant", TEST_ULDN_SCRIPT, "Traditional Han" },
{ "US", TEST_ULDN_REGION, "United States" },
{ "CA", TEST_ULDN_REGION, "Canada" },
{ "GB", TEST_ULDN_REGION, "United Kingdom" },
{ "HK", TEST_ULDN_REGION, "Hong Kong (China)" },
};
static const UldnItem en_DiaMidShrt[] = {
{ "en_US", TEST_ULDN_LOCALE, "US English" },
{ "en_US_POSIX", TEST_ULDN_LOCALE, "US English (Computer)" },
{ "en_US@calendar=chinese", TEST_ULDN_LOCALE, "US English (Calendar: chinese)" },
{ "en_CA", TEST_ULDN_LOCALE, "Canadian English" },
{ "pt", TEST_ULDN_LOCALE, "Portuguese" },
{ "pt_BR", TEST_ULDN_LOCALE, "Brazilian Portuguese" },
{ "pt_PT", TEST_ULDN_LOCALE, "European Portuguese" },
{ "zh_Hans", TEST_ULDN_LOCALE, "Simplified Chinese" },
{ "zh_Hant_HK", TEST_ULDN_LOCALE, "Traditional Chinese (Hong Kong)" },
{ "zh_HK", TEST_ULDN_LOCALE, "Chinese (Hong Kong)" },
{ "Latn", TEST_ULDN_SCRIPT, "Latin" },
{ "Hans", TEST_ULDN_SCRIPT, "Simplified Han" },
{ "Hant", TEST_ULDN_SCRIPT, "Traditional Han" },
{ "US", TEST_ULDN_REGION, "US" },
{ "CA", TEST_ULDN_REGION, "Canada" },
{ "GB", TEST_ULDN_REGION, "UK" },
{ "HK", TEST_ULDN_REGION, "Hong Kong" },
};
static const UldnItem fr_StdMidLong[] = {
{ "en_US", TEST_ULDN_LOCALE, "anglais (\\u00C9.-U.)" },
{ "US", TEST_ULDN_REGION, "\\u00C9tats-Unis" },
{ "HK", TEST_ULDN_REGION, "Hong Kong (Chine)" },
};
static const UldnItem fr_StdMidShrt[] = {
{ "en_US", TEST_ULDN_LOCALE, "anglais (\\u00C9.-U.)" },
{ "US", TEST_ULDN_REGION, "\\u00C9.-U." },
{ "HK", TEST_ULDN_REGION, "Hong Kong" },
};
static const UldnItem fr_StdBegLong[] = {
{ "en_US", TEST_ULDN_LOCALE, "Anglais (\\u00C9.-U.)" },
};
static const UldnItem fr_StdLstLong[] = {
{ "en_US", TEST_ULDN_LOCALE, "Anglais (\\u00C9.-U.)" },
{ "PS", TEST_ULDN_REGION, "Territoires palestiniens" },
};
static const UldnItem fr_DiaMidLong[] = {
{ "en_US", TEST_ULDN_LOCALE, "anglais am\\u00E9ricain" },
};
static const UldnItem ca_StdLstLong[] = {
{ "PS", TEST_ULDN_REGION, "Territoris palestins" },
};
static const UldnLocAndOpts uldnLocAndOpts[] = {
{ "en", optStdMidLong, en_StdMidLong, UPRV_LENGTHOF(en_StdMidLong) },
{ "en", optStdMidShrt, en_StdMidShrt, UPRV_LENGTHOF(en_StdMidShrt) },
{ "en", optDiaMidLong, en_DiaMidLong, UPRV_LENGTHOF(en_DiaMidLong) },
{ "en", optDiaMidShrt, en_DiaMidShrt, UPRV_LENGTHOF(en_DiaMidShrt) },
{ "fr", optStdMidLong, fr_StdMidLong, UPRV_LENGTHOF(fr_StdMidLong) },
{ "fr", optStdMidShrt, fr_StdMidShrt, UPRV_LENGTHOF(fr_StdMidShrt) },
{ "fr", optStdBegLong, fr_StdBegLong, UPRV_LENGTHOF(fr_StdBegLong) },
{ "fr", optStdLstLong, fr_StdLstLong, UPRV_LENGTHOF(fr_StdLstLong) },
{ "fr_CA", optStdLstLong, fr_StdLstLong, UPRV_LENGTHOF(fr_StdLstLong) },
{ "fr", optDiaMidLong, fr_DiaMidLong, UPRV_LENGTHOF(fr_DiaMidLong) },
{ "ca", optStdLstLong, ca_StdLstLong, UPRV_LENGTHOF(ca_StdLstLong) },
{ NULL, NULL, NULL, 0 }
};
enum { kUNameBuf = 128, kBNameBuf = 256 };
static void TestUldnNameVariants() {
const UldnLocAndOpts * uloPtr;
for (uloPtr = uldnLocAndOpts; uloPtr->displayLocale != NULL; uloPtr++) {
UErrorCode status = U_ZERO_ERROR;
ULocaleDisplayNames * uldn = uldn_openForContext(uloPtr->displayLocale, (UDisplayContext*)uloPtr->displayOptions, 3, &status);
if (U_FAILURE(status)) {
log_data_err("uldn_openForContext fails, displayLocale %s, contexts %03X %03X %03X: %s - Are you missing data?\n",
uloPtr->displayLocale, uloPtr->displayOptions[0], uloPtr->displayOptions[1], uloPtr->displayOptions[2],
u_errorName(status) );
continue;
}
const UldnItem * itemPtr = uloPtr->testItems;
int32_t itemCount = uloPtr->countItems;
for (; itemCount-- > 0; itemPtr++) {
UChar uget[kUNameBuf], uexp[kUNameBuf];
int32_t ulenget, ulenexp;
const char* typeString;
status = U_ZERO_ERROR;
switch (itemPtr->nameType) {
case TEST_ULDN_LOCALE:
ulenget = uldn_localeDisplayName(uldn, itemPtr->localeToName, uget, kUNameBuf, &status);
typeString = "locale";
break;
case TEST_ULDN_LANGUAGE:
ulenget = uldn_languageDisplayName(uldn, itemPtr->localeToName, uget, kUNameBuf, &status);
typeString = "language";
break;
case TEST_ULDN_SCRIPT:
ulenget = uldn_scriptDisplayName(uldn, itemPtr->localeToName, uget, kUNameBuf, &status);
typeString = "script";
break;
case TEST_ULDN_REGION:
ulenget = uldn_regionDisplayName(uldn, itemPtr->localeToName, uget, kUNameBuf, &status);
typeString = "region";
break;
default:
continue;
}
if (U_FAILURE(status)) {
log_data_err("uldn_%sDisplayName fails, displayLocale %s, contexts %03X %03X %03X, localeToName %s: %s\n",
typeString, uloPtr->displayLocale, uloPtr->displayOptions[0], uloPtr->displayOptions[1], uloPtr->displayOptions[2],
itemPtr->localeToName, u_errorName(status) );
continue;
}
ulenexp = u_unescape(itemPtr->expectResult, uexp, kUNameBuf);
if (ulenget != ulenexp || u_strncmp(uget, uexp, ulenexp) != 0) {
char bexp[kBNameBuf], bget[kBNameBuf];
u_strToUTF8(bexp, kBNameBuf, NULL, uexp, ulenexp, &status);
u_strToUTF8(bget, kBNameBuf, NULL, uget, ulenget, &status);
log_data_err("uldn_%sDisplayName fails, displayLocale %s, contexts %03X %03X %03X, localeToName %s:\n expect %2d: %s\n get %2d: %s\n",
typeString, uloPtr->displayLocale, uloPtr->displayOptions[0], uloPtr->displayOptions[1], uloPtr->displayOptions[2],
itemPtr->localeToName, ulenexp, bexp, ulenget, bget );
}
}
uldn_close(uldn);
}
}
static const char* localesAndAppleParent[] = {
"en", "root",
"en-US", "en",
"en-CA", "en_001",
"en-CN", "en",
"en-JP", "en",
"en-TW", "en",
"en-001", "en",
"en_001", "en",
"en-150", "en_GB",
"en-GB", "en_001",
"en_GB", "en_001",
"en-AU", "en_GB",
"en-BE", "en_150",
"en-DG", "en_GB",
"en-FK", "en_GB",
"en-GG", "en_GB",
"en-GI", "en_GB",
"en-HK", "en_GB",
"en-IE", "en_GB",
"en-IM", "en_GB",
"en-IN", "en_GB",
"en-IO", "en_GB",
"en-JE", "en_GB",
"en-JM", "en_GB",
"en-MO", "en_GB",
"en-MT", "en_GB",
"en-MV", "en_GB",
"en-NZ", "en_AU",
"en-PK", "en_GB",
"en-SG", "en_GB",
"en-SH", "en_GB",
"en-VG", "en_GB",
"es", "root",
"es-ES", "es",
"es-419", "es",
"es_419", "es",
"es-MX", "es_419",
"es-AR", "es_419",
"es-BR", "es_419",
"es-BZ", "es_419",
"es-AG", "es_419",
"es-AW", "es_419",
"es-CA", "es_419",
"es-CW", "es_419",
"es-SX", "es_419",
"es-TT", "es_419",
"fr", "root",
"fr-CA", "fr",
"fr-CH", "fr",
"haw", "root",
"nl", "root",
"nl-BE", "nl",
"pt", "root",
"pt-BR", "pt",
"pt-PT", "pt",
"pt-MO", "pt_PT",
"pt-CH", "pt_PT",
"pt-GQ", "pt_PT",
"pt-LU", "pt_PT",
"sr", "root",
"sr-Cyrl", "sr",
"sr-Latn", "root",
"tlh", "root",
"zh_CN", "root",
"zh-CN", "root",
"zh", "zh_CN",
"zh-Hans", "zh",
"zh_TW", "root",
"zh-TW", "root",
"zh-Hant", "zh_TW",
"zh_HK", "zh_Hant_HK",
"zh-HK", "zh_Hant_HK",
"zh_Hant", "zh_TW",
"zh-Hant-HK", "zh_Hant",
"zh_Hant_HK", "zh_Hant",
"zh-Hant-MO", "zh_Hant_HK",
"zh-Hans-HK", "zh_Hans",
"root", "root",
"en-Latn", "en",
"en-Latn-US", "en_Latn",
"en_US_POSIX", "en_US",
"en_Latn_US_POSIX", "en_Latn_US",
"en-u-ca-hebrew", "root",
"en@calendar=hebrew", "root",
"en_@calendar=hebrew", "root",
"en-", "root",
"en_", "root",
"Default@2x", "root",
"default", "root",
NULL
};
static void TestGetAppleParent() {
const char **localesPtr = localesAndAppleParent;
const char * locale;
while ((locale = *localesPtr++) != NULL) {
const char * expectParent = *localesPtr++;
UErrorCode status = U_ZERO_ERROR;
char getParent[ULOC_FULLNAME_CAPACITY];
int32_t plen = ualoc_getAppleParent(locale, getParent, ULOC_FULLNAME_CAPACITY, &status);
if (U_FAILURE(status)) {
log_err("FAIL: ualoc_getAppleParent input \"%s\", status %s\n", locale, u_errorName(status));
} else if (uprv_strcmp(expectParent, getParent) != 0) {
log_err("FAIL: ualoc_getAppleParent input \"%s\", expected parent \"%s\", got parent \"%s\"\n", locale, expectParent, getParent);
}
}
}
enum { kUALanguageEntryMax = 10 };
static void TestGetLanguagesForRegion() {
UALanguageEntry entries[kUALanguageEntryMax];
int32_t entryCount;
UErrorCode status;
const char * region;
status = U_ZERO_ERROR;
region = "CN";
entryCount = ualoc_getLanguagesForRegion(region, 0.001, entries, kUALanguageEntryMax, &status);
if (U_FAILURE(status)) {
log_err("FAIL: ualoc_getLanguagesForRegion %s, status %s\n", region, u_errorName(status));
} else {
if (entryCount < kUALanguageEntryMax) {
log_err("FAIL: ualoc_getLanguagesForRegion %s, entryCount %d is too small\n", region, entryCount);
} else {
UALanguageEntry* entryPtr = entries;
if (uprv_strcmp(entryPtr->languageCode, "zh_Hans") != 0 || entryPtr->userFraction < 0.8 || entryPtr->userFraction > 1.0 || entryPtr->status != UALANGSTATUS_OFFICIAL) {
log_err("FAIL: ualoc_getLanguagesForRegion %s, invalid entries[0] { %s, %.3f, %d }\n", region, entryPtr->languageCode, entryPtr->userFraction, (int)entryPtr->status);
}
for (entryPtr++; entryPtr < entries + kUALanguageEntryMax && uprv_strcmp(entryPtr->languageCode, "ug_Arab") != 0; entryPtr++)
;
if (entryPtr < entries + kUALanguageEntryMax) {
if (entryPtr->status != UALANGSTATUS_REGIONAL_OFFICIAL) {
log_err("FAIL: ualoc_getLanguagesForRegion %s, ug_Arab had incorrect status %d\n", (int)entryPtr->status);
}
} else {
log_err("FAIL: ualoc_getLanguagesForRegion %s, entries did not include ug_Arab\n", region);
}
}
}
status = U_ZERO_ERROR;
region = "CA";
entryCount = ualoc_getLanguagesForRegion(region, 0.001, entries, kUALanguageEntryMax, &status);
if (U_FAILURE(status)) {
log_err("FAIL: ualoc_getLanguagesForRegion %s, status %s\n", region, u_errorName(status));
} else {
if (entryCount < 2) {
log_err("FAIL: ualoc_getLanguagesForRegion %s, entryCount %d is too small\n", region, entryCount);
} else {
if (uprv_strcmp(entries[0].languageCode, "en") != 0 || entries[0].userFraction < 0.7 || entries[0].userFraction > 1.0 || entries[0].status != UALANGSTATUS_OFFICIAL) {
log_err("FAIL: ualoc_getLanguagesForRegion %s, invalid entries[0] { %s, %.3f, %d }\n", region, entries[0].languageCode, entries[0].userFraction, (int)entries[0].status);
}
if (uprv_strcmp(entries[1].languageCode, "fr") != 0 || entries[1].userFraction < 0.1 || entries[1].userFraction > 1.0 || entries[1].status != UALANGSTATUS_OFFICIAL) {
log_err("FAIL: ualoc_getLanguagesForRegion %s, invalid entries[1] { %s, %.3f, %d }\n", region, entries[1].languageCode, entries[1].userFraction, (int)entries[1].status);
}
}
}
status = U_ZERO_ERROR;
region = "IN";
entryCount = ualoc_getLanguagesForRegion(region, 0.001, NULL, 0, &status);
if (U_FAILURE(status)) {
log_err("FAIL: ualoc_getLanguagesForRegion %s, status %s\n", region, u_errorName(status));
} else {
if (entryCount < 40) {
log_err("FAIL: ualoc_getLanguagesForRegion %s, entryCount %d is too small\n", region, entryCount);
}
}
}
typedef struct {
const char * const *locs;
int32_t locCount;
} AppleLocsAndCount;
enum { kNumLocSets = 6 };
typedef struct {
const char * language;
const char ** expLocsForSets[kNumLocSets];
} LangAndExpLocs;
static const char * appleLocs1[] = {
"Arabic",
"Danish",
"Dutch",
"English",
"Finnish",
"French",
"German",
"Italian",
"Japanese",
"Korean",
"Norwegian",
"Polish",
"Portuguese",
"Russian",
"Spanish",
"Swedish",
"Thai",
"Turkish",
"ca",
"cs",
"el",
"he",
"hr",
"hu",
"id",
"ms",
"ro",
"sk",
"uk",
"vi",
"zh_CN", "zh_TW",
};
static const char * appleLocs2[] = {
"ar",
"ca",
"cs",
"da",
"de",
"el",
"en", "en_AU", "en_GB",
"es", "es_MX",
"fi",
"fr", "fr_CA",
"he",
"hr",
"hu",
"id",
"it",
"ja",
"ko",
"ms",
"nl",
"no",
"pl",
"pt", "pt_PT",
"ro",
"ru",
"sk",
"sv",
"th",
"tr",
"uk",
"vi",
"zh_CN", "zh_HK", "zh_TW",
};
static const char * appleLocs3[] = {
"ar",
"ca",
"cs",
"da",
"de",
"el",
"en", "en_AU", "en_CA", "en_GB",
"es", "es_419",
"fi",
"fr", "fr_CA", "fr_FR",
"he",
"hr",
"hu",
"id",
"it",
"ja",
"ko",
"ms",
"nb",
"nl",
"pl",
"pt", "pt_BR", "pt_PT",
"ro",
"ru",
"sk",
"sv",
"th",
"tr",
"uk",
"vi",
"zh_CN", "zh_HK", "zh_MO", "zh_TW",
};
static const char * appleLocs4[] = {
"en", "en_AU", "en_CA", "en_GB", "en_IN", "en_US",
"es", "es_419", "es_MX",
"fr", "fr_CA", "fr_CH", "fr_FR",
"nl", "nl_BE", "nl_NL",
"pt", "pt_BR",
"ro", "ro_MD", "ro_RO",
"zh_Hans", "zh_Hant", "zh_Hant_HK",
};
static const char * appleLocs5[] = {
"en", "en_001", "en_AU", "en_GB",
"es", "es_ES", "es_MX",
"zh_CN", "zh_Hans", "zh_Hant", "zh_TW",
"yi",
"fil",
"haw",
"tlh",
"sr",
"sr-Latn",
};
static const char * appleLocs6[] = {
"en", "en_001", "en_150", "en_AU", "en_GB",
"es", "es_419", "es_ES", "es_MX",
"zh_CN", "zh_Hans", "zh_Hant", "zh_Hant_HK", "zh_HK", "zh_TW",
"iw",
"in",
"mo",
"tl",
};
static const AppleLocsAndCount locAndCountEntries[kNumLocSets] = {
{ appleLocs1, UPRV_LENGTHOF(appleLocs1) },
{ appleLocs2, UPRV_LENGTHOF(appleLocs2) },
{ appleLocs3, UPRV_LENGTHOF(appleLocs3) },
{ appleLocs4, UPRV_LENGTHOF(appleLocs4) },
{ appleLocs5, UPRV_LENGTHOF(appleLocs5) },
{ appleLocs6, UPRV_LENGTHOF(appleLocs6) },
};
static const char* l1_ar[] = { "ar", NULL };
static const char* l1_Ara[] = { "Arabic", NULL };
static const char* l1_ca[] = { "ca", NULL };
static const char* l1_cs[] = { "cs", NULL };
static const char* l1_da[] = { "da", NULL };
static const char* l1_Dan[] = { "Danish", NULL };
static const char* l1_de[] = { "de", NULL };
static const char* l1_Ger[] = { "German", NULL };
static const char* l1_el[] = { "el", NULL };
static const char* l1_en[] = { "en", NULL };
static const char* l1_Eng[] = { "English", NULL };
static const char* l2_en_001_[] = { "en_001", "en", NULL };
static const char* l2_en_CA_[] = { "en_CA", "en", NULL };
static const char* l2_en_GB_[] = { "en_GB", "en", NULL };
static const char* l2_en_US_[] = { "en_US", "en", NULL };
static const char* l2_en_GB_Eng[] = { "en_GB", "English", NULL };
static const char* l3_en_GB001_[] = { "en_GB", "en_001", "en", NULL };
static const char* l3_en_AUGB_[] = { "en_AU", "en_GB", "en", NULL };
static const char* l3_en_INGB_[] = { "en_IN", "en_GB", "en", NULL };
static const char* l4_en_150GB001_[] = { "en_150", "en_GB", "en_001", "en", NULL };
static const char* l4_en_AUGB001_[] = { "en_AU", "en_GB", "en_001", "en", NULL };
static const char* l1_es[] = { "es", NULL };
static const char* l1_Spa[] = { "Spanish", NULL };
static const char* l2_es_419_[] = { "es_419", "es", NULL };
static const char* l2_es_ES_[] = { "es_ES", "es", NULL };
static const char* l2_es_MX_[] = { "es_MX", "es", NULL };
static const char* l2_es_MX_Spa[] = { "es_MX", "Spanish", NULL };
static const char* l3_es_MX419_[] = { "es_MX", "es_419", "es", NULL };
static const char* l1_fi[] = { "fi", NULL };
static const char* l1_Fin[] = { "Finnish", NULL };
static const char* l1_fil[] = { "fil", NULL };
static const char* l1_tl[] = { "tl", NULL };
static const char* l1_fr[] = { "fr", NULL };
static const char* l1_Fre[] = { "French", NULL };
static const char* l2_fr_CA_[] = { "fr_CA", "fr", NULL };
static const char* l2_fr_CH_[] = { "fr_CH", "fr", NULL };
static const char* l2_fr_FR_[] = { "fr_FR", "fr", NULL };
static const char* l1_haw[] = { "haw", NULL };
static const char* l1_he[] = { "he", NULL };
static const char* l1_hr[] = { "hr", NULL };
static const char* l1_hu[] = { "hu", NULL };
static const char* l1_id[] = { "id", NULL };
static const char* l1_in[] = { "in", NULL };
static const char* l1_it[] = { "it", NULL };
static const char* l1_Ita[] = { "Italian", NULL };
static const char* l1_ja[] = { "ja", NULL };
static const char* l1_Japn[] = { "Japanese", NULL };
static const char* l1_ko[] = { "ko", NULL };
static const char* l1_Kor[] = { "Korean", NULL };
static const char* l1_ms[] = { "ms", NULL };
static const char* l1_nb[] = { "nb", NULL };
static const char* l1_no[] = { "no", NULL };
static const char* l1_Nor[] = { "Norwegian", NULL };
static const char* l2_no_NO_[] = { "no_NO", "no", NULL };
static const char* l1_nl[] = { "nl", NULL };
static const char* l1_Dut[] = { "Dutch", NULL };
static const char* l2_nl_BE_[] = { "nl_BE", "nl", NULL };
static const char* l1_pl[] = { "pl", NULL };
static const char* l1_Pol[] = { "Polish", NULL };
static const char* l1_pt[] = { "pt", NULL };
static const char* l1_pt_PT[] = { "pt_PT", NULL };
static const char* l1_Port[] = { "Portuguese", NULL };
static const char* l2_pt_BR_[] = { "pt_BR", "pt", NULL };
static const char* l2_pt_PT_[] = { "pt_PT", "pt", NULL };
static const char* l1_ro[] = { "ro", NULL };
static const char* l2_ro_MD_[] = { "ro_MD", "ro", NULL };
static const char* l1_mo[] = { "mo", NULL };
static const char* l1_ru[] = { "ru", NULL };
static const char* l1_Rus[] = { "Russian", NULL };
static const char* l1_sk[] = { "sk", NULL };
static const char* l1_sr[] = { "sr", NULL };
static const char* l1_srLatn[] = { "sr-Latn", NULL };
static const char* l1_sv[] = { "sv", NULL };
static const char* l1_Swe[] = { "Swedish", NULL };
static const char* l1_th[] = { "th", NULL };
static const char* l1_Thai[] = { "Thai", NULL };
static const char* l1_tlh[] = { "tlh", NULL };
static const char* l1_tr[] = { "tr", NULL };
static const char* l1_Tur[] = { "Turkish", NULL };
static const char* l1_uk[] = { "uk", NULL };
static const char* l1_vi[] = { "vi", NULL };
static const char* l1_yi[] = { "yi", NULL };
static const char* l1_iw[] = { "iw", NULL };
static const char* l1_zh_CN[] = { "zh_CN", NULL };
static const char* l1_zh_TW[] = { "zh_TW", NULL };
static const char* l1_zh_Hans[] = { "zh_Hans", NULL };
static const char* l1_zh_Hant[] = { "zh_Hant", NULL };
static const char* l1_zhHant[] = { "zh-Hant", NULL };
static const char* l2_zh_HKTW[] = { "zh_HK", "zh_TW", NULL };
static const char* l2_zh_Hant_HK_[] = { "zh_Hant_HK", "zh_Hant", NULL };
static const char* l2_zh_CN_Hans[] = { "zh_CN", "zh_Hans", NULL };
static const char* l2_zh_TW_Hant[] = { "zh_TW", "zh_Hant", NULL };
static const char* l3_zh_MOHKTW[] = { "zh_MO", "zh_HK", "zh_TW", NULL };
static const char* l3_zh_HK_HantHK_Hant[] = { "zh_HK", "zh_Hant_HK", "zh_Hant", NULL };
static const LangAndExpLocs appleLangAndLoc[] = {
{ "zh", { l1_zh_CN, l1_zh_CN, l1_zh_CN, l1_zh_Hans, l1_zh_Hans, l1_zh_Hans } },
{ "zh-Hans", { l1_zh_CN, l1_zh_CN, l1_zh_CN, l1_zh_Hans, l1_zh_Hans, l1_zh_Hans } },
{ "zh-Hant", { l1_zh_TW, l1_zh_TW, l1_zh_TW, l1_zh_Hant, l1_zh_Hant, l1_zh_Hant } },
{ "zh-Hans-CN", { l1_zh_CN, l1_zh_CN, l1_zh_CN, l1_zh_Hans, l2_zh_CN_Hans, l2_zh_CN_Hans } },
{ "zh-Hans-SG", { l1_zh_CN, l1_zh_CN, l1_zh_CN, l1_zh_Hans, l1_zh_Hans, l1_zh_Hans } },
{ "zh-Hant-TW", { l1_zh_TW, l1_zh_TW, l1_zh_TW, l1_zh_Hant, l2_zh_TW_Hant, l2_zh_TW_Hant } },
{ "zh-Hant-HK", { l1_zh_TW, l2_zh_HKTW, l2_zh_HKTW, l2_zh_Hant_HK_, l1_zh_Hant, l2_zh_Hant_HK_ } },
{ "zh-Hant-MO", { l1_zh_TW, l2_zh_HKTW, l3_zh_MOHKTW, l2_zh_Hant_HK_, l1_zh_Hant, l2_zh_Hant_HK_ } },
{ "zh-Hans-HK", { l1_zh_CN, l1_zh_CN, l1_zh_CN, l1_zh_Hans, l1_zh_Hans, l1_zh_Hans } },
{ "zh-CN", { l1_zh_CN, l1_zh_CN, l1_zh_CN, l1_zh_Hans, l2_zh_CN_Hans, l2_zh_CN_Hans } },
{ "zh-SG", { l1_zh_CN, l1_zh_CN, l1_zh_CN, l1_zh_Hans, l1_zh_Hans, l1_zh_Hans } },
{ "zh-TW", { l1_zh_TW, l1_zh_TW, l1_zh_TW, l1_zh_Hant, l2_zh_TW_Hant, l2_zh_TW_Hant } },
{ "zh-HK", { l1_zh_TW, l2_zh_HKTW, l2_zh_HKTW, l2_zh_Hant_HK_, l1_zh_Hant, l3_zh_HK_HantHK_Hant } },
{ "zh-MO", { l1_zh_TW, l2_zh_HKTW, l3_zh_MOHKTW, l2_zh_Hant_HK_, l1_zh_Hant, l2_zh_Hant_HK_ } },
{ "en", { l1_Eng, l1_en, l1_en, l1_en, l1_en, l1_en } },
{ "en-US", { l1_Eng, l1_en, l1_en, l2_en_US_, l1_en, l1_en } },
{ "en_US", { l1_Eng, l1_en, l1_en, l2_en_US_, l1_en, l1_en } },
{ "en-CN", { l1_Eng, l1_en, l1_en, l1_en, l1_en, l1_en } },
{ "en-JP", { l1_Eng, l1_en, l1_en, l1_en, l1_en, l1_en } },
{ "en-TW", { l1_Eng, l1_en, l1_en, l1_en, l1_en, l1_en } },
{ "en-TR", { l1_Eng, l1_en, l1_en, l1_en, l1_en, l1_en } },
{ "en-001", { l1_Eng, l1_en, l1_en, l1_en, l2_en_001_, l2_en_001_ } },
{ "en-CA", { l1_Eng, l1_en, l2_en_CA_, l2_en_CA_, l2_en_001_, l2_en_001_ } },
{ "en-IL", { l1_Eng, l1_en, l1_en, l1_en, l2_en_001_, l2_en_001_ } },
{ "en-GB", { l1_Eng, l2_en_GB_, l2_en_GB_, l2_en_GB_, l3_en_GB001_, l3_en_GB001_ } },
{ "en-IN", { l1_Eng, l2_en_GB_, l2_en_GB_, l3_en_INGB_, l3_en_GB001_, l3_en_GB001_ } },
{ "en-BD", { l1_Eng, l2_en_GB_, l2_en_GB_, l2_en_GB_, l3_en_GB001_, l3_en_GB001_ } },
{ "en-GG", { l1_Eng, l2_en_GB_, l2_en_GB_, l2_en_GB_, l3_en_GB001_, l3_en_GB001_ } },
{ "en-HK", { l1_Eng, l2_en_GB_, l2_en_GB_, l2_en_GB_, l3_en_GB001_, l3_en_GB001_ } },
{ "en-IE", { l1_Eng, l2_en_GB_, l2_en_GB_, l2_en_GB_, l3_en_GB001_, l3_en_GB001_ } },
{ "en-JM", { l1_Eng, l2_en_GB_, l2_en_GB_, l2_en_GB_, l3_en_GB001_, l3_en_GB001_ } },
{ "en-MO", { l1_Eng, l2_en_GB_, l2_en_GB_, l2_en_GB_, l3_en_GB001_, l3_en_GB001_ } },
{ "en-MT", { l1_Eng, l2_en_GB_, l2_en_GB_, l2_en_GB_, l3_en_GB001_, l3_en_GB001_ } },
{ "en-PK", { l1_Eng, l2_en_GB_, l2_en_GB_, l2_en_GB_, l3_en_GB001_, l3_en_GB001_ } },
{ "en-SG", { l1_Eng, l2_en_GB_, l2_en_GB_, l2_en_GB_, l3_en_GB001_, l3_en_GB001_ } },
{ "en-VG", { l1_Eng, l2_en_GB_, l2_en_GB_, l2_en_GB_, l3_en_GB001_, l3_en_GB001_ } },
{ "en-ZA", { l1_Eng, l2_en_GB_, l2_en_GB_, l2_en_GB_, l3_en_GB001_, l3_en_GB001_ } },
{ "en-AU", { l1_Eng, l3_en_AUGB_, l3_en_AUGB_, l3_en_AUGB_, l4_en_AUGB001_, l4_en_AUGB001_ } },
{ "en-NZ", { l1_Eng, l3_en_AUGB_, l3_en_AUGB_, l3_en_AUGB_, l4_en_AUGB001_, l4_en_AUGB001_ } },
{ "en-WS", { l1_Eng, l3_en_AUGB_, l3_en_AUGB_, l3_en_AUGB_, l4_en_AUGB001_, l4_en_AUGB001_ } },
{ "en-150", { l1_Eng, l2_en_GB_, l2_en_GB_, l2_en_GB_, l3_en_GB001_, l4_en_150GB001_ } },
{ "en-FR", { l1_Eng, l2_en_GB_, l2_en_GB_, l2_en_GB_, l3_en_GB001_, l4_en_150GB001_ } },
{ "en-BE", { l1_Eng, l2_en_GB_, l2_en_GB_, l2_en_GB_, l3_en_GB001_, l4_en_150GB001_ } },
{ "en-Latn", { l1_Eng, l1_en, l1_en, l1_en, l1_en, l1_en } },
{ "en-Latn-US", { l1_Eng, l1_en, l1_en, l1_en, l1_en, l1_en } },
{ "en-US-POSIX", { l1_Eng, l1_en, l1_en, l2_en_US_, l1_en, l1_en } },
{ "en-Latn-US-POSIX", { l1_Eng, l1_en, l1_en, l1_en, l1_en, l1_en } },
{ "en-u-ca-hebrew", { l1_Eng, l1_en, l1_en, l1_en, l1_en, l1_en } },
{ "en@calendar=hebrew", { l1_Eng, l1_en, l1_en, l1_en, l1_en, l1_en } },
{ "en-", { l1_Eng, l1_en, l1_en, l1_en, l1_en, l1_en } },
{ "en_", { l1_Eng, l1_en, l1_en, l1_en, l1_en, l1_en } },
{ "es", { l1_Spa, l1_es, l1_es, l1_es, l1_es, l1_es } },
{ "es-ES", { l1_Spa, l1_es, l1_es, l1_es, l2_es_ES_, l2_es_ES_ } },
{ "es-419", { l1_Spa, l1_es, l2_es_419_, l2_es_419_, l1_es, l2_es_419_ } },
{ "es-MX", { l1_Spa, l2_es_MX_, l2_es_419_, l3_es_MX419_, l2_es_MX_, l3_es_MX419_ } },
{ "es-AR", { l1_Spa, l1_es, l2_es_419_, l2_es_419_, l1_es, l2_es_419_ } },
{ "es-BR", { l1_Spa, l1_es, l2_es_419_, l2_es_419_, l1_es, l2_es_419_ } },
{ "es-BZ", { l1_Spa, l1_es, l2_es_419_, l2_es_419_, l1_es, l2_es_419_ } },
{ "es-AG", { l1_Spa, l1_es, l2_es_419_, l2_es_419_, l1_es, l2_es_419_ } },
{ "es-AW", { l1_Spa, l1_es, l2_es_419_, l2_es_419_, l1_es, l2_es_419_ } },
{ "es-CA", { l1_Spa, l1_es, l2_es_419_, l2_es_419_, l1_es, l2_es_419_ } },
{ "es-CW", { l1_Spa, l1_es, l2_es_419_, l2_es_419_, l1_es, l2_es_419_ } },
{ "es-SX", { l1_Spa, l1_es, l2_es_419_, l2_es_419_, l1_es, l2_es_419_ } },
{ "es-TT", { l1_Spa, l1_es, l2_es_419_, l2_es_419_, l1_es, l2_es_419_ } },
{ "es-Latn", { l1_Spa, l1_es, l1_es, l1_es, l1_es, l1_es } },
{ "es-Latn-MX", { l1_Spa, l1_es, l1_es, l1_es, l1_es, l1_es } },
{ "pt", { l1_Port, l1_pt, l1_pt, l1_pt, NULL, NULL } },
{ "pt-BR", { l1_Port, l1_pt, l2_pt_BR_, l2_pt_BR_, NULL, NULL } },
{ "pt-PT", { l1_Port, l2_pt_PT_, l2_pt_PT_, l1_pt, NULL, NULL } },
{ "pt-MO", { l1_Port, l2_pt_PT_, l2_pt_PT_, l1_pt, NULL, NULL } },
{ "pt-CH", { l1_Port, l2_pt_PT_, l2_pt_PT_, l1_pt, NULL, NULL } },
{ "pt-FR", { l1_Port, l2_pt_PT_, l2_pt_PT_, l1_pt, NULL, NULL } },
{ "pt-GQ", { l1_Port, l2_pt_PT_, l2_pt_PT_, l1_pt, NULL, NULL } },
{ "pt-LU", { l1_Port, l2_pt_PT_, l2_pt_PT_, l1_pt, NULL, NULL } },
{ "fr", { l1_Fre, l1_fr, l1_fr, l1_fr, NULL, NULL } },
{ "fr-FR", { l1_Fre, l1_fr, l2_fr_FR_, l2_fr_FR_, NULL, NULL } },
{ "fr-CA", { l1_Fre, l2_fr_CA_, l2_fr_CA_, l2_fr_CA_, NULL, NULL } },
{ "fr-CH", { l1_Fre, l1_fr, l1_fr, l2_fr_CH_, NULL, NULL } },
{ "ar", { l1_Ara, l1_ar, l1_ar, NULL, NULL, NULL } },
{ "da", { l1_Dan, l1_da, l1_da, NULL, NULL, NULL } },
{ "nl", { l1_Dut, l1_nl, l1_nl, l1_nl, NULL, NULL } },
{ "nl-BE", { l1_Dut, l1_nl, l1_nl, l2_nl_BE_, NULL, NULL } },
{ "fi", { l1_Fin, l1_fi, l1_fi, NULL, NULL, NULL } },
{ "de", { l1_Ger, l1_de, l1_de, NULL, NULL, NULL } },
{ "it", { l1_Ita, l1_it, l1_it, NULL, NULL, NULL } },
{ "ja", { l1_Japn, l1_ja, l1_ja, NULL, NULL, NULL } },
{ "ko", { l1_Kor, l1_ko, l1_ko, NULL, NULL, NULL } },
{ "nb", { l1_Nor, l1_no, l1_nb, NULL, NULL, NULL } },
{ "no", { l1_Nor, l1_no, l1_nb, NULL, NULL, NULL } },
{ "pl", { l1_Pol, l1_pl, l1_pl, NULL, NULL, NULL } },
{ "ru", { l1_Rus, l1_ru, l1_ru, NULL, NULL, NULL } },
{ "sv", { l1_Swe, l1_sv, l1_sv, NULL, NULL, NULL } },
{ "th", { l1_Thai, l1_th, l1_th, NULL, NULL, NULL } },
{ "tr", { l1_Tur, l1_tr, l1_tr, NULL, NULL, NULL } },
{ "ca", { l1_ca, l1_ca, l1_ca, NULL, NULL, NULL } },
{ "cs", { l1_cs, l1_cs, l1_cs, NULL, NULL, NULL } },
{ "el", { l1_el, l1_el, l1_el, NULL, NULL, NULL } },
{ "he", { l1_he, l1_he, l1_he, NULL, NULL, l1_iw } },
{ "iw", { l1_he, l1_he, l1_he, NULL, NULL, l1_iw } },
{ "hr", { l1_hr, l1_hr, l1_hr, NULL, NULL, NULL } },
{ "hu", { l1_hu, l1_hu, l1_hu, NULL, NULL, NULL } },
{ "id", { l1_id, l1_id, l1_id, NULL, NULL, l1_in } },
{ "in", { l1_id, l1_id, l1_id, NULL, NULL, l1_in } },
{ "ms", { l1_ms, l1_ms, l1_ms, NULL, NULL, NULL } },
{ "ro", { l1_ro, l1_ro, l1_ro, l1_ro, NULL, l1_mo } },
{ "mo", { l1_ro, l1_ro, l1_ro, l2_ro_MD_, NULL, l1_mo } },
{ "sk", { l1_sk, l1_sk, l1_sk, NULL, NULL, NULL } },
{ "uk", { l1_uk, l1_uk, l1_uk, NULL, NULL, NULL } },
{ "vi", { l1_vi, l1_vi, l1_vi, NULL, NULL, NULL } },
{ "yi", { NULL, NULL, NULL, NULL, l1_yi, NULL } },
{ "ji", { NULL, NULL, NULL, NULL, l1_yi, NULL } },
{ "fil", { NULL, NULL, NULL, NULL, l1_fil, l1_tl } },
{ "tl", { NULL, NULL, NULL, NULL, l1_fil, l1_tl } },
{ "haw", { NULL, NULL, NULL, NULL, l1_haw, NULL } },
{ "sr", { NULL, NULL, NULL, NULL, l1_sr, NULL } },
{ "sr-Cyrl", { NULL, NULL, NULL, NULL, l1_sr, NULL } },
{ "sr-Latn", { NULL, NULL, NULL, NULL, l1_srLatn, NULL } },
{ "tlh", { NULL, NULL, NULL, NULL, l1_tlh, NULL } },
{ "Default@2x", { NULL, NULL, NULL, NULL, NULL, NULL } },
{ "default", { NULL, NULL, NULL, NULL, NULL, NULL } },
{ "root", { NULL, NULL, NULL, NULL, NULL, NULL } },
{ "", { NULL, NULL, NULL, NULL, NULL, NULL } },
{ "_US", { NULL, NULL, NULL, NULL, NULL, NULL } },
{ "-US", { NULL, NULL, NULL, NULL, NULL, NULL } },
{ "-u-ca-hebrew", { NULL, NULL, NULL, NULL, NULL, NULL } },
{ "-u-ca-hebrew", { NULL, NULL, NULL, NULL, NULL, NULL } },
{ "@calendar=hebrew", { NULL, NULL, NULL, NULL, NULL, NULL } },
};
enum { kNumAppleLangAndLoc = UPRV_LENGTHOF(appleLangAndLoc) };
static const char * appleLocsA1[] = { "en", "fr", "no", "zh-Hant" };
static const char * appleLocsA2[] = { "en", "fr", "nb", "zh_TW", "zh_CN", "zh-Hant" };
static const char * appleLocsA3[] = { "en", "en_IN", "en_GB", "fr", "de", "zh_TW" };
static const char * appleLocsA4[] = { "Spanish", "es_MX", "English", "en_GB" };
static const char * appleLocsA5[] = { "en", "fr", "de", "pt", "pt_PT" };
static const char * appleLocsA6[] = { "en", "no", "no_NO", "pt_PT" };
static const AppleLocsAndCount locAndCountEntriesA[kNumLocSets] = {
{ appleLocsA1, UPRV_LENGTHOF(appleLocsA1) },
{ appleLocsA2, UPRV_LENGTHOF(appleLocsA2) },
{ appleLocsA3, UPRV_LENGTHOF(appleLocsA3) },
{ appleLocsA4, UPRV_LENGTHOF(appleLocsA4) },
{ appleLocsA5, UPRV_LENGTHOF(appleLocsA5) },
{ appleLocsA6, UPRV_LENGTHOF(appleLocsA6) },
};
static const LangAndExpLocs appleLangAndLocA[] = {
{ "zh-Hant", { l1_zhHant, l1_zhHant, l1_zh_TW, NULL, NULL, NULL } },
{ "zh_Hant", { l1_zhHant, l1_zhHant, l1_zh_TW, NULL, NULL, NULL } },
{ "zh_HK", { l1_zhHant, l1_zhHant, l1_zh_TW, NULL, NULL, NULL } },
{ "en_IN", { l1_en, l1_en, l3_en_INGB_, l2_en_GB_Eng, l1_en, l1_en } },
{ "es_MX", { NULL, NULL, NULL, l2_es_MX_Spa, NULL, NULL } },
{ "pt_PT", { NULL, NULL, NULL, NULL, l2_pt_PT_, l1_pt_PT } },
{ "pt", { NULL, NULL, NULL, NULL, l1_pt, l1_pt_PT } },
{ "no", { l1_no, l1_nb, NULL, NULL, NULL, l1_no } },
{ "no_NO", { l1_no, l1_nb, NULL, NULL, NULL, l2_no_NO_ } },
{ "nb", { l1_no, l1_nb, NULL, NULL, NULL, l1_no } },
{ "nb_NO", { l1_no, l1_nb, NULL, NULL, NULL, l2_no_NO_ } },
};
enum { kNumAppleLangAndLocA = UPRV_LENGTHOF(appleLangAndLocA) };
static const char * appleLocsB1[] = {
"ar", "Base", "ca", "cs",
"da", "Dutch", "el", "English",
"es_MX", "fi", "French", "German",
"he", "hr", "hu", "id",
"Italian", "Japanese", "ko", "ms",
"no", "pl", "pt", "pt_PT",
"ro", "ru", "sk", "Spanish",
"sv", "th", "tr", "uk",
"vi", "zh_CN", "zh_TW"
};
static const char * appleLocsB2[] = {
"ar", "ca", "cs",
"da", "Dutch", "el", "English",
"es_MX", "fi", "French", "German",
"he", "hr", "hu", "id",
"Italian", "Japanese", "ko", "ms",
"no", "pl", "pt", "pt_PT",
"ro", "ru", "sk", "Spanish",
"sv", "th", "tr", "uk",
"vi", "zh_CN", "zh_TW"
};
static const char * appleLocsB3[] = {
"ar", "ca", "cs", "da",
"de", "el", "en", "es",
"es_MX", "fi", "French", "he",
"hr", "hu", "id", "Italian",
"ja", "ko", "ms", "nl",
"no", "pl", "pt", "pt_PT",
"ro", "ru", "sk", "sv",
"th", "tr", "uk", "vi",
"zh_CN", "zh_TW"
};
static const char * appleLocsB4[] = {
"ar", "ca", "cs", "da",
"de", "el", "en", "es",
"es_MX", "fi", "fr", "he",
"hr", "hu", "id", "it",
"ja", "ko", "ms", "nl",
"no", "pl", "pt", "pt_PT",
"ro", "ru", "sk", "sv",
"th", "tr", "uk", "vi",
"zh_CN", "zh_TW"
};
static const char * appleLocsB5[] = { "en" };
static const char * appleLocsB6[] = { "English" };
static const AppleLocsAndCount locAndCountEntriesB[kNumLocSets] = {
{ appleLocsB1, UPRV_LENGTHOF(appleLocsB1) },
{ appleLocsB2, UPRV_LENGTHOF(appleLocsB2) },
{ appleLocsB3, UPRV_LENGTHOF(appleLocsB3) },
{ appleLocsB4, UPRV_LENGTHOF(appleLocsB4) },
{ appleLocsB5, UPRV_LENGTHOF(appleLocsB5) },
{ appleLocsB6, UPRV_LENGTHOF(appleLocsB6) },
};
static const LangAndExpLocs appleLangAndLocB[] = {
{ "en", { l1_Eng, l1_Eng, l1_en, l1_en, l1_en, l1_Eng } },
{ "es", { l1_Spa, l1_Spa, l1_es, l1_es, NULL, NULL } },
{ "English", { l1_Eng, l1_Eng, l1_en, l1_en, l1_en, l1_Eng } },
{ "Spanish", { l1_Spa, l1_Spa, l1_es, l1_es, NULL, NULL } },
};
enum { kNumAppleLangAndLocB = UPRV_LENGTHOF(appleLangAndLocB) };
typedef struct {
const AppleLocsAndCount * locAndCountEntriesPtr;
const LangAndExpLocs * appleLangAndLocPtr;
int32_t appleLangAndLocCount;
} AppleLocToUseTestSet;
static const AppleLocToUseTestSet altuTestSets[] = {
{ locAndCountEntries, appleLangAndLoc, kNumAppleLangAndLoc },
{ locAndCountEntriesA, appleLangAndLocA, kNumAppleLangAndLocA },
{ locAndCountEntriesB, appleLangAndLocB, kNumAppleLangAndLocB },
{ NULL, NULL, 0 }
};
static const char * appleLocsM1[] = { "en", "en_GB", "pt", "pt_PT", "zh_CN", "zh_Hant" };
static const char * prefLangsM1[] = { "tlh", "zh_HK", "zh_SG", "zh_Hans", "pt_BR", "pt_PT", "en_IN", "en" };
static const char * locsToUseM1[] = { "zh_Hant" };
static const char * appleLocsM2[] = { "fr-FR", "en-US", "en-GB" };
static const char * prefLangsM2[] = { "fr-CH" };
static const char * locsToUseM2[] = { "fr-FR" };
static const char * appleLocsM3[] = { "es-es", "fr-fr" };
static const char * prefLangsM3[] = { "fr-US", "fr", "en-US" };
static const char * locsToUseM3[] = { "fr-fr" };
static const char * appleLocsM4[] = { "es-es", "fr-fr", "fr" };
static const char * prefLangsM4[] = { "fr-US", "fr", "en-US" };
static const char * locsToUseM4[] = { "fr" };
static const char * appleLocsM5[] = { "en-US", "fr-FR", "de-DE", "es-ES", "es-419", "pt-PT", "pt-BR", "zh-CN", "zh-TW", "zh-HK", "ja-JP", "ko-KR" };
static const char * prefLangsM5[] = { "fr-US", "en-US" };
static const char * locsToUseM5[] = { "fr-FR" };
static const char * appleLocsM6[] = { "de-CH", "en-US" };
static const char * prefLangsM6[] = { "de-DE", "en-US" };
static const char * locsToUseM6[] = { "de-CH" };
static const char * appleLocsMx[] = { "de-DE", "en-AU", "es-ES", "fr-FR", "hi-IN", "pt-BR", "zh-HK", "zh-TW" };
static const char * prefLangsM7[] = { "fr-ES", "en-AU" };
static const char * locsToUseM7[] = { "fr-FR" };
static const char * prefLangsM8[] = { "de-IT", "en-AU" };
static const char * locsToUseM8[] = { "de-DE" };
static const char * prefLangsM9[] = { "hi-US", "en-AU" };
static const char * locsToUseM9[] = { "hi-IN" };
static const char * prefLangsMA[] = { "en-IN", "zh-HK" };
static const char * locsToUseMA[] = { "en-AU" };
static const char * prefLangsMB[] = { "pt-PT", "en-AU" };
static const char * locsToUseMB[] = { "en-AU" };
static const char * prefLangsMC[] = { "pt-PT", "ar" };
static const char * locsToUseMC[] = { "pt-BR" };
static const char * prefLangsMD[] = { "zh-CN", "en-AU" };
static const char * locsToUseMD[] = { "en-AU" };
static const char * appleLocsME[] = { "de-DE", "en-AU", "es-ES", "fr-FR", "hi-IN", "pt-BR", "zh-CN", "zh-HK" };
static const char * prefLangsME[] = { "zh-TW", "en-AU" };
static const char * locsToUseME[] = { "zh-HK" };
static const char * appleLocsMF[] = { "en", "en-GB", "fr", "es" };
static const char * prefLangsMF[] = { "en-IN", "en-GB", "de", "fr" };
static const char * locsToUseMF[] = { "en-GB", "en" };
static const char * appleLocsMG[] = { "zh-Hans", "zh-Hant", "zh-HK" };
static const char * prefLangsMG[] = { "zh-Hans-US", "zh-HK", "en-US" };
static const char * locsToUseMG[] = { "zh-Hans" };
static const char * appleLocsMH[] = { "zh-TW", "zh-CN", "zh-HK" };
static const char * prefLangsMH[] = { "zh-Hans-HK", "zh-HK", "en" };
static const char * locsToUseMH[] = { "zh-CN" };
static const char * appleLocsMI[] = { "unk", "en-US", "ar-SA" };
static const char * prefLangsMI[] = { "ar-US" };
static const char * locsToUseMI[] = { "ar-SA" };
static const char * appleLocsMJ[] = { "zh-CN", "en-US" };
static const char * prefLangsMJ[] = { "zh", "zh_AC" };
static const char * locsToUseMJ[] = { "zh-CN" };
static const char * appleLocsMK[] = { "yue-CN", "en-US" };
static const char * prefLangsMK[] = { "yue", "yue_AC" };
static const char * locsToUseMK[] = { "yue-CN" };
static const char * appleLocsML[] = { "nl_NL", "es_MX", "fr_FR", "zh_TW", "it_IT", "vi_VN", "fr_CH", "es_CL",
"en_ZA", "ko_KR", "ca_ES", "ro_RO", "en_PH", "en_CA", "en_SG", "en_IN",
"en_NZ", "it_CH", "fr_CA", "da_DK", "de_AT", "pt_BR", "yue_CN", "zh_CN",
"sv_SE", "es_ES", "ar_SA", "hu_HU", "fr_BE", "en_GB", "ja_JP", "zh_HK",
"fi_FI", "tr_TR", "nb_NO", "en_ID", "en_SA", "pl_PL", "ms_MY", "cs_CZ",
"el_GR", "id_ID", "hr_HR", "en_AE", "he_IL", "ru_RU", "wuu_CN", "de_DE",
"de_CH", "en_AU", "nl_BE", "th_TH", "pt_PT", "sk_SK", "en_US", "en_IE",
"es_CO", "uk_UA", "es_US" };
static const char * prefLangsML[] = { "en-JP" };
static const char * locsToUseML[] = { "en_US" };
static const char * appleLocsMM1[] = { "pt-PT" };
static const char * appleLocsMM2[] = { "pt-BR" };
static const char * appleLocsMM3[] = { "pt-PT", "pt-BR" };
static const char * appleLocsMM4[] = { "en", "pt-PT" };
static const char * appleLocsMM5[] = { "en", "pt-BR" };
static const char * appleLocsMM6[] = { "en", "pt-PT", "pt-BR" };
static const char * prefLangsMM1[] = { "pt-PT" };
static const char * prefLangsMM2[] = { "pt-BR" };
static const char * prefLangsMM3[] = { "pt" };
static const char * prefLangsMM4[] = { "pt-PT", "en" };
static const char * prefLangsMM5[] = { "pt-BR", "en" };
static const char * prefLangsMM6[] = { "pt", "en" };
static const char * locsToUseMMptPT[] = { "pt-PT" };
static const char * locsToUseMMptBR[] = { "pt-BR" };
static const char * locsToUseMMen[] = { "en" };
static const char * appleLocsMN[] = { "en-US", "en-GB" };
static const char * prefLangsMN1[] = { "en-KR" };
static const char * prefLangsMN2[] = { "en-SA" };
static const char * prefLangsMN3[] = { "en-TW" };
static const char * prefLangsMN4[] = { "en-JP" };
static const char * locsToUseMN_U[] = { "en-US" };
static const char * appleLocsMO[] = { "Dutch", "French", "German", "Italian", "Japanese", "Spanish",
"ar", "ca", "cs", "da", "el", "en_AU", "en_GB", "en_IN",
"es_419", "fi", "fr_CA", "he", "hi", "hr", "hu", "id", "ko",
"ms", "no", "pl", "pt", "pt_PT", "ro", "ru", "sk", "sv",
"th", "tr", "uk", "vi", "zh_CN", "zh_HK", "zh_TW" };
static const char * prefLangsMO1[] = { "en-US" };
static const char * locsToUseMO1[] = { "en_GB" };
typedef struct {
const char * name;
const char ** availLocs;
int32_t availLocsCount;
const char ** prefLangs;
int32_t prefLangsCount;
const char ** locsToUse;
int32_t locsToUseCount;
} MultiPrefTest;
static const MultiPrefTest multiTestSets[] = {
{ "M1", appleLocsM1, UPRV_LENGTHOF(appleLocsM1), prefLangsM1, UPRV_LENGTHOF(prefLangsM1), locsToUseM1, UPRV_LENGTHOF(locsToUseM1) },
{ "M2", appleLocsM2, UPRV_LENGTHOF(appleLocsM2), prefLangsM2, UPRV_LENGTHOF(prefLangsM2), locsToUseM2, UPRV_LENGTHOF(locsToUseM2) },
{ "M3", appleLocsM3, UPRV_LENGTHOF(appleLocsM3), prefLangsM3, UPRV_LENGTHOF(prefLangsM3), locsToUseM3, UPRV_LENGTHOF(locsToUseM3) },
{ "M4", appleLocsM4, UPRV_LENGTHOF(appleLocsM4), prefLangsM4, UPRV_LENGTHOF(prefLangsM4), locsToUseM4, UPRV_LENGTHOF(locsToUseM4) },
{ "M5", appleLocsM5, UPRV_LENGTHOF(appleLocsM5), prefLangsM5, UPRV_LENGTHOF(prefLangsM5), locsToUseM5, UPRV_LENGTHOF(locsToUseM5) },
{ "M6", appleLocsM6, UPRV_LENGTHOF(appleLocsM6), prefLangsM6, UPRV_LENGTHOF(prefLangsM6), locsToUseM6, UPRV_LENGTHOF(locsToUseM6) },
{ "M7", appleLocsMx, UPRV_LENGTHOF(appleLocsMx), prefLangsM7, UPRV_LENGTHOF(prefLangsM7), locsToUseM7, UPRV_LENGTHOF(locsToUseM7) },
{ "M8", appleLocsMx, UPRV_LENGTHOF(appleLocsMx), prefLangsM8, UPRV_LENGTHOF(prefLangsM8), locsToUseM8, UPRV_LENGTHOF(locsToUseM8) },
{ "M9", appleLocsMx, UPRV_LENGTHOF(appleLocsMx), prefLangsM9, UPRV_LENGTHOF(prefLangsM9), locsToUseM9, UPRV_LENGTHOF(locsToUseM9) },
{ "MA", appleLocsMx, UPRV_LENGTHOF(appleLocsMx), prefLangsMA, UPRV_LENGTHOF(prefLangsMA), locsToUseMA, UPRV_LENGTHOF(locsToUseMA) },
{ "MB", appleLocsMx, UPRV_LENGTHOF(appleLocsMx), prefLangsMB, UPRV_LENGTHOF(prefLangsMB), locsToUseMB, UPRV_LENGTHOF(locsToUseMB) },
{ "MC", appleLocsMx, UPRV_LENGTHOF(appleLocsMx), prefLangsMC, UPRV_LENGTHOF(prefLangsMC), locsToUseMC, UPRV_LENGTHOF(locsToUseMC) },
{ "MD", appleLocsMx, UPRV_LENGTHOF(appleLocsMx), prefLangsMD, UPRV_LENGTHOF(prefLangsMD), locsToUseMD, UPRV_LENGTHOF(locsToUseMD) },
{ "ME", appleLocsME, UPRV_LENGTHOF(appleLocsME), prefLangsME, UPRV_LENGTHOF(prefLangsME), locsToUseME, UPRV_LENGTHOF(locsToUseME) },
{ "MF", appleLocsMF, UPRV_LENGTHOF(appleLocsMF), prefLangsMF, UPRV_LENGTHOF(prefLangsMF), locsToUseMF, UPRV_LENGTHOF(locsToUseMF) },
{ "MG", appleLocsMG, UPRV_LENGTHOF(appleLocsMG), prefLangsMG, UPRV_LENGTHOF(prefLangsMG), locsToUseMG, UPRV_LENGTHOF(locsToUseMG) },
{ "MH", appleLocsMH, UPRV_LENGTHOF(appleLocsMH), prefLangsMH, UPRV_LENGTHOF(prefLangsMH), locsToUseMH, UPRV_LENGTHOF(locsToUseMH) },
{ "MI", appleLocsMI, UPRV_LENGTHOF(appleLocsMI), prefLangsMI, UPRV_LENGTHOF(prefLangsMI), locsToUseMI, UPRV_LENGTHOF(locsToUseMI) },
{ "MJ", appleLocsMJ, UPRV_LENGTHOF(appleLocsMJ), prefLangsMJ, UPRV_LENGTHOF(prefLangsMJ), locsToUseMJ, UPRV_LENGTHOF(locsToUseMJ) },
{ "MK", appleLocsMK, UPRV_LENGTHOF(appleLocsMK), prefLangsMK, UPRV_LENGTHOF(prefLangsMK), locsToUseMK, UPRV_LENGTHOF(locsToUseMK) },
{ "ML", appleLocsML, UPRV_LENGTHOF(appleLocsML), prefLangsML, UPRV_LENGTHOF(prefLangsML), locsToUseML, UPRV_LENGTHOF(locsToUseML) },
{ "MM11", appleLocsMM1, UPRV_LENGTHOF(appleLocsMM1), prefLangsMM1, UPRV_LENGTHOF(prefLangsMM1), locsToUseMMptPT, UPRV_LENGTHOF(locsToUseMMptPT) },
{ "MM21", appleLocsMM2, UPRV_LENGTHOF(appleLocsMM2), prefLangsMM1, UPRV_LENGTHOF(prefLangsMM1), locsToUseMMptBR, UPRV_LENGTHOF(locsToUseMMptBR) },
{ "MM31", appleLocsMM3, UPRV_LENGTHOF(appleLocsMM3), prefLangsMM1, UPRV_LENGTHOF(prefLangsMM1), locsToUseMMptPT, UPRV_LENGTHOF(locsToUseMMptPT) },
{ "MM41", appleLocsMM4, UPRV_LENGTHOF(appleLocsMM4), prefLangsMM1, UPRV_LENGTHOF(prefLangsMM1), locsToUseMMptPT, UPRV_LENGTHOF(locsToUseMMptPT) },
{ "MM51", appleLocsMM5, UPRV_LENGTHOF(appleLocsMM5), prefLangsMM1, UPRV_LENGTHOF(prefLangsMM1), locsToUseMMptBR, UPRV_LENGTHOF(locsToUseMMptBR) },
{ "MM61", appleLocsMM6, UPRV_LENGTHOF(appleLocsMM6), prefLangsMM1, UPRV_LENGTHOF(prefLangsMM1), locsToUseMMptPT, UPRV_LENGTHOF(locsToUseMMptPT) },
{ "MM12", appleLocsMM1, UPRV_LENGTHOF(appleLocsMM1), prefLangsMM2, UPRV_LENGTHOF(prefLangsMM2), locsToUseMMptPT, UPRV_LENGTHOF(locsToUseMMptPT) },
{ "MM22", appleLocsMM2, UPRV_LENGTHOF(appleLocsMM2), prefLangsMM2, UPRV_LENGTHOF(prefLangsMM2), locsToUseMMptBR, UPRV_LENGTHOF(locsToUseMMptBR) },
{ "MM32", appleLocsMM3, UPRV_LENGTHOF(appleLocsMM3), prefLangsMM2, UPRV_LENGTHOF(prefLangsMM2), locsToUseMMptBR, UPRV_LENGTHOF(locsToUseMMptBR) },
{ "MM42", appleLocsMM4, UPRV_LENGTHOF(appleLocsMM4), prefLangsMM2, UPRV_LENGTHOF(prefLangsMM2), locsToUseMMptPT, UPRV_LENGTHOF(locsToUseMMptPT) },
{ "MM52", appleLocsMM5, UPRV_LENGTHOF(appleLocsMM5), prefLangsMM2, UPRV_LENGTHOF(prefLangsMM2), locsToUseMMptBR, UPRV_LENGTHOF(locsToUseMMptBR) },
{ "MM62", appleLocsMM6, UPRV_LENGTHOF(appleLocsMM6), prefLangsMM2, UPRV_LENGTHOF(prefLangsMM2), locsToUseMMptBR, UPRV_LENGTHOF(locsToUseMMptBR) },
{ "MM13", appleLocsMM1, UPRV_LENGTHOF(appleLocsMM1), prefLangsMM3, UPRV_LENGTHOF(prefLangsMM3), locsToUseMMptPT, UPRV_LENGTHOF(locsToUseMMptPT) },
{ "MM23", appleLocsMM2, UPRV_LENGTHOF(appleLocsMM2), prefLangsMM3, UPRV_LENGTHOF(prefLangsMM3), locsToUseMMptBR, UPRV_LENGTHOF(locsToUseMMptBR) },
{ "MM33", appleLocsMM3, UPRV_LENGTHOF(appleLocsMM3), prefLangsMM3, UPRV_LENGTHOF(prefLangsMM3), locsToUseMMptBR, UPRV_LENGTHOF(locsToUseMMptBR) },
{ "MM43", appleLocsMM4, UPRV_LENGTHOF(appleLocsMM4), prefLangsMM3, UPRV_LENGTHOF(prefLangsMM3), locsToUseMMptPT, UPRV_LENGTHOF(locsToUseMMptPT) },
{ "MM53", appleLocsMM5, UPRV_LENGTHOF(appleLocsMM5), prefLangsMM3, UPRV_LENGTHOF(prefLangsMM3), locsToUseMMptBR, UPRV_LENGTHOF(locsToUseMMptBR) },
{ "MM63", appleLocsMM6, UPRV_LENGTHOF(appleLocsMM6), prefLangsMM3, UPRV_LENGTHOF(prefLangsMM3), locsToUseMMptBR, UPRV_LENGTHOF(locsToUseMMptBR) },
{ "MM14", appleLocsMM1, UPRV_LENGTHOF(appleLocsMM1), prefLangsMM4, UPRV_LENGTHOF(prefLangsMM4), locsToUseMMptPT, UPRV_LENGTHOF(locsToUseMMptPT) },
{ "MM24", appleLocsMM2, UPRV_LENGTHOF(appleLocsMM2), prefLangsMM4, UPRV_LENGTHOF(prefLangsMM4), locsToUseMMptBR, UPRV_LENGTHOF(locsToUseMMptBR) },
{ "MM34", appleLocsMM3, UPRV_LENGTHOF(appleLocsMM3), prefLangsMM4, UPRV_LENGTHOF(prefLangsMM4), locsToUseMMptPT, UPRV_LENGTHOF(locsToUseMMptPT) },
{ "MM44", appleLocsMM4, UPRV_LENGTHOF(appleLocsMM4), prefLangsMM4, UPRV_LENGTHOF(prefLangsMM4), locsToUseMMptPT, UPRV_LENGTHOF(locsToUseMMptPT) },
{ "MM54", appleLocsMM5, UPRV_LENGTHOF(appleLocsMM5), prefLangsMM4, UPRV_LENGTHOF(prefLangsMM4), locsToUseMMen, UPRV_LENGTHOF(locsToUseMMen) }, { "MM64", appleLocsMM6, UPRV_LENGTHOF(appleLocsMM6), prefLangsMM4, UPRV_LENGTHOF(prefLangsMM4), locsToUseMMptPT, UPRV_LENGTHOF(locsToUseMMptPT) },
{ "MM15", appleLocsMM1, UPRV_LENGTHOF(appleLocsMM1), prefLangsMM5, UPRV_LENGTHOF(prefLangsMM5), locsToUseMMptPT, UPRV_LENGTHOF(locsToUseMMptPT) },
{ "MM25", appleLocsMM2, UPRV_LENGTHOF(appleLocsMM2), prefLangsMM5, UPRV_LENGTHOF(prefLangsMM5), locsToUseMMptBR, UPRV_LENGTHOF(locsToUseMMptBR) },
{ "MM35", appleLocsMM3, UPRV_LENGTHOF(appleLocsMM3), prefLangsMM5, UPRV_LENGTHOF(prefLangsMM5), locsToUseMMptBR, UPRV_LENGTHOF(locsToUseMMptBR) },
{ "MM45", appleLocsMM4, UPRV_LENGTHOF(appleLocsMM4), prefLangsMM5, UPRV_LENGTHOF(prefLangsMM5), locsToUseMMptPT, UPRV_LENGTHOF(locsToUseMMptPT) },
{ "MM55", appleLocsMM5, UPRV_LENGTHOF(appleLocsMM5), prefLangsMM5, UPRV_LENGTHOF(prefLangsMM5), locsToUseMMptBR, UPRV_LENGTHOF(locsToUseMMptBR) },
{ "MM65", appleLocsMM6, UPRV_LENGTHOF(appleLocsMM6), prefLangsMM5, UPRV_LENGTHOF(prefLangsMM5), locsToUseMMptBR, UPRV_LENGTHOF(locsToUseMMptBR) },
{ "MM16", appleLocsMM1, UPRV_LENGTHOF(appleLocsMM1), prefLangsMM6, UPRV_LENGTHOF(prefLangsMM6), locsToUseMMptPT, UPRV_LENGTHOF(locsToUseMMptPT) },
{ "MM26", appleLocsMM2, UPRV_LENGTHOF(appleLocsMM2), prefLangsMM6, UPRV_LENGTHOF(prefLangsMM6), locsToUseMMptBR, UPRV_LENGTHOF(locsToUseMMptBR) },
{ "MM36", appleLocsMM3, UPRV_LENGTHOF(appleLocsMM3), prefLangsMM6, UPRV_LENGTHOF(prefLangsMM6), locsToUseMMptBR, UPRV_LENGTHOF(locsToUseMMptBR) },
{ "MM46", appleLocsMM4, UPRV_LENGTHOF(appleLocsMM4), prefLangsMM6, UPRV_LENGTHOF(prefLangsMM6), locsToUseMMptPT, UPRV_LENGTHOF(locsToUseMMptPT) },
{ "MM56", appleLocsMM5, UPRV_LENGTHOF(appleLocsMM5), prefLangsMM6, UPRV_LENGTHOF(prefLangsMM6), locsToUseMMptBR, UPRV_LENGTHOF(locsToUseMMptBR) },
{ "MM66", appleLocsMM6, UPRV_LENGTHOF(appleLocsMM6), prefLangsMM6, UPRV_LENGTHOF(prefLangsMM6), locsToUseMMptBR, UPRV_LENGTHOF(locsToUseMMptBR) },
{ "MN1", appleLocsMN, UPRV_LENGTHOF(appleLocsMN), prefLangsMN1, UPRV_LENGTHOF(prefLangsMN1), locsToUseMN_U, UPRV_LENGTHOF(locsToUseMN_U) },
{ "MN2", appleLocsMN, UPRV_LENGTHOF(appleLocsMN), prefLangsMN2, UPRV_LENGTHOF(prefLangsMN2), locsToUseMN_U, UPRV_LENGTHOF(locsToUseMN_U) },
{ "MN3", appleLocsMN, UPRV_LENGTHOF(appleLocsMN), prefLangsMN3, UPRV_LENGTHOF(prefLangsMN3), locsToUseMN_U, UPRV_LENGTHOF(locsToUseMN_U) },
{ "MN4", appleLocsMN, UPRV_LENGTHOF(appleLocsMN), prefLangsMN4, UPRV_LENGTHOF(prefLangsMN4), locsToUseMN_U, UPRV_LENGTHOF(locsToUseMN_U) },
{ "MO", appleLocsMO, UPRV_LENGTHOF(appleLocsMO), prefLangsMO1, UPRV_LENGTHOF(prefLangsMO1), locsToUseMO1, UPRV_LENGTHOF(locsToUseMO1) },
{ NULL, NULL, 0, NULL, 0, NULL, 0 }
};
enum { kMaxLocalizationsToUse = 8, kPrintArrayBufSize = 128 };
static void printStringArray(const char **array, int32_t count, char *buf, int32_t bufSize) {
char * bufPtr = buf;
const char * curEntry;
int32_t idx, countMax = bufSize/16;
if (count < 0 || count > countMax) {
count = countMax;
}
for (idx = 0; idx < count && (curEntry = *array++) != NULL; idx++) {
int32_t len = sprintf(bufPtr, "%s\"%.12s\"", (idx > 0)? ", ": "", curEntry);
if (len <= 0) {
break;
}
bufPtr += len;
}
*bufPtr = 0;
}
static UBool equalStringArrays(const char **array1, int32_t count1, const char **array2, int32_t count2) {
const char ** array1Ptr = array1;
const char ** array2Ptr = array2;
int32_t idx;
if (count1 < 0) {
count1 = 0;
while (*array1Ptr++ != NULL) {
count1++;
}
}
if (count2 < 0) {
count2 = 0;
while (*array2Ptr++ != NULL) {
count2++;
}
}
if (count1 != count2) {
return FALSE;
}
for (idx = 0; idx < count1; idx++) {
if (uprv_strcmp(array1[idx], array2[idx]) != 0) {
return FALSE;
}
}
return TRUE;
}
static void TestAppleLocalizationsToUse() {
const AppleLocToUseTestSet * testSetPtr;
const MultiPrefTest * multiSetPtr;
const char * locsToUse[kMaxLocalizationsToUse];
int32_t numLocsToUse;
UErrorCode status;
char printExpected[kPrintArrayBufSize];
char printActual[kPrintArrayBufSize];
for (testSetPtr = altuTestSets; testSetPtr->locAndCountEntriesPtr != NULL; testSetPtr++) {
int32_t iLocSet, iLang;
for (iLocSet = 0; iLocSet < kNumLocSets; iLocSet++) {
for (iLang = 0; iLang < testSetPtr->appleLangAndLocCount; iLang++) {
const char * language = testSetPtr->appleLangAndLocPtr[iLang].language;
const char ** expLocsForSet = testSetPtr->appleLangAndLocPtr[iLang].expLocsForSets[iLocSet];
status = U_ZERO_ERROR;
numLocsToUse = ualoc_localizationsToUse(&language, 1,
testSetPtr->locAndCountEntriesPtr[iLocSet].locs, testSetPtr->locAndCountEntriesPtr[iLocSet].locCount,
locsToUse, kMaxLocalizationsToUse, &status);
if (U_FAILURE(status)) {
log_err("FAIL: ualoc_localizationsToUse testSet %d, locSet %d, lang %s, status %s\n",
testSetPtr-altuTestSets, iLocSet+1, language, u_errorName(status));
} else if (numLocsToUse == 0 && expLocsForSet != NULL) {
printStringArray(expLocsForSet, -1, printExpected, kPrintArrayBufSize);
log_err("FAIL: ualoc_localizationsToUse testSet %d, locSet %d, lang %s, expect {%s}, get no results\n",
testSetPtr-altuTestSets, iLocSet+1, language, printExpected);
} else if (numLocsToUse > 0 && expLocsForSet == NULL) {
printStringArray(locsToUse, numLocsToUse, printActual, kPrintArrayBufSize);
log_err("FAIL: ualoc_localizationsToUse testSet %d, locSet %d, lang %s, expect no results, get {%s}\n",
testSetPtr-altuTestSets, iLocSet+1, language, printActual);
} else if (numLocsToUse > 0 && !equalStringArrays(expLocsForSet, -1, locsToUse, numLocsToUse)) {
printStringArray(expLocsForSet, -1, printExpected, kPrintArrayBufSize);
printStringArray(locsToUse, numLocsToUse, printActual, kPrintArrayBufSize);
log_err("FAIL: ualoc_localizationsToUse testSet %d, locSet %d, lang %s:\n expect {%s}\n get {%s}\n",
testSetPtr-altuTestSets, iLocSet+1, language, printExpected, printActual);
}
}
}
}
for (multiSetPtr = multiTestSets; multiSetPtr->name != NULL; multiSetPtr++) {
status = U_ZERO_ERROR;
numLocsToUse = ualoc_localizationsToUse(multiSetPtr->prefLangs, multiSetPtr->prefLangsCount, multiSetPtr->availLocs, multiSetPtr->availLocsCount, locsToUse, kMaxLocalizationsToUse, &status);
if (U_FAILURE(status)) {
log_err("FAIL: ualoc_localizationsToUse appleLocs%s, langs prefLangs%s, status %s\n", multiSetPtr->name, multiSetPtr->name, u_errorName(status));
} else if (!equalStringArrays(multiSetPtr->locsToUse, multiSetPtr->locsToUseCount, locsToUse, numLocsToUse)) {
printStringArray(multiSetPtr->locsToUse, multiSetPtr->locsToUseCount, printExpected, kPrintArrayBufSize);
printStringArray(locsToUse, numLocsToUse, printActual, kPrintArrayBufSize);
log_err("FAIL: ualoc_localizationsToUse appleLocs%s, langs prefLangs%s:\n expect {%s}\n get {%s}\n",
multiSetPtr->name, multiSetPtr->name, printExpected, printActual);
}
}
}