formula/source/core/api/FormulaCompiler.cxx | 19 ++--
sc/inc/compiler.hxx |9 ++--
sc/source/core/tool/compiler.cxx| 62 ++--
3 files changed, 62 insertions(+), 28 deletions(-)
New commits:
commit 3c6177be2705303044e3de262689d593f3d0f282
Author: Eike Rathke
AuthorDate: Mon Sep 28 21:02:23 2020 +0200
Commit: Eike Rathke
CommitDate: Tue Sep 29 00:54:12 2020 +0200
Resolves: tdf#137091 Use CharClass matching the formula language
... not the current locale. Specifically important for
uppercase/lowercase conversions that may yield different results
for example in Turkish i with/without dot.
Change-Id: I2aa57cdcf530d7a0697c4ffbd5dccb86bb526d8e
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/103588
Tested-by: Jenkins
Reviewed-by: Eike Rathke
diff --git a/formula/source/core/api/FormulaCompiler.cxx
b/formula/source/core/api/FormulaCompiler.cxx
index e6a224fa93a7..e969ecba4344 100644
--- a/formula/source/core/api/FormulaCompiler.cxx
+++ b/formula/source/core/api/FormulaCompiler.cxx
@@ -29,6 +29,9 @@
#include
#include
+#include
+#include
+#include
#include
#include
#include
@@ -140,6 +143,14 @@ void lclPushOpCodeMapEntries( ::std::vector<
sheet::FormulaOpCodeMapEntry >& rVe
lclPushOpCodeMapEntry( rVec, pTable, *pnOpCodes );
}
+CharClass* createCharClassIfNonEnglishUI()
+{
+const LanguageTag& rLanguageTag(
Application::GetSettings().GetUILanguageTag());
+if (rLanguageTag.getLanguage() == "en")
+return nullptr;
+return new CharClass( ::comphelper::getProcessComponentContext(),
rLanguageTag);
+}
+
class OpCodeList
{
public:
@@ -163,8 +174,8 @@ OpCodeList::OpCodeList(bool bLocalized, const
std::pair* pSymb
, mpSymbols(pSymbols)
, mbLocalized(bLocalized)
{
-SvtSysLocale aSysLocale;
-const CharClass* pCharClass = (xMap->isEnglish() ? nullptr :
aSysLocale.GetCharClassPtr());
+std::unique_ptr xCharClass( xMap->isEnglish() ? nullptr :
createCharClassIfNonEnglishUI());
+const CharClass* pCharClass = xCharClass.get();
if (meSepType == FormulaCompiler::SeparatorType::RESOURCE_BASE)
{
for (sal_uInt16 i = 0; i <= SC_OPCODE_LAST_OPCODE_ID; ++i)
@@ -809,8 +820,8 @@ FormulaCompiler::OpCodeMapPtr
FormulaCompiler::CreateOpCodeMap(
NonConstOpCodeMapPtr xMap = std::make_shared(
SC_OPCODE_LAST_OPCODE_ID + 1, false,
FormulaGrammar::mergeToGrammar( FormulaGrammar::setEnglishBit(
FormulaGrammar::GRAM_EXTERNAL, bEnglish),
FormulaGrammar::CONV_UNSPECIFIED));
-SvtSysLocale aSysLocale;
-const CharClass* pCharClass = (xMap->isEnglish() ? nullptr :
aSysLocale.GetCharClassPtr());
+std::unique_ptr xCharClass( xMap->isEnglish() ? nullptr :
createCharClassIfNonEnglishUI());
+const CharClass* pCharClass = xCharClass.get();
for (auto const& rMapEntry : rMapping)
{
OpCode eOp = OpCode(rMapEntry.Token.OpCode);
diff --git a/sc/inc/compiler.hxx b/sc/inc/compiler.hxx
index b09bce06797d..c4550a2ae3f6 100644
--- a/sc/inc/compiler.hxx
+++ b/sc/inc/compiler.hxx
@@ -254,7 +254,8 @@ public:
private:
-static CharClass*pCharClassEnglish; //
character classification for en_US locale
+static const CharClass *pCharClassEnglish; // character
classification for en_US locale
+static const CharClass *pCharClassLocalized; // character
classification for UI locale
static const Convention *pConventions[
formula::FormulaGrammar::CONV_LAST ];
static const struct AddInMap
@@ -285,7 +286,7 @@ private:
std::queue maPendingOpCodes; // additional opcodes generated from
a single symbol
-const CharClass*pCharClass; // which character classification
is used for parseAnyToken
+const CharClass* pCharClass; // which character classification is used for
parseAnyToken and upper/lower
sal_uInt16 mnPredetectedReference; // reference when reading ODF,
0 (none), 1 (single) or 2 (double)
sal_Int32 mnRangeOpPosInSymbol; // if and where a range operator
is in symbol
const Convention *pConv;
@@ -322,6 +323,7 @@ private:
#endif
bool NextNewToken(bool bInArray);
+bool ToUpperAsciiOrI18nIsAscii( OUString& rUpper, const OUString& rOrg )
const;
virtual void SetError(FormulaError nError) override;
sal_Int32 NextSymbol(bool bInArray);
@@ -352,7 +354,8 @@ private:
*/
ScRangeData* GetRangeData( const formula::FormulaToken& pToken ) const;
-static void InitCharClassEnglish();
+static const CharClass* GetCharClassEnglish();
+static const CharClass* GetCharClassLocalized();
public:
ScCompiler( sc::CompileFormulaContext& rCxt, const ScAddress& rPos,
diff --git a/sc/source/core/tool/compiler.cxx b/sc/source/core/tool/compiler.cxx
index 9ab2b6107cf5..2050a2100579 100644
--- a/sc/source/