#include "ulocimp.h"
#include "ustr_imp.h"
+/**
+ * These are the canonical strings for unknown languages, scripts and regions.
+ **/
+static const char* const unknownLanguage = "und";
+static const char* const unknownScript = "Zzzz";
+static const char* const unknownRegion = "ZZ";
+
/**
* This function looks for the localeID in the likelySubtags resource.
*
UErrorCode tmpErr = U_ZERO_ERROR;
icu::LocalUResourceBundlePointer subtags(ures_openDirect(NULL, "likelySubtags", &tmpErr));
if (U_SUCCESS(tmpErr)) {
+ icu::CharString und;
+ if (localeID != NULL) {
+ if (*localeID == '\0') {
+ localeID = unknownLanguage;
+ } else if (*localeID == '_') {
+ und.append(unknownLanguage, *err);
+ und.append(localeID, *err);
+ if (U_FAILURE(*err)) {
+ return NULL;
+ }
+ localeID = und.data();
+ }
+ }
s = ures_getStringByKey(subtags.getAlias(), localeID, &resLen, &tmpErr);
if (U_FAILURE(tmpErr)) {
}
else {
u_UCharsToChars(s, buffer, resLen + 1);
+ if (resLen >= 3 &&
+ uprv_strnicmp(buffer, unknownLanguage, 3) == 0 &&
+ (resLen == 3 || buffer[3] == '_')) {
+ uprv_memmove(buffer, buffer + 3, resLen - 3 + 1);
+ }
result = buffer;
}
} else {
const char* tag,
int32_t tagLength,
char* buffer,
- int32_t* bufferLength) {
+ int32_t* bufferLength,
+ UBool withSeparator) {
- if (*bufferLength > 0) {
+ if (withSeparator) {
buffer[*bufferLength] = '_';
++(*bufferLength);
}
*bufferLength += tagLength;
}
-/**
- * These are the canonical strings for unknown languages, scripts and regions.
- **/
-static const char* const unknownLanguage = "und";
-static const char* const unknownScript = "Zzzz";
-static const char* const unknownRegion = "ZZ";
-
/**
* Create a tag string from the supplied parameters. The lang, script and region
* parameters may be NULL pointers. If they are, their corresponding length parameters
lang,
langLength,
tagBuffer,
- &tagLength);
+ &tagLength,
+ /*withSeparator=*/FALSE);
}
else if (alternateTags == NULL) {
/*
- * Append the value for an unknown language, if
+ * Use the empty string for an unknown language, if
* we found no language.
*/
- appendTag(
- unknownLanguage,
- (int32_t)uprv_strlen(unknownLanguage),
- tagBuffer,
- &tagLength);
}
else {
/*
}
else if (alternateLangLength == 0) {
/*
- * Append the value for an unknown language, if
+ * Use the empty string for an unknown language, if
* we found no language.
*/
- appendTag(
- unknownLanguage,
- (int32_t)uprv_strlen(unknownLanguage),
- tagBuffer,
- &tagLength);
}
else {
appendTag(
alternateLang,
alternateLangLength,
tagBuffer,
- &tagLength);
+ &tagLength,
+ /*withSeparator=*/FALSE);
}
}
script,
scriptLength,
tagBuffer,
- &tagLength);
+ &tagLength,
+ /*withSeparator=*/TRUE);
}
else if (alternateTags != NULL) {
/*
alternateScript,
alternateScriptLength,
tagBuffer,
- &tagLength);
+ &tagLength,
+ /*withSeparator=*/TRUE);
}
}
region,
regionLength,
tagBuffer,
- &tagLength);
+ &tagLength,
+ /*withSeparator=*/TRUE);
regionAppended = TRUE;
}
alternateRegion,
alternateRegionLength,
tagBuffer,
- &tagLength);
+ &tagLength,
+ /*withSeparator=*/TRUE);
regionAppended = TRUE;
}
*langLength = subtagLength;
/*
- * If no language was present, use the value of unknownLanguage
- * instead. Otherwise, move past any separator.
+ * If no language was present, use the empty string instead.
+ * Otherwise, move past any separator.
*/
- if (*langLength == 0) {
- uprv_strcpy(
- lang,
- unknownLanguage);
- *langLength = (int32_t)uprv_strlen(lang);
- }
if (_isIDSeparator(*position)) {
++position;
}
if(U_FAILURE(*err)) {
goto error;
}
- else if (uprv_strnicmp(
+ else if (!tagBuffer.isEmpty() && uprv_strnicmp(
maximizedTagBuffer.data(),
tagBuffer.data(),
tagBuffer.length()) == 0) {
TESTCASE_AUTO(TestUnd);
TESTCASE_AUTO(TestUndScript);
TESTCASE_AUTO(TestUndRegion);
+ TESTCASE_AUTO(TestUndCAPI);
TESTCASE_AUTO_END;
}
assertEquals("getDisplayName()", displayName, locale_tag.getDisplayName(displayLocale, tmp));
assertEquals("getDisplayName()", displayName, locale_build.getDisplayName(displayLocale, tmp));
}
+
+void LocaleTest::TestUndCAPI() {
+ IcuTestErrorCode status(*this, "TestUndCAPI()");
+
+ static const char empty[] = "";
+ static const char root[] = "root";
+ static const char und[] = "und";
+
+ static const char empty_script[] = "_Cyrl";
+ static const char empty_region[] = "_AQ";
+
+ static const char und_script[] = "und_Cyrl";
+ static const char und_region[] = "und_AQ";
+
+ char tmp[ULOC_FULLNAME_CAPACITY];
+ int32_t reslen;
+
+ // uloc_getName()
+
+ uprv_memset(tmp, '!', sizeof tmp);
+ reslen = uloc_getName(empty, tmp, sizeof tmp, status);
+ status.errIfFailureAndReset("\"%s\"", empty);
+ assertTrue("reslen >= 0", reslen >= 0);
+ assertEquals("uloc_getName()", empty, tmp);
+
+ uprv_memset(tmp, '!', sizeof tmp);
+ reslen = uloc_getName(root, tmp, sizeof tmp, status);
+ status.errIfFailureAndReset("\"%s\"", root);
+ assertTrue("reslen >= 0", reslen >= 0);
+ assertEquals("uloc_getName()", empty, tmp);
+
+ uprv_memset(tmp, '!', sizeof tmp);
+ reslen = uloc_getName(und, tmp, sizeof tmp, status);
+ status.errIfFailureAndReset("\"%s\"", und);
+ assertTrue("reslen >= 0", reslen >= 0);
+ assertEquals("uloc_getName()", empty, tmp);
+
+ uprv_memset(tmp, '!', sizeof tmp);
+ reslen = uloc_getName(empty_script, tmp, sizeof tmp, status);
+ status.errIfFailureAndReset("\"%s\"", empty_script);
+ assertTrue("reslen >= 0", reslen >= 0);
+ assertEquals("uloc_getName()", empty_script, tmp);
+
+ uprv_memset(tmp, '!', sizeof tmp);
+ reslen = uloc_getName(empty_region, tmp, sizeof tmp, status);
+ status.errIfFailureAndReset("\"%s\"", empty_region);
+ assertTrue("reslen >= 0", reslen >= 0);
+ assertEquals("uloc_getName()", empty_region, tmp);
+
+ uprv_memset(tmp, '!', sizeof tmp);
+ reslen = uloc_getName(und_script, tmp, sizeof tmp, status);
+ status.errIfFailureAndReset("\"%s\"", und_script);
+ assertTrue("reslen >= 0", reslen >= 0);
+ assertEquals("uloc_getName()", empty_script, tmp);
+
+ uprv_memset(tmp, '!', sizeof tmp);
+ reslen = uloc_getName(und_region, tmp, sizeof tmp, status);
+ status.errIfFailureAndReset("\"%s\"", und_region);
+ assertTrue("reslen >= 0", reslen >= 0);
+ assertEquals("uloc_getName()", empty_region, tmp);
+
+ // uloc_getBaseName()
+
+ uprv_memset(tmp, '!', sizeof tmp);
+ reslen = uloc_getBaseName(empty, tmp, sizeof tmp, status);
+ status.errIfFailureAndReset("\"%s\"", empty);
+ assertTrue("reslen >= 0", reslen >= 0);
+ assertEquals("uloc_getBaseName()", empty, tmp);
+
+ uprv_memset(tmp, '!', sizeof tmp);
+ reslen = uloc_getBaseName(root, tmp, sizeof tmp, status);
+ status.errIfFailureAndReset("\"%s\"", root);
+ assertTrue("reslen >= 0", reslen >= 0);
+ assertEquals("uloc_getBaseName()", empty, tmp);
+
+ uprv_memset(tmp, '!', sizeof tmp);
+ reslen = uloc_getBaseName(und, tmp, sizeof tmp, status);
+ status.errIfFailureAndReset("\"%s\"", und);
+ assertTrue("reslen >= 0", reslen >= 0);
+ assertEquals("uloc_getBaseName()", empty, tmp);
+
+ uprv_memset(tmp, '!', sizeof tmp);
+ reslen = uloc_getBaseName(empty_script, tmp, sizeof tmp, status);
+ status.errIfFailureAndReset("\"%s\"", empty_script);
+ assertTrue("reslen >= 0", reslen >= 0);
+ assertEquals("uloc_getBaseName()", empty_script, tmp);
+
+ uprv_memset(tmp, '!', sizeof tmp);
+ reslen = uloc_getBaseName(empty_region, tmp, sizeof tmp, status);
+ status.errIfFailureAndReset("\"%s\"", empty_region);
+ assertTrue("reslen >= 0", reslen >= 0);
+ assertEquals("uloc_getBaseName()", empty_region, tmp);
+
+ uprv_memset(tmp, '!', sizeof tmp);
+ reslen = uloc_getBaseName(und_script, tmp, sizeof tmp, status);
+ status.errIfFailureAndReset("\"%s\"", und_script);
+ assertTrue("reslen >= 0", reslen >= 0);
+ assertEquals("uloc_getBaseName()", empty_script, tmp);
+
+ uprv_memset(tmp, '!', sizeof tmp);
+ reslen = uloc_getBaseName(und_region, tmp, sizeof tmp, status);
+ status.errIfFailureAndReset("\"%s\"", und_region);
+ assertTrue("reslen >= 0", reslen >= 0);
+ assertEquals("uloc_getBaseName()", empty_region, tmp);
+
+ // uloc_getParent()
+
+ uprv_memset(tmp, '!', sizeof tmp);
+ reslen = uloc_getParent(empty, tmp, sizeof tmp, status);
+ status.errIfFailureAndReset("\"%s\"", empty);
+ assertTrue("reslen >= 0", reslen >= 0);
+ assertEquals("uloc_getParent()", empty, tmp);
+
+ uprv_memset(tmp, '!', sizeof tmp);
+ reslen = uloc_getParent(root, tmp, sizeof tmp, status);
+ status.errIfFailureAndReset("\"%s\"", root);
+ assertTrue("reslen >= 0", reslen >= 0);
+ assertEquals("uloc_getParent()", empty, tmp);
+
+ uprv_memset(tmp, '!', sizeof tmp);
+ reslen = uloc_getParent(und, tmp, sizeof tmp, status);
+ status.errIfFailureAndReset("\"%s\"", und);
+ assertTrue("reslen >= 0", reslen >= 0);
+ assertEquals("uloc_getParent()", empty, tmp);
+
+ uprv_memset(tmp, '!', sizeof tmp);
+ reslen = uloc_getParent(empty_script, tmp, sizeof tmp, status);
+ status.errIfFailureAndReset("\"%s\"", empty_script);
+ assertTrue("reslen >= 0", reslen >= 0);
+ assertEquals("uloc_getParent()", empty, tmp);
+
+ uprv_memset(tmp, '!', sizeof tmp);
+ reslen = uloc_getParent(empty_region, tmp, sizeof tmp, status);
+ status.errIfFailureAndReset("\"%s\"", empty_region);
+ assertTrue("reslen >= 0", reslen >= 0);
+ assertEquals("uloc_getParent()", empty, tmp);
+
+ uprv_memset(tmp, '!', sizeof tmp);
+ reslen = uloc_getParent(und_script, tmp, sizeof tmp, status);
+ status.errIfFailureAndReset("\"%s\"", und_script);
+ assertTrue("reslen >= 0", reslen >= 0);
+ assertEquals("uloc_getParent()", empty, tmp);
+
+ uprv_memset(tmp, '!', sizeof tmp);
+ reslen = uloc_getParent(und_region, tmp, sizeof tmp, status);
+ status.errIfFailureAndReset("\"%s\"", und_region);
+ assertTrue("reslen >= 0", reslen >= 0);
+ assertEquals("uloc_getParent()", empty, tmp);
+
+ // uloc_getLanguage()
+
+ uprv_memset(tmp, '!', sizeof tmp);
+ reslen = uloc_getLanguage(empty, tmp, sizeof tmp, status);
+ status.errIfFailureAndReset("\"%s\"", empty);
+ assertTrue("reslen >= 0", reslen >= 0);
+ assertEquals("uloc_getLanguage()", empty, tmp);
+
+ uprv_memset(tmp, '!', sizeof tmp);
+ reslen = uloc_getLanguage(root, tmp, sizeof tmp, status);
+ status.errIfFailureAndReset("\"%s\"", root);
+ assertTrue("reslen >= 0", reslen >= 0);
+ assertEquals("uloc_getLanguage()", empty, tmp);
+
+ uprv_memset(tmp, '!', sizeof tmp);
+ reslen = uloc_getLanguage(und, tmp, sizeof tmp, status);
+ status.errIfFailureAndReset("\"%s\"", und);
+ assertTrue("reslen >= 0", reslen >= 0);
+ assertEquals("uloc_getLanguage()", empty, tmp);
+
+ uprv_memset(tmp, '!', sizeof tmp);
+ reslen = uloc_getLanguage(empty_script, tmp, sizeof tmp, status);
+ status.errIfFailureAndReset("\"%s\"", empty_script);
+ assertTrue("reslen >= 0", reslen >= 0);
+ assertEquals("uloc_getLanguage()", empty, tmp);
+
+ uprv_memset(tmp, '!', sizeof tmp);
+ reslen = uloc_getLanguage(empty_region, tmp, sizeof tmp, status);
+ status.errIfFailureAndReset("\"%s\"", empty_region);
+ assertTrue("reslen >= 0", reslen >= 0);
+ assertEquals("uloc_getLanguage()", empty, tmp);
+
+ uprv_memset(tmp, '!', sizeof tmp);
+ reslen = uloc_getLanguage(und_script, tmp, sizeof tmp, status);
+ status.errIfFailureAndReset("\"%s\"", und_script);
+ assertTrue("reslen >= 0", reslen >= 0);
+ assertEquals("uloc_getLanguage()", empty, tmp);
+
+ uprv_memset(tmp, '!', sizeof tmp);
+ reslen = uloc_getLanguage(und_region, tmp, sizeof tmp, status);
+ status.errIfFailureAndReset("\"%s\"", und_region);
+ assertTrue("reslen >= 0", reslen >= 0);
+ assertEquals("uloc_getLanguage()", empty, tmp);
+}