diff options
author | Eike Rathke <erack@redhat.com> | 2013-10-17 18:33:47 +0200 |
---|---|---|
committer | Eike Rathke <erack@redhat.com> | 2013-10-17 18:36:05 +0200 |
commit | c450aafad00da4553fc6f7abadb19b4b16df6b88 (patch) | |
tree | 1521226863a3fba436f010f68b307f96c0d45dfb /i18nlangtag | |
parent | 7bbd58eafc3146abcefc73d2d1ca6869bb47ef5a (diff) |
solve the 'dz' vs 'bo' and 'nn', 'nb' and 'nn' share primary ID cases
Change-Id: I7ccead4493c9848b55f642c2636daa3c60aeb7a6
Diffstat (limited to 'i18nlangtag')
-rw-r--r-- | i18nlangtag/qa/cppunit/test_languagetag.cxx | 24 | ||||
-rw-r--r-- | i18nlangtag/source/isolang/isolang.cxx | 1 | ||||
-rw-r--r-- | i18nlangtag/source/languagetag/languagetag.cxx | 71 |
3 files changed, 74 insertions, 22 deletions
diff --git a/i18nlangtag/qa/cppunit/test_languagetag.cxx b/i18nlangtag/qa/cppunit/test_languagetag.cxx index 8a055be653ec..6f7cc2d3dc49 100644 --- a/i18nlangtag/qa/cppunit/test_languagetag.cxx +++ b/i18nlangtag/qa/cppunit/test_languagetag.cxx @@ -335,13 +335,35 @@ void TestLanguageTag::testAllTags() CPPUNIT_ASSERT( aLocale.Variant == "" ); LanguageType de_LangID = de.getLanguageType(); CPPUNIT_ASSERT( de_LangID != LANGUAGE_GERMAN ); - CPPUNIT_ASSERT( MsLangId::getPrimaryLanguage( de_LangID) == MsLangId::getPrimaryLanguage( LANGUAGE_GERMAN) ); + CPPUNIT_ASSERT( de_LangID == MsLangId::getPrimaryLanguage( LANGUAGE_GERMAN) ); CPPUNIT_ASSERT( de.makeFallback().getBcp47() == "de-DE"); // Check registered mapping. LanguageTag de_l( de_LangID); CPPUNIT_ASSERT( de_l.getBcp47() == s_de ); } + // "bo" and "dz" share the same primary language ID, only one gets it + // assigned, "dz" language-only has a special mapping. + { + LanguageTag bo( "bo", true ); + CPPUNIT_ASSERT( bo.getLanguageType() == MsLangId::getPrimaryLanguage( LANGUAGE_TIBETAN) ); + LanguageTag dz( "dz", true ); + CPPUNIT_ASSERT( dz.getLanguageType() == LANGUAGE_USER_DZONGKHA_MAP_LONLY ); + } + + // "no", "nb" and "nn" share the same primary language ID, which even is + // assigned to "no-NO" for legacy so none gets it assigned, all on-the-fly. + { + LanguageTag no( "no", true ); + CPPUNIT_ASSERT( LanguageTag::isOnTheFlyID( no.getLanguageType()) ); + LanguageTag nb( "nb", true ); + CPPUNIT_ASSERT( LanguageTag::isOnTheFlyID( nb.getLanguageType()) ); + LanguageTag nn( "nn", true ); + CPPUNIT_ASSERT( LanguageTag::isOnTheFlyID( nn.getLanguageType()) ); + LanguageTag no_NO( "no-NO", true ); + CPPUNIT_ASSERT( no_NO.getLanguageType() == LANGUAGE_NORWEGIAN ); + } + // 'de-1901' derived from 'de-DE-1901' grandfathered to check that it is // accepted as (DIGIT 3ALNUM) variant { diff --git a/i18nlangtag/source/isolang/isolang.cxx b/i18nlangtag/source/isolang/isolang.cxx index 25e8eb29529a..fb7539518900 100644 --- a/i18nlangtag/source/isolang/isolang.cxx +++ b/i18nlangtag/source/isolang/isolang.cxx @@ -352,6 +352,7 @@ static IsoLanguageCountryEntry const aImplIsoLangEntries[] = { LANGUAGE_TIBETAN, "bo", "CN", false }, // CN politically correct? { LANGUAGE_USER_TIBETAN_INDIA, "bo", "IN", false }, { LANGUAGE_DZONGKHA, "dz", "BT", false }, + { LANGUAGE_USER_DZONGKHA_MAP_LONLY, "dz", "" , false }, // because of the MS error, see lang.h { LANGUAGE_TURKMEN, "tk", "TM", false }, { LANGUAGE_WELSH, "cy", "GB", false }, { LANGUAGE_SESOTHO, "st", "ZA", false }, diff --git a/i18nlangtag/source/languagetag/languagetag.cxx b/i18nlangtag/source/languagetag/languagetag.cxx index fc1f5b53eb09..4f8af9ade4bb 100644 --- a/i18nlangtag/source/languagetag/languagetag.cxx +++ b/i18nlangtag/source/languagetag/languagetag.cxx @@ -309,8 +309,10 @@ private: /** Generates on-the-fly LangID and registers the maBcp47,mnLangID pair. @param nRegisterID - If not 0 and not LANGUAGE_DONTKNOW, use that ID instead of - generating an on-the-fly ID. + If not 0 and not LANGUAGE_DONTKNOW, suggest (!) to use that ID + instead of generating an on-the-fly ID. Implementation may + still generate an ID if the suggested ID is already used for + another language tag. @return NULL if no ID could be obtained or registration failed. */ @@ -616,10 +618,10 @@ LanguageTag::ImplPtr LanguageTagImpl::registerOnTheFly( LanguageType nRegisterID osl::MutexGuard aGuard( theMutex::get()); - MapBcp47& rMap = theMapBcp47::get(); - MapBcp47::const_iterator it( rMap.find( maBcp47)); + MapBcp47& rMapBcp47 = theMapBcp47::get(); + MapBcp47::const_iterator it( rMapBcp47.find( maBcp47)); bool bOtherImpl = false; - if (it != rMap.end()) + if (it != rMapBcp47.end()) { SAL_INFO( "i18nlangtag", "LanguageTag::registerOnTheFly: found impl for '" << maBcp47 << "'"); pImpl = (*it).second; @@ -639,23 +641,47 @@ LanguageTag::ImplPtr LanguageTagImpl::registerOnTheFly( LanguageType nRegisterID { SAL_INFO( "i18nlangtag", "LanguageTag::registerOnTheFly: new impl for '" << maBcp47 << "'"); pImpl.reset( new LanguageTagImpl( *this)); - rMap.insert( ::std::make_pair( maBcp47, pImpl)); + rMapBcp47.insert( ::std::make_pair( maBcp47, pImpl)); } if (!bOtherImpl || !pImpl->mbInitializedLangID) { - LanguageType nLang = ((nRegisterID == 0 || nRegisterID == LANGUAGE_DONTKNOW) ? - getNextOnTheFlyLanguage() : nRegisterID); - if (!nLang) + if (nRegisterID == 0 || nRegisterID == LANGUAGE_DONTKNOW) + nRegisterID = getNextOnTheFlyLanguage(); + else + { + // Accept a suggested ID only if it is not mapped yet to something + // different, otherwise we would end up with ambiguous assignments + // of different language tags, for example for the same primary + // LangID with "no", "nb" and "nn". + const MapLangID& rMapLangID = theMapLangID::get(); + MapLangID::const_iterator itID( rMapLangID.find( nRegisterID)); + if (itID != rMapLangID.end()) + { + if ((*itID).second->maBcp47 != maBcp47) + { + SAL_INFO( "i18nlangtag", "LanguageTag::registerOnTheFly: not using suggested 0x" + << ::std::hex << nRegisterID << " for '" << maBcp47 << "' have '" + << (*itID).second->maBcp47 << "'"); + nRegisterID = getNextOnTheFlyLanguage(); + } + else + { + SAL_WARN( "i18nlangtag", "LanguageTag::registerOnTheFly: suggested 0x" + << ::std::hex << nRegisterID << " for '" << maBcp47 << "' already registered"); + } + } + } + if (!nRegisterID) { // out of IDs, nothing to register return pImpl; } - pImpl->mnLangID = nLang; + pImpl->mnLangID = nRegisterID; pImpl->mbInitializedLangID = true; if (pImpl.get() != this) { - mnLangID = nLang; + mnLangID = nRegisterID; mbInitializedLangID = true; } } @@ -678,6 +704,13 @@ LanguageTag::ImplPtr LanguageTagImpl::registerOnTheFly( LanguageType nRegisterID } +static bool lcl_isKnownOnTheFlyID( LanguageType nLang ) +{ + return nLang != LANGUAGE_DONTKNOW && nLang != LANGUAGE_SYSTEM && + (LanguageTag::isOnTheFlyID( nLang) || (nLang == MsLangId::getPrimaryLanguage( nLang))); +} + + LanguageTag::ImplPtr LanguageTag::registerImpl() const { // XXX NOTE: Do not use non-static LanguageTag::convert...() member methods @@ -884,10 +917,8 @@ LanguageTag::ImplPtr LanguageTag::registerImpl() const if (!pImpl->mbInitializedLangID) pImpl->convertLocaleToLang( true); // Unconditionally insert (round-trip is possible) for - // on-the-fly IDs and (generated or not) primary language IDs. - bool bInsert = (pImpl->mnLangID != LANGUAGE_DONTKNOW && - (LanguageTag::isOnTheFlyID( pImpl->mnLangID) || - (pImpl->mnLangID == MsLangId::getPrimaryLanguage( pImpl->mnLangID)))); + // on-the-fly IDs and (generated or not) suggested IDs. + bool bInsert = lcl_isKnownOnTheFlyID( pImpl->mnLangID); OUString aBcp47; if (!bInsert) { @@ -1309,8 +1340,8 @@ void LanguageTagImpl::convertLocaleToLang( bool bAllowOnTheFlyID ) if (isValidBcp47()) { // For language-only (including script) look if we know some - // locale of that language and if so use the primary language - // ID of that instead of generating an on-the-fly-ID. + // locale of that language and if so try to use the primary + // language ID of that instead of generating an on-the-fly ID. if (getCountry().isEmpty() && isIsoODF()) { lang::Locale aLoc( MsLangId::Conversion::lookupFallbackLocale( maLocale)); @@ -1319,10 +1350,8 @@ void LanguageTagImpl::convertLocaleToLang( bool bAllowOnTheFlyID ) if (aLoc.Language != "en" || getLanguage() == "en") { mnLangID = MsLangId::Conversion::convertLocaleToLanguage( aLoc); - // LANGUAGE_DONTKNOW is all bits of primary language, - // so this is ok even if the conversion failed, which - // it should not anyway.. - mnLangID = MsLangId::getPrimaryLanguage( mnLangID); + if (mnLangID != LANGUAGE_DONTKNOW) + mnLangID = MsLangId::getPrimaryLanguage( mnLangID); } } registerOnTheFly( mnLangID); |