formula/source/core/api/FormulaCompiler.cxx | 22 +- include/formula/FormulaCompiler.hxx | 21 +- sc/Library_sc.mk | 1 sc/inc/compiler.hxx | 23 +-- sc/inc/document.hxx | 2 sc/inc/tokenarray.hxx | 7 sc/inc/tokenstringcontext.hxx | 39 +++++ sc/qa/unit/ucalc.hxx | 2 sc/qa/unit/ucalc_formula.cxx | 31 ++++ sc/source/core/data/document.cxx | 16 ++ sc/source/core/tool/compiler.cxx | 211 ++++++++++++++++------------ sc/source/core/tool/token.cxx | 158 ++++++++++++++++++++ sc/source/core/tool/tokenstringcontext.cxx | 29 +++ 13 files changed, 439 insertions(+), 123 deletions(-)
New commits: commit 4cd9203a81b17c2208bc84f3a7665ccb46f9fd22 Author: Kohei Yoshida <kohei.yosh...@collabora.com> Date: Thu Nov 14 21:20:12 2013 -0500 Create string from token array directly from ScTokenArray. Still WIP. And make it re-entrant for thread safety. This method should not modify the internal state of the token array object. The one with ScCompiler is not re-entrant. Still some way to go. Change-Id: I06de3637341727aef0963dddfb98527f415bf7fa diff --git a/sc/Library_sc.mk b/sc/Library_sc.mk index 5754ad9..c9f0b5f 100644 --- a/sc/Library_sc.mk +++ b/sc/Library_sc.mk @@ -254,6 +254,7 @@ $(eval $(call gb_Library_add_exception_objects,sc,\ sc/source/core/tool/stylehelper \ sc/source/core/tool/subtotal \ sc/source/core/tool/token \ + sc/source/core/tool/tokenstringcontext \ sc/source/core/tool/typedstrdata \ sc/source/core/tool/unitconv \ sc/source/core/tool/userlist \ diff --git a/sc/inc/compiler.hxx b/sc/inc/compiler.hxx index 4cd31a3..6844b28 100644 --- a/sc/inc/compiler.hxx +++ b/sc/inc/compiler.hxx @@ -234,10 +234,11 @@ public: Convention( formula::FormulaGrammar::AddressConvention eConvP ); virtual ~Convention(); - virtual void MakeRefStr( OUStringBuffer& rBuffer, - const ScCompiler& rCompiler, - const ScComplexRefData& rRef, - bool bSingleRef ) const = 0; + virtual void makeRefStr( + OUStringBuffer& rBuffer, const ScAddress& rPos, formula::FormulaGrammar::Grammar eGram, + const OUString& rErrRef, const std::vector<OUString>& rTabNames, + const ScComplexRefData& rRef, bool bSingleRef ) const = 0; + virtual ::com::sun::star::i18n::ParseResult parseAnyToken( const OUString& rFormula, sal_Int32 nSrcPos, @@ -397,6 +398,8 @@ public: void SetRefConvention( const Convention *pConvP ); void SetRefConvention( const formula::FormulaGrammar::AddressConvention eConv ); + static const Convention* GetRefConvention( formula::FormulaGrammar::AddressConvention eConv ); + /// Set symbol map if not empty. void SetFormulaLanguage( const OpCodeMapPtr & xMap ); diff --git a/sc/inc/document.hxx b/sc/inc/document.hxx index 09f1466..68e57d2 100644 --- a/sc/inc/document.hxx +++ b/sc/inc/document.hxx @@ -555,6 +555,8 @@ public: SC_DLLPUBLIC bool SetCodeName( SCTAB nTab, const OUString& rName ); SC_DLLPUBLIC bool GetTable( const OUString& rName, SCTAB& rTab ) const; + std::vector<OUString> GetAllTableNames() const; + OUString GetCopyTabName(SCTAB nTab) const; SC_DLLPUBLIC void SetAnonymousDBData(SCTAB nTab, ScDBData* pDBData); diff --git a/sc/inc/tokenarray.hxx b/sc/inc/tokenarray.hxx index 83a3988..b8aec07 100644 --- a/sc/inc/tokenarray.hxx +++ b/sc/inc/tokenarray.hxx @@ -36,6 +36,7 @@ struct RefUpdateInsertTabContext; struct RefUpdateDeleteTabContext; struct RefUpdateMoveTabContext; struct RefUpdateResult; +struct TokenStringContext; } @@ -171,6 +172,12 @@ public: void CheckRelativeReferenceBounds( const sc::RefUpdateContext& rCxt, const ScAddress& rPos, SCROW nGroupLen, std::vector<SCROW>& rBounds ) const; + /** + * Create a string representation of formula token array without modifying + * the internal state of the token array. + */ + OUString CreateString( sc::TokenStringContext& rCxt, const ScAddress& rPos ) const; + #if DEBUG_FORMULA_COMPILER void Dump() const; #endif diff --git a/sc/inc/tokenstringcontext.hxx b/sc/inc/tokenstringcontext.hxx new file mode 100644 index 0000000..e5bb01c --- /dev/null +++ b/sc/inc/tokenstringcontext.hxx @@ -0,0 +1,39 @@ +/* -*- 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/. + */ + +#ifndef SC_TOKENSTRINGCONTEXT_HXX +#define SC_TOKENSTRINGCONTEXT_HXX + +#include "compiler.hxx" + +namespace sc { + +/** + * Context for creating string from an array of formula tokens, used in + * ScTokenArray::CreateString(). You can re-use the same string context + * between multiple CreateString() calls as long as the document content is + * unmodified. + */ +struct TokenStringContext +{ + formula::FormulaGrammar::Grammar meGram; + formula::FormulaCompiler::OpCodeMapPtr mxOpCodeMap; + const ScCompiler::Convention* mpRefConv; + OUString maErrRef; + + std::vector<OUString> maTabNames; + + TokenStringContext( formula::FormulaGrammar::Grammar eGram ); +}; + +} + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sc/qa/unit/ucalc.hxx b/sc/qa/unit/ucalc.hxx index 19c94d7..1298e73 100644 --- a/sc/qa/unit/ucalc.hxx +++ b/sc/qa/unit/ucalc.hxx @@ -84,6 +84,7 @@ public: void testRangeList(); void testInput(); + void testFormulaCreateStringFromTokens(); void testFormulaParseReference(); void testFetchVectorRefArray(); void testFormulaHashAndTag(); @@ -293,6 +294,7 @@ public: CPPUNIT_TEST(testSharedStringPool); CPPUNIT_TEST(testRangeList); CPPUNIT_TEST(testInput); + CPPUNIT_TEST(testFormulaCreateStringFromTokens); CPPUNIT_TEST(testFormulaParseReference); CPPUNIT_TEST(testFetchVectorRefArray); CPPUNIT_TEST(testFormulaHashAndTag); diff --git a/sc/qa/unit/ucalc_formula.cxx b/sc/qa/unit/ucalc_formula.cxx index d12e45d..c780717 100644 --- a/sc/qa/unit/ucalc_formula.cxx +++ b/sc/qa/unit/ucalc_formula.cxx @@ -22,6 +22,7 @@ #include "docsh.hxx" #include "docfunc.hxx" #include "paramisc.hxx" +#include "tokenstringcontext.hxx" #include "formula/vectortoken.hxx" @@ -29,6 +30,36 @@ using namespace formula; +void Test::testFormulaCreateStringFromTokens() +{ + m_pDoc->InsertTab(0, "Test"); + + const char* aTests[] = { + "1+2", + "SUM(A1:A10;B1:B10;C5;D6)" + }; + + boost::scoped_ptr<ScTokenArray> pArray; + + sc::TokenStringContext aCxt(formula::FormulaGrammar::GRAM_ENGLISH); + aCxt.maTabNames = m_pDoc->GetAllTableNames(); + ScAddress aPos(0,0,0); + + for (size_t i = 0, n = SAL_N_ELEMENTS(aTests); i < n; ++i) + { + OUString aFormula = OUString::createFromAscii(aTests[i]); + ScCompiler aComp(m_pDoc, aPos); + aComp.SetGrammar(FormulaGrammar::GRAM_ENGLISH); + pArray.reset(aComp.CompileString(aFormula)); + CPPUNIT_ASSERT_MESSAGE("Failed to compile formula string.", pArray.get()); + + OUString aCheck = pArray->CreateString(aCxt, aPos); + CPPUNIT_ASSERT_EQUAL(aFormula, aCheck); + } + + m_pDoc->DeleteTab(0); +} + namespace { bool isEmpty( const formula::VectorRefArray& rArray, size_t nPos ) diff --git a/sc/source/core/data/document.cxx b/sc/source/core/data/document.cxx index f8a6d92..80696e4 100644 --- a/sc/source/core/data/document.cxx +++ b/sc/source/core/data/document.cxx @@ -251,6 +251,22 @@ bool ScDocument::GetTable( const OUString& rName, SCTAB& rTab ) const return false; } +std::vector<OUString> ScDocument::GetAllTableNames() const +{ + std::vector<OUString> aNames; + aNames.reserve(maTabs.size()); + TableContainer::const_iterator it = maTabs.begin(), itEnd = maTabs.end(); + for (; it != itEnd; ++it) + { + OUString aName; + const ScTable& rTab = **it; + rTab.GetName(aName); + aNames.push_back(aName); + } + + return aNames; +} + ScDBData* ScDocument::GetAnonymousDBData(SCTAB nTab) { if (ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab]) diff --git a/sc/source/core/tool/compiler.cxx b/sc/source/core/tool/compiler.cxx index 52d47df..dc2bd4a 100644 --- a/sc/source/core/tool/compiler.cxx +++ b/sc/source/core/tool/compiler.cxx @@ -726,15 +726,15 @@ struct ConventionOOO_A1 : public Convention_A1 { ConventionOOO_A1() : Convention_A1 (FormulaGrammar::CONV_OOO) { } ConventionOOO_A1( FormulaGrammar::AddressConvention eConv ) : Convention_A1 (eConv) { } - static OUString MakeTabStr( const ScCompiler& rComp, SCTAB nTab, OUString& aDoc ) + + static OUString MakeTabStr( const std::vector<OUString>& rTabNames, SCTAB nTab, OUString& aDoc ) { OUString aString; - OUString aTmp; - if (!rComp.GetDoc()->GetName( nTab, aTmp )) + if (static_cast<size_t>(nTab) >= rTabNames.size()) aString = ScGlobal::GetRscString(STR_NO_REF_TABLE); else { - aString = aTmp; + aString = rTabNames[nTab]; // "'Doc'#Tab" sal_Int32 nPos = ScCompiler::GetDocTabPos( aString ); if ( nPos != -1 ) @@ -753,7 +753,7 @@ struct ConventionOOO_A1 : public Convention_A1 } void MakeOneRefStrImpl( - OUStringBuffer& rBuffer, const ScCompiler& rComp, + OUStringBuffer& rBuffer, const OUString& rErrRef, const std::vector<OUString>& rTabNames, const ScSingleRefData& rRef, const ScAddress& rAbsRef, bool bForceTab, bool bODF ) const { @@ -763,13 +763,13 @@ struct ConventionOOO_A1 : public Convention_A1 { if (!rRef.IsTabRel()) rBuffer.append(sal_Unicode('$')); - rBuffer.append( rComp.GetCurrentOpCodeMap()->getSymbol( ocErrRef)); + rBuffer.append(rErrRef); rBuffer.append(sal_Unicode('.')); } else { OUString aDoc; - OUString aRefStr(MakeTabStr(rComp, rAbsRef.Tab(), aDoc)); + OUString aRefStr(MakeTabStr(rTabNames, rAbsRef.Tab(), aDoc)); rBuffer.append(aDoc); if (!rRef.IsTabRel()) rBuffer.append(sal_Unicode('$')); @@ -781,58 +781,38 @@ struct ConventionOOO_A1 : public Convention_A1 if (!rRef.IsColRel()) rBuffer.append(sal_Unicode('$')); if (!ValidCol(rAbsRef.Col())) - rBuffer.append( rComp.GetCurrentOpCodeMap()->getSymbol( ocErrRef)); + rBuffer.append(rErrRef); else MakeColStr(rBuffer, rAbsRef.Col()); if (!rRef.IsRowRel()) rBuffer.append(sal_Unicode('$')); if (!ValidRow(rAbsRef.Row())) - rBuffer.append( rComp.GetCurrentOpCodeMap()->getSymbol( ocErrRef)); + rBuffer.append(rErrRef); else MakeRowStr(rBuffer, rAbsRef.Row()); } - void MakeRefStrImpl( OUStringBuffer& rBuffer, - const ScCompiler& rComp, - const ScComplexRefData& rRef, - bool bSingleRef, - bool bODF ) const + void makeRefStr( OUStringBuffer& rBuffer, + const ScAddress& rPos, + FormulaGrammar::Grammar /*eGram*/, + const OUString& rErrRef, + const std::vector<OUString>& rTabNames, + const ScComplexRefData& rRef, + bool bSingleRef ) const { - if (bODF) - rBuffer.append(sal_Unicode('[')); ScComplexRefData aRef( rRef ); // In case absolute/relative positions weren't separately available: // transform relative to absolute! - ScAddress aAbs1 = aRef.Ref1.toAbs(rComp.GetPos()), aAbs2; + ScAddress aAbs1 = aRef.Ref1.toAbs(rPos), aAbs2; if( !bSingleRef ) - aAbs2 = aRef.Ref2.toAbs(rComp.GetPos()); + aAbs2 = aRef.Ref2.toAbs(rPos); - if (bODF && FormulaGrammar::isODFF( rComp.GetGrammar()) && (!ValidAddress(aAbs1) || !ValidAddress(aAbs2))) - { - rBuffer.append( rComp.GetCurrentOpCodeMap()->getSymbol( ocErrRef)); - // For ODFF write [#REF!], but not for PODF so apps reading ODF - // 1.0/1.1 may have a better chance if they implemented the old - // form. - } - else + MakeOneRefStrImpl(rBuffer, rErrRef, rTabNames, aRef.Ref1, aAbs1, false, false); + if (!bSingleRef) { - MakeOneRefStrImpl(rBuffer, rComp, aRef.Ref1, aAbs1, false, bODF); - if (!bSingleRef) - { - rBuffer.append(sal_Unicode(':')); - MakeOneRefStrImpl(rBuffer, rComp, aRef.Ref2, aAbs2, aAbs1.Tab() != aAbs2.Tab(), bODF); - } + rBuffer.append(sal_Unicode(':')); + MakeOneRefStrImpl(rBuffer, rErrRef, rTabNames, aRef.Ref2, aAbs2, aAbs1.Tab() != aAbs2.Tab(), false); } - if (bODF) - rBuffer.append(sal_Unicode(']')); - } - - void MakeRefStr( OUStringBuffer& rBuffer, - const ScCompiler& rComp, - const ScComplexRefData& rRef, - bool bSingleRef ) const - { - MakeRefStrImpl( rBuffer, rComp, rRef, bSingleRef, false); } virtual sal_Unicode getSpecialSymbol( SpecialSymbolType eSymType ) const @@ -1005,12 +985,39 @@ const ScCompiler::Convention * const ScCompiler::pConvOOO_A1 = &ConvOOO_A1; struct ConventionOOO_A1_ODF : public ConventionOOO_A1 { ConventionOOO_A1_ODF() : ConventionOOO_A1 (FormulaGrammar::CONV_ODF) { } - void MakeRefStr( OUStringBuffer& rBuffer, - const ScCompiler& rComp, + void makeRefStr( OUStringBuffer& rBuffer, + const ScAddress& rPos, + FormulaGrammar::Grammar eGram, + const OUString& rErrRef, + const std::vector<OUString>& rTabNames, const ScComplexRefData& rRef, bool bSingleRef ) const { - MakeRefStrImpl( rBuffer, rComp, rRef, bSingleRef, true); + rBuffer.append(sal_Unicode('[')); + ScComplexRefData aRef( rRef ); + // In case absolute/relative positions weren't separately available: + // transform relative to absolute! + ScAddress aAbs1 = aRef.Ref1.toAbs(rPos), aAbs2; + if( !bSingleRef ) + aAbs2 = aRef.Ref2.toAbs(rPos); + + if (FormulaGrammar::isODFF(eGram) && (!ValidAddress(aAbs1) || !ValidAddress(aAbs2))) + { + rBuffer.append(rErrRef); + // For ODFF write [#REF!], but not for PODF so apps reading ODF + // 1.0/1.1 may have a better chance if they implemented the old + // form. + } + else + { + MakeOneRefStrImpl(rBuffer, rErrRef, rTabNames, aRef.Ref1, aAbs1, false, true); + if (!bSingleRef) + { + rBuffer.append(sal_Unicode(':')); + MakeOneRefStrImpl(rBuffer, rErrRef, rTabNames, aRef.Ref2, aAbs2, aAbs1.Tab() != aAbs2.Tab(), true); + } + } + rBuffer.append(sal_Unicode(']')); } virtual OUString makeExternalNameStr( const OUString& rFile, const OUString& rName ) const @@ -1038,22 +1045,20 @@ const ScCompiler::Convention * const ScCompiler::pConvOOO_A1_ODF = &ConvOOO_A1_O struct ConventionXL { - static bool GetDocAndTab( const ScCompiler& rComp, - const ScSingleRefData& rRef, - OUString& rDocName, - OUString& rTabName ) + static bool GetDocAndTab( + const ScAddress& rPos, const std::vector<OUString>& rTabNames, + const ScSingleRefData& rRef, OUString& rDocName, OUString& rTabName ) { bool bHasDoc = false; rDocName = ""; - OUString aTmp; - ScAddress aAbs = rRef.toAbs(rComp.GetPos()); - if (rRef.IsTabDeleted() || !rComp.GetDoc()->GetName(aAbs.Tab(), aTmp)) + ScAddress aAbs = rRef.toAbs(rPos); + if (rRef.IsTabDeleted() || static_cast<size_t>(aAbs.Tab()) >= rTabNames.size()) { rTabName = ScGlobal::GetRscString( STR_NO_REF_TABLE ); return false; } - rTabName = aTmp; + rTabName = rTabNames[aAbs.Tab()]; // Cheesy hack to unparse the OOO style "'Doc'#Tab" sal_Int32 nPos = ScCompiler::GetDocTabPos( rTabName); @@ -1074,7 +1079,8 @@ struct ConventionXL } static void MakeDocStr( OUStringBuffer& rBuf, - const ScCompiler& rComp, + const ScAddress& rPos, + const std::vector<OUString>& rTabNames, const ScComplexRefData& rRef, bool bSingleRef ) { @@ -1083,13 +1089,13 @@ struct ConventionXL OUString aStartTabName, aStartDocName, aEndTabName, aEndDocName; bool bStartHasDoc = false, bEndHasDoc = false; - bStartHasDoc = GetDocAndTab( rComp, rRef.Ref1, - aStartDocName, aStartTabName); + bStartHasDoc = GetDocAndTab( + rPos, rTabNames, rRef.Ref1, aStartDocName, aStartTabName); if( !bSingleRef && rRef.Ref2.IsFlag3D() ) { - bEndHasDoc = GetDocAndTab( rComp, rRef.Ref2, - aEndDocName, aEndTabName); + bEndHasDoc = GetDocAndTab( + rPos, rTabNames, rRef.Ref2, aEndDocName, aEndTabName); } else bEndHasDoc = bStartHasDoc; @@ -1259,8 +1265,11 @@ struct ConventionXL_A1 : public Convention_A1, public ConventionXL MakeRowStr(rBuf, rAbs.Row()); } - void MakeRefStr( OUStringBuffer& rBuf, - const ScCompiler& rComp, + void makeRefStr( OUStringBuffer& rBuf, + const ScAddress& rPos, + FormulaGrammar::Grammar /*eGram*/, + const OUString& /*rErrRef*/, + const std::vector<OUString>& rTabNames, const ScComplexRefData& rRef, bool bSingleRef ) const { @@ -1268,9 +1277,9 @@ struct ConventionXL_A1 : public Convention_A1, public ConventionXL // Play fast and loose with invalid refs. There is not much point in producing // Foo!A1:#REF! versus #REF! at this point - ScAddress aAbs1 = aRef.Ref1.toAbs(rComp.GetPos()), aAbs2; + ScAddress aAbs1 = aRef.Ref1.toAbs(rPos), aAbs2; - MakeDocStr( rBuf, rComp, aRef, bSingleRef ); + MakeDocStr(rBuf, rPos, rTabNames, aRef, bSingleRef); if (!ValidAddress(aAbs1)) { @@ -1280,7 +1289,7 @@ struct ConventionXL_A1 : public Convention_A1, public ConventionXL if( !bSingleRef ) { - aAbs2 = aRef.Ref2.toAbs(rComp.GetPos()); + aAbs2 = aRef.Ref2.toAbs(rPos); if (!ValidAddress(aAbs2)) { rBuf.append(ScGlobal::GetRscString(STR_NO_REF_TABLE)); @@ -1448,15 +1457,18 @@ r1c1_add_row( OUStringBuffer &rBuf, const ScSingleRefData& rRef, const ScAddress struct ConventionXL_R1C1 : public ScCompiler::Convention, public ConventionXL { ConventionXL_R1C1() : ScCompiler::Convention( FormulaGrammar::CONV_XL_R1C1 ) { } - void MakeRefStr( OUStringBuffer& rBuf, - const ScCompiler& rComp, + void makeRefStr( OUStringBuffer& rBuf, + const ScAddress& rPos, + FormulaGrammar::Grammar /*eGram*/, + const OUString& /*rErrRef*/, + const std::vector<OUString>& rTabNames, const ScComplexRefData& rRef, bool bSingleRef ) const { - ScRange aAbsRef = rRef.toAbs(rComp.GetPos()); + ScRange aAbsRef = rRef.toAbs(rPos); ScComplexRefData aRef( rRef ); - MakeDocStr( rBuf, rComp, aRef, bSingleRef ); + MakeDocStr(rBuf, rPos, rTabNames, aRef, bSingleRef); // Play fast and loose with invalid refs. There is not much point in producing // Foo!A1:#REF! versus #REF! at this point @@ -1662,7 +1674,7 @@ ScCompiler::ScCompiler( ScDocument* pDocument, const ScAddress& rPos) : pDoc( pDocument ), aPos( rPos ), - mpFormatter(pDoc->GetFormatTable()), + mpFormatter(pDoc ? pDoc->GetFormatTable() : NULL), pCharClass( ScGlobal::pCharClass ), mnPredetectedReference(0), mnRangeOpPosInSymbol(-1), @@ -1729,16 +1741,31 @@ sal_Int32 ScCompiler::GetDocTabPos( const OUString& rString ) void ScCompiler::SetRefConvention( FormulaGrammar::AddressConvention eConv ) { - switch ( eConv ) { - case FormulaGrammar::CONV_UNSPECIFIED : - break; - default : - case FormulaGrammar::CONV_OOO : SetRefConvention( pConvOOO_A1 ); break; - case FormulaGrammar::CONV_ODF : SetRefConvention( pConvOOO_A1_ODF ); break; - case FormulaGrammar::CONV_XL_A1 : SetRefConvention( pConvXL_A1 ); break; - case FormulaGrammar::CONV_XL_R1C1 : SetRefConvention( pConvXL_R1C1 ); break; - case FormulaGrammar::CONV_XL_OOX : SetRefConvention( pConvXL_OOX ); break; + const Convention* p = GetRefConvention(eConv); + if (p) + SetRefConvention(p); +} + +const ScCompiler::Convention* ScCompiler::GetRefConvention( FormulaGrammar::AddressConvention eConv ) +{ + switch (eConv) + { + case FormulaGrammar::CONV_OOO: + return pConvOOO_A1; + case FormulaGrammar::CONV_ODF: + return pConvOOO_A1_ODF; + case FormulaGrammar::CONV_XL_A1: + return pConvXL_A1; + case FormulaGrammar::CONV_XL_R1C1: + return pConvXL_R1C1; + case FormulaGrammar::CONV_XL_OOX: + return pConvXL_OOX; + case FormulaGrammar::CONV_UNSPECIFIED: + default: + ; } + + return NULL; } void ScCompiler::SetRefConvention( const ScCompiler::Convention *pConvP ) @@ -4188,6 +4215,8 @@ void ScCompiler::CreateStringFromSingleRef(OUStringBuffer& rBuffer,FormulaToken* const ScSingleRefData& rRef = static_cast<const ScToken*>(_pTokenP)->GetSingleRef(); ScComplexRefData aRef; aRef.Ref1 = aRef.Ref2 = rRef; + OUString aErrRef = GetCurrentOpCodeMap()->getSymbol( ocErrRef); + std::vector<OUString> aTabNames = GetDoc()->GetAllTableNames(); if ( eOp == ocColRowName ) { ScAddress aAbs = rRef.toAbs(aPos); @@ -4200,16 +4229,18 @@ void ScCompiler::CreateStringFromSingleRef(OUStringBuffer& rBuffer,FormulaToken* else { rBuffer.append(ScGlobal::GetRscString(STR_NO_NAME_REF)); - pConv->MakeRefStr (rBuffer, *this, aRef, true ); + pConv->makeRefStr(rBuffer, aPos, meGrammar, aErrRef, aTabNames, aRef, true); } } else - pConv->MakeRefStr( rBuffer, *this, aRef, true ); + pConv->makeRefStr(rBuffer, aPos, meGrammar, aErrRef, aTabNames, aRef, true); } void ScCompiler::CreateStringFromDoubleRef(OUStringBuffer& rBuffer,FormulaToken* _pTokenP) const { - pConv->MakeRefStr( rBuffer, *this, static_cast<ScToken*>(_pTokenP)->GetDoubleRef(), false ); + OUString aErrRef = GetCurrentOpCodeMap()->getSymbol( ocErrRef); + std::vector<OUString> aTabNames = GetDoc()->GetAllTableNames(); + pConv->makeRefStr(rBuffer, aPos, meGrammar, aErrRef, aTabNames, static_cast<ScToken*>(_pTokenP)->GetDoubleRef(), false); } void ScCompiler::CreateStringFromIndex(OUStringBuffer& rBuffer,FormulaToken* _pTokenP) const diff --git a/sc/source/core/tool/token.cxx b/sc/source/core/tool/token.cxx index aa6e68c..0361414 100644 --- a/sc/source/core/tool/token.cxx +++ b/sc/source/core/tool/token.cxx @@ -38,6 +38,7 @@ #include "externalrefmgr.hxx" #include "document.hxx" #include "refupdatecontext.hxx" +#include "tokenstringcontext.hxx" #include "types.hxx" #include "svl/sharedstring.hxx" @@ -3104,6 +3105,163 @@ void ScTokenArray::CheckRelativeReferenceBounds( } } +namespace { + +void appendTokenByType( sc::TokenStringContext& rCxt, OUStringBuffer& rBuf, const FormulaToken& rToken, const ScAddress& rPos ) +{ + if (rToken.IsExternalRef()) + { + // TODO : Implement this. + return; + } + + OpCode eOp = rToken.GetOpCode(); + switch (rToken.GetType()) + { + case svDouble: + { + if (rCxt.mxOpCodeMap->isEnglish()) + { + rtl::math::doubleToUStringBuffer( + rBuf, rToken.GetDouble(), rtl_math_StringFormat_Automatic, rtl_math_DecimalPlaces_Max, '.', true); + } + else + { + SvtSysLocale aSysLocale; + rtl::math::doubleToUStringBuffer( + rBuf, rToken.GetDouble(), + rtl_math_StringFormat_Automatic, rtl_math_DecimalPlaces_Max, + aSysLocale.GetLocaleDataPtr()->getNumDecimalSep()[0], true); + } + } + break; + case svString: + { + OUString aStr = rToken.GetString().getString(); + if (eOp == ocBad || eOp == ocStringXML) + { + rBuf.append(aStr); + return; + } + + rBuf.append(sal_Unicode('"')); + rBuf.append(aStr.replaceAll("\"", "\"\"")); + rBuf.append(sal_Unicode('"')); + } + break; + case svSingleRef: + { + if (rCxt.mpRefConv) + { + const ScSingleRefData& rRef = static_cast<const ScToken&>(rToken).GetSingleRef(); + ScComplexRefData aRef; + aRef.Ref1 = rRef; + aRef.Ref2 = rRef; + rCxt.mpRefConv->makeRefStr(rBuf, rPos, rCxt.meGram, rCxt.maErrRef, rCxt.maTabNames, aRef, true); + } + else + rBuf.append(rCxt.maErrRef); + } + break; + case svDoubleRef: + { + if (rCxt.mpRefConv) + { + const ScComplexRefData& rRef = static_cast<const ScToken&>(rToken).GetDoubleRef(); + rCxt.mpRefConv->makeRefStr(rBuf, rPos, rCxt.meGram, rCxt.maErrRef, rCxt.maTabNames, rRef, false); + } + else + rBuf.append(rCxt.maErrRef); + } + break; + case svMatrix: + // TODO : Implement this. + break; + case svIndex: + // TODO : Implement this. + break; + case svExternal: + // TODO : Implement this. + break; + case svError: + { + sal_uInt16 nErr = rToken.GetError(); + OpCode eOpErr; + switch (nErr) + { + break; + case errDivisionByZero: + eOpErr = ocErrDivZero; + break; + case errNoValue: + eOpErr = ocErrValue; + break; + case errNoRef: + eOpErr = ocErrRef; + break; + case errNoName: + eOpErr = ocErrName; + break; + case errIllegalFPOperation: + eOpErr = ocErrNum; + break; + case NOTAVAILABLE: + eOpErr = ocErrNA; + break; + case errNoCode: + default: + eOpErr = ocErrNull; + } + rBuf.append(rCxt.mxOpCodeMap->getSymbol(eOpErr)); + } + break; + case svByte: + case svJump: + case svFAP: + case svMissing: + case svSep: + default: + ; + } +} + +} + +OUString ScTokenArray::CreateString( sc::TokenStringContext& rCxt, const ScAddress& rPos ) const +{ + if (!nLen) + return OUString(); + + OUStringBuffer aBuf; + + FormulaToken** p = pCode; + FormulaToken** pEnd = p + static_cast<size_t>(nLen); + for (; p != pEnd; ++p) + { + const FormulaToken* pToken = *p; + OpCode eOp = pToken->GetOpCode(); + switch (eOp) + { + case ocPush: + appendTokenByType(rCxt, aBuf, *pToken, rPos); + break; + case ocSpaces: + // TODO : Handle intersection operator '!!'. + aBuf.append(sal_Unicode(' ')); + break; + default: + { + if (eOp < rCxt.mxOpCodeMap->getSymbolCount()) + aBuf.append(rCxt.mxOpCodeMap->getSymbol(eOp)); + else + return OUString(); + } + } + } + + return aBuf.makeStringAndClear(); +} + #if DEBUG_FORMULA_COMPILER void ScTokenArray::Dump() const { diff --git a/sc/source/core/tool/tokenstringcontext.cxx b/sc/source/core/tool/tokenstringcontext.cxx new file mode 100644 index 0000000..5fea0a9 --- /dev/null +++ b/sc/source/core/tool/tokenstringcontext.cxx @@ -0,0 +1,29 @@ +/* -*- 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/. + */ + +#include "tokenstringcontext.hxx" +#include "compiler.hxx" + +using namespace com::sun::star; + +namespace sc { + +TokenStringContext::TokenStringContext( formula::FormulaGrammar::Grammar eGram ) : + meGram(eGram), + mpRefConv(ScCompiler::GetRefConvention(formula::FormulaGrammar::extractRefConvention(eGram))) +{ + ScCompiler aComp(NULL, ScAddress()); + mxOpCodeMap = aComp.GetOpCodeMap(formula::FormulaGrammar::extractFormulaLanguage(eGram)); + if (mxOpCodeMap) + maErrRef = mxOpCodeMap->getSymbol(ocErrRef); +} + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ commit 3269d73ed327ea02ee34994170812a6c7600abd8 Author: Kohei Yoshida <kohei.yosh...@collabora.com> Date: Thu Nov 14 14:57:21 2013 -0500 Remove unused member. Change-Id: I8331251f77fb202375370a425e01862aa0f6310d diff --git a/formula/source/core/api/FormulaCompiler.cxx b/formula/source/core/api/FormulaCompiler.cxx index 803a46a..0dba793 100644 --- a/formula/source/core/api/FormulaCompiler.cxx +++ b/formula/source/core/api/FormulaCompiler.cxx @@ -529,7 +529,6 @@ DBG_NAME(FormulaCompiler) FormulaCompiler::FormulaCompiler( FormulaTokenArray& rArr ) : pArr( &rArr ), - pExternalRef(NULL), pStack( NULL ), nRecursion(0), nNumFmt( NUMBERFORMAT_UNDEFINED ), @@ -546,7 +545,6 @@ FormulaCompiler::FormulaCompiler( FormulaTokenArray& rArr ) FormulaCompiler::FormulaCompiler() : pArr( NULL ), - pExternalRef(NULL), pStack( NULL ), nRecursion(0), nNumFmt( NUMBERFORMAT_UNDEFINED ), diff --git a/include/formula/FormulaCompiler.hxx b/include/formula/FormulaCompiler.hxx index e851fcf..b450ed6 100644 --- a/include/formula/FormulaCompiler.hxx +++ b/include/formula/FormulaCompiler.hxx @@ -320,7 +320,6 @@ protected: FormulaTokenRef mpToken; // current token FormulaTokenRef pCurrentFactorToken; // current factor token (of Factor() method) FormulaTokenArray* pArr; - ExternalReferenceHelper* pExternalRef; FormulaToken** pCode; FormulaArrayStack* pStack; commit 4554e122401e0d06f3f0adf02e7307983e4b77a6 Author: Kohei Yoshida <kohei.yosh...@collabora.com> Date: Thu Nov 14 14:39:56 2013 -0500 Identify methods that don't modify internal state and mark them const. Change-Id: Ie63d93d51640bfb80dc02bb226d742c2f9be96d8 diff --git a/formula/source/core/api/FormulaCompiler.cxx b/formula/source/core/api/FormulaCompiler.cxx index d099042..803a46a 100644 --- a/formula/source/core/api/FormulaCompiler.cxx +++ b/formula/source/core/api/FormulaCompiler.cxx @@ -963,7 +963,7 @@ sal_uInt16 FormulaCompiler::GetErrorConstant( const OUString& rName ) const } -void FormulaCompiler::AppendErrorConstant( OUStringBuffer& rBuffer, sal_uInt16 nError ) +void FormulaCompiler::AppendErrorConstant( OUStringBuffer& rBuffer, sal_uInt16 nError ) const { OpCode eOp; switch (nError) @@ -1875,7 +1875,7 @@ FormulaToken* FormulaCompiler::CreateStringFromToken( OUStringBuffer& rBuffer, F } -void FormulaCompiler::AppendDouble( OUStringBuffer& rBuffer, double fVal ) +void FormulaCompiler::AppendDouble( OUStringBuffer& rBuffer, double fVal ) const { if ( mxSymbols->isEnglish() ) { @@ -1894,12 +1894,12 @@ void FormulaCompiler::AppendDouble( OUStringBuffer& rBuffer, double fVal ) } } -void FormulaCompiler::AppendBoolean( OUStringBuffer& rBuffer, bool bVal ) +void FormulaCompiler::AppendBoolean( OUStringBuffer& rBuffer, bool bVal ) const { rBuffer.append( mxSymbols->getSymbol( static_cast<OpCode>(bVal ? ocTrue : ocFalse)) ); } -void FormulaCompiler::AppendString( OUStringBuffer& rBuffer, const OUString & rStr ) +void FormulaCompiler::AppendString( OUStringBuffer& rBuffer, const OUString & rStr ) const { rBuffer.append( sal_Unicode('"')); if ( lcl_UnicodeStrChr( rStr.getStr(), '"' ) == NULL ) @@ -2074,27 +2074,27 @@ bool FormulaCompiler::HandleDbData() return true; } -void FormulaCompiler::CreateStringFromSingleRef( OUStringBuffer& /*rBuffer*/, FormulaToken* /*pTokenP*/) +void FormulaCompiler::CreateStringFromSingleRef( OUStringBuffer& /*rBuffer*/, FormulaToken* /*pTokenP*/) const { } -void FormulaCompiler::CreateStringFromDoubleRef( OUStringBuffer& /*rBuffer*/, FormulaToken* /*pTokenP*/) +void FormulaCompiler::CreateStringFromDoubleRef( OUStringBuffer& /*rBuffer*/, FormulaToken* /*pTokenP*/) const { } -void FormulaCompiler::CreateStringFromIndex( OUStringBuffer& /*rBuffer*/, FormulaToken* /*pTokenP*/) +void FormulaCompiler::CreateStringFromIndex( OUStringBuffer& /*rBuffer*/, FormulaToken* /*pTokenP*/) const { } -void FormulaCompiler::CreateStringFromMatrix( OUStringBuffer& /*rBuffer*/, FormulaToken* /*pTokenP*/) +void FormulaCompiler::CreateStringFromMatrix( OUStringBuffer& /*rBuffer*/, FormulaToken* /*pTokenP*/) const { } -void FormulaCompiler::CreateStringFromExternal( OUStringBuffer& /*rBuffer*/, FormulaToken* /*pTokenP*/) +void FormulaCompiler::CreateStringFromExternal( OUStringBuffer& /*rBuffer*/, FormulaToken* /*pTokenP*/) const { } -void FormulaCompiler::LocalizeString( OUString& /*rName*/ ) +void FormulaCompiler::LocalizeString( OUString& /*rName*/ ) const { } diff --git a/include/formula/FormulaCompiler.hxx b/include/formula/FormulaCompiler.hxx index ff2ebf3..e851fcf 100644 --- a/include/formula/FormulaCompiler.hxx +++ b/include/formula/FormulaCompiler.hxx @@ -245,9 +245,9 @@ public: FormulaToken* CreateStringFromToken( OUStringBuffer& rBuffer, FormulaToken* pToken, bool bAllowArrAdvance = false ); - void AppendBoolean( OUStringBuffer& rBuffer, bool bVal ); - void AppendDouble( OUStringBuffer& rBuffer, double fVal ); - void AppendString( OUStringBuffer& rBuffer, const OUString & rStr ); + void AppendBoolean( OUStringBuffer& rBuffer, bool bVal ) const; + void AppendDouble( OUStringBuffer& rBuffer, double fVal ) const; + void AppendString( OUStringBuffer& rBuffer, const OUString & rStr ) const; /** Set symbol map corresponding to one of predefined formula::FormulaGrammar::Grammar, including an address reference convention. */ @@ -282,14 +282,14 @@ protected: virtual bool HandleSingleRef(); virtual bool HandleDbData(); - virtual void CreateStringFromExternal(OUStringBuffer& rBuffer, FormulaToken* pTokenP); - virtual void CreateStringFromSingleRef(OUStringBuffer& rBuffer,FormulaToken* pTokenP); - virtual void CreateStringFromDoubleRef(OUStringBuffer& rBuffer,FormulaToken* pTokenP); - virtual void CreateStringFromMatrix(OUStringBuffer& rBuffer,FormulaToken* pTokenP); - virtual void CreateStringFromIndex(OUStringBuffer& rBuffer,FormulaToken* pTokenP); - virtual void LocalizeString(OUString& rName ); // modify rName - input: exact name + virtual void CreateStringFromExternal(OUStringBuffer& rBuffer, FormulaToken* pTokenP) const; + virtual void CreateStringFromSingleRef(OUStringBuffer& rBuffer,FormulaToken* pTokenP) const; + virtual void CreateStringFromDoubleRef(OUStringBuffer& rBuffer,FormulaToken* pTokenP) const; + virtual void CreateStringFromMatrix(OUStringBuffer& rBuffer,FormulaToken* pTokenP) const; + virtual void CreateStringFromIndex(OUStringBuffer& rBuffer,FormulaToken* pTokenP) const; + virtual void LocalizeString( OUString& rName ) const; // modify rName - input: exact name - void AppendErrorConstant( OUStringBuffer& rBuffer, sal_uInt16 nError ); + void AppendErrorConstant( OUStringBuffer& rBuffer, sal_uInt16 nError ) const; bool GetToken(); OpCode NextToken(); diff --git a/sc/inc/compiler.hxx b/sc/inc/compiler.hxx index 3b366c0..4cd31a3 100644 --- a/sc/inc/compiler.hxx +++ b/sc/inc/compiler.hxx @@ -472,12 +472,12 @@ private: virtual bool HandleDbData(); virtual formula::FormulaTokenRef ExtendRangeReference( formula::FormulaToken & rTok1, formula::FormulaToken & rTok2, bool bReuseDoubleRef ); - virtual void CreateStringFromExternal(OUStringBuffer& rBuffer, formula::FormulaToken* pTokenP); - virtual void CreateStringFromSingleRef(OUStringBuffer& rBuffer,formula::FormulaToken* _pTokenP); - virtual void CreateStringFromDoubleRef(OUStringBuffer& rBuffer,formula::FormulaToken* _pTokenP); - virtual void CreateStringFromMatrix( OUStringBuffer& rBuffer, formula::FormulaToken* _pTokenP); - virtual void CreateStringFromIndex(OUStringBuffer& rBuffer,formula::FormulaToken* _pTokenP); - virtual void LocalizeString( OUString& rName ); // modify rName - input: exact name + virtual void CreateStringFromExternal(OUStringBuffer& rBuffer, formula::FormulaToken* pTokenP) const; + virtual void CreateStringFromSingleRef(OUStringBuffer& rBuffer,formula::FormulaToken* _pTokenP) const; + virtual void CreateStringFromDoubleRef(OUStringBuffer& rBuffer,formula::FormulaToken* _pTokenP) const; + virtual void CreateStringFromMatrix( OUStringBuffer& rBuffer, formula::FormulaToken* _pTokenP) const; + virtual void CreateStringFromIndex(OUStringBuffer& rBuffer,formula::FormulaToken* _pTokenP) const; + virtual void LocalizeString( OUString& rName ) const; // modify rName - input: exact name /// Access the CharTable flags inline sal_uLong GetCharTableFlags( sal_Unicode c, sal_Unicode cLast ) diff --git a/sc/source/core/tool/compiler.cxx b/sc/source/core/tool/compiler.cxx index bcff41e..52d47df 100644 --- a/sc/source/core/tool/compiler.cxx +++ b/sc/source/core/tool/compiler.cxx @@ -4109,7 +4109,7 @@ bool ScCompiler::IsCharFlagAllConventions( return false; } -void ScCompiler::CreateStringFromExternal(OUStringBuffer& rBuffer, FormulaToken* pTokenP) +void ScCompiler::CreateStringFromExternal(OUStringBuffer& rBuffer, FormulaToken* pTokenP) const { FormulaToken* t = pTokenP; ScExternalRefManager* pRefMgr = pDoc->GetExternalRefManager(); @@ -4137,8 +4137,8 @@ void ScCompiler::CreateStringFromExternal(OUStringBuffer& rBuffer, FormulaToken* } } -void ScCompiler::CreateStringFromMatrix( OUStringBuffer& rBuffer, - FormulaToken* pTokenP) +void ScCompiler::CreateStringFromMatrix( + OUStringBuffer& rBuffer, FormulaToken* pTokenP) const { const ScMatrix* pMatrix = static_cast<ScToken*>(pTokenP)->GetMatrix(); SCSIZE nC, nMaxC, nR, nMaxR; @@ -4182,10 +4182,10 @@ void ScCompiler::CreateStringFromMatrix( OUStringBuffer& rBuffer, rBuffer.append( mxSymbols->getSymbol(ocArrayClose) ); } -void ScCompiler::CreateStringFromSingleRef(OUStringBuffer& rBuffer,FormulaToken* _pTokenP) +void ScCompiler::CreateStringFromSingleRef(OUStringBuffer& rBuffer,FormulaToken* _pTokenP) const { const OpCode eOp = _pTokenP->GetOpCode(); - ScSingleRefData& rRef = static_cast<ScToken*>(_pTokenP)->GetSingleRef(); + const ScSingleRefData& rRef = static_cast<const ScToken*>(_pTokenP)->GetSingleRef(); ScComplexRefData aRef; aRef.Ref1 = aRef.Ref2 = rRef; if ( eOp == ocColRowName ) @@ -4207,12 +4207,12 @@ void ScCompiler::CreateStringFromSingleRef(OUStringBuffer& rBuffer,FormulaToken* pConv->MakeRefStr( rBuffer, *this, aRef, true ); } -void ScCompiler::CreateStringFromDoubleRef(OUStringBuffer& rBuffer,FormulaToken* _pTokenP) +void ScCompiler::CreateStringFromDoubleRef(OUStringBuffer& rBuffer,FormulaToken* _pTokenP) const { pConv->MakeRefStr( rBuffer, *this, static_cast<ScToken*>(_pTokenP)->GetDoubleRef(), false ); } -void ScCompiler::CreateStringFromIndex(OUStringBuffer& rBuffer,FormulaToken* _pTokenP) +void ScCompiler::CreateStringFromIndex(OUStringBuffer& rBuffer,FormulaToken* _pTokenP) const { const OpCode eOp = _pTokenP->GetOpCode(); OUStringBuffer aBuffer; @@ -4220,14 +4220,14 @@ void ScCompiler::CreateStringFromIndex(OUStringBuffer& rBuffer,FormulaToken* _pT { case ocName: { - ScRangeData* pData = GetRangeData( *_pTokenP); + const ScRangeData* pData = GetRangeData( *_pTokenP); if (pData) aBuffer.append(pData->GetName()); } break; case ocDBArea: { - ScDBData* pDBData = pDoc->GetDBCollection()->getNamedDBs().findByIndex(_pTokenP->GetIndex()); + const ScDBData* pDBData = pDoc->GetDBCollection()->getNamedDBs().findByIndex(_pTokenP->GetIndex()); if (pDBData) aBuffer.append(pDBData->GetName()); } @@ -4241,7 +4241,7 @@ void ScCompiler::CreateStringFromIndex(OUStringBuffer& rBuffer,FormulaToken* _pT rBuffer.append(ScGlobal::GetRscString(STR_NO_NAME_REF)); } -void ScCompiler::LocalizeString( OUString& rName ) +void ScCompiler::LocalizeString( OUString& rName ) const { ScGlobal::GetAddInCollection()->LocalizeString( rName ); } _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits