Index: patches/locid.patch |
diff --git a/patches/locid.patch b/patches/locid.patch |
deleted file mode 100644 |
index c67d31a8624a3aef1c321e43baa6477cb1a732bf..0000000000000000000000000000000000000000 |
--- a/patches/locid.patch |
+++ /dev/null |
@@ -1,331 +0,0 @@ |
-diff --git a/source/test/intltest/loctest.cpp b/source/test/intltest/loctest.cpp |
-index 1bcf771..5922e1c 100644 |
---- a/source/test/intltest/loctest.cpp |
-+++ b/source/test/intltest/loctest.cpp |
-@@ -1,6 +1,6 @@ |
- /******************************************************************** |
- * COPYRIGHT: |
-- * Copyright (c) 1997-2014, International Business Machines Corporation and |
-+ * Copyright (c) 1997-2015, International Business Machines Corporation and |
- * others. All Rights Reserved. |
- ********************************************************************/ |
- |
-@@ -181,6 +181,7 @@ LocaleTest::~LocaleTest() |
- void LocaleTest::runIndexedTest( int32_t index, UBool exec, const char* &name, char* /*par*/ ) |
- { |
- TESTCASE_AUTO_BEGIN; |
-+ TESTCASE_AUTO(TestBug11421); // Must run early in list to trigger failure. |
- TESTCASE_AUTO(TestBasicGetters); |
- TESTCASE_AUTO(TestSimpleResourceInfo); |
- TESTCASE_AUTO(TestDisplayNames); |
-@@ -1756,12 +1757,13 @@ LocaleTest::TestGetBaseName(void) { |
- } testCases[] = { |
- { "de_DE@ C o ll A t i o n = Phonebook ", "de_DE" }, |
- { "de@currency = euro; CoLLaTion = PHONEBOOk", "de" }, |
-- { "ja@calendar = buddhist", "ja" } |
-+ { "ja@calendar = buddhist", "ja" }, |
-+ { "de-u-co-phonebk", "de"} |
- }; |
- |
- int32_t i = 0; |
- |
-- for(i = 0; i < (int32_t)(sizeof(testCases)/sizeof(testCases[0])); i++) { |
-+ for(i = 0; i < UPRV_LENGTHOF(testCases); i++) { |
- Locale loc(testCases[i].localeID); |
- if(strcmp(testCases[i].baseName, loc.getBaseName())) { |
- errln("For locale \"%s\" expected baseName \"%s\", but got \"%s\"", |
-@@ -1769,6 +1771,20 @@ LocaleTest::TestGetBaseName(void) { |
- return; |
- } |
- } |
-+ |
-+ // Verify that adding a keyword to an existing Locale doesn't change the base name. |
-+ UErrorCode status = U_ZERO_ERROR; |
-+ Locale loc2("en-US"); |
-+ if (strcmp("en_US", loc2.getBaseName())) { |
-+ errln("%s:%d Expected \"en_US\", got \"%s\"", __FILE__, __LINE__, loc2.getBaseName()); |
-+ } |
-+ loc2.setKeywordValue("key", "value", status); |
-+ if (strcmp("en_US@key=value", loc2.getName())) { |
-+ errln("%s:%d Expected \"en_US@key=value\", got \"%s\"", __FILE__, __LINE__, loc2.getName()); |
-+ } |
-+ if (strcmp("en_US", loc2.getBaseName())) { |
-+ errln("%s:%d Expected \"en_US\", got \"%s\"", __FILE__, __LINE__, loc2.getBaseName()); |
-+ } |
- } |
- |
- /** |
-@@ -2549,3 +2565,17 @@ void LocaleTest::TestIsRightToLeft() { |
- assertFalse("fil LTR", Locale("fil").isRightToLeft()); |
- assertFalse("he-Zyxw LTR", Locale("he-Zyxw").isRightToLeft()); |
- } |
-+ |
-+void LocaleTest::TestBug11421() { |
-+ Locale::getDefault().getBaseName(); |
-+ int32_t numLocales; |
-+ const Locale *localeList = Locale::getAvailableLocales(numLocales); |
-+ for (int localeIndex = 0; localeIndex < numLocales; localeIndex++) { |
-+ const Locale &loc = localeList[localeIndex]; |
-+ if (strncmp(loc.getName(), loc.getBaseName(), strlen(loc.getBaseName()))) { |
-+ errln("%s:%d loc.getName=\"%s\"; loc.getBaseName=\"%s\"", |
-+ __FILE__, __LINE__, loc.getName(), loc.getBaseName()); |
-+ break; |
-+ } |
-+ } |
-+} |
-diff --git a/source/test/intltest/loctest.h b/source/test/intltest/loctest.h |
-index 53f606d..d556571 100644 |
---- a/source/test/intltest/loctest.h |
-+++ b/source/test/intltest/loctest.h |
-@@ -1,6 +1,6 @@ |
- /******************************************************************** |
- * COPYRIGHT: |
-- * Copyright (c) 1997-2014, International Business Machines Corporation and |
-+ * Copyright (c) 1997-2015, International Business Machines Corporation and |
- * others. All Rights Reserved. |
- ********************************************************************/ |
- |
-@@ -102,6 +102,7 @@ public: |
- |
- void TestGetVariantWithKeywords(void); |
- void TestIsRightToLeft(); |
-+ void TestBug11421(); |
- |
- private: |
- void _checklocs(const char* label, |
-diff --git a/source/common/locid.cpp b/source/common/locid.cpp |
-index f073aad..c99c61c 100644 |
---- a/source/common/locid.cpp |
-+++ b/source/common/locid.cpp |
-@@ -38,6 +38,7 @@ |
- #include "uassert.h" |
- #include "cmemory.h" |
- #include "cstring.h" |
-+#include "uassert.h" |
- #include "uhash.h" |
- #include "ucln_cmn.h" |
- #include "ustr_imp.h" |
-@@ -240,16 +241,16 @@ UOBJECT_DEFINE_RTTI_IMPLEMENTATION(Locale) |
- |
- Locale::~Locale() |
- { |
-+ if (baseName != fullName) { |
-+ uprv_free(baseName); |
-+ } |
-+ baseName = NULL; |
- /*if fullName is on the heap, we free it*/ |
- if (fullName != fullNameBuffer) |
- { |
- uprv_free(fullName); |
- fullName = NULL; |
- } |
-- if (baseName && baseName != baseNameBuffer) { |
-- uprv_free(baseName); |
-- baseName = NULL; |
-- } |
- } |
- |
- Locale::Locale() |
-@@ -421,6 +422,10 @@ Locale &Locale::operator=(const Locale &other) |
- } |
- |
- /* Free our current storage */ |
-+ if (baseName != fullName) { |
-+ uprv_free(baseName); |
-+ } |
-+ baseName = NULL; |
- if(fullName != fullNameBuffer) { |
- uprv_free(fullName); |
- fullName = fullNameBuffer; |
-@@ -436,18 +441,13 @@ Locale &Locale::operator=(const Locale &other) |
- /* Copy the full name */ |
- uprv_strcpy(fullName, other.fullName); |
- |
-- /* baseName is the cached result of getBaseName. if 'other' has a |
-- baseName and it fits in baseNameBuffer, then copy it. otherwise set |
-- it to NULL, and let the user lazy-create it (in getBaseName) if they |
-- want it. */ |
-- if(baseName && baseName != baseNameBuffer) { |
-- uprv_free(baseName); |
-- } |
-- baseName = NULL; |
-- |
-- if(other.baseName == other.baseNameBuffer) { |
-- uprv_strcpy(baseNameBuffer, other.baseNameBuffer); |
-- baseName = baseNameBuffer; |
-+ /* Copy the baseName if it differs from fullName. */ |
-+ if (other.baseName == other.fullName) { |
-+ baseName = fullName; |
-+ } else { |
-+ if (other.baseName) { |
-+ baseName = uprv_strdup(other.baseName); |
-+ } |
- } |
- |
- /* Copy the language and country fields */ |
-@@ -479,16 +479,15 @@ Locale& Locale::init(const char* localeID, UBool canonicalize) |
- { |
- fIsBogus = FALSE; |
- /* Free our current storage */ |
-+ if (baseName != fullName) { |
-+ uprv_free(baseName); |
-+ } |
-+ baseName = NULL; |
- if(fullName != fullNameBuffer) { |
- uprv_free(fullName); |
- fullName = fullNameBuffer; |
- } |
- |
-- if(baseName && baseName != baseNameBuffer) { |
-- uprv_free(baseName); |
-- baseName = NULL; |
-- } |
-- |
- // not a loop: |
- // just an easy way to have a common error-exit |
- // without goto and without another function |
-@@ -588,6 +587,12 @@ Locale& Locale::init(const char* localeID, UBool canonicalize) |
- variantBegin = (int32_t)(field[variantField] - fullName); |
- } |
- |
-+ err = U_ZERO_ERROR; |
-+ initBaseName(err); |
-+ if (U_FAILURE(err)) { |
-+ break; |
-+ } |
-+ |
- // successful end of init() |
- return *this; |
- } while(0); /*loop doesn't iterate*/ |
-@@ -598,6 +603,43 @@ Locale& Locale::init(const char* localeID, UBool canonicalize) |
- return *this; |
- } |
- |
-+/* |
-+ * Set up the base name. |
-+ * If there are no key words, it's exactly the full name. |
-+ * If key words exist, it's the full name truncated at the '@' character. |
-+ * Need to set up both at init() and after setting a keyword. |
-+ */ |
-+void |
-+Locale::initBaseName(UErrorCode &status) { |
-+ if (U_FAILURE(status)) { |
-+ return; |
-+ } |
-+ U_ASSERT(baseName==NULL || baseName==fullName); |
-+ const char *atPtr = uprv_strchr(fullName, '@'); |
-+ const char *eqPtr = uprv_strchr(fullName, '='); |
-+ if (atPtr && eqPtr && atPtr < eqPtr) { |
-+ // Key words exist. |
-+ int32_t baseNameLength = (int32_t)(atPtr - fullName); |
-+ baseName = (char *)uprv_malloc(baseNameLength + 1); |
-+ if (baseName == NULL) { |
-+ status = U_MEMORY_ALLOCATION_ERROR; |
-+ return; |
-+ } |
-+ uprv_strncpy(baseName, fullName, baseNameLength); |
-+ baseName[baseNameLength] = 0; |
-+ |
-+ // The original computation of variantBegin leaves it equal to the length |
-+ // of fullName if there is no variant. It should instead be |
-+ // the length of the baseName. |
-+ if (variantBegin > baseNameLength) { |
-+ variantBegin = baseNameLength; |
-+ } |
-+ } else { |
-+ baseName = fullName; |
-+ } |
-+} |
-+ |
-+ |
- int32_t |
- Locale::hashCode() const |
- { |
-@@ -607,14 +649,14 @@ Locale::hashCode() const |
- void |
- Locale::setToBogus() { |
- /* Free our current storage */ |
-+ if(baseName != fullName) { |
-+ uprv_free(baseName); |
-+ } |
-+ baseName = NULL; |
- if(fullName != fullNameBuffer) { |
- uprv_free(fullName); |
- fullName = fullNameBuffer; |
- } |
-- if(baseName && baseName != baseNameBuffer) { |
-- uprv_free(baseName); |
-- baseName = NULL; |
-- } |
- *fullNameBuffer = 0; |
- *language = 0; |
- *script = 0; |
-@@ -990,33 +1032,14 @@ void |
- Locale::setKeywordValue(const char* keywordName, const char* keywordValue, UErrorCode &status) |
- { |
- uloc_setKeywordValue(keywordName, keywordValue, fullName, ULOC_FULLNAME_CAPACITY, &status); |
-+ if (U_SUCCESS(status) && baseName == fullName) { |
-+ // May have added the first keyword, meaning that the fullName is no longer also the baseName. |
-+ initBaseName(status); |
-+ } |
- } |
- |
- const char * |
--Locale::getBaseName() const |
--{ |
-- // lazy init |
-- UErrorCode status = U_ZERO_ERROR; |
-- // semantically const |
-- if(baseName == 0) { |
-- ((Locale *)this)->baseName = ((Locale *)this)->baseNameBuffer; |
-- int32_t baseNameSize = uloc_getBaseName(fullName, baseName, ULOC_FULLNAME_CAPACITY, &status); |
-- if(baseNameSize >= ULOC_FULLNAME_CAPACITY) { |
-- ((Locale *)this)->baseName = (char *)uprv_malloc(sizeof(char) * baseNameSize + 1); |
-- if (baseName == NULL) { |
-- return baseName; |
-- } |
-- uloc_getBaseName(fullName, baseName, baseNameSize+1, &status); |
-- } |
-- baseName[baseNameSize] = 0; |
-- |
-- // the computation of variantBegin leaves it equal to the length |
-- // of fullName if there is no variant. It should instead be |
-- // the length of the baseName. Patch around this for now. |
-- if (variantBegin == (int32_t)uprv_strlen(fullName)) { |
-- ((Locale*)this)->variantBegin = baseNameSize; |
-- } |
-- } |
-+Locale::getBaseName() const { |
- return baseName; |
- } |
- |
-diff --git a/source/common/unicode/locid.h b/source/common/unicode/locid.h |
-index 3546192..1ad5cb5 100644 |
---- a/source/common/unicode/locid.h |
-+++ b/source/common/unicode/locid.h |
-@@ -1,7 +1,7 @@ |
- /* |
- ****************************************************************************** |
- * |
--* Copyright (C) 1996-2014, International Business Machines |
-+* Copyright (C) 1996-2015, International Business Machines |
- * Corporation and others. All Rights Reserved. |
- * |
- ****************************************************************************** |
-@@ -750,7 +750,7 @@ private: |
- char fullNameBuffer[ULOC_FULLNAME_CAPACITY]; |
- // name without keywords |
- char* baseName; |
-- char baseNameBuffer[ULOC_FULLNAME_CAPACITY]; |
-+ void initBaseName(UErrorCode& status); |
- |
- UBool fIsBogus; |
- |
-@@ -795,7 +795,6 @@ Locale::getScript() const |
- inline const char * |
- Locale::getVariant() const |
- { |
-- getBaseName(); // lazy init |
- return &baseName[variantBegin]; |
- } |
- |