i18nlangtag/qa/cppunit/test_languagetag.cxx | 11 - i18nlangtag/source/languagetag/simple-langtag.cxx | 129 +++++++++++++++++----- 2 files changed, 104 insertions(+), 36 deletions(-)
New commits: commit 9b98e25ce1e76a86ecf1dce71349e13ce1c1e6d5 Author: Eike Rathke <er...@redhat.com> Date: Thu Aug 29 17:31:52 2013 +0200 handle variants in replacement code Change-Id: I57da3bcd415c060b1e785e0d1cf3966de819c196 diff --git a/i18nlangtag/qa/cppunit/test_languagetag.cxx b/i18nlangtag/qa/cppunit/test_languagetag.cxx index fd55e0b..915d5cb 100644 --- a/i18nlangtag/qa/cppunit/test_languagetag.cxx +++ b/i18nlangtag/qa/cppunit/test_languagetag.cxx @@ -167,19 +167,11 @@ void TestLanguageTag::testAllTags() CPPUNIT_ASSERT( ca_ES_valencia.getScript() == "" ); CPPUNIT_ASSERT( ca_ES_valencia.getLanguageAndScript() == "ca" ); ::std::vector< OUString > ca_ES_valencia_Fallbacks( ca_ES_valencia.getFallbackStrings()); - /* TODO: replacement doesn't handle variants yet. */ -#if USE_LIBLANGTAG CPPUNIT_ASSERT( ca_ES_valencia_Fallbacks.size() == 4); CPPUNIT_ASSERT( ca_ES_valencia_Fallbacks[0] == "ca-ES-valencia"); CPPUNIT_ASSERT( ca_ES_valencia_Fallbacks[1] == "ca-valencia"); CPPUNIT_ASSERT( ca_ES_valencia_Fallbacks[2] == "ca-ES"); CPPUNIT_ASSERT( ca_ES_valencia_Fallbacks[3] == "ca"); -#else - CPPUNIT_ASSERT( ca_ES_valencia_Fallbacks.size() == 3); - CPPUNIT_ASSERT( ca_ES_valencia_Fallbacks[0] == "ca-ES-valencia"); - CPPUNIT_ASSERT( ca_ES_valencia_Fallbacks[1] == "ca-ES"); - CPPUNIT_ASSERT( ca_ES_valencia_Fallbacks[2] == "ca"); -#endif /* TODO: conversion doesn't know this yet, once it does activate test. */ #if 0 CPPUNIT_ASSERT( ca_ES_valencia.makeFallback().getBcp47() == "ca-ES-valencia"); @@ -189,8 +181,6 @@ void TestLanguageTag::testAllTags() } { - /* TODO: replacement doesn't handle variants yet. */ -#if USE_LIBLANGTAG OUString s_ca_valencia( "ca-valencia" ); LanguageTag ca_valencia( s_ca_valencia, true ); lang::Locale aLocale = ca_valencia.getLocale(); @@ -216,7 +206,6 @@ void TestLanguageTag::testAllTags() #else CPPUNIT_ASSERT( ca_valencia.makeFallback().getBcp47() == "ca-ES"); #endif -#endif } { diff --git a/i18nlangtag/source/languagetag/simple-langtag.cxx b/i18nlangtag/source/languagetag/simple-langtag.cxx index 153500a..a9588ea 100644 --- a/i18nlangtag/source/languagetag/simple-langtag.cxx +++ b/i18nlangtag/source/languagetag/simple-langtag.cxx @@ -95,7 +95,7 @@ struct my_t_impl : public my_ref else mpStr = NULL; } - void append( const char* str, const char* stop ) + virtual void append( const char* str, const char* stop ) { if (str && str < stop) { @@ -110,7 +110,7 @@ struct my_t_impl : public my_ref mpStr = p; } } - void zero() + virtual void zero() { g_free( mpStr); mpStr = NULL; @@ -162,8 +162,9 @@ struct lt_list_t : public my_t_impl static lt_pointer_t lt_list_value( const lt_list_t* p ) { - // Assuming only char* here. - return p ? p->mpStr : NULL; + // This may look odd, but in this implementation the list element itself + // holds the char* mpStr to be obtained with lt_variant_get_tag() + return static_cast<lt_pointer_t>(const_cast<lt_list_t*>(p)); } static const lt_list_t* lt_list_next( const lt_list_t* p ) @@ -201,24 +202,72 @@ static void my_unrefList( lt_list_t* pList ) } } +static void my_appendToList( lt_list_t** ppList, lt_list_t* pEntry ) +{ + if (ppList) + { + if (!*ppList) + *ppList = pEntry; + else + { + lt_list_t* pThat = *ppList; + for (lt_list_t* pNext = pThat->mpNext; pNext; pNext = pThat->mpNext) + pThat = pNext; + pThat->mpNext = pEntry; + pEntry->mpPrev = pThat; + } + } +} + +// my_t_impl has a superfluous mpStr here, but simplifies things much in the +// parser. +struct my_t_list : public my_t_impl +{ + lt_list_t* mpList; + explicit my_t_list() : my_t_impl(), mpList(NULL) {} + explicit my_t_list( const my_t_list& r ) : my_t_impl( r), mpList( my_copyList( r.mpList)) {} + virtual ~my_t_list() + { + my_unrefList( mpList); + } + my_t_list& operator=( const my_t_list& r ) + { + if (this == &r) + return *this; + my_t_impl::operator=( r); + lt_list_t* pList = my_copyList( r.mpList); + my_unrefList( mpList); + mpList = pList; + } + virtual void append( const char* str, const char* stop ) + { + lt_list_t* p = new lt_list_t; + p->assign( str, stop); + my_appendToList( &mpList, p); + } + virtual void zero() + { + my_t_impl::zero(); + my_unrefList( mpList); + mpList = NULL; + } +}; + struct lt_tag_t : public my_t_impl { lt_lang_t maLanguage; lt_script_t maScript; lt_region_t maRegion; - lt_list_t* mpVariants; - explicit lt_tag_t() : my_t_impl(), maLanguage(), maScript(), maRegion(), mpVariants(NULL) {} - virtual ~lt_tag_t() - { - my_unrefList( mpVariants); - } + my_t_list maVariants; + explicit lt_tag_t() : my_t_impl(), maLanguage(), maScript(), maRegion(), maVariants() {} + virtual ~lt_tag_t() {} explicit lt_tag_t( const lt_tag_t& r ) : my_t_impl( r), maLanguage( r.maLanguage), maScript( r.maScript), maRegion( r.maRegion), - mpVariants( my_copyList( r.mpVariants)) + maVariants( r.maVariants) { } lt_tag_t& operator=( const lt_tag_t& r ) @@ -229,8 +278,7 @@ struct lt_tag_t : public my_t_impl maLanguage = r.maLanguage; maScript = r.maScript; maRegion = r.maRegion; - my_unrefList( mpVariants); - mpVariants = my_copyList( r.mpVariants); + maVariants = r.maVariants; return *this; } void assign( const char* str ) @@ -238,8 +286,7 @@ struct lt_tag_t : public my_t_impl maLanguage.zero(); maScript.zero(); maRegion.zero(); - my_unrefList( mpVariants); - mpVariants = NULL; + maVariants.zero(); my_t_impl::assign( str); } }; @@ -282,8 +329,7 @@ static lt_bool_t lt_tag_parse(lt_tag_t *tag, if (!tag_string) return 0; // In case we supported other subtags this would get more complicated. - /* TODO: variants */ - my_t_impl* aSubtags[] = { &tag->maLanguage, &tag->maScript, &tag->maRegion, NULL }; + my_t_impl* aSubtags[] = { &tag->maLanguage, &tag->maScript, &tag->maRegion, &tag->maVariants, NULL }; my_t_impl** ppSub = &aSubtags[0]; const char* pStart = tag_string; const char* p = pStart; @@ -369,10 +415,13 @@ static lt_bool_t lt_tag_parse(lt_tag_t *tag, { case 4: // script subtag, or a (DIGIT 3alphanum) variant with - // no script and no region in which case we stop - // parsing. + // no script and no region if ('0' <= *pStart && *pStart <= '9') - ppSub = NULL; + { + ppSub += 2; // &tag->maVariants XXX watch this when inserting fields + --p; + continue; // for + } else (*ppSub++)->assign( pStart, p); break; @@ -404,9 +453,11 @@ static lt_bool_t lt_tag_parse(lt_tag_t *tag, case 6: case 7: case 8: - // script omitted, region omitted, variant subtag, stop - // parsing. - ppSub = NULL; + // script omitted, region omitted, variant subtag + ppSub += 2; // &tag->maVariants XXX watch this when inserting fields + --p; + continue; // for + break; default: return 0; // bad } @@ -416,7 +467,35 @@ static lt_bool_t lt_tag_parse(lt_tag_t *tag, if (nLen == 2 || nLen == 3) (*ppSub++)->assign( pStart, p); else - return 0; // bad + { + // advance to variants + ++ppSub; + --p; + continue; // for + } + } + else if (*ppSub == &tag->maVariants) + { + // Stuff the remainder into variants, might not be correct, but ... + switch (nLen) + { + case 4: + // a (DIGIT 3alphanum) variant + if ('0' <= *pStart && *pStart <= '9') + ; // nothing + else + return 0; // bad + break; + case 5: + case 6: + case 7: + case 8: + ; // nothing, variant + break; + default: + return 0; // bad + } + (*ppSub)->append( pStart, p); } pStart = p+1; } @@ -448,7 +527,7 @@ static const lt_region_t *lt_tag_get_region(const lt_tag_t *tag) static const lt_list_t *lt_tag_get_variants(const lt_tag_t *tag) { - return tag ? tag->mpVariants : NULL; + return tag ? tag->maVariants.mpList : NULL; } static const char *lt_lang_get_tag(const lt_lang_t *lang) _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits