From 086ee675a86e60a7d4e1129afb593ac70ac9aa7b Mon Sep 17 00:00:00 2001 From: Peter Edberg Date: Mon, 15 Feb 2016 17:58:23 +0000 Subject: [PATCH] ICU-12085 manually integrate branch > trunk (had network problems committing updated branch) X-SVN-Rev: 38311 --- icu4c/source/common/ucurr.cpp | 14 +++----- icu4c/source/common/uloc.cpp | 52 ++++++++++++++++++++++++++- icu4c/source/common/uloc_keytype.cpp | 35 +++++++++++++++++- icu4c/source/common/ulocimp.h | 31 +++++++++++++++- icu4c/source/i18n/calendar.cpp | 18 ++++------ icu4c/source/i18n/ucal.cpp | 14 +++----- icu4c/source/i18n/ulocdata.c | 10 ++---- icu4c/source/test/cintltst/ccaltst.c | 15 ++++++-- icu4c/source/test/cintltst/cloctst.c | 34 +++++++++++++++++- icu4c/source/test/cintltst/cnmdptst.c | 39 ++++++++++++++++++-- 10 files changed, 214 insertions(+), 48 deletions(-) diff --git a/icu4c/source/common/ucurr.cpp b/icu4c/source/common/ucurr.cpp index fce330569ad..40a5591c429 100644 --- a/icu4c/source/common/ucurr.cpp +++ b/icu4c/source/common/ucurr.cpp @@ -26,6 +26,7 @@ #include "uresimp.h" #include "ulist.h" #include "ureslocs.h" +#include "ulocimp.h" //#define UCURR_DEBUG_EQUIV 1 #ifdef UCURR_DEBUG_EQUIV @@ -367,7 +368,7 @@ idForLocale(const char* locale, char* countryAndVariant, int capacity, UErrorCod // Extract the country name and variant name. We only // recognize two variant names, EURO and PREEURO. char variant[ULOC_FULLNAME_CAPACITY]; - uloc_getCountry(locale, countryAndVariant, capacity, ec); + ulocimp_getRegionForSupplementalData(locale, FALSE, countryAndVariant, capacity, ec); uloc_getVariant(locale, variant, sizeof(variant), ec); if (variant[0] != 0) { variantType = (uint32_t)(0 == uprv_strcmp(variant, VAR_EURO)) @@ -2472,15 +2473,8 @@ static const UEnumeration defaultKeywordValues = { U_CAPI UEnumeration *U_EXPORT2 ucurr_getKeywordValuesForLocale(const char *key, const char *locale, UBool commonlyUsed, UErrorCode* status) { // Resolve region - char prefRegion[ULOC_FULLNAME_CAPACITY] = ""; - int32_t prefRegionLength = 0; - prefRegionLength = uloc_getCountry(locale, prefRegion, sizeof(prefRegion), status); - if (prefRegionLength == 0) { - char loc[ULOC_FULLNAME_CAPACITY] = ""; - uloc_addLikelySubtags(locale, loc, sizeof(loc), status); - - /*prefRegionLength = */ uloc_getCountry(loc, prefRegion, sizeof(prefRegion), status); - } + char prefRegion[ULOC_COUNTRY_CAPACITY]; + ulocimp_getRegionForSupplementalData(locale, TRUE, prefRegion, sizeof(prefRegion), status); // Read value from supplementalData UList *values = ulist_createEmptyList(status); diff --git a/icu4c/source/common/uloc.cpp b/icu4c/source/common/uloc.cpp index 32a06bf84fc..8959d253863 100644 --- a/icu4c/source/common/uloc.cpp +++ b/icu4c/source/common/uloc.cpp @@ -1,6 +1,6 @@ /* ********************************************************************** -* Copyright (C) 1997-2015, International Business Machines +* Copyright (C) 1997-2016, International Business Machines * Corporation and others. All Rights Reserved. ********************************************************************** * @@ -1348,6 +1348,56 @@ ulocimp_getCountry(const char *localeID, return idLen; } +// the following must at least allow for rg key value (6) plus terminator (1). +#define ULOC_RG_BUFLEN 8 + +U_CAPI int32_t U_EXPORT2 +ulocimp_getRegionForSupplementalData(const char *localeID, UBool inferRegion, + char *region, int32_t regionCapacity, UErrorCode* status) +{ + if (U_FAILURE(*status)) { + return 0; + } + char rgBuf[ULOC_RG_BUFLEN]; + UErrorCode rgStatus = U_ZERO_ERROR; + + // First check for rg keyword value + int32_t rgLen = uloc_getKeywordValue(localeID, "rg", rgBuf, ULOC_RG_BUFLEN, &rgStatus); + if (U_FAILURE(rgStatus) || rgLen != 6) { + rgLen = 0; + } else { + // rgBuf guaranteed to be zero terminated here, with text len 6 + char *rgPtr = rgBuf; + for (; *rgPtr!= 0; rgPtr++) { + *rgPtr = uprv_toupper(*rgPtr); + } + rgLen = (uprv_strcmp(rgBuf+2, "ZZZZ") == 0)? 2: 0; + } + + if (rgLen == 0) { + // No valid rg keyword value, try for unicode_region_subtag + rgLen = uloc_getCountry(localeID, rgBuf, ULOC_RG_BUFLEN, status); + if (U_FAILURE(*status)) { + rgLen = 0; + } else if (rgLen == 0 && inferRegion) { + // no unicode_region_subtag but inferRegion TRUE, try likely subtags + char locBuf[ULOC_FULLNAME_CAPACITY]; + rgStatus = U_ZERO_ERROR; + (void)uloc_addLikelySubtags(localeID, locBuf, ULOC_FULLNAME_CAPACITY, &rgStatus); + if (U_SUCCESS(rgStatus)) { + rgLen = uloc_getCountry(locBuf, rgBuf, ULOC_RG_BUFLEN, status); + if (U_FAILURE(*status)) { + rgLen = 0; + } + } + } + } + + rgBuf[rgLen] = 0; + uprv_strncpy(region, rgBuf, regionCapacity); + return u_terminateChars(region, regionCapacity, rgLen, status); +} + /** * @param needSeparator if true, then add leading '_' if any variants * are added to 'variant' diff --git a/icu4c/source/common/uloc_keytype.cpp b/icu4c/source/common/uloc_keytype.cpp index adca57821de..811da505a31 100644 --- a/icu4c/source/common/uloc_keytype.cpp +++ b/icu4c/source/common/uloc_keytype.cpp @@ -24,7 +24,8 @@ static icu::UVector* gLocExtTypeEntries = NULL; typedef enum { SPECIALTYPE_NONE = 0, SPECIALTYPE_CODEPOINTS = 1, - SPECIALTYPE_REORDER_CODE = 2 + SPECIALTYPE_REORDER_CODE = 2, + SPECIALTYPE_RG_KEY_VALUE = 4 } SpecialType; typedef struct LocExtKeyData { @@ -215,6 +216,10 @@ initFromResourceBundle(UErrorCode& sts) { specialTypes |= SPECIALTYPE_REORDER_CODE; continue; } + if (uprv_strcmp(legacyTypeId, "RG_KEY_VALUE") == 0) { + specialTypes |= SPECIALTYPE_RG_KEY_VALUE; + continue; + } if (isTZ) { // a timezone key uses a colon instead of a slash in the resource. @@ -450,6 +455,28 @@ isSpecialTypeReorderCode(const char* val) { return (subtagLen >=3 && subtagLen <=8); } +static UBool +isSpecialTypeRgKeyValue(const char* val) { + int32_t subtagLen = 0; + const char* p = val; + while (*p) { + if (*p == '-') { + if (subtagLen != 6) { + return FALSE; + } + subtagLen = 0; + } else if ( (subtagLen < 2 && uprv_isASCIILetter(*p)) || + (subtagLen >= 2 && (*p == 'Z' || *p == 'z')) ) { + subtagLen++; + } else { + return FALSE; + } + p++; + } + return (subtagLen == 6); + return TRUE; +} + U_CFUNC const char* ulocimp_toBcpKey(const char* key) { if (!init()) { @@ -506,6 +533,9 @@ ulocimp_toBcpType(const char* key, const char* type, UBool* isKnownKey, UBool* i if (!matched && keyData->specialTypes & SPECIALTYPE_REORDER_CODE) { matched = isSpecialTypeReorderCode(type); } + if (!matched && keyData->specialTypes & SPECIALTYPE_RG_KEY_VALUE) { + matched = isSpecialTypeRgKeyValue(type); + } if (matched) { if (isSpecialType != NULL) { *isSpecialType = TRUE; @@ -548,6 +578,9 @@ ulocimp_toLegacyType(const char* key, const char* type, UBool* isKnownKey, UBool if (!matched && keyData->specialTypes & SPECIALTYPE_REORDER_CODE) { matched = isSpecialTypeReorderCode(type); } + if (!matched && keyData->specialTypes & SPECIALTYPE_RG_KEY_VALUE) { + matched = isSpecialTypeRgKeyValue(type); + } if (matched) { if (isSpecialType != NULL) { *isSpecialType = TRUE; diff --git a/icu4c/source/common/ulocimp.h b/icu4c/source/common/ulocimp.h index 164a730c005..d06db3fb2ac 100644 --- a/icu4c/source/common/ulocimp.h +++ b/icu4c/source/common/ulocimp.h @@ -1,6 +1,6 @@ /* ********************************************************************** -* Copyright (C) 2004-2014, International Business Machines +* Copyright (C) 2004-2016, International Business Machines * Corporation and others. All Rights Reserved. ********************************************************************** */ @@ -59,6 +59,35 @@ ulocimp_getCountry(const char *localeID, char *country, int32_t countryCapacity, const char **pEnd); +/** + * Get the region to use for supplemental data lookup. Uses + * (1) any region specified by locale tag "rg"; if none then + * (2) any unicode_region_tag in the locale ID; if none then + * (3) if inferRegion is TRUE, the region suggested by + * getLikelySubtags on the localeID. + * If no region is found, returns length 0. + * + * @param localeID + * The complete locale ID (with keywords) from which + * to get the region to use for supplemental data. + * @param inferRegion + * If TRUE, will try to infer region from localeID if + * no other region is found. + * @param region + * Buffer in which to put the region ID found; should + * have a capacity at least ULOC_COUNTRY_CAPACITY. + * @param regionCapacity + * The actual capacity of the region buffer. + * @param status + * Pointer to in/out UErrorCode value for latest status. + * @return + * The length of any region code found, or 0 if none. + * @internal ICU 57 + */ +U_CAPI int32_t U_EXPORT2 +ulocimp_getRegionForSupplementalData(const char *localeID, UBool inferRegion, + char *region, int32_t regionCapacity, UErrorCode* status); + U_CAPI const char * U_EXPORT2 locale_getKeywordsStart(const char *localeID); diff --git a/icu4c/source/i18n/calendar.cpp b/icu4c/source/i18n/calendar.cpp index d07269d75c8..1cd18d3a4fa 100644 --- a/icu4c/source/i18n/calendar.cpp +++ b/icu4c/source/i18n/calendar.cpp @@ -1,6 +1,6 @@ /* ******************************************************************************* -* Copyright (C) 1997-2015, International Business Machines Corporation and * +* Copyright (C) 1997-2016, International Business Machines Corporation and * * others. All Rights Reserved. * ******************************************************************************* * @@ -59,6 +59,7 @@ #include "olsontz.h" #include "sharedcalendar.h" #include "unifiedcache.h" +#include "ulocimp.h" #if !UCONFIG_NO_SERVICE static icu::ICULocaleService* gService = NULL; @@ -284,17 +285,10 @@ static ECalType getCalendarTypeForLocale(const char *locid) { // when calendar keyword is not available or not supported, read supplementalData // to get the default calendar type for the locale's region char region[ULOC_COUNTRY_CAPACITY]; - int32_t regionLen = 0; - regionLen = uloc_getCountry(canonicalName, region, sizeof(region) - 1, &status); - if (regionLen == 0) { - char fullLoc[256]; - uloc_addLikelySubtags(locid, fullLoc, sizeof(fullLoc) - 1, &status); - regionLen = uloc_getCountry(fullLoc, region, sizeof(region) - 1, &status); - } + (void)ulocimp_getRegionForSupplementalData(canonicalName, TRUE, region, sizeof(region), &status); if (U_FAILURE(status)) { return CALTYPE_GREGORIAN; } - region[regionLen] = 0; // Read preferred calendar values from supplementalData calendarPreference UResourceBundle *rb = ures_openDirect(NULL, "supplementalData", &status); @@ -3806,11 +3800,13 @@ Calendar::setWeekData(const Locale& desiredLocale, const char *type, UErrorCode& return; } - + char region[ULOC_COUNTRY_CAPACITY]; + (void)ulocimp_getRegionForSupplementalData(desiredLocale.getName(), TRUE, region, sizeof(region), &status); + // Read week data values from supplementalData week data UResourceBundle *rb = ures_openDirect(NULL, "supplementalData", &status); ures_getByKey(rb, "weekData", rb, &status); - UResourceBundle *weekData = ures_getByKey(rb, useLocale.getCountry(), NULL, &status); + UResourceBundle *weekData = ures_getByKey(rb, region, NULL, &status); if (status == U_MISSING_RESOURCE_ERROR && rb != NULL) { status = U_ZERO_ERROR; weekData = ures_getByKey(rb, "001", NULL, &status); diff --git a/icu4c/source/i18n/ucal.cpp b/icu4c/source/i18n/ucal.cpp index dbbd711a3e3..754eef9a6a5 100644 --- a/icu4c/source/i18n/ucal.cpp +++ b/icu4c/source/i18n/ucal.cpp @@ -1,6 +1,6 @@ /* ******************************************************************************* -* Copyright (C) 1996-2015, International Business Machines +* Copyright (C) 1996-2016, International Business Machines * Corporation and others. All Rights Reserved. ******************************************************************************* */ @@ -25,6 +25,7 @@ #include "ustrenum.h" #include "uenumimp.h" #include "ulist.h" +#include "ulocimp.h" U_NAMESPACE_USE @@ -669,15 +670,8 @@ static const char * const CAL_TYPES[] = { U_CAPI UEnumeration* U_EXPORT2 ucal_getKeywordValuesForLocale(const char * /* key */, const char* locale, UBool commonlyUsed, UErrorCode *status) { // Resolve region - char prefRegion[ULOC_FULLNAME_CAPACITY] = ""; - int32_t prefRegionLength = 0; - prefRegionLength = uloc_getCountry(locale, prefRegion, sizeof(prefRegion), status); - if (prefRegionLength == 0) { - char loc[ULOC_FULLNAME_CAPACITY] = ""; - uloc_addLikelySubtags(locale, loc, sizeof(loc), status); - - prefRegionLength = uloc_getCountry(loc, prefRegion, sizeof(prefRegion), status); - } + char prefRegion[ULOC_COUNTRY_CAPACITY]; + (void)ulocimp_getRegionForSupplementalData(locale, TRUE, prefRegion, sizeof(prefRegion), status); // Read preferred calendar values from supplementalData calendarPreference UResourceBundle *rb = ures_openDirect(NULL, "supplementalData", status); diff --git a/icu4c/source/i18n/ulocdata.c b/icu4c/source/i18n/ulocdata.c index 48902f8655c..1f602444bd0 100644 --- a/icu4c/source/i18n/ulocdata.c +++ b/icu4c/source/i18n/ulocdata.c @@ -1,7 +1,7 @@ /* ****************************************************************************** * * -* Copyright (C) 2003-2013, International Business Machines * +* Copyright (C) 2003-2016, International Business Machines * * Corporation and others. All Rights Reserved. * * * ****************************************************************************** @@ -21,6 +21,7 @@ #include "unicode/ulocdata.h" #include "uresimp.h" #include "ureslocs.h" +#include "ulocimp.h" #define MEASUREMENT_SYSTEM "MeasurementSystem" #define PAPER_SIZE "PaperSize" @@ -189,16 +190,11 @@ ulocdata_getDelimiter(ULocaleData *uld, ULocaleDataDelimiterType type, } static UResourceBundle * measurementTypeBundleForLocale(const char *localeID, const char *measurementType, UErrorCode *status){ - char fullLoc[ULOC_FULLNAME_CAPACITY]; char region[ULOC_COUNTRY_CAPACITY]; UResourceBundle *rb; UResourceBundle *measTypeBundle = NULL; - /* The following code is basically copied from Calendar::setWeekData and - * Calendar::getCalendarTypeForLocale with adjustments for resource name - */ - uloc_addLikelySubtags(localeID, fullLoc, ULOC_FULLNAME_CAPACITY, status); - uloc_getCountry(fullLoc, region, ULOC_COUNTRY_CAPACITY, status); + ulocimp_getRegionForSupplementalData(localeID, TRUE, region, ULOC_COUNTRY_CAPACITY, status); rb = ures_openDirect(NULL, "supplementalData", status); ures_getByKey(rb, "measurementData", rb, status); diff --git a/icu4c/source/test/cintltst/ccaltst.c b/icu4c/source/test/cintltst/ccaltst.c index 4571cda1b42..909815eb3ac 100644 --- a/icu4c/source/test/cintltst/ccaltst.c +++ b/icu4c/source/test/cintltst/ccaltst.c @@ -1,5 +1,5 @@ /******************************************************************** - * Copyright (c) 1997-2014, International Business Machines + * Copyright (c) 1997-2016, International Business Machines * Corporation and others. All Rights Reserved. ******************************************************************** * @@ -85,6 +85,12 @@ static const UCalGetTypeTest ucalGetTypeTests[] = { { "th_TH", UCAL_DEFAULT, "buddhist" }, { "th-TH-u-ca-gregory", UCAL_DEFAULT, "gregorian" }, { "ja_JP@calendar=japanese", UCAL_GREGORIAN, "gregorian" }, + { "fr_CH", UCAL_DEFAULT, "gregorian" }, + { "fr_SA", UCAL_DEFAULT, "islamic-umalqura" }, + { "fr_CH@rg=sazzzz", UCAL_DEFAULT, "islamic-umalqura" }, + { "fr_CH@calendar=japanese;rg=sazzzz", UCAL_DEFAULT, "japanese" }, + { "fr_TH@rg=SA", UCAL_DEFAULT, "buddhist" }, /* ignore malformed rg tag */ + { "th@rg=SA", UCAL_DEFAULT, "buddhist" }, /* ignore malformed rg tag */ { "", UCAL_GREGORIAN, "gregorian" }, { NULL, UCAL_GREGORIAN, "gregorian" }, { NULL, 0, NULL } /* terminator */ @@ -1546,7 +1552,7 @@ void TestGregorianChange() { } static void TestGetKeywordValuesForLocale() { -#define PREFERRED_SIZE 15 +#define PREFERRED_SIZE 16 #define MAX_NUMBER_OF_KEYWORDS 5 const char *PREFERRED[PREFERRED_SIZE][MAX_NUMBER_OF_KEYWORDS+1] = { { "root", "gregorian", NULL, NULL, NULL, NULL }, @@ -1564,8 +1570,9 @@ static void TestGetKeywordValuesForLocale() { { "en@calendar=islamic", "gregorian", NULL, NULL, NULL, NULL }, { "zh_TW", "gregorian", "roc", "chinese", NULL, NULL }, { "ar_IR", "persian", "gregorian", "islamic", "islamic-civil", "islamic-tbla" }, + { "th@rg=SAZZZZ", "islamic-umalqura", "gregorian", "islamic", "islamic-rgsa", NULL }, }; - const int32_t EXPECTED_SIZE[PREFERRED_SIZE] = { 1, 1, 1, 1, 2, 2, 2, 5, 5, 2, 2, 2, 1, 3, 5 }; + const int32_t EXPECTED_SIZE[PREFERRED_SIZE] = { 1, 1, 1, 1, 2, 2, 2, 5, 5, 2, 2, 2, 1, 3, 5, 4 }; UErrorCode status = U_ZERO_ERROR; int32_t i, size, j; UEnumeration *all, *pref; @@ -1724,6 +1731,8 @@ static const TestDaysOfWeekList testDays[] = { { "en_US", daysOfWeek_en_US, sizeof(daysOfWeek_en_US)/sizeof(daysOfWeek_en_US[0]) }, { "ar_OM", daysOfWeek_ar_OM, sizeof(daysOfWeek_ar_OM)/sizeof(daysOfWeek_ar_OM[0]) }, { "hi_IN", daysOfWeek_hi_IN, sizeof(daysOfWeek_hi_IN)/sizeof(daysOfWeek_hi_IN[0]) }, + { "en_US@rg=OMZZZZ", daysOfWeek_ar_OM, sizeof(daysOfWeek_ar_OM)/sizeof(daysOfWeek_ar_OM[0]) }, + { "hi@rg=USZZZZ", daysOfWeek_en_US, sizeof(daysOfWeek_en_US)/sizeof(daysOfWeek_en_US[0]) }, }; static const UChar logDateFormat[] = { 0x0045,0x0045,0x0045,0x0020,0x004D,0x004D,0x004D,0x0020,0x0064,0x0064,0x0020,0x0079, diff --git a/icu4c/source/test/cintltst/cloctst.c b/icu4c/source/test/cintltst/cloctst.c index 7531ffe46e7..bb61ed6bb65 100644 --- a/icu4c/source/test/cintltst/cloctst.c +++ b/icu4c/source/test/cintltst/cloctst.c @@ -1,6 +1,6 @@ /******************************************************************** * COPYRIGHT: - * Copyright (c) 1997-2015, International Business Machines Corporation and + * Copyright (c) 1997-2016, International Business Machines Corporation and * others. All Rights Reserved. ********************************************************************/ /***************************************************************************** @@ -40,6 +40,7 @@ static void TestNullDefault(void); static void TestNonexistentLanguageExemplars(void); static void TestLocDataErrorCodeChaining(void); +static void TestLocDataWithRgTag(void); static void TestLanguageExemplarsFallbacks(void); static void TestDisplayNameBrackets(void); @@ -232,6 +233,7 @@ void addLocaleTest(TestNode** root) TESTCASE(TestDisplayNameWarning); TESTCASE(TestNonexistentLanguageExemplars); TESTCASE(TestLocDataErrorCodeChaining); + TESTCASE(TestLocDataWithRgTag); TESTCASE(TestLanguageExemplarsFallbacks); TESTCASE(TestCalendar); TESTCASE(TestDateFormat); @@ -2705,6 +2707,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; diff --git a/icu4c/source/test/cintltst/cnmdptst.c b/icu4c/source/test/cintltst/cnmdptst.c index 8b3cbd61d24..b096b7732be 100644 --- a/icu4c/source/test/cintltst/cnmdptst.c +++ b/icu4c/source/test/cintltst/cnmdptst.c @@ -1,6 +1,6 @@ /******************************************************************** * COPYRIGHT: - * Copyright (c) 1997-2014, International Business Machines Corporation + * Copyright (c) 1997-2016, International Business Machines Corporation * and others. All Rights Reserved. ********************************************************************/ /******************************************************************************* @@ -25,6 +25,7 @@ #include "unicode/uloc.h" #include "unicode/unum.h" #include "unicode/ustring.h" +#include "unicode/putil.h" #include "cintltst.h" #include "cnmdptst.h" #include "cmemory.h" @@ -868,7 +869,7 @@ static void TestCurrencyKeywords(void) } static void TestGetKeywordValuesForLocale(void) { -#define PREFERRED_SIZE 12 +#define PREFERRED_SIZE 15 #define MAX_NUMBER_OF_KEYWORDS 4 const char *PREFERRED[PREFERRED_SIZE][MAX_NUMBER_OF_KEYWORDS] = { { "root", "USD", "USN", NULL }, @@ -884,9 +885,19 @@ static void TestGetKeywordValuesForLocale(void) { { "en@currency=CAD", "USD", "USN", NULL }, { "fr@currency=zzz", "EUR", NULL, NULL }, { "de_DE@currency=DEM", "EUR", NULL, NULL }, + { "en_US@rg=THZZZZ", "THB", NULL, NULL }, + { "de@rg=USZZZZ", "USD", "USN", NULL }, + { "en_US@currency=CAD;rg=THZZZZ", "THB", NULL, NULL }, }; const int32_t EXPECTED_SIZE[PREFERRED_SIZE] = { - 2, 2, 2, 2, 1, 1, 1, 1, 2, 2, 1, 1 + 2, 2, 2, 2, 1, 1, 1, 1, 2, 2, 1, 1, 1, 2, 1 + }; + /* ucurr_forLocale results for same locales; "" if no result expected */ + const char *FORLOCALE[PREFERRED_SIZE] = { + "", "", "USD", "", + "THB", "", "EUR", "", + "ILS", "CAD", "ZZZ", "DEM", + "THB", "USD", "CAD" }; UErrorCode status = U_ZERO_ERROR; int32_t i, j, size; @@ -905,6 +916,10 @@ static void TestGetKeywordValuesForLocale(void) { } for (i = 0; i < PREFERRED_SIZE; i++) { + UChar getCurrU[4]; + int32_t getCurrLen; + + status = U_ZERO_ERROR; pref = NULL; all = NULL; loc = PREFERRED[i][0]; @@ -972,6 +987,24 @@ static void TestGetKeywordValuesForLocale(void) { } uenum_close(all); + + status = U_ZERO_ERROR; + getCurrLen = ucurr_forLocale(loc, getCurrU, 4, &status); + if(U_FAILURE(status)) { + if (FORLOCALE[i][0] != 0) { + log_err("ERROR: ucurr_forLocale %s, status %s\n", loc, u_errorName(status)); + } + } else if (getCurrLen != 3) { + if (FORLOCALE[i][0] != 0 || getCurrLen != -1) { + log_err("ERROR: ucurr_forLocale %s, returned len %d\n", loc, getCurrLen); + } + } else { + char getCurrB[4]; + u_UCharsToChars(getCurrU, getCurrB, 4); + if ( uprv_strncmp(getCurrB, FORLOCALE[i], 4) != 0 ) { + log_err("ERROR: ucurr_forLocale %s, expected %s, got %s\n", loc, FORLOCALE[i], getCurrB); + } + } } uenum_close(ALL); -- 2.40.0