Always enable liblangtag
The license should not be an issue any more since liblangtag now has an LGPL/MPLv2 dual licence. Change-Id: I4dfffcccf5d710bd16b21c3254c1449ae041b8ab Reviewed-on: https://gerrit.libreoffice.org/34511 Tested-by: Jenkins <ci@libreoffice.org> Reviewed-by: Eike Rathke <erack@redhat.com>
This commit is contained in:
parent
2793561bb6
commit
8dc27a0bbf
@ -926,7 +926,6 @@ endef
|
||||
|
||||
endif # SYSTEM_LIBXSLT
|
||||
|
||||
ifeq ($(ENABLE_LIBLANGTAG),TRUE)
|
||||
|
||||
ifneq ($(SYSTEM_LIBLANGTAG),)
|
||||
|
||||
@ -985,12 +984,6 @@ endef
|
||||
|
||||
endif # SYSTEM_LIBLANGTAG
|
||||
|
||||
else
|
||||
|
||||
gb_LinkTarget__use_liblangtag :=
|
||||
gb_ExternalProject__use_liblangtag :=
|
||||
|
||||
endif # ENABLE_LIBLANGTAG
|
||||
|
||||
gb_ExternalProject__use_apr :=
|
||||
|
||||
|
@ -142,7 +142,6 @@ export ENABLE_GTK_PRINT=@ENABLE_GTK_PRINT@
|
||||
export ENABLE_HEADLESS=@ENABLE_HEADLESS@
|
||||
export ENABLE_JAVA=@ENABLE_JAVA@
|
||||
export ENABLE_KDE4=@ENABLE_KDE4@
|
||||
export ENABLE_LIBLANGTAG=@ENABLE_LIBLANGTAG@
|
||||
export ENABLE_LPSOLVE=@ENABLE_LPSOLVE@
|
||||
export ENABLE_LTO=@ENABLE_LTO@
|
||||
export ENABLE_LWP=@ENABLE_LWP@
|
||||
|
@ -1,7 +1,6 @@
|
||||
#ifndef CONFIG_LIBLANGTAG_H
|
||||
#define CONFIG_LIBLANGTAG_H
|
||||
|
||||
#define ENABLE_LIBLANGTAG 0
|
||||
#define LIBLANGTAG_INLINE_FIX 0
|
||||
|
||||
#endif
|
||||
|
51
configure.ac
51
configure.ac
@ -1485,12 +1485,6 @@ libo_FUZZ_ARG_ENABLE(firebird-sdbc,
|
||||
[Disable the build of the Firebird-SDBC driver if it doesn't compile for you.]),
|
||||
,test "${enable_firebird_sdbc+set}" = set || enable_firebird_sdbc=yes)
|
||||
|
||||
libo_FUZZ_ARG_ENABLE(liblangtag,
|
||||
AS_HELP_STRING([--disable-liblangtag],
|
||||
[Disable use of liblangtag, and instead use an own simple
|
||||
implementation.]),
|
||||
)
|
||||
|
||||
AC_ARG_ENABLE(bogus-pkg-config,
|
||||
AS_HELP_STRING([--enable-bogus-pkg-config],
|
||||
[MACOSX only: on MacOSX pkg-config can cause trouble. by default if one is found in the PATH, an error is issued. This flag turn that error into a warning.]),
|
||||
@ -11585,39 +11579,28 @@ AC_SUBST(AVAHI_LIBS)
|
||||
dnl ===================================================================
|
||||
dnl Test whether to use liblangtag
|
||||
dnl ===================================================================
|
||||
ENABLE_LIBLANGTAG=
|
||||
SYSTEM_LIBLANGTAG=
|
||||
AC_MSG_CHECKING([whether to use liblangtag])
|
||||
if test "$enable_liblangtag" = "yes" -o "$enable_liblangtag" = ""; then
|
||||
ENABLE_LIBLANGTAG=TRUE
|
||||
AC_MSG_CHECKING([whether to use system liblangtag])
|
||||
if test "$with_system_liblangtag" = yes; then
|
||||
SYSTEM_LIBLANGTAG=TRUE
|
||||
AC_MSG_RESULT([yes])
|
||||
AC_MSG_CHECKING([whether to use system liblangtag])
|
||||
if test "$with_system_liblangtag" = yes; then
|
||||
SYSTEM_LIBLANGTAG=TRUE
|
||||
AC_MSG_RESULT([yes])
|
||||
PKG_CHECK_MODULES( LIBLANGTAG, liblangtag >= 0.4.0)
|
||||
dnl cf. <https://bitbucket.org/tagoh/liblangtag/commits/9324836a0d1c> "Fix a build issue with inline keyword"
|
||||
PKG_CHECK_EXISTS([liblangtag >= 0.5.5], [], [AC_DEFINE([LIBLANGTAG_INLINE_FIX])])
|
||||
LIBLANGTAG_CFLAGS=$(printf '%s' "$LIBLANGTAG_CFLAGS" | sed -e "s/-I/${ISYSTEM?}/g")
|
||||
FilterLibs "${LIBLANGTAG_LIBS}"
|
||||
LIBLANGTAG_LIBS="${filteredlibs}"
|
||||
else
|
||||
SYSTEM_LIBLANGTAG=
|
||||
AC_MSG_RESULT([no])
|
||||
BUILD_TYPE="$BUILD_TYPE LIBLANGTAG"
|
||||
LIBLANGTAG_CFLAGS="-I${WORKDIR}/UnpackedTarball/langtag"
|
||||
if test "$COM" = "MSC"; then
|
||||
LIBLANGTAG_LIBS="${WORKDIR}/UnpackedTarball/langtag/liblangtag/.libs/liblangtag.lib"
|
||||
else
|
||||
LIBLANGTAG_LIBS="-L${WORKDIR}/UnpackedTarball/langtag/liblangtag/.libs -llangtag"
|
||||
fi
|
||||
fi
|
||||
AC_DEFINE(ENABLE_LIBLANGTAG)
|
||||
PKG_CHECK_MODULES( LIBLANGTAG, liblangtag >= 0.4.0)
|
||||
dnl cf. <https://bitbucket.org/tagoh/liblangtag/commits/9324836a0d1c> "Fix a build issue with inline keyword"
|
||||
PKG_CHECK_EXISTS([liblangtag >= 0.5.5], [], [AC_DEFINE([LIBLANGTAG_INLINE_FIX])])
|
||||
LIBLANGTAG_CFLAGS=$(printf '%s' "$LIBLANGTAG_CFLAGS" | sed -e "s/-I/${ISYSTEM?}/g")
|
||||
FilterLibs "${LIBLANGTAG_LIBS}"
|
||||
LIBLANGTAG_LIBS="${filteredlibs}"
|
||||
else
|
||||
SYSTEM_LIBLANGTAG=
|
||||
AC_MSG_RESULT([no])
|
||||
LIBLANGTAG_CFLAGS="-DDISABLE_LIBLANGTAG"
|
||||
BUILD_TYPE="$BUILD_TYPE LIBLANGTAG"
|
||||
LIBLANGTAG_CFLAGS="-I${WORKDIR}/UnpackedTarball/langtag"
|
||||
if test "$COM" = "MSC"; then
|
||||
LIBLANGTAG_LIBS="${WORKDIR}/UnpackedTarball/langtag/liblangtag/.libs/liblangtag.lib"
|
||||
else
|
||||
LIBLANGTAG_LIBS="-L${WORKDIR}/UnpackedTarball/langtag/liblangtag/.libs -llangtag"
|
||||
fi
|
||||
fi
|
||||
AC_SUBST(ENABLE_LIBLANGTAG)
|
||||
AC_SUBST(SYSTEM_LIBLANGTAG)
|
||||
AC_SUBST(LIBLANGTAG_CFLAGS)
|
||||
AC_SUBST(LIBLANGTAG_LIBS)
|
||||
|
@ -4,7 +4,6 @@
|
||||
--enable-mergelibs
|
||||
--disable-runtime-optimizations
|
||||
--disable-database-connectivity
|
||||
--disable-liblangtag
|
||||
--disable-gui
|
||||
--disable-gtk
|
||||
--disable-gtk3
|
||||
|
@ -24,7 +24,6 @@ ifneq ($(OS),MACOSX)
|
||||
ifneq ($(OS),WNT)
|
||||
$(eval $(call gb_UnpackedTarball_add_patches,libetonyek,\
|
||||
external/libetonyek/libetonyek-bundled-soname.patch.0 \
|
||||
external/libetonyek/libetonyek-support-disable-liblangtag.patch.0 \
|
||||
))
|
||||
endif
|
||||
endif
|
||||
|
@ -1,130 +0,0 @@
|
||||
--- src/lib/IWORKLanguageManager.cpp.orig 2017-02-21 10:28:39.646017140 +0000
|
||||
+++ src/lib/IWORKLanguageManager.cpp 2017-02-21 10:29:26.601817549 +0000
|
||||
@@ -12,7 +12,9 @@
|
||||
#include <cstdlib>
|
||||
#include <stdexcept>
|
||||
|
||||
+#if !defined(DISABLE_LIBLANGTAG)
|
||||
#include <liblangtag/langtag.h>
|
||||
+#endif
|
||||
|
||||
#include "libetonyek_utils.h"
|
||||
|
||||
@@ -27,6 +29,7 @@
|
||||
|
||||
using std::string;
|
||||
|
||||
+#if !defined(DISABLE_LIBLANGTAG)
|
||||
namespace
|
||||
{
|
||||
|
||||
@@ -56,6 +59,7 @@
|
||||
}
|
||||
|
||||
}
|
||||
+#endif
|
||||
|
||||
struct IWORKLanguageManager::LangDB
|
||||
{
|
||||
@@ -67,6 +71,7 @@
|
||||
IWORKLanguageManager::LangDB::LangDB()
|
||||
: m_db()
|
||||
{
|
||||
+#if !defined(DISABLE_LIBLANGTAG)
|
||||
shared_ptr<lt_lang_db_t> langDB(lt_db_get_lang(), lt_lang_db_unref);
|
||||
shared_ptr<lt_iter_t> it(LT_ITER_INIT(langDB.get()), lt_iter_finish);
|
||||
lt_pointer_t key(0);
|
||||
@@ -77,6 +82,7 @@
|
||||
lt_lang_t *const lang = reinterpret_cast<lt_lang_t *>(value);
|
||||
m_db[lt_lang_get_name(lang)] = tag;
|
||||
}
|
||||
+#endif
|
||||
}
|
||||
|
||||
IWORKLanguageManager::IWORKLanguageManager()
|
||||
@@ -102,6 +108,10 @@
|
||||
if (invIt != m_invalidTags.end())
|
||||
return "";
|
||||
|
||||
+#if defined(DISABLE_LIBLANGTAG)
|
||||
+ m_invalidTags.insert(tag);
|
||||
+ return "";
|
||||
+#else
|
||||
const shared_ptr<lt_tag_t> &langTag = parseTag(tag);
|
||||
if (!langTag)
|
||||
{
|
||||
@@ -114,6 +124,7 @@
|
||||
addProperties(fullTag);
|
||||
|
||||
return fullTag;
|
||||
+#endif
|
||||
}
|
||||
|
||||
const std::string IWORKLanguageManager::addLanguage(const std::string &lang)
|
||||
@@ -134,6 +145,10 @@
|
||||
return "";
|
||||
}
|
||||
|
||||
+#if defined(DISABLE_LIBLANGTAG)
|
||||
+ m_invalidLangs.insert(lang);
|
||||
+ return "";
|
||||
+#else
|
||||
const shared_ptr<lt_tag_t> &langTag = parseTag(langIt->second);
|
||||
if (!langTag)
|
||||
throw std::logic_error("cannot parse tag that came from liblangtag language DB");
|
||||
@@ -143,6 +158,7 @@
|
||||
addProperties(fullTag);
|
||||
|
||||
return fullTag;
|
||||
+#endif
|
||||
}
|
||||
|
||||
const std::string IWORKLanguageManager::addLocale(const std::string &locale)
|
||||
@@ -156,6 +172,9 @@
|
||||
if (invIt != m_invalidLocales.end())
|
||||
return "";
|
||||
|
||||
+#if defined(DISABLE_LIBLANGTAG)
|
||||
+ return "";
|
||||
+#else
|
||||
lt_error_t *error = 0;
|
||||
const shared_ptr<lt_tag_t> tag(lt_tag_convert_from_locale_string(locale.c_str(), &error), lt_tag_unref);
|
||||
if ((error && lt_error_is_set(error, LT_ERR_ANY)) || !tag)
|
||||
@@ -170,14 +189,19 @@
|
||||
addProperties(fullTag);
|
||||
|
||||
return fullTag;
|
||||
+#endif
|
||||
}
|
||||
|
||||
const std::string IWORKLanguageManager::getLanguage(const std::string &tag) const
|
||||
{
|
||||
+#if defined(DISABLE_LIBLANGTAG)
|
||||
+ return "";
|
||||
+#else
|
||||
const shared_ptr<lt_tag_t> &langTag = parseTag(tag);
|
||||
if (!langTag)
|
||||
throw std::logic_error("cannot parse tag that has been successfully parsed before");
|
||||
return lt_lang_get_name(lt_tag_get_language(langTag.get()));
|
||||
+#endif
|
||||
}
|
||||
|
||||
const IWORKLanguageManager::LangDB &IWORKLanguageManager::getLangDB() const
|
||||
@@ -189,6 +213,9 @@
|
||||
|
||||
void IWORKLanguageManager::addProperties(const std::string &tag)
|
||||
{
|
||||
+#if defined(DISABLE_LIBLANGTAG)
|
||||
+ return;
|
||||
+#else
|
||||
const shared_ptr<lt_tag_t> &langTag = parseTag(tag);
|
||||
if (!langTag)
|
||||
throw std::logic_error("cannot parse tag that has been successfully parsed before");
|
||||
@@ -205,6 +232,7 @@
|
||||
props.insert("fo:script", lt_script_get_tag(script));
|
||||
|
||||
m_propsMap[tag] = props;
|
||||
+#endif
|
||||
}
|
||||
|
||||
void IWORKLanguageManager::writeProperties(const std::string &tag, librevenge::RVNGPropertyList &props) const
|
@ -21,7 +21,6 @@ $(eval $(call gb_CppunitTest_use_libraries,i18nlangtag_test_languagetag,\
|
||||
$(gb_UWINAPI) \
|
||||
))
|
||||
|
||||
ifeq ($(ENABLE_LIBLANGTAG),TRUE)
|
||||
$(eval $(call gb_CppunitTest_use_externals,i18nlangtag_test_languagetag,\
|
||||
liblangtag \
|
||||
libxml2 \
|
||||
@ -32,7 +31,6 @@ $(eval $(call gb_CppunitTest_add_defs,i18nlangtag_test_languagetag,-DSYSTEM_LIBL
|
||||
else
|
||||
$(eval $(call gb_CppunitTest_use_package,i18nlangtag_test_languagetag,liblangtag_data))
|
||||
endif
|
||||
endif
|
||||
|
||||
$(eval $(call gb_CppunitTest_add_exception_objects,i18nlangtag_test_languagetag,\
|
||||
i18nlangtag/qa/cppunit/test_languagetag \
|
||||
|
@ -35,7 +35,6 @@ $(eval $(call gb_Library_add_exception_objects,i18nlangtag,\
|
||||
))
|
||||
|
||||
|
||||
ifeq ($(ENABLE_LIBLANGTAG),TRUE)
|
||||
$(eval $(call gb_Library_use_external,i18nlangtag,liblangtag))
|
||||
$(eval $(call gb_Library_use_external,i18nlangtag,libxml2))
|
||||
$(eval $(call gb_Library_use_system_win32_libs,i18nlangtag,\
|
||||
@ -43,6 +42,5 @@ $(eval $(call gb_Library_use_system_win32_libs,i18nlangtag,\
|
||||
kernel32 \
|
||||
) \
|
||||
))
|
||||
endif
|
||||
|
||||
# vim: set noet sw=4 ts=4:
|
||||
|
@ -17,7 +17,6 @@
|
||||
#include <i18nlangtag/mslangid.hxx>
|
||||
#include <i18nlangtag/languagetag.hxx>
|
||||
|
||||
#include <config_liblangtag.h>
|
||||
#include <rtl/ustring.hxx>
|
||||
#include <rtl/ustrbuf.hxx>
|
||||
#include <osl/file.hxx>
|
||||
@ -51,7 +50,6 @@ void TestLanguageTag::testAllTags()
|
||||
OUString aBcp47 = de_DE.getBcp47();
|
||||
lang::Locale aLocale = de_DE.getLocale();
|
||||
LanguageType nLanguageType = de_DE.getLanguageType();
|
||||
#if ENABLE_LIBLANGTAG
|
||||
CPPUNIT_ASSERT_EQUAL_MESSAGE("Default script should be stripped after canonicalize.", OUString("de-DE"), aBcp47 );
|
||||
CPPUNIT_ASSERT_EQUAL( OUString("de"), aLocale.Language );
|
||||
CPPUNIT_ASSERT_EQUAL( OUString("DE"), aLocale.Country );
|
||||
@ -61,18 +59,6 @@ void TestLanguageTag::testAllTags()
|
||||
CPPUNIT_ASSERT_EQUAL( OUString("DE"), de_DE.getCountry() );
|
||||
CPPUNIT_ASSERT( de_DE.getScript().isEmpty() );
|
||||
CPPUNIT_ASSERT_EQUAL( OUString("de"), de_DE.getLanguageAndScript() );
|
||||
#else
|
||||
// The simple replacement code doesn't do any fancy stuff.
|
||||
CPPUNIT_ASSERT_MESSAGE("Default script was stripped after canonicalize!?!", aBcp47 == s_de_Latn_DE );
|
||||
CPPUNIT_ASSERT( aLocale.Language == "qlt" );
|
||||
CPPUNIT_ASSERT( aLocale.Country == "DE" );
|
||||
CPPUNIT_ASSERT( aLocale.Variant == "de-Latn-DE" );
|
||||
CPPUNIT_ASSERT( LanguageTag::isOnTheFlyID( nLanguageType) ); // XXX not canonicalized!
|
||||
CPPUNIT_ASSERT( de_DE.getLanguage() == "de" );
|
||||
CPPUNIT_ASSERT( de_DE.getCountry() == "DE" );
|
||||
CPPUNIT_ASSERT( de_DE.getScript() == "Latn" );
|
||||
CPPUNIT_ASSERT( de_DE.getLanguageAndScript() == "de-Latn" );
|
||||
#endif
|
||||
CPPUNIT_ASSERT_EQUAL( OUString("de-DE"), de_DE.makeFallback().getBcp47() );
|
||||
}
|
||||
|
||||
@ -80,7 +66,6 @@ void TestLanguageTag::testAllTags()
|
||||
OUString s_klingon( "i-klingon" );
|
||||
LanguageTag klingon( s_klingon, true );
|
||||
lang::Locale aLocale = klingon.getLocale();
|
||||
#if ENABLE_LIBLANGTAG
|
||||
CPPUNIT_ASSERT_EQUAL( OUString("tlh"), klingon.getBcp47() );
|
||||
CPPUNIT_ASSERT_EQUAL( OUString("tlh"), aLocale.Language );
|
||||
CPPUNIT_ASSERT( aLocale.Country.isEmpty() );
|
||||
@ -92,19 +77,6 @@ void TestLanguageTag::testAllTags()
|
||||
LanguageType nLang = klingon.getLanguageType();
|
||||
LanguageTag klingon_id( nLang);
|
||||
CPPUNIT_ASSERT_EQUAL( OUString("tlh"), klingon_id.getBcp47() );
|
||||
#else
|
||||
CPPUNIT_ASSERT( klingon.getBcp47() == s_klingon );
|
||||
CPPUNIT_ASSERT( aLocale.Language == "qlt" );
|
||||
CPPUNIT_ASSERT_EQUAL( OUString(), aLocale.Country );
|
||||
CPPUNIT_ASSERT( aLocale.Variant == s_klingon );
|
||||
CPPUNIT_ASSERT( LanguageTag::isOnTheFlyID( klingon.getLanguageType()) );
|
||||
CPPUNIT_ASSERT( klingon.isValidBcp47() );
|
||||
CPPUNIT_ASSERT( !klingon.isIsoLocale() );
|
||||
CPPUNIT_ASSERT( !klingon.isIsoODF() );
|
||||
LanguageType nLang = klingon.getLanguageType();
|
||||
LanguageTag klingon_id( nLang);
|
||||
CPPUNIT_ASSERT( klingon_id.getBcp47() == s_klingon );
|
||||
#endif
|
||||
}
|
||||
|
||||
{
|
||||
@ -462,7 +434,6 @@ void TestLanguageTag::testAllTags()
|
||||
CPPUNIT_ASSERT_EQUAL( OUString("en"), en_GB_oxendict_Fallbacks[4]);
|
||||
}
|
||||
|
||||
#if ENABLE_LIBLANGTAG
|
||||
// 'zh-yue-HK' uses redundant 'zh-yue' and should be preferred 'yue-HK'
|
||||
#if 0
|
||||
/* XXX Disabled because liblangtag in lt_tag_canonicalize() after replacing
|
||||
@ -491,7 +462,6 @@ void TestLanguageTag::testAllTags()
|
||||
CPPUNIT_ASSERT( zh_yue_HK_Fallbacks[0] == "yue-HK");
|
||||
CPPUNIT_ASSERT( zh_yue_HK_Fallbacks[1] == "yue");
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// 'qtz' is a local use known pseudolocale for key ID resource
|
||||
@ -651,7 +621,6 @@ void TestLanguageTag::testAllTags()
|
||||
CPPUNIT_ASSERT( LanguageTag::isValidBcp47( "en-US", &aCanonicalized, true) && aCanonicalized == "en-US" );
|
||||
CPPUNIT_ASSERT( !LanguageTag::isValidBcp47( "x-foobar", &aCanonicalized, true) && aCanonicalized == "x-foobar" );
|
||||
CPPUNIT_ASSERT( LanguageTag::isValidBcp47( "qaa", &aCanonicalized, true) && aCanonicalized == "qaa" );
|
||||
#if ENABLE_LIBLANGTAG
|
||||
CPPUNIT_ASSERT( LanguageTag::isValidBcp47( "de-Latn-DE", &aCanonicalized) && aCanonicalized == "de-DE" );
|
||||
/* TODO: at least some (those we know) grandfathered tags should be
|
||||
* recognized by the replacement code. */
|
||||
@ -659,9 +628,6 @@ void TestLanguageTag::testAllTags()
|
||||
// en-GB-oed has become deprecated in updated language-subtag-registry database
|
||||
// (liblangtag 0.5.7)
|
||||
CPPUNIT_ASSERT( ( aCanonicalized == "en-GB-oxendict" ) || ( aCanonicalized == "en-GB-oed" ) );
|
||||
#else
|
||||
CPPUNIT_ASSERT( LanguageTag::isValidBcp47( "de-Latn-DE", &aCanonicalized) && aCanonicalized == "de-Latn-DE" );
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -24,19 +24,10 @@
|
||||
|
||||
//#define erDEBUG
|
||||
|
||||
#if ENABLE_LIBLANGTAG
|
||||
#if LIBLANGTAG_INLINE_FIX
|
||||
#define LT_HAVE_INLINE
|
||||
#endif
|
||||
#include <liblangtag/langtag.h>
|
||||
#else
|
||||
/* Replacement code for LGPL phobic and Android systems.
|
||||
* For iOS we could probably use NSLocale instead, that should have more or
|
||||
* less required functionality. If it is good enough, it could be used for Mac
|
||||
* OS X, too.
|
||||
*/
|
||||
#include "simple-langtag.cxx"
|
||||
#endif
|
||||
|
||||
using namespace com::sun::star;
|
||||
|
||||
|
@ -1,590 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/*
|
||||
* This file is part of the LibreOffice project.
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
/** Cheap and cheesy replacement code for liblangtag on systems that do not
|
||||
allow / want LGPL code or dependencies on glib.
|
||||
|
||||
XXX NOTE: This code does not check language tags for validity or if they
|
||||
are registered with IANA, does not canonicalize or strip default script
|
||||
tags if included nor does it do any other fancy stuff that liblangtag is
|
||||
capable of. It just makes depending code work without.
|
||||
*/
|
||||
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <cstdio>
|
||||
|
||||
namespace {
|
||||
|
||||
typedef void* lt_pointer_t;
|
||||
|
||||
struct lt_error_t {
|
||||
void *something;
|
||||
lt_error_t() : something(nullptr) {}
|
||||
};
|
||||
|
||||
void* g_malloc(size_t s)
|
||||
{
|
||||
return malloc(s);
|
||||
}
|
||||
|
||||
void g_free(void* p)
|
||||
{
|
||||
if (p)
|
||||
free(p);
|
||||
}
|
||||
|
||||
void lt_error_unref(lt_error_t *error)
|
||||
{
|
||||
if (error)
|
||||
{
|
||||
g_free( error->something);
|
||||
g_free( error);
|
||||
}
|
||||
}
|
||||
|
||||
struct my_ref
|
||||
{
|
||||
sal_uInt32 mnRef;
|
||||
explicit my_ref() : mnRef(1) {}
|
||||
virtual ~my_ref() {}
|
||||
void incRef() { ++mnRef; }
|
||||
void decRef() { if (--mnRef == 0) delete this; }
|
||||
};
|
||||
|
||||
struct my_t_impl : public my_ref
|
||||
{
|
||||
char* mpStr;
|
||||
explicit my_t_impl() : my_ref(), mpStr(nullptr) {}
|
||||
virtual ~my_t_impl() override { g_free( mpStr); }
|
||||
explicit my_t_impl( const my_t_impl& r )
|
||||
:
|
||||
my_ref(),
|
||||
mpStr(r.mpStr ? strdup( r.mpStr) : nullptr)
|
||||
{
|
||||
}
|
||||
my_t_impl& operator=( const my_t_impl& r )
|
||||
{
|
||||
if (this == &r)
|
||||
return *this;
|
||||
g_free( mpStr);
|
||||
mpStr = (r.mpStr ? strdup( r.mpStr) : nullptr);
|
||||
return *this;
|
||||
}
|
||||
void assign( const char* str )
|
||||
{
|
||||
g_free( mpStr);
|
||||
mpStr = (str ? strdup( str) : nullptr);
|
||||
}
|
||||
void assign( const char* str, const char* stop )
|
||||
{
|
||||
g_free( mpStr);
|
||||
if (str && str < stop)
|
||||
{
|
||||
mpStr = static_cast<char*>(g_malloc( stop - str + 1));
|
||||
memcpy( mpStr, str, stop - str);
|
||||
mpStr[stop - str] = 0;
|
||||
}
|
||||
else
|
||||
mpStr = nullptr;
|
||||
}
|
||||
virtual void append( const char* str, const char* stop )
|
||||
{
|
||||
if (str && str < stop)
|
||||
{
|
||||
size_t nOld = mpStr ? strlen( mpStr) : 0;
|
||||
size_t nNew = nOld + (stop - str) + 1;
|
||||
char* p = static_cast<char*>(g_malloc( nNew));
|
||||
if (nOld)
|
||||
memcpy( p, mpStr, nOld);
|
||||
memcpy( p + nOld, str, stop - str);
|
||||
p[nNew-1] = 0;
|
||||
g_free( mpStr);
|
||||
mpStr = p;
|
||||
}
|
||||
}
|
||||
virtual void zero()
|
||||
{
|
||||
g_free( mpStr);
|
||||
mpStr = nullptr;
|
||||
}
|
||||
};
|
||||
|
||||
struct lt_lang_t : public my_t_impl
|
||||
{
|
||||
explicit lt_lang_t() : my_t_impl() {}
|
||||
virtual ~lt_lang_t() override {}
|
||||
};
|
||||
|
||||
struct lt_script_t : public my_t_impl
|
||||
{
|
||||
explicit lt_script_t() : my_t_impl() {}
|
||||
virtual ~lt_script_t() override {}
|
||||
};
|
||||
|
||||
struct lt_region_t : public my_t_impl
|
||||
{
|
||||
explicit lt_region_t() : my_t_impl() {}
|
||||
virtual ~lt_region_t() override {}
|
||||
};
|
||||
|
||||
struct lt_variant_t : public my_t_impl
|
||||
{
|
||||
explicit lt_variant_t() : my_t_impl() {}
|
||||
virtual ~lt_variant_t() override {}
|
||||
};
|
||||
|
||||
struct lt_string_t : public my_t_impl
|
||||
{
|
||||
explicit lt_string_t() : my_t_impl() {}
|
||||
virtual ~lt_string_t() override {}
|
||||
};
|
||||
|
||||
struct lt_list_t : public my_t_impl
|
||||
{
|
||||
lt_list_t* mpPrev;
|
||||
lt_list_t* mpNext;
|
||||
explicit lt_list_t() : my_t_impl(), mpPrev(nullptr), mpNext(nullptr) {}
|
||||
explicit lt_list_t( const lt_list_t& r )
|
||||
:
|
||||
my_t_impl( r), mpPrev(nullptr), mpNext(nullptr)
|
||||
{
|
||||
}
|
||||
virtual ~lt_list_t() override
|
||||
{
|
||||
if (mpPrev)
|
||||
mpPrev->mpNext = mpNext;
|
||||
if (mpNext)
|
||||
mpNext->mpPrev = mpPrev;
|
||||
}
|
||||
};
|
||||
|
||||
lt_pointer_t lt_list_value( const lt_list_t* p )
|
||||
{
|
||||
// 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));
|
||||
}
|
||||
|
||||
const lt_list_t* lt_list_next( const lt_list_t* p )
|
||||
{
|
||||
return p ? p->mpNext : nullptr;
|
||||
}
|
||||
|
||||
lt_list_t* my_copyList( const lt_list_t * pList )
|
||||
{
|
||||
lt_list_t* pNewList = nullptr;
|
||||
lt_list_t* pLast = nullptr;
|
||||
while (pList)
|
||||
{
|
||||
lt_list_t* p = new lt_list_t( *pList);
|
||||
if (!pNewList)
|
||||
pNewList = p;
|
||||
if (pLast)
|
||||
{
|
||||
pLast->mpNext = p;
|
||||
p->mpPrev = pLast;
|
||||
}
|
||||
pLast = p;
|
||||
pList = pList->mpNext;
|
||||
}
|
||||
return pNewList;
|
||||
}
|
||||
|
||||
void my_unrefList( lt_list_t* pList )
|
||||
{
|
||||
while (pList)
|
||||
{
|
||||
lt_list_t* pNext = pList->mpNext;
|
||||
pList->decRef();
|
||||
pList = pNext;
|
||||
}
|
||||
}
|
||||
|
||||
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(nullptr) {}
|
||||
explicit my_t_list( const my_t_list& r ) : my_t_impl( r), mpList( my_copyList( r.mpList)) {}
|
||||
virtual ~my_t_list() override
|
||||
{
|
||||
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;
|
||||
return *this;
|
||||
}
|
||||
virtual void append( const char* str, const char* stop ) override
|
||||
{
|
||||
lt_list_t* p = new lt_list_t;
|
||||
p->assign( str, stop);
|
||||
my_appendToList( &mpList, p);
|
||||
}
|
||||
virtual void zero() override
|
||||
{
|
||||
my_t_impl::zero();
|
||||
my_unrefList( mpList);
|
||||
mpList = nullptr;
|
||||
}
|
||||
};
|
||||
|
||||
struct lt_tag_t : public my_t_impl
|
||||
{
|
||||
lt_lang_t maLanguage;
|
||||
lt_script_t maScript;
|
||||
lt_region_t maRegion;
|
||||
my_t_list maVariants;
|
||||
lt_string_t maPrivateUse;
|
||||
explicit lt_tag_t() : my_t_impl(), maLanguage(), maScript(), maRegion(), maVariants() {}
|
||||
virtual ~lt_tag_t() override {}
|
||||
explicit lt_tag_t( const lt_tag_t& r )
|
||||
:
|
||||
my_t_impl( r),
|
||||
maLanguage( r.maLanguage),
|
||||
maScript( r.maScript),
|
||||
maRegion( r.maRegion),
|
||||
maVariants( r.maVariants)
|
||||
{
|
||||
}
|
||||
lt_tag_t& operator=( const lt_tag_t& r )
|
||||
{
|
||||
if (this == &r)
|
||||
return *this;
|
||||
my_t_impl::operator=( r);
|
||||
maLanguage = r.maLanguage;
|
||||
maScript = r.maScript;
|
||||
maRegion = r.maRegion;
|
||||
maVariants = r.maVariants;
|
||||
return *this;
|
||||
}
|
||||
void assign( const char* str )
|
||||
{
|
||||
maLanguage.zero();
|
||||
maScript.zero();
|
||||
maRegion.zero();
|
||||
maVariants.zero();
|
||||
my_t_impl::assign( str);
|
||||
}
|
||||
};
|
||||
|
||||
void lt_db_initialize() { }
|
||||
void lt_db_finalize() { }
|
||||
void lt_db_set_datadir( const char* /* dir */ ) { }
|
||||
|
||||
lt_tag_t* lt_tag_new()
|
||||
{
|
||||
return new lt_tag_t;
|
||||
}
|
||||
|
||||
lt_tag_t* lt_tag_copy(lt_tag_t *tag)
|
||||
{
|
||||
return (tag ? new lt_tag_t( *tag) : nullptr);
|
||||
}
|
||||
|
||||
void lt_tag_unref(lt_tag_t *tag)
|
||||
{
|
||||
if (tag)
|
||||
tag->decRef();
|
||||
}
|
||||
|
||||
/** See http://tools.ietf.org/html/rfc5646
|
||||
|
||||
We are simply ignorant of grandfathered (irregular and regular) subtags and
|
||||
may either bail out or accept them, sorry (or not). However, we do accept
|
||||
any i-* irregular and x-* privateuse. Subtags are not checked for validity
|
||||
(alpha, digit, registered, ...).
|
||||
*/
|
||||
int lt_tag_parse(lt_tag_t *tag,
|
||||
const char *tag_string,
|
||||
lt_error_t **error)
|
||||
{
|
||||
(void) error;
|
||||
if (!tag)
|
||||
return 0;
|
||||
tag->assign( tag_string);
|
||||
if (!tag_string)
|
||||
return 0;
|
||||
// In case we supported other subtags this would get more complicated.
|
||||
my_t_impl* aSubtags[] = { &tag->maLanguage, &tag->maScript, &tag->maRegion, &tag->maVariants, nullptr };
|
||||
my_t_impl** ppSub = &aSubtags[0];
|
||||
const char* pStart = tag_string;
|
||||
const char* p = pStart;
|
||||
const char* pEnd = pStart + strlen( pStart); // scanning includes \0
|
||||
bool bStartLang = true;
|
||||
bool bPrivate = false;
|
||||
for ( ; p <= pEnd && ppSub && *ppSub; ++p)
|
||||
{
|
||||
if (p == pEnd || *p == '-')
|
||||
{
|
||||
size_t nLen = p - pStart;
|
||||
if (*ppSub == &tag->maLanguage)
|
||||
{
|
||||
if (bStartLang)
|
||||
{
|
||||
bStartLang = false;
|
||||
switch (nLen)
|
||||
{
|
||||
case 1: // irregular or privateuse
|
||||
if (*pStart == 'i' || *pStart == 'x')
|
||||
{
|
||||
(*ppSub)->assign( pStart, p);
|
||||
bPrivate = true;
|
||||
if (*pStart == 'x')
|
||||
{
|
||||
// Simply copy all to privateuse field, we
|
||||
// do not care here what part actually is
|
||||
// private.
|
||||
tag->maPrivateUse.assign( pStart, pEnd);
|
||||
}
|
||||
}
|
||||
else
|
||||
return 0; // bad
|
||||
break;
|
||||
case 2: // ISO 639 alpha-2
|
||||
case 3: // ISO 639 alpha-3
|
||||
(*ppSub)->assign( pStart, p);
|
||||
break;
|
||||
case 4: // reserved for future use
|
||||
return 0; // bad
|
||||
break;
|
||||
case 5:
|
||||
case 6:
|
||||
case 7:
|
||||
case 8: // registered language subtag
|
||||
(*ppSub++)->assign( pStart, p);
|
||||
break;
|
||||
default:
|
||||
return 0; // bad
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (nLen > 8)
|
||||
return 0; // bad
|
||||
if (bPrivate)
|
||||
{
|
||||
// Any combination of "x" 1*("-" (2*8alphanum))
|
||||
// allowed, store first as language and return ok.
|
||||
// For i-* simply assume the same.
|
||||
(*ppSub)->append( pStart-1, p);
|
||||
return 1; // ok
|
||||
}
|
||||
else if (nLen == 3)
|
||||
{
|
||||
// extlang subtag, 1 to 3 allowed we don't check that.
|
||||
// But if it's numeric it's a region UN M.49 code
|
||||
// instead and no script subtag is present, so advance.
|
||||
if ('0' <= *pStart && *pStart <= '9')
|
||||
{
|
||||
ppSub += 2; // &tag->maRegion XXX watch this when inserting fields
|
||||
--p;
|
||||
continue; // for
|
||||
}
|
||||
else
|
||||
(*ppSub)->append( pStart-1, p);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Not part of language subtag, advance.
|
||||
++ppSub;
|
||||
--p;
|
||||
continue; // for
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (*ppSub == &tag->maScript)
|
||||
{
|
||||
switch (nLen)
|
||||
{
|
||||
case 4:
|
||||
// script subtag, or a (DIGIT 3alphanum) variant with
|
||||
// no script and no region
|
||||
if ('0' <= *pStart && *pStart <= '9')
|
||||
{
|
||||
ppSub += 2; // &tag->maVariants XXX watch this when inserting fields
|
||||
--p;
|
||||
continue; // for
|
||||
}
|
||||
else
|
||||
(*ppSub++)->assign( pStart, p);
|
||||
break;
|
||||
case 3:
|
||||
// This may be a region UN M.49 code if 3DIGIT and no
|
||||
// script code present. Just check first character and
|
||||
// advance.
|
||||
if ('0' <= *pStart && *pStart <= '9')
|
||||
{
|
||||
++ppSub;
|
||||
--p;
|
||||
continue; // for
|
||||
}
|
||||
else
|
||||
return 0; // bad
|
||||
break;
|
||||
case 2:
|
||||
// script omitted, region subtag, advance.
|
||||
++ppSub;
|
||||
--p;
|
||||
continue; // for
|
||||
break;
|
||||
case 1:
|
||||
// script omitted, region omitted, extension subtag
|
||||
// with singleton, stop parsing
|
||||
ppSub = nullptr;
|
||||
break;
|
||||
case 5:
|
||||
case 6:
|
||||
case 7:
|
||||
case 8:
|
||||
// script omitted, region omitted, variant subtag
|
||||
ppSub += 2; // &tag->maVariants XXX watch this when inserting fields
|
||||
--p;
|
||||
continue; // for
|
||||
break;
|
||||
default:
|
||||
return 0; // bad
|
||||
}
|
||||
}
|
||||
else if (*ppSub == &tag->maRegion)
|
||||
{
|
||||
if (nLen == 2 || nLen == 3)
|
||||
(*ppSub++)->assign( pStart, p);
|
||||
else
|
||||
{
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
char* lt_tag_canonicalize(lt_tag_t *tag,
|
||||
lt_error_t **error)
|
||||
{
|
||||
(void) error;
|
||||
return tag && tag->mpStr ? strdup( tag->mpStr) : nullptr;
|
||||
}
|
||||
|
||||
const lt_lang_t* lt_tag_get_language(const lt_tag_t *tag)
|
||||
{
|
||||
return tag && tag->maLanguage.mpStr ? &tag->maLanguage : nullptr;
|
||||
}
|
||||
|
||||
const lt_script_t *lt_tag_get_script(const lt_tag_t *tag)
|
||||
{
|
||||
return tag && tag->maScript.mpStr ? &tag->maScript : nullptr;
|
||||
}
|
||||
|
||||
const lt_region_t *lt_tag_get_region(const lt_tag_t *tag)
|
||||
{
|
||||
return tag && tag->maRegion.mpStr ? &tag->maRegion : nullptr;
|
||||
}
|
||||
|
||||
const lt_list_t *lt_tag_get_variants(const lt_tag_t *tag)
|
||||
{
|
||||
return tag ? tag->maVariants.mpList : nullptr;
|
||||
}
|
||||
|
||||
const lt_string_t *lt_tag_get_privateuse(const lt_tag_t *tag)
|
||||
{
|
||||
return tag && tag->maPrivateUse.mpStr ? &tag->maPrivateUse : nullptr;
|
||||
}
|
||||
|
||||
const char *lt_lang_get_tag(const lt_lang_t *lang)
|
||||
{
|
||||
return lang ? lang->mpStr : nullptr;
|
||||
}
|
||||
|
||||
const char *lt_script_get_tag(const lt_script_t *script)
|
||||
{
|
||||
return script ? script->mpStr : nullptr;
|
||||
}
|
||||
|
||||
const char *lt_region_get_tag(const lt_region_t *region)
|
||||
{
|
||||
return region ? region->mpStr : nullptr;
|
||||
}
|
||||
|
||||
const char *lt_variant_get_tag(const lt_variant_t *variant)
|
||||
{
|
||||
return variant ? variant->mpStr : nullptr;
|
||||
}
|
||||
|
||||
size_t lt_string_length(const lt_string_t *string)
|
||||
{
|
||||
return string ? strlen(string->mpStr) : 0;
|
||||
}
|
||||
|
||||
#ifdef erDEBUG
|
||||
void lt_tag_dump(const lt_tag_t *tag)
|
||||
{
|
||||
fprintf( stderr, "\n");
|
||||
fprintf( stderr, "SimpleLangtag langtag: %s\n", tag->mpStr);
|
||||
fprintf( stderr, "SimpleLangtag language: %s\n", tag->maLanguage.mpStr);
|
||||
fprintf( stderr, "SimpleLangtag script: %s\n", tag->maScript.mpStr);
|
||||
fprintf( stderr, "SimpleLangtag region: %s\n", tag->maRegion.mpStr);
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|
Loading…
x
Reference in New Issue
Block a user