[Libreoffice-commits] core.git: 4 commits - formula/source include/formula

Tor Lillqvist tml at collabora.com
Mon Jun 19 09:24:20 UTC 2017


 formula/source/core/api/FormulaCompiler.cxx |   24 ++---
 formula/source/core/api/token.cxx           |  122 +++++++++++++---------------
 include/formula/tokenarray.hxx              |   82 ++++++++++++++++--
 3 files changed, 140 insertions(+), 88 deletions(-)

New commits:
commit c3fae6be6067572aaf9f0c72ad35b69019a79135
Author: Tor Lillqvist <tml at collabora.com>
Date:   Mon Jun 19 11:37:43 2017 +0300

    Add yet another kind of iterator for the two arrays in FormulaTokenArray
    
    This one has no extra functionality at all, and its only purpose is to
    be used in range-based for loops. If there is a cleaner way to do
    this, feel free. Not sure if this functionality could or should be
    combined with either of the two existing iterator classes related to
    FormulaTokenArray (FormulaTokenIterator and
    FormulaTokenArrayPlainIterator). Probably not.
    
    Change-Id: I32599b0800fd2585624d3742a46ad4896ce7e47a

diff --git a/formula/source/core/api/token.cxx b/formula/source/core/api/token.cxx
index 2cd4b63f92a4..bb634fcdfa46 100644
--- a/formula/source/core/api/token.cxx
+++ b/formula/source/core/api/token.cxx
@@ -495,15 +495,15 @@ FormulaToken* FormulaTokenArray::FirstRPNToken() const
 
 bool FormulaTokenArray::HasReferences() const
 {
-    for (sal_uInt16 i = 0; i < nLen; ++i)
+    for (auto i: Tokens())
     {
-        if (pCode[i]->IsRef())
+        if (i->IsRef())
             return true;
     }
 
-    for (sal_uInt16 i = 0; i < nRPN; ++i)
+    for (auto i: RPNTokens())
     {
-        if (pRPN[i]->IsRef())
+        if (i->IsRef())
             return true;
     }
 
@@ -512,9 +512,9 @@ bool FormulaTokenArray::HasReferences() const
 
 bool FormulaTokenArray::HasExternalRef() const
 {
-    for ( sal_uInt16 j=0; j < nLen; j++ )
+    for (auto i: Tokens())
     {
-        if (pCode[j]->IsExternalRef())
+        if (i->IsExternalRef())
             return true;
     }
     return false;
@@ -522,9 +522,9 @@ bool FormulaTokenArray::HasExternalRef() const
 
 bool FormulaTokenArray::HasOpCode( OpCode eOp ) const
 {
-    for ( sal_uInt16 j=0; j < nLen; j++ )
+    for (auto i: Tokens())
     {
-        if ( pCode[j]->GetOpCode() == eOp )
+        if (i->GetOpCode() == eOp)
             return true;
     }
     return false;
@@ -532,9 +532,9 @@ bool FormulaTokenArray::HasOpCode( OpCode eOp ) const
 
 bool FormulaTokenArray::HasOpCodeRPN( OpCode eOp ) const
 {
-    for ( sal_uInt16 j=0; j < nRPN; j++ )
+    for (auto i: RPNTokens())
     {
-        if ( pRPN[j]->GetOpCode() == eOp )
+        if (i->GetOpCode() == eOp)
             return true;
     }
     return false;
@@ -542,9 +542,9 @@ bool FormulaTokenArray::HasOpCodeRPN( OpCode eOp ) const
 
 bool FormulaTokenArray::HasNameOrColRowName() const
 {
-    for ( sal_uInt16 j=0; j < nLen; j++ )
+    for (auto i: Tokens())
     {
-        if( pCode[j]->GetType() == svIndex || pCode[j]->GetOpCode() == ocColRowName )
+        if (i->GetType() == svIndex || i->GetOpCode() == ocColRowName )
             return true;
     }
     return false;
@@ -552,12 +552,9 @@ bool FormulaTokenArray::HasNameOrColRowName() const
 
 bool FormulaTokenArray::HasOpCodes(const unordered_opcode_set& rOpCodes) const
 {
-    FormulaToken** p = pCode;
-    FormulaToken** pEnd = p + static_cast<size_t>(nLen);
-    for (; p != pEnd; ++p)
+    for (auto i: Tokens())
     {
-        OpCode eOp = (*p)->GetOpCode();
-        if (rOpCodes.count(eOp) > 0)
+        if (rOpCodes.count(i->GetOpCode()) > 0)
             return true;
     }
 
@@ -853,9 +850,8 @@ bool FormulaTokenArray::HasMatrixDoubleRefOps()
         std::unique_ptr<FormulaToken*[]> pStack(new FormulaToken* [nRPN]);
         FormulaToken* pResult = new FormulaDoubleToken( 0.0 );
         short sp = 0;
-        for ( sal_uInt16 j = 0; j < nRPN; j++ )
+        for ( auto t: RPNTokens() )
         {
-            FormulaToken* t = pRPN[j];
             OpCode eOp = t->GetOpCode();
             sal_uInt8 nParams = t->GetParamCount();
             switch ( eOp )
@@ -1248,9 +1244,9 @@ bool FormulaMissingContext::AddMissing( FormulaTokenArray *pNewArr, const Missin
 
 bool FormulaTokenArray::NeedsPodfRewrite( const MissingConventionODF & rConv )
 {
-    for ( int i = 0; i < nLen; ++i )
+    for ( auto i: Tokens()  )
     {
-        if ( rConv.isRewriteNeeded( pCode[i]->GetOpCode()))
+        if ( rConv.isRewriteNeeded( i->GetOpCode()))
             return true;
     }
     return false;
@@ -1258,9 +1254,9 @@ bool FormulaTokenArray::NeedsPodfRewrite( const MissingConventionODF & rConv )
 
 bool FormulaTokenArray::NeedsOoxmlRewrite()
 {
-    for ( int i = 0; i < nLen; ++i )
+    for ( auto i: Tokens() )
     {
-        if ( MissingConventionOOXML::isRewriteNeeded( pCode[i]->GetOpCode()))
+        if ( MissingConventionOOXML::isRewriteNeeded( i->GetOpCode()))
             return true;
     }
     return false;
@@ -1484,12 +1480,12 @@ FormulaToken* FormulaTokenArray::AddOpCode( OpCode eOp )
 
 void FormulaTokenArray::ReinternStrings( svl::SharedStringPool& rPool )
 {
-    for (sal_uInt16 i=0; i < nLen; ++i)
+    for (auto i: Tokens())
     {
-        switch (pCode[i]->GetType())
+        switch (i->GetType())
         {
             case svString:
-                pCode[i]->SetString( rPool.intern( pCode[i]->GetString().getString()));
+                i->SetString( rPool.intern( i->GetString().getString()));
                 break;
             default:
                 ;   // nothing
diff --git a/include/formula/tokenarray.hxx b/include/formula/tokenarray.hxx
index 2014994e03fc..7252613cf713 100644
--- a/include/formula/tokenarray.hxx
+++ b/include/formula/tokenarray.hxx
@@ -112,6 +112,30 @@ public:
 
 typedef std::unordered_set<OpCode, std::hash<std::underlying_type<OpCode>::type> > unordered_opcode_set;
 
+class FORMULA_DLLPUBLIC FormulaTokenArrayStandardIterator
+{
+private:
+    FormulaToken** mpBegin;
+    FormulaToken** mpEnd;
+
+public:
+    FormulaTokenArrayStandardIterator(FormulaToken** pBegin, sal_uInt16 nSize) :
+        mpBegin(pBegin),
+        mpEnd(pBegin + nSize)
+    {
+    }
+
+    FormulaToken** begin() const
+    {
+        return mpBegin;
+    }
+
+    FormulaToken** end() const
+    {
+        return mpEnd;
+    }
+};
+
 class FORMULA_DLLPUBLIC FormulaTokenArray
 {
 protected:
@@ -247,7 +271,19 @@ public:
     }
 
     FormulaToken** GetArray() const  { return pCode; }
+
+    FormulaTokenArrayStandardIterator Tokens() const
+    {
+        return FormulaTokenArrayStandardIterator(pCode, nLen);
+    }
+
     FormulaToken** GetCode()  const  { return pRPN; }
+
+    FormulaTokenArrayStandardIterator RPNTokens() const
+    {
+        return FormulaTokenArrayStandardIterator(pRPN, nRPN);
+    }
+
     sal_uInt16     GetLen() const     { return nLen; }
     sal_uInt16     GetCodeLen() const { return nRPN; }
     FormulaError   GetCodeError() const      { return nError; }
commit cfd5d203e9c641c150f92c2b1ee5b84e89e6dc99
Author: Tor Lillqvist <tml at collabora.com>
Date:   Fri Jun 16 17:08:17 2017 +0300

    Drop another friend declaration
    
    Change-Id: I06dd3639e4110700e070f1224112a9fa6597a832

diff --git a/formula/source/core/api/FormulaCompiler.cxx b/formula/source/core/api/FormulaCompiler.cxx
index 1ba70a90f81d..24b7d15d723b 100644
--- a/formula/source/core/api/FormulaCompiler.cxx
+++ b/formula/source/core/api/FormulaCompiler.cxx
@@ -1300,7 +1300,7 @@ bool FormulaCompiler::GetToken()
             if ( nWasColRowName >= 2 && mpToken->GetOpCode() == ocColRowName )
             {   // convert an ocSpaces to ocIntersect in RPN
                 mpLastToken = mpToken = new FormulaByteToken( ocIntersect );
-                maArrIterator.mnIndex--;     // we advanced to the second ocColRowName, step back
+                maArrIterator.StepBack();     // we advanced to the second ocColRowName, step back
             }
             else if (pSpacesToken && FormulaGrammar::isExcelSyntax( meGrammar) &&
                     mpLastToken && mpToken &&
@@ -1310,7 +1310,7 @@ bool FormulaCompiler::GetToken()
                 // Let IntersectionLine() <- Factor() decide how to treat this,
                 // once the actual arguments are determined in RPN.
                 mpLastToken = mpToken = pSpacesToken;
-                maArrIterator.mnIndex--;     // step back from next non-spaces token
+                maArrIterator.StepBack();     // step back from next non-spaces token
                 return true;
             }
         }
@@ -1498,7 +1498,7 @@ void FormulaCompiler::Factor()
                 else
                     SetError( FormulaError::PairExpected);
                 sal_uInt8 nSepCount = 0;
-                const sal_uInt16 nSepPos = maArrIterator.mnIndex - 1;    // separator position, if any
+                const sal_uInt16 nSepPos = maArrIterator.GetIndex() - 1;    // separator position, if any
                 if( !bNoParam )
                 {
                     nSepCount++;
@@ -1525,7 +1525,7 @@ void FormulaCompiler::Factor()
                     // Current index is nSepPos+3 if expression stops, or
                     // nSepPos+4 if expression continues after the call because
                     // we just called NextToken() to move away from it.
-                    if (pc >= 2 && (maArrIterator.mnIndex == nSepPos + 3 || maArrIterator.mnIndex == nSepPos + 4) &&
+                    if (pc >= 2 && (maArrIterator.GetIndex() == nSepPos + 3 || maArrIterator.GetIndex() == nSepPos + 4) &&
                             pArr->TokenAt(nSepPos+1)->GetType() == svDouble &&
                             pArr->TokenAt(nSepPos+1)->GetDouble() != 1.0 &&
                             pArr->TokenAt(nSepPos+2)->GetOpCode() == ocClose &&
@@ -1788,7 +1788,7 @@ void FormulaCompiler::IntersectionLine()
     RangeLine();
     while (mpToken->GetOpCode() == ocIntersect || mpToken->GetOpCode() == ocSpaces)
     {
-        sal_uInt16 nCodeIndex = maArrIterator.mnIndex - 1;
+        sal_uInt16 nCodeIndex = maArrIterator.GetIndex() - 1;
         FormulaToken** pCode1 = pCode - 1;
         FormulaTokenRef p = mpToken;
         NextToken();
diff --git a/formula/source/core/api/token.cxx b/formula/source/core/api/token.cxx
index 51f3e0fa928d..2cd4b63f92a4 100644
--- a/formula/source/core/api/token.cxx
+++ b/formula/source/core/api/token.cxx
@@ -1536,15 +1536,15 @@ void FormulaTokenIterator::Reset()
 
 FormulaToken* FormulaTokenArrayPlainIterator::GetNextName()
 {
-    if( mpFTA->pCode )
+    if( mpFTA->GetArray() )
     {
-        while ( mnIndex < mpFTA->nLen )
+        while ( mnIndex < mpFTA->GetLen() )
         {
-            FormulaToken* t = mpFTA->pCode[ mnIndex++ ];
+            FormulaToken* t = mpFTA->GetArray()[ mnIndex++ ];
             if( t->GetType() == svIndex )
                 return t;
         }
-    } // if( pCode )
+    }
     return nullptr;
 }
 
@@ -1595,9 +1595,9 @@ const FormulaToken* FormulaTokenIterator::GetNonEndOfPathToken( short nIdx ) con
 {
     FormulaTokenIterator::Item cur = maStack.back();
 
-    if (nIdx < cur.pArr->nRPN && nIdx < cur.nStop)
+    if (nIdx < cur.pArr->GetCodeLen() && nIdx < cur.nStop)
     {
-        const FormulaToken* t = cur.pArr->pRPN[ nIdx ];
+        const FormulaToken* t = cur.pArr->GetCode()[ nIdx ];
         // such an OpCode ends an IF() or CHOOSE() path
         return (t->GetOpCode() == ocSep || t->GetOpCode() == ocClose) ? nullptr : t;
     }
@@ -1611,9 +1611,9 @@ bool FormulaTokenIterator::IsEndOfPath() const
 
 FormulaToken* FormulaTokenArrayPlainIterator::GetNextReference()
 {
-    while( mnIndex < mpFTA->nLen )
+    while( mnIndex < mpFTA->GetLen() )
     {
-        FormulaToken* t = mpFTA->pCode[ mnIndex++ ];
+        FormulaToken* t = mpFTA->GetArray()[ mnIndex++ ];
         switch( t->GetType() )
         {
             case svSingleRef:
@@ -1632,9 +1632,9 @@ FormulaToken* FormulaTokenArrayPlainIterator::GetNextReference()
 
 FormulaToken* FormulaTokenArrayPlainIterator::GetNextColRowName()
 {
-    while( mnIndex < mpFTA->nLen )
+    while( mnIndex < mpFTA->GetLen() )
     {
-        FormulaToken* t = mpFTA->pCode[ mnIndex++ ];
+        FormulaToken* t = mpFTA->GetArray()[ mnIndex++ ];
         if ( t->GetOpCode() == ocColRowName )
             return t;
     }
@@ -1643,9 +1643,9 @@ FormulaToken* FormulaTokenArrayPlainIterator::GetNextColRowName()
 
 FormulaToken* FormulaTokenArrayPlainIterator::GetNextReferenceRPN()
 {
-    while( mnIndex < mpFTA->nRPN )
+    while( mnIndex < mpFTA->GetCodeLen() )
     {
-        FormulaToken* t = mpFTA->pRPN[ mnIndex++ ];
+        FormulaToken* t = mpFTA->GetCode()[ mnIndex++ ];
         switch( t->GetType() )
         {
             case svSingleRef:
@@ -1664,11 +1664,11 @@ FormulaToken* FormulaTokenArrayPlainIterator::GetNextReferenceRPN()
 
 FormulaToken* FormulaTokenArrayPlainIterator::GetNextReferenceOrName()
 {
-    if( mpFTA->pCode )
+    if( mpFTA->GetArray() )
     {
-        while ( mnIndex < mpFTA->nLen )
+        while ( mnIndex < mpFTA->GetLen() )
         {
-            FormulaToken* t = mpFTA->pCode[ mnIndex++ ];
+            FormulaToken* t = mpFTA->GetArray()[ mnIndex++ ];
             switch( t->GetType() )
             {
                 case svSingleRef:
@@ -1690,57 +1690,57 @@ FormulaToken* FormulaTokenArrayPlainIterator::GetNextReferenceOrName()
 
 FormulaToken* FormulaTokenArrayPlainIterator::Next()
 {
-    if( mpFTA->pCode && mnIndex < mpFTA->nLen )
-        return mpFTA->pCode[ mnIndex++ ];
+    if( mpFTA->GetArray() && mnIndex < mpFTA->GetLen() )
+        return mpFTA->GetArray()[ mnIndex++ ];
     else
         return nullptr;
 }
 
 FormulaToken* FormulaTokenArrayPlainIterator::NextNoSpaces()
 {
-    if( mpFTA->pCode )
+    if( mpFTA->GetArray() )
     {
-        while( (mnIndex < mpFTA->nLen) && (mpFTA->pCode[ mnIndex ]->GetOpCode() == ocSpaces) )
+        while( (mnIndex < mpFTA->GetLen()) && (mpFTA->GetArray()[ mnIndex ]->GetOpCode() == ocSpaces) )
             ++mnIndex;
-        if( mnIndex < mpFTA->nLen )
-            return mpFTA->pCode[ mnIndex++ ];
+        if( mnIndex < mpFTA->GetLen() )
+            return mpFTA->GetArray()[ mnIndex++ ];
     }
     return nullptr;
 }
 
 FormulaToken* FormulaTokenArrayPlainIterator::NextRPN()
 {
-    if( mpFTA->pRPN && mnIndex < mpFTA->nRPN )
-        return mpFTA->pRPN[ mnIndex++ ];
+    if( mpFTA->GetCode() && mnIndex < mpFTA->GetCodeLen() )
+        return mpFTA->GetCode()[ mnIndex++ ];
     else
         return nullptr;
 }
 
 FormulaToken* FormulaTokenArrayPlainIterator::PrevRPN()
 {
-    if( mpFTA->pRPN && mnIndex )
-        return mpFTA->pRPN[ --mnIndex ];
+    if( mpFTA->GetCode() && mnIndex )
+        return mpFTA->GetCode()[ --mnIndex ];
     else
         return nullptr;
 }
 
 FormulaToken* FormulaTokenArrayPlainIterator::PeekNext()
 {
-    if( mpFTA->pCode && mnIndex < mpFTA->nLen )
-        return mpFTA->pCode[ mnIndex ];
+    if( mpFTA->GetArray() && mnIndex < mpFTA->GetLen() )
+        return mpFTA->GetArray()[ mnIndex ];
     else
         return nullptr;
 }
 
 FormulaToken* FormulaTokenArrayPlainIterator::PeekNextNoSpaces() const
 {
-    if( mpFTA->pCode && mnIndex < mpFTA->nLen )
+    if( mpFTA->GetArray() && mnIndex < mpFTA->GetLen() )
     {
         sal_uInt16 j = mnIndex;
-        while ( j < mpFTA->nLen && mpFTA->pCode[j]->GetOpCode() == ocSpaces )
+        while ( j < mpFTA->GetLen() && mpFTA->GetArray()[j]->GetOpCode() == ocSpaces )
             j++;
-        if ( j < mpFTA->nLen )
-            return mpFTA->pCode[ j ];
+        if ( j < mpFTA->GetLen() )
+            return mpFTA->GetArray()[ j ];
         else
             return nullptr;
     }
@@ -1750,13 +1750,13 @@ FormulaToken* FormulaTokenArrayPlainIterator::PeekNextNoSpaces() const
 
 FormulaToken* FormulaTokenArrayPlainIterator::PeekPrevNoSpaces() const
 {
-    if( mpFTA->pCode && mnIndex > 1 )
+    if( mpFTA->GetArray() && mnIndex > 1 )
     {
         sal_uInt16 j = mnIndex - 2;
-        while ( mpFTA->pCode[j]->GetOpCode() == ocSpaces && j > 0 )
+        while ( mpFTA->GetArray()[j]->GetOpCode() == ocSpaces && j > 0 )
             j--;
-        if ( j > 0 || mpFTA->pCode[j]->GetOpCode() != ocSpaces )
-            return mpFTA->pCode[ j ];
+        if ( j > 0 || mpFTA->GetArray()[j]->GetOpCode() != ocSpaces )
+            return mpFTA->GetArray()[ j ];
         else
             return nullptr;
     }
@@ -1766,7 +1766,7 @@ FormulaToken* FormulaTokenArrayPlainIterator::PeekPrevNoSpaces() const
 
 void FormulaTokenArrayPlainIterator::AfterRemoveToken( sal_uInt16 nOffset, sal_uInt16 nCount )
 {
-    const sal_uInt16 nStop = std::min( static_cast<sal_uInt16>(nOffset + nCount), mpFTA->nLen);
+    const sal_uInt16 nStop = std::min( static_cast<sal_uInt16>(nOffset + nCount), mpFTA->GetLen());
 
     if (mnIndex >= nOffset)
     {
diff --git a/include/formula/tokenarray.hxx b/include/formula/tokenarray.hxx
index 7be78298af39..2014994e03fc 100644
--- a/include/formula/tokenarray.hxx
+++ b/include/formula/tokenarray.hxx
@@ -114,9 +114,6 @@ typedef std::unordered_set<OpCode, std::hash<std::underlying_type<OpCode>::type>
 
 class FORMULA_DLLPUBLIC FormulaTokenArray
 {
-    friend class FormulaTokenIterator;
-    friend class FormulaTokenArrayPlainIterator;
-
 protected:
     FormulaToken**  pCode;                  // Token code array
     FormulaToken**  pRPN;                   // RPN array
@@ -431,8 +428,6 @@ inline std::basic_ostream<charT, traits> & operator <<(std::basic_ostream<charT,
 
 class FORMULA_DLLPUBLIC FormulaTokenArrayPlainIterator
 {
-    friend class FormulaCompiler;
-
 private:
     const FormulaTokenArray* mpFTA;
     sal_uInt16 mnIndex;                 // Current step index
@@ -465,6 +460,12 @@ public:
         mnIndex = nIndex;
     }
 
+    void StepBack()
+    {
+        assert(mnIndex > 0);
+        mnIndex--;
+    }
+
     FormulaToken* Next();
     FormulaToken* NextNoSpaces();
     FormulaToken* GetNextName();
@@ -486,7 +487,7 @@ public:
 
     FormulaToken* LastRPN()
     {
-        mnIndex = mpFTA->nRPN;
+        mnIndex = mpFTA->GetCodeLen();
         return PrevRPN();
     }
 
commit 896dbaee45ca0dd2d4127a4b27455e8e8509d9c7
Author: Tor Lillqvist <tml at collabora.com>
Date:   Fri Jun 16 17:04:12 2017 +0300

    Drop an unnecessary friend declaration
    
    Change-Id: I05ee0c0db2d54625413c9b89a12e24b9de7c45da

diff --git a/include/formula/tokenarray.hxx b/include/formula/tokenarray.hxx
index 059c4fba7a7e..7be78298af39 100644
--- a/include/formula/tokenarray.hxx
+++ b/include/formula/tokenarray.hxx
@@ -116,7 +116,6 @@ class FORMULA_DLLPUBLIC FormulaTokenArray
 {
     friend class FormulaTokenIterator;
     friend class FormulaTokenArrayPlainIterator;
-    friend class FormulaMissingContext;
 
 protected:
     FormulaToken**  pCode;                  // Token code array
commit a056978ace7e355fa9a6fc0e1488013e5836d262
Author: Tor Lillqvist <tml at collabora.com>
Date:   Fri Jun 16 16:57:40 2017 +0300

    Drop one friend declaration and instead add some useful member functions
    
    Change-Id: I9a947078d9f2c1c06cb8524be137ba5e36e97a0b

diff --git a/formula/source/core/api/FormulaCompiler.cxx b/formula/source/core/api/FormulaCompiler.cxx
index 310ddb2346f3..1ba70a90f81d 100644
--- a/formula/source/core/api/FormulaCompiler.cxx
+++ b/formula/source/core/api/FormulaCompiler.cxx
@@ -1264,7 +1264,7 @@ bool FormulaCompiler::GetToken()
     {
         FormulaTokenRef pSpacesToken;
         short nWasColRowName;
-        if ( maArrIterator.mnIndex > 0 && pArr->pCode[ maArrIterator.mnIndex-1 ]->GetOpCode() == ocColRowName )
+        if ( pArr->OpCodeBefore( maArrIterator.GetIndex() ) == ocColRowName )
              nWasColRowName = 1;
         else
              nWasColRowName = 0;
@@ -1526,9 +1526,9 @@ void FormulaCompiler::Factor()
                     // nSepPos+4 if expression continues after the call because
                     // we just called NextToken() to move away from it.
                     if (pc >= 2 && (maArrIterator.mnIndex == nSepPos + 3 || maArrIterator.mnIndex == nSepPos + 4) &&
-                            pArr->pCode[nSepPos+1]->GetType() == svDouble &&
-                            pArr->pCode[nSepPos+1]->GetDouble() != 1.0 &&
-                            pArr->pCode[nSepPos+2]->GetOpCode() == ocClose &&
+                            pArr->TokenAt(nSepPos+1)->GetType() == svDouble &&
+                            pArr->TokenAt(nSepPos+1)->GetDouble() != 1.0 &&
+                            pArr->TokenAt(nSepPos+2)->GetOpCode() == ocClose &&
                             pArr->RemoveToken( nSepPos, 2) == 2)
                     {
                         maArrIterator.AfterRemoveToken( nSepPos, 2);
@@ -2014,11 +2014,7 @@ bool FormulaCompiler::CompileTokenArray()
         while( pStack )
             PopTokenArray();
         if( pc )
-        {
-            pArr->pRPN = new FormulaToken*[ pc ];
-            pArr->nRPN = pc;
-            memcpy( pArr->pRPN, pData, pc * sizeof( FormulaToken* ) );
-        }
+            pArr->CreateNewRPNArrayFromData( pData, pc );
 
         // once an error, always an error
         if( pArr->GetCodeError() == FormulaError::NONE && nErrorBeforePop != FormulaError::NONE )
diff --git a/formula/source/core/api/token.cxx b/formula/source/core/api/token.cxx
index 78c69ea7360a..51f3e0fa928d 100644
--- a/formula/source/core/api/token.cxx
+++ b/formula/source/core/api/token.cxx
@@ -479,7 +479,7 @@ FormulaToken* FormulaTokenArray::FirstToken() const
     return pCode[0];
 }
 
-FormulaToken* FormulaTokenArray::PeekPrev( sal_uInt16 & nIdx )
+FormulaToken* FormulaTokenArray::PeekPrev( sal_uInt16 & nIdx ) const
 {
     if (0 < nIdx && nIdx <= nLen)
         return pCode[--nIdx];
diff --git a/include/formula/tokenarray.hxx b/include/formula/tokenarray.hxx
index 8a00c0287126..059c4fba7a7e 100644
--- a/include/formula/tokenarray.hxx
+++ b/include/formula/tokenarray.hxx
@@ -114,7 +114,6 @@ typedef std::unordered_set<OpCode, std::hash<std::underlying_type<OpCode>::type>
 
 class FORMULA_DLLPUBLIC FormulaTokenArray
 {
-    friend class FormulaCompiler;
     friend class FormulaTokenIterator;
     friend class FormulaTokenArrayPlainIterator;
     friend class FormulaMissingContext;
@@ -145,7 +144,6 @@ public:
         CODE_AND_RPN    ///< replacement in pCode and pRPN
     };
 
-protected:
     /** Also used by the compiler. The token MUST had been allocated with new!
         @param  nOffset
                 Absolute offset in pCode of the token to be replaced.
@@ -182,7 +180,6 @@ protected:
     void            SetMaskedRecalcMode( ScRecalcMode nBits )
                                 { nMode = GetCombinedBitsRecalcMode() | nBits; }
 
-public:
     FormulaTokenArray();
     /// Assignment with references to FormulaToken entries (not copied!)
     FormulaTokenArray( const FormulaTokenArray& );
@@ -204,8 +201,27 @@ public:
     void Clear();
     void DelRPN();
     FormulaToken* FirstToken() const;
+
+    /// Return pCode[nIdx], or nullptr if nIdx is out of bounds
+    FormulaToken* TokenAt( sal_uInt16 nIdx) const
+    {
+        if (nIdx >= nLen)
+            return nullptr;
+        return pCode[nIdx];
+    }
+
     /// Peek at nIdx-1 if not out of bounds, decrements nIdx if successful. Returns NULL if not.
-    FormulaToken* PeekPrev( sal_uInt16 & nIdx );
+    FormulaToken* PeekPrev( sal_uInt16 & nIdx ) const;
+
+    /// Return the opcode at pCode[nIdx-1], ocNone if nIdx-1 is out of bounds
+    OpCode OpCodeBefore( sal_uInt16 nIdx) const
+    {
+        if (nIdx == 0 || nIdx > nLen)
+            return ocNone;
+
+        return pCode[nIdx-1]->GetOpCode();
+    }
+
     FormulaToken* FirstRPNToken() const;
 
     bool HasReferences() const;
@@ -226,6 +242,14 @@ public:
      */
     bool HasOpCodes( const unordered_opcode_set& rOpCodes ) const;
 
+    /// Assign pRPN to point to a newly created array filled with the data from pData
+    void CreateNewRPNArrayFromData( FormulaToken** pData, sal_uInt16 nSize )
+    {
+        pRPN = new FormulaToken*[ nSize ];
+        nRPN = nSize;
+        memcpy( pRPN, pData, nSize * sizeof( FormulaToken* ) );
+    }
+
     FormulaToken** GetArray() const  { return pCode; }
     FormulaToken** GetCode()  const  { return pRPN; }
     sal_uInt16     GetLen() const     { return nLen; }


More information about the Libreoffice-commits mailing list