X-Git-Url: https://git.saurik.com/apple/icu.git/blobdiff_plain/a961784b162035fa3dc7db15b9576b6cd23462ab..4f1e1a09ce4daed860e35d359ce2fceccb0764e8:/icuSources/test/cintltst/cloctst.c diff --git a/icuSources/test/cintltst/cloctst.c b/icuSources/test/cintltst/cloctst.c index 5a90cb67..662af053 100644 --- a/icuSources/test/cintltst/cloctst.c +++ b/icuSources/test/cintltst/cloctst.c @@ -1,3 +1,5 @@ +// © 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /******************************************************************** * COPYRIGHT: * Copyright (c) 1997-2016, International Business Machines Corporation and @@ -17,6 +19,7 @@ #include #include #include "cintltst.h" +#include "cmemory.h" #include "cstring.h" #include "uparse.h" #include "uresimp.h" @@ -37,21 +40,28 @@ #include "unicode/uldnames.h" #include "unicode/parseerr.h" /* may not be included with some uconfig switches */ #include "udbgutil.h" +#if !U_PLATFORM_HAS_WIN32_API #include "unicode/ualoc.h" /* Apple-specific */ +#endif 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); +#if !U_PLATFORM_HAS_WIN32_API static void TestGetLanguagesForRegion(void); static void TestGetAppleParent(void); static void TestAppleLocalizationsToUse(void); +#endif void PrintDataTable(); @@ -86,12 +96,12 @@ static const char* const rawData2[LOCALE_INFO_SIZE][LOCALE_SIZE] = { /* display script code (English) */ { "", "", "", "", "", "Simplified Han", "", "", "" }, /* display country (English) */ - { "United States", "France", "Spain", "Greece", "Norway", "China", "Germany", "", "Japan" }, + { "United States", "France", "Spain", "Greece", "Norway", "China mainland", "Germany", "", "Japan" }, /* display variant (English) */ { "", "", "", "", "NY", "", "", "", "" }, /* display name (English) */ { "English (United States)", "French (France)", "Catalan (Spain)", - "Greek (Greece)", "Norwegian (Norway, NY)", "Chinese (Simplified, China)", + "Greek (Greece)", "Norwegian (Norway, NY)", "Chinese (Simplified, China mainland)", "German (Germany, Sort Order=Phonebook Sort Order)", "Spanish (Sort Order=Traditional Sort Order)", "Japanese (Japan, Calendar=Japanese Calendar)" }, /* display language (French) */ @@ -99,12 +109,12 @@ static const char* const rawData2[LOCALE_INFO_SIZE][LOCALE_SIZE] = { /* display script code (French) */ { "", "", "", "", "", "sinogrammes simplifi\\u00e9s", "", "", "" }, /* display country (French) */ - { "\\u00C9tats-Unis", "France", "Espagne", "Gr\\u00E8ce", "Norv\\u00E8ge", "Chine", "Allemagne", "", "Japon" }, + { "\\u00C9tats-Unis", "France", "Espagne", "Gr\\u00E8ce", "Norv\\u00E8ge", "Chine continentale", "Allemagne", "", "Japon" }, /* display variant (French) */ { "", "", "", "", "NY", "", "", "", "" }, /* display name (French) */ { "anglais (\\u00C9tats-Unis)", "fran\\u00E7ais (France)", "catalan (Espagne)", - "grec (Gr\\u00E8ce)", "norv\\u00E9gien (Norv\\u00E8ge, NY)", "chinois (simplifi\\u00e9, Chine)", + "grec (Gr\\u00E8ce)", "norv\\u00E9gien (Norv\\u00E8ge, NY)", "chinois (simplifi\\u00e9, Chine continentale)", "allemand (Allemagne, ordre de tri=ordre de l\\u2019annuaire)", "espagnol (ordre de tri=ordre traditionnel)", "japonais (Japon, calendrier=calendrier japonais)" }, /* display language (Catalan) */ @@ -112,12 +122,12 @@ static const char* const rawData2[LOCALE_INFO_SIZE][LOCALE_SIZE] = { /* display script code (Catalan) */ { "", "", "", "", "", "han simplificat", "", "", "" }, /* display country (Catalan) */ - { "Estats Units", "Fran\\u00E7a", "Espanya", "Gr\\u00E8cia", "Noruega", "Xina", "Alemanya", "", "Jap\\u00F3" }, + { "Estats Units", "Fran\\u00E7a", "Espanya", "Gr\\u00E8cia", "Noruega", "Xina continental", "Alemanya", "", "Jap\\u00F3" }, /* display variant (Catalan) */ { "", "", "", "", "NY", "", "", "", "" }, /* display name (Catalan) */ { "angl\\u00E8s (Estats Units)", "franc\\u00E8s (Fran\\u00E7a)", "catal\\u00E0 (Espanya)", - "grec (Gr\\u00E8cia)", "noruec (Noruega, NY)", "xin\\u00E8s (simplificat, Xina)", + "grec (Gr\\u00E8cia)", "noruec (Noruega, NY)", "xin\\u00E8s (simplificat, Xina continental)", "alemany (Alemanya, ordenaci\\u00F3=ordre de la guia telef\\u00F2nica)", "espanyol (ordenaci\\u00F3=ordre tradicional)", "japon\\u00E8s (Jap\\u00F3, calendari=calendari japon\\u00e8s)" }, /* display language (Greek) */ @@ -142,7 +152,7 @@ static const char* const rawData2[LOCALE_INFO_SIZE][LOCALE_SIZE] = { "\\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", + "\\u039A\\u03AF\\u03BD\\u03B1 \\u03B7\\u03C0\\u03B5\\u03B9\\u03C1\\u03C9\\u03C4\\u03B9\\u03BA\\u03AE", "\\u0393\\u03B5\\u03C1\\u03BC\\u03B1\\u03BD\\u03AF\\u03B1", "", "\\u0399\\u03B1\\u03C0\\u03C9\\u03BD\\u03AF\\u03B1" @@ -156,7 +166,7 @@ static const char* const rawData2[LOCALE_INFO_SIZE][LOCALE_SIZE] = { "\\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\\u03bf, \\u039A\\u03AF\\u03BD\\u03B1)", + "\\u039A\\u03B9\\u03BD\\u03B5\\u03B6\\u03B9\\u03BA\\u03AC (\\u0391\\u03c0\\u03bb\\u03bf\\u03c0\\u03bf\\u03b9\\u03b7\\u03bc\\u03ad\\u03bd\\u03b1, \\u039A\\u03AF\\u03BD\\u03B1 \\u03B7\\u03C0\\u03B5\\u03B9\\u03C1\\u03C9\\u03C4\\u03B9\\u03BA\\u03AE)", "\\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)" @@ -238,6 +248,7 @@ void addLocaleTest(TestNode** root) TESTCASE(TestDisplayNameWarning); TESTCASE(TestNonexistentLanguageExemplars); TESTCASE(TestLocDataErrorCodeChaining); + TESTCASE(TestLocDataWithRgTag); TESTCASE(TestLanguageExemplarsFallbacks); TESTCASE(TestCalendar); TESTCASE(TestDateFormat); @@ -260,9 +271,13 @@ void addLocaleTest(TestNode** root) TESTCASE(TestToLegacyKey); TESTCASE(TestToUnicodeLocaleType); TESTCASE(TestToLegacyType); + TESTCASE(TestBadLocaleIDs); + TESTCASE(TestUldnNameVariants); +#if !U_PLATFORM_HAS_WIN32_API TESTCASE(TestGetLanguagesForRegion); TESTCASE(TestGetAppleParent); TESTCASE(TestAppleLocalizationsToUse); +#endif } @@ -598,7 +613,7 @@ static int32_t UCharsToEscapedAscii(const UChar* utext, int32_t len, char* resul /*t*/ {'t', 0x09}, /*v*/ {'v', 0x0b} }; - static const int32_t ESCAPE_MAP_LENGTH = sizeof(ESCAPE_MAP)/sizeof(ESCAPE_MAP[0]); + 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' @@ -1701,9 +1716,9 @@ static void TestKeywordVariants(void) { static const struct { const char *localeID; - const char *expectedLocaleID; - const char *expectedLocaleIDNoKeywords; - const char *expectedCanonicalID; + const char *expectedLocaleID; /* uloc_getName */ + const char *expectedLocaleIDNoKeywords; /* uloc_getBaseName */ + const char *expectedCanonicalID; /* uloc_canonicalize */ const char *expectedKeywords[10]; int32_t numKeywords; UErrorCode expectedStatus; /* from uloc_openKeywords */ @@ -1720,20 +1735,29 @@ static void TestKeywordVariants(void) { "de_DE@euro", "de_DE@euro", - "de_DE", + "de_DE@euro", /* we probably should strip off the POSIX style variant @euro see #11690 */ "de_DE@currency=EUR", {"","","","","","",""}, 0, U_INVALID_FORMAT_ERROR /* must have '=' after '@' */ }, { - "de_DE@euro;collation=phonebook", - "de_DE", /* error result; bad format */ - "de_DE", /* error result; bad format */ - "de_DE", /* error result; bad format */ + "de_DE@euro;collation=phonebook", /* The POSIX style variant @euro cannot be combined with key=value? */ + "de_DE", /* getName returns de_DE - should be INVALID_FORMAT_ERROR? */ + "de_DE", /* getBaseName returns de_DE - should be INVALID_FORMAT_ERROR? see #11690 */ + "de_DE", /* canonicalize returns de_DE - should be INVALID_FORMAT_ERROR? */ {"","","","","","",""}, 0, U_INVALID_FORMAT_ERROR + }, + { + "de_DE@collation=", + 0, /* expected getName to fail */ + "de_DE", /* getBaseName returns de_DE - should be INVALID_FORMAT_ERROR? see #11690 */ + 0, /* expected canonicalize to fail */ + {"","","","","","",""}, + 0, + U_INVALID_FORMAT_ERROR /* must have '=' after '@' */ } }; UErrorCode status = U_ZERO_ERROR; @@ -1746,7 +1770,7 @@ static void TestKeywordVariants(void) const char *keyword = NULL; int32_t keywordLen = 0; - for(i = 0; i < sizeof(testCases)/sizeof(testCases[0]); i++) { + for(i = 0; i < UPRV_LENGTHOF(testCases); i++) { status = U_ZERO_ERROR; *buffer = 0; keywords = uloc_openKeywords(testCases[i].localeID, &status); @@ -1780,19 +1804,58 @@ static void TestKeywordVariants(void) } uenum_close(keywords); } + + status = U_ZERO_ERROR; resultLen = uloc_getName(testCases[i].localeID, buffer, 256, &status); - (void)resultLen; /* Suppress set but not used warning. */ - 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); + 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 (uprv_strcmp(testCases[i].expectedCanonicalID, buffer) != 0) { - log_err("Expected uloc_canonicalize(\"%s\") => \"%s\"; got \"%s\"\n", - testCases[i].localeID, testCases[i].expectedCanonicalID, buffer); - } + 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) @@ -1800,27 +1863,38 @@ static void TestKeywordVariantParsing(void) static const struct { const char *localeID; const char *keyword; - const char *expectedValue; + const char *expectedValue; /* NULL if failure is expected */ } testCases[] = { - { "de_DE@ C o ll A t i o n = Phonebook ", "c o ll a t i o n", "Phonebook" }, + { "de_DE@ C o ll A t i o n = Phonebook ", "c o ll a t i o n", NULL }, /* malformed key name */ { "de_DE", "collation", ""}, { "de_DE@collation=PHONEBOOK", "collation", "PHONEBOOK" }, { "de_DE@currency = euro; CoLLaTion = PHONEBOOk", "collatiON", "PHONEBOOk" }, }; - UErrorCode status = U_ZERO_ERROR; - + UErrorCode status; int32_t i = 0; int32_t resultLen = 0; char buffer[256]; - for(i = 0; i < sizeof(testCases)/sizeof(testCases[0]); i++) { + 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; /* Suppress set but not used warning. */ - if(uprv_strcmp(testCases[i].expectedValue, buffer) != 0) { - log_err("Expected to extract \"%s\" from \"%s\" for keyword \"%s\". Got \"%s\" instead\n", - testCases[i].expectedValue, testCases[i].localeID, testCases[i].keyword, buffer); + if (testCases[i].expectedValue) { + /* expect success */ + 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)) { + /* expect failure */ + log_err("Expected failure but got success from \"%s\" for keyword \"%s\". Got \"%s\"\n", + testCases[i].localeID, testCases[i].keyword, buffer); + } } } @@ -1873,7 +1947,40 @@ static const struct { /* 4. removal of only item */ { "de@collation=phonebook", "collation", NULL, "de" }, #endif - { "de@collation=phonebook", "Currency", "CHF", "de@collation=phonebook;currency=CHF" } + { "de@collation=phonebook", "Currency", "CHF", "de@collation=phonebook;currency=CHF" }, + /* cases with legal extra spacing */ + /*31*/{ "en_US@ calendar = islamic", "calendar", "japanese", "en_US@calendar=japanese" }, + /*32*/{ "en_US@ calendar = gregorian ; collation = phonebook", "calendar", "japanese", "en_US@calendar=japanese;collation=phonebook" }, + /*33*/{ "en_US@ calendar = islamic", "currency", "CHF", "en_US@calendar=islamic;currency=CHF" }, + /*34*/{ "en_US@ currency = CHF", "calendar", "japanese", "en_US@calendar=japanese;currency=CHF" }, + /* cases in which setKeywordValue expected to fail (implied by NULL for expected); locale need not be canonical */ + /*35*/{ "en_US@calendar=gregorian;", "calendar", "japanese", NULL }, + /*36*/{ "en_US@calendar=gregorian;=", "calendar", "japanese", NULL }, + /*37*/{ "en_US@calendar=gregorian;currency=", "calendar", "japanese", NULL }, + /*38*/{ "en_US@=", "calendar", "japanese", NULL }, + /*39*/{ "en_US@=;", "calendar", "japanese", NULL }, + /*40*/{ "en_US@= ", "calendar", "japanese", NULL }, + /*41*/{ "en_US@ =", "calendar", "japanese", NULL }, + /*42*/{ "en_US@ = ", "calendar", "japanese", NULL }, + /*43*/{ "en_US@=;calendar=gregorian", "calendar", "japanese", NULL }, + /*44*/{ "en_US@= calen dar = gregorian", "calendar", "japanese", NULL }, + /*45*/{ "en_US@= calendar = greg orian", "calendar", "japanese", NULL }, + /*46*/{ "en_US@=;cal...endar=gregorian", "calendar", "japanese", NULL }, + /*47*/{ "en_US@=;calendar=greg...orian", "calendar", "japanese", NULL }, + /*48*/{ "en_US@calendar=gregorian", "cale ndar", "japanese", NULL }, + /*49*/{ "en_US@calendar=gregorian", "calendar", "japa..nese", NULL }, + /* cases in which getKeywordValue and setKeyword expected to fail (implied by NULL for value and expected) */ + /*50*/{ "en_US@=", "calendar", NULL, NULL }, + /*51*/{ "en_US@=;", "calendar", NULL, NULL }, + /*52*/{ "en_US@= ", "calendar", NULL, NULL }, + /*53*/{ "en_US@ =", "calendar", NULL, NULL }, + /*54*/{ "en_US@ = ", "calendar", NULL, NULL }, + /*55*/{ "en_US@=;calendar=gregorian", "calendar", NULL, NULL }, + /*56*/{ "en_US@= calen dar = gregorian", "calendar", NULL, NULL }, + /*57*/{ "en_US@= calendar = greg orian", "calendar", NULL, NULL }, + /*58*/{ "en_US@=;cal...endar=gregorian", "calendar", NULL, NULL }, + /*59*/{ "en_US@=;calendar=greg...orian", "calendar", NULL, NULL }, + /*60*/{ "en_US@calendar=gregorian", "cale ndar", NULL, NULL }, }; @@ -1885,32 +1992,60 @@ static void TestKeywordSet(void) char cbuffer[1024]; - for(i = 0; i < sizeof(kwSetTestCases)/sizeof(kwSetTestCases[0]); i++) { - UErrorCode status = U_ZERO_ERROR; - memset(buffer,'%',1023); - strcpy(buffer, kwSetTestCases[i].l); + 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); } - /* sanity check test case results for canonicity */ + /* sanity check test case results for canonicity */ 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: got error %s\n", i, u_errorName(status)); - continue; - } - if(strcmp(buffer,kwSetTestCases[i].x) || ((int32_t)strlen(buffer)!=resultLen)) { - log_err("FAIL: #%d: %s + [%s=%s] -> %s (%d) expected %s (%d)\n", i, kwSetTestCases[i].l, kwSetTestCases[i].k, + 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 { + /* test cases expected to result in error */ + 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); + } + } + } } } @@ -2107,7 +2242,7 @@ static void TestCanonicalization(void) int32_t i, j, resultLen = 0, origResultLen; char buffer[256]; - for (i=0; i < sizeof(testCases)/sizeof(testCases[0]); i++) { + 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; @@ -2169,7 +2304,7 @@ static void TestDisplayKeywords(void) {0x0053, 0x006f, 0x0072, 0x0074, 0x0069, 0x0065, 0x0072, 0x0075, 0x006e, 0x0067, 0x0000} }, }; - for(i = 0; i < sizeof(testCases)/sizeof(testCases[0]); i++) { + for(i = 0; i < UPRV_LENGTHOF(testCases); i++) { UErrorCode status = U_ZERO_ERROR; const char* keyword =NULL; int32_t keywordLen = 0; @@ -2251,7 +2386,7 @@ static void TestDisplayKeywordValues(void){ {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 < sizeof(testCases)/sizeof(testCases[0]); i++) { + for(i = 0; i < UPRV_LENGTHOF(testCases); i++) { UErrorCode status = U_ZERO_ERROR; const char* keyword =NULL; int32_t keywordLen = 0; @@ -2380,7 +2515,7 @@ static void TestGetBaseName(void) { char baseName[256]; UErrorCode status = U_ZERO_ERROR; - for(i = 0; i < sizeof(testCases)/sizeof(testCases[0]); i++) { + for(i = 0; i < UPRV_LENGTHOF(testCases); i++) { baseNameLen = uloc_getBaseName(testCases[i].localeID, baseName, 256, &status); (void)baseNameLen; /* Suppress set but not used warning. */ if(strcmp(testCases[i].baseName, baseName)) { @@ -2418,7 +2553,7 @@ static void TestDisplayNameWarning(void) { int32_t size; UErrorCode status = U_ZERO_ERROR; - size = uloc_getDisplayLanguage("qqq", "kl", name, sizeof(name)/sizeof(name[0]), &status); + size = uloc_getDisplayLanguage("qqq", "kl", name, UPRV_LENGTHOF(name), &status); (void)size; /* Suppress set but not used warning. */ if (status != U_USING_DEFAULT_WARNING) { log_err("For language \"qqq\" in locale \"kl\", expecting U_USING_DEFAULT_WARNING, but got %s\n", @@ -2684,6 +2819,36 @@ static void TestLocDataErrorCodeChaining(void) { } } +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 } /* terminator */ +}; + +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) { /* Test that en_US fallsback, but en doesn't fallback. */ UErrorCode ec = U_ZERO_ERROR; @@ -2721,18 +2886,22 @@ static void TestAcceptLanguage(void) { const char *icuSet; /**< ? */ const char *expect; /**< The expected locale result */ UAcceptResult res; /**< The expected error code */ + UErrorCode expectStatus; /**< expected status */ } tests[] = { - /*0*/{ 0, NULL, "mt_MT", ULOC_ACCEPT_VALID }, - /*1*/{ 1, NULL, "en", ULOC_ACCEPT_VALID }, - /*2*/{ 2, NULL, "en", ULOC_ACCEPT_FALLBACK }, - /*3*/{ 3, NULL, "", ULOC_ACCEPT_FAILED }, - /*4*/{ 4, NULL, "es", ULOC_ACCEPT_VALID }, - - /*5*/{ 5, NULL, "en", ULOC_ACCEPT_VALID }, /* XF */ - /*6*/{ 6, NULL, "ja", ULOC_ACCEPT_FALLBACK }, /* XF */ - /*7*/{ 7, NULL, "zh", ULOC_ACCEPT_FALLBACK }, /* XF */ + /*0*/{ 0, NULL, "mt_MT", ULOC_ACCEPT_VALID, U_ZERO_ERROR}, + /*1*/{ 1, NULL, "en", ULOC_ACCEPT_VALID, U_ZERO_ERROR}, + /*2*/{ 2, NULL, "en", ULOC_ACCEPT_FALLBACK, U_ZERO_ERROR}, + /*3*/{ 3, NULL, "", ULOC_ACCEPT_FAILED, U_ZERO_ERROR}, + /*4*/{ 4, NULL, "es", ULOC_ACCEPT_VALID, U_ZERO_ERROR}, + /*5*/{ 5, NULL, "en", ULOC_ACCEPT_VALID, U_ZERO_ERROR}, /* XF */ + /*6*/{ 6, NULL, "ja", ULOC_ACCEPT_FALLBACK, U_ZERO_ERROR}, /* XF */ + /*7*/{ 7, NULL, "zh", ULOC_ACCEPT_FALLBACK, U_ZERO_ERROR}, /* XF */ + /*8*/{ 8, NULL, "", ULOC_ACCEPT_FAILED, U_ZERO_ERROR }, /* */ + /*9*/{ 9, NULL, "", ULOC_ACCEPT_FAILED, U_ZERO_ERROR }, /* */ + /*10*/{10, NULL, "", ULOC_ACCEPT_FAILED, U_BUFFER_OVERFLOW_ERROR }, /* */ + /*11*/{11, NULL, "", ULOC_ACCEPT_FAILED, U_BUFFER_OVERFLOW_ERROR }, /* */ }; - const int32_t numTests = sizeof(tests)/sizeof(tests[0]); + const int32_t numTests = UPRV_LENGTHOF(tests); static const char *http[] = { /*0*/ "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", /*1*/ "ja;q=0.5, en;q=0.8, tlh", @@ -2746,10 +2915,25 @@ static void TestAcceptLanguage(void) { "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", - /*5*/ "zh-xx;q=0.9, en;q=0.6", /*6*/ "ja-JA", /*7*/ "zh-xx;q=0.9", + /*08*/ "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", // 156 + /*09*/ "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB", // 157 (this hits U_STRING_NOT_TERMINATED_WARNING ) + /*10*/ "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABC", // 158 + /*11*/ "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", // 163 bytes }; for(i=0;i0)&&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)); + } + 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)); + } } } } @@ -2970,7 +3159,7 @@ static void TestOrientation() }; size_t i = 0; - for (; i < sizeof(toTest) / sizeof(toTest[0]); ++i) { + for (; i < UPRV_LENGTHOF(toTest); ++i) { UErrorCode statusCO = U_ZERO_ERROR; UErrorCode statusLO = U_ZERO_ERROR; const char* const localeId = toTest[i].localeId; @@ -3157,7 +3346,7 @@ static void TestGetLocaleForLCID() { status = U_ZERO_ERROR; } - length = uloc_getLocaleForLCID(lcid, temp2, sizeof(temp2)/sizeof(char), &status); + 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; @@ -3167,7 +3356,7 @@ static void TestGetLocaleForLCID() { log_err(" uloc_getLocaleForLCID(0x0409): returned length %d does not match preflight length %d\n", length, lengthPre); } - length = uloc_getLocaleForLCID(0x12345, temp2, sizeof(temp2)/sizeof(char), &status); + 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)); } @@ -3181,7 +3370,7 @@ static void TestGetLocaleForLCID() { log_verbose("Testing %s ......\n", testLocale); sscanf(rawData2[LCID][i], "%x", &lcid); - length = uloc_getLocaleForLCID(lcid, temp2, sizeof(temp2)/sizeof(char), &status); + 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; @@ -3193,7 +3382,7 @@ static void TestGetLocaleForLCID() { } /* Compare language, country, script */ - length = uloc_getLanguage(temp2, temp3, sizeof(temp3)/sizeof(char), &status); + 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; @@ -3202,7 +3391,7 @@ static void TestGetLocaleForLCID() { 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, sizeof(temp3)/sizeof(char), &status); + 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; @@ -3211,7 +3400,7 @@ static void TestGetLocaleForLCID() { 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, sizeof(temp3)/sizeof(char), &status); + 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; @@ -3320,6 +3509,21 @@ const char* const basic_maximize_data[][2] = { }, { "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" } }; @@ -5165,6 +5369,10 @@ const char* const full_data[][3] = { "zh_AQ", "zh_Hans_AQ", "zh_AQ" + }, { + "zh_MY", + "zh_Hans_MY", + "zh_MY" }, { "zh_Zzzz", "zh_Hans_CN", @@ -5525,7 +5733,7 @@ static void TestLikelySubtags() char buffer[ULOC_FULLNAME_CAPACITY + ULOC_KEYWORD_AND_VALUES_CAPACITY + 1]; int32_t i = 0; - for (; i < sizeof(basic_maximize_data) / sizeof(basic_maximize_data[0]); ++i) + for (; i < UPRV_LENGTHOF(basic_maximize_data); ++i) { UErrorCode status = U_ZERO_ERROR; const char* const minimal = basic_maximize_data[i][0]; @@ -5551,7 +5759,7 @@ static void TestLikelySubtags() } } - for (i = 0; i < sizeof(basic_minimize_data) / sizeof(basic_minimize_data[0]); ++i) { + for (i = 0; i < UPRV_LENGTHOF(basic_minimize_data); ++i) { UErrorCode status = U_ZERO_ERROR; const char* const maximal = basic_minimize_data[i][0]; @@ -5578,7 +5786,7 @@ static void TestLikelySubtags() } } - for (i = 0; i < sizeof(full_data) / sizeof(full_data[0]); ++i) { + for (i = 0; i < UPRV_LENGTHOF(full_data); ++i) { UErrorCode status = U_ZERO_ERROR; const char* const minimal = full_data[i][0]; @@ -5604,7 +5812,7 @@ static void TestLikelySubtags() } } - for (i = 0; i < sizeof(full_data) / sizeof(full_data[0]); ++i) { + for (i = 0; i < UPRV_LENGTHOF(full_data); ++i) { UErrorCode status = U_ZERO_ERROR; const char* const maximal = full_data[i][1]; @@ -5634,7 +5842,7 @@ static void TestLikelySubtags() } } - for (i = 0; i < sizeof(maximizeErrors) / sizeof(maximizeErrors[0]); ++i) { + for (i = 0; i < UPRV_LENGTHOF(maximizeErrors); ++i) { UErrorCode status = U_ZERO_ERROR; const char* const minimal = maximizeErrors[i].tag; @@ -5668,7 +5876,7 @@ static void TestLikelySubtags() } } - for (i = 0; i < sizeof(minimizeErrors) / sizeof(minimizeErrors[0]); ++i) { + for (i = 0; i < UPRV_LENGTHOF(minimizeErrors); ++i) { UErrorCode status = U_ZERO_ERROR; const char* const maximal = minimizeErrors[i].tag; @@ -5744,6 +5952,13 @@ const char* const locale_to_langtag[][3] = { {"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"}, + /* #12671 */ + {"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} }; @@ -5809,7 +6024,6 @@ static const struct { const char *locID; int32_t len; } langtag_to_locale[] = { - {"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}, {"en", "en", FULL_LENGTH}, {"en-us", "en_US", FULL_LENGTH}, {"und-US", "_US", FULL_LENGTH}, @@ -5853,9 +6067,20 @@ static const struct { {"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}, + /* #12761 */ + {"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} }; @@ -5977,6 +6202,7 @@ static void TestToUnicodeLocaleType(void) {"calendar", "islamicc", "islamic-civil"}, /* bcp type alias */ {"colalternate", "NON-IGNORABLE", "noignore"}, {"colcaselevel", "yes", "true"}, + {"rg", "GBzzzz", "$IN"}, {"tz", "america/new_york", "usnyc"}, {"tz", "Asia/Kolkata", "inccu"}, {"timezone", "navajo", "usden"}, @@ -6028,6 +6254,7 @@ static void TestToLegacyType(void) {"calendar", "islamicc", "islamic-civil"}, /* bcp type alias */ {"colalternate", "noignore", "non-ignorable"}, {"colcaselevel", "true", "yes"}, + {"rg", "gbzzzz", "gbzzzz"}, {"tz", "usnyc", "America/New_York"}, {"tz", "inccu", "Asia/Calcutta"}, {"timezone", "usden", "America/Denver"}, @@ -6065,6 +6292,8 @@ static void TestToLegacyType(void) } } 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); } } } @@ -6099,11 +6328,273 @@ static void TestIsRightToLeft() { } } +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 }, + /* add more in the future */ + { NULL, NULL, NULL, U_ZERO_ERROR } /* terminator */ +}; + +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; // NULL to terminate a list of these + UldnNameType nameType; + const char * expectResult; +} UldnItem; + +typedef struct { + const char * displayLocale; + const UDisplayContext * displayOptions; // set of 3 UDisplayContext items + 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" }, +}; + +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" }, +}; + +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" }, +}; + +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); + } +} + +#if !U_PLATFORM_HAS_WIN32_API /* Apple-specific, test for Apple-specific function ualoc_getAppleParent */ 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", @@ -6121,9 +6612,11 @@ static const char* localesAndAppleParent[] = { "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-NZ", "en_GB", + "en-MV", "en_GB", + "en-NZ", "en_AU", "en-PK", "en_GB", "en-SG", "en_GB", "en-SH", "en_GB", @@ -6134,6 +6627,14 @@ static const char* localesAndAppleParent[] = { "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", @@ -6144,6 +6645,9 @@ static const char* localesAndAppleParent[] = { "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", @@ -6212,6 +6716,7 @@ static void TestGetLanguagesForRegion() { // zh_Hans 0.90 UALANGSTATUS_OFFICIAL // wuu 0.06 Wu // hsn 0.06 Xiang + // yue 0.043 Yue including Cantonese // hak 0.023 Hakka // nan 0.019 Minnan // gan 0.017 Gan @@ -6546,26 +7051,33 @@ static const LangAndExpLocs appleLangAndLoc[] = { { "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-AU", { l1_Eng, l3_en_AUGB_, l3_en_AUGB_, l3_en_AUGB_, l4_en_AUGB001_, l4_en_AUGB001_ } }, + { "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-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-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-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-NZ", { 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-IL", { l1_Eng, l1_en, l1_en, l1_en, l2_en_001_, l2_en_001_ } }, - { "en-001", { l1_Eng, l1_en, l1_en, l1_en, l2_en_001_, l2_en_001_ } }, + { "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,/*TODO*/ l1_en, l1_en } }, { "en-US-POSIX", { l1_Eng, l1_en, l1_en, l2_en_US_, l1_en, l1_en } }, @@ -6579,12 +7091,24 @@ static const LangAndExpLocs appleLangAndLoc[] = { { "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 } }, @@ -6615,7 +7139,7 @@ static const LangAndExpLocs appleLangAndLoc[] = { { "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, 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 } }, @@ -6764,15 +7288,206 @@ static const AppleLocToUseTestSet altuTestSets[] = { /* tests for multiple prefs sets */ -static const char * appleLocsM[] = { "en", "en_GB", "pt", "pt_PT", "zh_CN", "zh_Hant" }; -static const char * prefLangsM[] = { "tlh", "zh_HK", "zh_SG", "zh_Hans", "pt_BR", "pt_PT", "en_IN", "en" }; -static const char * locsToUseM[] = { "zh_Hant" }; -enum { - kNumAppleLocsM = UPRV_LENGTHOF(appleLocsM), - kNumPrefLangsM = UPRV_LENGTHOF(prefLangsM), - kNumLocsToUseM = UPRV_LENGTHOF(locsToUseM), +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" }; + +// Tests from first pass at , 2015-11-18 + +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" }; + +// Tests from second pass at , 2015-12-08 +// Per Karan M +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" }; +// Per Peter E; expected result changed from "en-US" to "de-CH" per +static const char * appleLocsM6[] = { "de-CH", "en-US" }; +static const char * prefLangsM6[] = { "de-DE", "en-US" }; +static const char * locsToUseM6[] = { "de-CH" }; +// The following is used for M7-MD +static const char * appleLocsMx[] = { "de-DE", "en-AU", "es-ES", "fr-FR", "hi-IN", "pt-BR", "zh-HK", "zh-TW" }; +// Per Karan M +static const char * prefLangsM7[] = { "fr-ES", "en-AU" }; +static const char * locsToUseM7[] = { "fr-FR" }; +// Per Karan M +static const char * prefLangsM8[] = { "de-IT", "en-AU" }; +static const char * locsToUseM8[] = { "de-DE" }; +// Per Karan M +static const char * prefLangsM9[] = { "hi-US", "en-AU" }; +static const char * locsToUseM9[] = { "hi-IN" }; +// Per Karan M +static const char * prefLangsMA[] = { "en-IN", "zh-HK" }; +static const char * locsToUseMA[] = { "en-AU" }; +// Per Karan M +static const char * prefLangsMB[] = { "pt-PT", "en-AU" }; +static const char * locsToUseMB[] = { "en-AU" }; +// per Paul B: +static const char * prefLangsMC[] = { "pt-PT", "ar" }; +static const char * locsToUseMC[] = { "pt-BR" }; +// Per Karan M +static const char * prefLangsMD[] = { "zh-CN", "en-AU" }; +static const char * locsToUseMD[] = { "en-AU" }; +// Per Karan M +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" }; +// Per Peter E in diagnosis for and +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" }; +// Per Karan M in +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" }; +// Per +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" }; +// Per +static const char * appleLocsMI[] = { "unk", "en-US", "ar-SA" }; +static const char * prefLangsMI[] = { "ar-US" }; +static const char * locsToUseMI[] = { "ar-SA" }; +// Per - first for comparison with zh, then real test +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" }; +// Per +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" }; +// Per +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" }; +// Per +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" }; +// Per +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) }, // want en, see + { "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 } }; + /* general enums */ enum { kMaxLocalizationsToUse = 8, kPrintArrayBufSize = 128 }; @@ -6801,6 +7516,7 @@ static void printStringArray(const char **array, int32_t count, char *buf, int32 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) { @@ -6816,7 +7532,6 @@ static UBool equalStringArrays(const char **array1, int32_t count1, const char * if (count1 != count2) { return FALSE; } - int32_t idx; for (idx = 0; idx < count1; idx++) { if (uprv_strcmp(array1[idx], array2[idx]) != 0) { return FALSE; @@ -6827,6 +7542,7 @@ static UBool equalStringArrays(const char **array1, int32_t count1, const char * static void TestAppleLocalizationsToUse() { const AppleLocToUseTestSet * testSetPtr; + const MultiPrefTest * multiSetPtr; const char * locsToUse[kMaxLocalizationsToUse]; int32_t numLocsToUse; UErrorCode status; @@ -6838,9 +7554,9 @@ static void TestAppleLocalizationsToUse() { for (iLocSet = 0; iLocSet < kNumLocSets; iLocSet++) { for (iLang = 0; iLang < testSetPtr->appleLangAndLocCount; iLang++) { - status = U_ZERO_ERROR; 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, @@ -6866,16 +7582,17 @@ static void TestAppleLocalizationsToUse() { } } - - status = U_ZERO_ERROR; - numLocsToUse = ualoc_localizationsToUse(prefLangsM, kNumPrefLangsM, appleLocsM, kNumAppleLocsM, locsToUse, kMaxLocalizationsToUse, &status); - if (U_FAILURE(status)) { - log_err("FAIL: ualoc_localizationsToUse appleLocsM, langs prefLangsM, status %s\n", u_errorName(status)); - } else if (!equalStringArrays(locsToUseM, kNumLocsToUseM, locsToUse, numLocsToUse)) { - printStringArray(locsToUseM, kNumLocsToUseM, printExpected, kPrintArrayBufSize); - printStringArray(locsToUse, numLocsToUse, printActual, kPrintArrayBufSize); - log_err("FAIL: ualoc_localizationsToUse appleLocsM, langs prefLangsM:\n expect {%s}\n get {%s}\n", - 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); + } + } } +#endif