ICU-21316 Fix bug under different default locales
See #1399
diff --git a/icu4c/source/common/locid.cpp b/icu4c/source/common/locid.cpp
index a00a7ab..2804e36 100644
--- a/icu4c/source/common/locid.cpp
+++ b/icu4c/source/common/locid.cpp
@@ -1333,7 +1333,10 @@
if (firstSpace != nullptr) {
// If there are are more than one region in the replacement.
// We need to check which one match based on the language.
- Locale l(language, nullptr, script);
+ // Cannot use nullptr for language because that will construct
+ // the default locale, in that case, use "und" to get the correct
+ // locale.
+ Locale l(language == nullptr ? "und" : language, nullptr, script);
l.addLikelySubtags(status);
const char* likelyRegion = l.getCountry();
CharString* item = nullptr;
diff --git a/icu4c/source/i18n/ulocdata.cpp b/icu4c/source/i18n/ulocdata.cpp
index 7f4e7b9..68b9e0c 100644
--- a/icu4c/source/i18n/ulocdata.cpp
+++ b/icu4c/source/i18n/ulocdata.cpp
@@ -172,7 +172,7 @@
return 0;
}
- delimiter = ures_getStringByKey(delimiterBundle, delimiterKeys[type], &len, &localStatus);
+ delimiter = ures_getStringByKeyWithFallback(delimiterBundle, delimiterKeys[type], &len, &localStatus);
ures_close(delimiterBundle);
if ( (localStatus == U_USING_DEFAULT_WARNING) && uld->noSubstitute ) {
diff --git a/icu4c/source/test/cintltst/cloctst.c b/icu4c/source/test/cintltst/cloctst.c
index 63a8d11..373c2d5 100644
--- a/icu4c/source/test/cintltst/cloctst.c
+++ b/icu4c/source/test/cintltst/cloctst.c
@@ -704,9 +704,19 @@
/* test that the default locale has a display name for its own language */
errorCode=U_ZERO_ERROR;
length=uloc_getDisplayLanguage(NULL, NULL, buffer, UPRV_LENGTHOF(buffer), &errorCode);
+ /* check <=3 to reject getting the language code as a display name */
if(U_FAILURE(errorCode) || (length<=3 && buffer[0]<=0x7f)) {
- /* check <=3 to reject getting the language code as a display name */
- log_data_err("unable to get a display string for the language of the default locale - %s (Are you missing data?)\n", u_errorName(errorCode));
+ const char* defaultLocale = uloc_getDefault();
+ for (int32_t i = 0, count = uloc_countAvailable(); i < count; i++) {
+ /* Only report error if the default locale is in the available list */
+ if (uprv_strcmp(defaultLocale, uloc_getAvailable(i)) == 0) {
+ log_data_err(
+ "unable to get a display string for the language of the "
+ "default locale - %s (Are you missing data?)\n",
+ u_errorName(errorCode));
+ break;
+ }
+ }
}
/* test that we get the language code itself for an unknown language, and a default warning */
diff --git a/icu4c/source/test/cintltst/crestst.c b/icu4c/source/test/cintltst/crestst.c
index b7af6ea..0803010 100644
--- a/icu4c/source/test/cintltst/crestst.c
+++ b/icu4c/source/test/cintltst/crestst.c
@@ -149,6 +149,15 @@
void TestResourceBundles()
{
+ // The test expectation only works if the default locale is not one of the
+ // locale bundle in the testdata which have those info. Therefore, we skip
+ // the test if the default locale is te, sh, mc, or them with subtags.
+ if ( uprv_strncmp(uloc_getDefault(), "te", 2) == 0 ||
+ uprv_strncmp(uloc_getDefault(), "sh", 2) == 0 ||
+ uprv_strncmp(uloc_getDefault(), "mc", 2) == 0) {
+ return;
+ }
+
UErrorCode status = U_ZERO_ERROR;
loadTestData(&status);
if(U_FAILURE(status)) {
@@ -595,16 +604,19 @@
ures_close(casing);
/*
- * verify that ures_open("ne") finds the root bundle but
- * ures_openDirect("ne") does not
+ * verify that ures_open("ne") finds the root bundle or default locale
+ * bundle but ures_openDirect("ne") does not.
*/
errorCode=U_ZERO_ERROR;
ne=ures_open("testdata", "ne", &errorCode);
if(U_FAILURE(errorCode)) {
log_data_err("ures_open(\"ne\") failed (expected to get root): %s\n", u_errorName(errorCode));
}
- if(errorCode!=U_USING_DEFAULT_WARNING || 0!=uprv_strcmp("root", ures_getLocale(ne, &errorCode))) {
- log_err("ures_open(\"ne\") found something other than \"root\" - %s\n", u_errorName(errorCode));
+ if( errorCode!=U_USING_DEFAULT_WARNING ||
+ (0!=uprv_strcmp("root", ures_getLocale(ne, &errorCode)) &&
+ 0!=uprv_strcmp(uloc_getDefault(), ures_getLocale(ne, &errorCode)))) {
+ log_err("ures_open(\"ne\") found something other than \"root\" "
+ "or default locale \"%s\" - %s\n", uloc_getDefault(), u_errorName(errorCode));
}
ures_close(ne);
diff --git a/icu4c/source/test/cintltst/creststn.c b/icu4c/source/test/cintltst/creststn.c
index 88ea652..3155172 100644
--- a/icu4c/source/test/cintltst/creststn.c
+++ b/icu4c/source/test/cintltst/creststn.c
@@ -1509,6 +1509,15 @@
static void TestResourceBundles()
{
+ // The test expectation only works if the default locale is not one of the
+ // locale bundle in the testdata which have those info. Therefore, we skip
+ // the test if the default locale is te, sh, mc, or them with subtags.
+ if ( uprv_strncmp(uloc_getDefault(), "te", 2) == 0 ||
+ uprv_strncmp(uloc_getDefault(), "sh", 2) == 0 ||
+ uprv_strncmp(uloc_getDefault(), "mc", 2) == 0) {
+ return;
+ }
+
UErrorCode status = U_ZERO_ERROR;
loadTestData(&status);
if(U_FAILURE(status)) {
@@ -1532,6 +1541,15 @@
static void TestConstruction1()
{
+ // The test expectation only works if the default locale is not one of the
+ // locale bundle in the testdata which have those info. Therefore, we skip
+ // the test if the default locale is te, sh, mc, or them with subtags.
+ if ( uprv_strncmp(uloc_getDefault(), "te", 2) == 0 ||
+ uprv_strncmp(uloc_getDefault(), "sh", 2) == 0 ||
+ uprv_strncmp(uloc_getDefault(), "mc", 2) == 0) {
+ return;
+ }
+
UResourceBundle *test1 = 0, *test2 = 0,*empty = 0;
const UChar *result1, *result2;
UErrorCode status= U_ZERO_ERROR;