diff --git a/icu4c/source/common/uloc.c b/icu4c/source/common/uloc.c index a33805a66eb..7a1b54282f5 100644 --- a/icu4c/source/common/uloc.c +++ b/icu4c/source/common/uloc.c @@ -1,6 +1,6 @@ /* ********************************************************************** -* Copyright (C) 1997-2006, International Business Machines +* Copyright (C) 1997-2007, International Business Machines * Corporation and others. All Rights Reserved. ********************************************************************** * @@ -2002,6 +2002,24 @@ uloc_getLCID(const char* localeID) return uprv_convertToLCID(langID, localeID, &status); } +U_CAPI int32_t U_EXPORT2 +uloc_getLocaleForLCID(uint32_t hostid, char *locale, int32_t localeCapacity, + UErrorCode *status) +{ + const char *posix = uprv_convertToPosix(hostid, status); + if (U_FAILURE(*status) || posix == NULL) { + return 0; + } + int32_t length = uprv_strlen(posix); + if (length+1 > localeCapacity) { + *status = U_BUFFER_OVERFLOW_ERROR; + } + else { + uprv_strcpy(locale, posix); + } + return length; +} + /* ### Default locale **************************************************/ U_CAPI const char* U_EXPORT2 diff --git a/icu4c/source/common/unicode/uloc.h b/icu4c/source/common/unicode/uloc.h index 61b70607866..2912f6770ef 100644 --- a/icu4c/source/common/unicode/uloc.h +++ b/icu4c/source/common/unicode/uloc.h @@ -1,6 +1,6 @@ /* ********************************************************************** -* Copyright (C) 1997-2006, International Business Machines +* Copyright (C) 1997-2007, International Business Machines * Corporation and others. All Rights Reserved. ********************************************************************** * @@ -910,6 +910,22 @@ uloc_acceptLanguage(char *result, int32_t resultAvailable, UErrorCode *status); +/** + * Gets the ICU locale ID for the specified Win32 LCID value. + * + * @param hostID the Win32 LCID to translate + * @param locale the output buffer for the ICU locale ID, which will be NUL-terminated + * if there is room. + * @param localeCapacity the size of the output buffer + * @param status an error is returned if the LCID is unrecognized or the output buffer + * is too small + * @return actual the actual size of the locale ID, not including NUL-termination + * @draft ICU 3.8 + */ +U_DRAFT int32_t U_EXPORT2 +uloc_getLocaleForLCID(uint32_t hostid, char *locale, int32_t localeCapacity, + UErrorCode *status); + #endif /*_ULOC*/ diff --git a/icu4c/source/test/cintltst/cloctst.c b/icu4c/source/test/cintltst/cloctst.c index 73ca071f3b7..49ee6e1f45c 100644 --- a/icu4c/source/test/cintltst/cloctst.c +++ b/icu4c/source/test/cintltst/cloctst.c @@ -227,6 +227,7 @@ void addLocaleTest(TestNode** root) TESTCASE(TestUResourceBundle); TESTCASE(TestDisplayName); TESTCASE(TestAcceptLanguage); + TESTCASE(TestGetLocaleForLCID); } @@ -2626,3 +2627,90 @@ static void TestDisplayName() { } } +static void TestGetLocaleForLCID() { + int32_t i, length, lengthPre; + const char* testLocale = 0; + UErrorCode status = U_ZERO_ERROR; + const char* temp; + char temp2[40], temp3[40]; + uint32_t lcid; + + lcid = uloc_getLCID("en_US"); + if (lcid != 0x0409) { + log_err(" uloc_getLCID(\"en_US\") = %d, expected 0x0409\n", lcid); + } + + lengthPre = uloc_getLocaleForLCID(lcid, temp2, 4, &status); + if (status != U_BUFFER_OVERFLOW_ERROR) { + log_err(" unexpected result from uloc_getLocaleForLCID with small buffer: %s\n", u_errorName(status)); + } + else { + status = U_ZERO_ERROR; + } + + length = uloc_getLocaleForLCID(lcid, temp2, sizeof(temp2)/sizeof(char), &status); + if (U_FAILURE(status)) { + log_err(" unexpected result from uloc_getLocaleForLCID(0x0409): %s\n", u_errorName(status)); + status = U_ZERO_ERROR; + } + + if (length != lengthPre) { + log_err(" uloc_getLocaleForLCID(0x0409): returned length %d does not match preflight length %d\n", length, lengthPre); + } + + length = uloc_getLocaleForLCID(0x12345, temp2, sizeof(temp2)/sizeof(char), &status); + if (U_SUCCESS(status)) { + log_err(" unexpected result from uloc_getLocaleForLCID(0x12345): %s, status %s\n", temp2, u_errorName(status)); + } + status = U_ZERO_ERROR; + + log_verbose("Testing getLocaleForLCID vs. locale data\n"); + for (i = 0; i < LOCALE_SIZE; i++) { + + testLocale=rawData2[NAME][i]; + + log_verbose("Testing %s ......\n", testLocale); + + sscanf(rawData2[LCID][i], "%x", &lcid); + length = uloc_getLocaleForLCID(lcid, temp2, sizeof(temp2)/sizeof(char), &status); + if (U_FAILURE(status)) { + log_err(" unexpected failure of uloc_getLocaleForLCID(%#04x), status %s\n", lcid, u_errorName(status)); + status = U_ZERO_ERROR; + continue; + } + + if (length != uprv_strlen(temp2)) { + log_err(" returned length %d not correct for uloc_getLocaleForLCID(%#04x), expected %d\n", length, lcid, uprv_strlen(temp2)); + } + + /* Compare language, country, script */ + length = uloc_getLanguage(temp2, temp3, sizeof(temp3)/sizeof(char), &status); + if (U_FAILURE(status)) { + log_err(" couldn't get language in uloc_getLocaleForLCID(%#04x) = %s, status %s\n", lcid, temp2, u_errorName(status)); + status = U_ZERO_ERROR; + } + else if (uprv_strcmp(temp3, rawData2[LANG][i]) && !(uprv_strcmp(temp3, "nn") == 0 && uprv_strcmp(rawData2[VAR][i], "NY") == 0)) { + log_err(" language doesn't match expected %s in in uloc_getLocaleForLCID(%#04x) = %s\n", rawData2[LANG][i], lcid, temp2); + } + + length = uloc_getScript(temp2, temp3, sizeof(temp3)/sizeof(char), &status); + if (U_FAILURE(status)) { + log_err(" couldn't get script in uloc_getLocaleForLCID(%#04x) = %s, status %s\n", lcid, temp2, u_errorName(status)); + status = U_ZERO_ERROR; + } + else if (uprv_strcmp(temp3, rawData2[SCRIPT][i])) { + log_err(" script doesn't match expected %s in in uloc_getLocaleForLCID(%#04x) = %s\n", rawData2[SCRIPT][i], lcid, temp2); + } + + length = uloc_getCountry(temp2, temp3, sizeof(temp3)/sizeof(char), &status); + if (U_FAILURE(status)) { + log_err(" couldn't get country in uloc_getLocaleForLCID(%#04x) = %s, status %s\n", lcid, temp2, u_errorName(status)); + status = U_ZERO_ERROR; + } + else if (uprv_strlen(rawData2[CTRY][i]) && uprv_strcmp(temp3, rawData2[CTRY][i])) { + log_err(" country doesn't match expected %s in in uloc_getLocaleForLCID(%#04x) = %s\n", rawData2[CTRY][i], lcid, temp2); + } + } + +} + diff --git a/icu4c/source/test/cintltst/cloctst.h b/icu4c/source/test/cintltst/cloctst.h index bc098b70fb8..c82fa356aed 100644 --- a/icu4c/source/test/cintltst/cloctst.h +++ b/icu4c/source/test/cintltst/cloctst.h @@ -1,6 +1,6 @@ /******************************************************************** * COPYRIGHT: - * Copyright (c) 1997-2006, International Business Machines Corporation and + * Copyright (c) 1997-2007, International Business Machines Corporation and * others. All Rights Reserved. ********************************************************************/ /******************************************************************************** @@ -73,6 +73,9 @@ static void TestDisplayNames(void); /* Test warning for no data in getDisplay* */ static void TestDisplayNameWarning(void); + /* Test uloc_getLocaleForLCID */ + static void TestGetLocaleForLCID(void); + /** * routine to perform subtests, used by TestDisplayNames */