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

Tor Lillqvist tml at collabora.com
Fri Jun 16 10:18:06 UTC 2017


 formula/source/core/api/FormulaCompiler.cxx |   58 ++++++--
 formula/source/core/api/token.cxx           |  181 ----------------------------
 include/formula/FormulaCompiler.hxx         |    6 
 include/formula/tokenarray.hxx              |   37 ++---
 sc/source/core/tool/compiler.cxx            |   51 +++----
 sc/source/core/tool/interpr4.cxx            |    5 
 6 files changed, 91 insertions(+), 247 deletions(-)

New commits:
commit 5c81adc51a05a016e754de7961d3a7bdb4494e01
Author: Tor Lillqvist <tml at collabora.com>
Date:   Fri Jun 16 00:18:57 2017 +0300

    Get rid of the index inside FormulaTokenArray
    
    Instead, use FormulaTokenArrrayPlainIterator everywhere, especially in
    the FormulaCompiler.
    
    This is the final step of a long chain of commits. (Split up into many
    "uncontroversial" bits, and then this, to make potential bisecting
    easier.)
    
    Also added a logging operator<< for FormulaTokenArray, for SAL_DEBUG,
    SAL_INFO etc goodness.
    
    Change-Id: I02fe29f3f1e0dc33e5cba69e594223b4178a12bc
    Reviewed-on: https://gerrit.libreoffice.org/38851
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Tor Lillqvist <tml at collabora.com>

diff --git a/formula/source/core/api/FormulaCompiler.cxx b/formula/source/core/api/FormulaCompiler.cxx
index 7da75874ea04..310ddb2346f3 100644
--- a/formula/source/core/api/FormulaCompiler.cxx
+++ b/formula/source/core/api/FormulaCompiler.cxx
@@ -700,6 +700,7 @@ FormulaCompiler::FormulaCompiler( FormulaTokenArray& rArr )
         :
         nCurrentFactorParam(0),
         pArr( &rArr ),
+        maArrIterator( rArr ),
         pCode( nullptr ),
         pStack( nullptr ),
         eLastOp( ocPush ),
@@ -715,10 +716,13 @@ FormulaCompiler::FormulaCompiler( FormulaTokenArray& rArr )
 {
 }
 
+FormulaTokenArray FormulaCompiler::smDummyTokenArray;
+
 FormulaCompiler::FormulaCompiler()
         :
         nCurrentFactorParam(0),
         pArr( nullptr ),
+        maArrIterator( smDummyTokenArray ),
         pCode( nullptr ),
         pStack( nullptr ),
         eLastOp( ocPush ),
@@ -1260,11 +1264,11 @@ bool FormulaCompiler::GetToken()
     {
         FormulaTokenRef pSpacesToken;
         short nWasColRowName;
-        if ( pArr->nIndex > 0 && pArr->pCode[ pArr->nIndex-1 ]->GetOpCode() == ocColRowName )
+        if ( maArrIterator.mnIndex > 0 && pArr->pCode[ maArrIterator.mnIndex-1 ]->GetOpCode() == ocColRowName )
              nWasColRowName = 1;
         else
              nWasColRowName = 0;
-        mpToken = pArr->Next();
+        mpToken = maArrIterator.Next();
         while( mpToken && mpToken->GetOpCode() == ocSpaces )
         {
             // For significant whitespace remember last ocSpaces token. Usually
@@ -1274,7 +1278,7 @@ bool FormulaCompiler::GetToken()
                 nWasColRowName++;
             if ( bAutoCorrect && !pStack )
                 CreateStringFromToken( aCorrectedFormula, mpToken.get() );
-            mpToken = pArr->Next();
+            mpToken = maArrIterator.Next();
         }
         if ( bAutoCorrect && !pStack && mpToken )
             CreateStringFromToken( aCorrectedSymbol, mpToken.get() );
@@ -1296,7 +1300,7 @@ bool FormulaCompiler::GetToken()
             if ( nWasColRowName >= 2 && mpToken->GetOpCode() == ocColRowName )
             {   // convert an ocSpaces to ocIntersect in RPN
                 mpLastToken = mpToken = new FormulaByteToken( ocIntersect );
-                pArr->nIndex--;     // we advanced to the second ocColRowName, step back
+                maArrIterator.mnIndex--;     // we advanced to the second ocColRowName, step back
             }
             else if (pSpacesToken && FormulaGrammar::isExcelSyntax( meGrammar) &&
                     mpLastToken && mpToken &&
@@ -1306,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;
-                pArr->nIndex--;     // step back from next non-spaces token
+                maArrIterator.mnIndex--;     // step back from next non-spaces token
                 return true;
             }
         }
@@ -1494,7 +1498,7 @@ void FormulaCompiler::Factor()
                 else
                     SetError( FormulaError::PairExpected);
                 sal_uInt8 nSepCount = 0;
-                const sal_uInt16 nSepPos = pArr->nIndex - 1;    // separator position, if any
+                const sal_uInt16 nSepPos = maArrIterator.mnIndex - 1;    // separator position, if any
                 if( !bNoParam )
                 {
                     nSepCount++;
@@ -1521,12 +1525,13 @@ 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 && (pArr->nIndex == nSepPos + 3 || pArr->nIndex == nSepPos + 4) &&
+                    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->RemoveToken( nSepPos, 2) == 2)
                     {
+                        maArrIterator.AfterRemoveToken( nSepPos, 2);
                         // Remove the ocPush/svDouble just removed also from
                         // the compiler local RPN array.
                         --pCode; --pc;
@@ -1783,7 +1788,7 @@ void FormulaCompiler::IntersectionLine()
     RangeLine();
     while (mpToken->GetOpCode() == ocIntersect || mpToken->GetOpCode() == ocSpaces)
     {
-        sal_uInt16 nCodeIndex = pArr->nIndex - 1;
+        sal_uInt16 nCodeIndex = maArrIterator.mnIndex - 1;
         FormulaToken** pCode1 = pCode - 1;
         FormulaTokenRef p = mpToken;
         NextToken();
@@ -1984,6 +1989,7 @@ bool FormulaCompiler::CompileTokenArray()
             aCorrectedSymbol.clear();
         }
         pArr->DelRPN();
+        maArrIterator.Reset();
         pStack = nullptr;
         FormulaToken* pData[ FORMULA_MAXTOKENS ];
         pCode = pData;
@@ -1994,7 +2000,7 @@ bool FormulaCompiler::CompileTokenArray()
                 aCorrectedFormula = "=";
         }
         pArr->ClearRecalcMode();
-        pArr->Reset();
+        maArrIterator.Reset();
         eLastOp = ocOpen;
         pc = 0;
         NextToken();
@@ -2021,6 +2027,7 @@ bool FormulaCompiler::CompileTokenArray()
         if (pArr->GetCodeError() != FormulaError::NONE && mbStopOnError)
         {
             pArr->DelRPN();
+            maArrIterator.Reset();
             pArr->SetHyperLink( false);
         }
 
@@ -2049,6 +2056,8 @@ void FormulaCompiler::PopTokenArray()
         if( p->bTemp )
             delete pArr;
         pArr = p->pArr;
+        maArrIterator = FormulaTokenArrayPlainIterator(*pArr);
+        maArrIterator.Jump(p->nIndex);
         mpLastToken = p->mpLastToken;
         delete p;
     }
@@ -2068,20 +2077,27 @@ void FormulaCompiler::CreateStringFromTokenArray( OUStringBuffer& rBuffer )
         return;
 
     FormulaTokenArray* pSaveArr = pArr;
+    int nSaveIndex = maArrIterator.GetIndex();
     bool bODFF = FormulaGrammar::isODFF( meGrammar);
     if (bODFF || FormulaGrammar::isPODF( meGrammar) )
     {
         // Scan token array for missing args and re-write if present.
         MissingConventionODF aConv( bODFF);
         if (pArr->NeedsPodfRewrite( aConv))
+        {
             pArr = pArr->RewriteMissing( aConv );
+            maArrIterator = FormulaTokenArrayPlainIterator( *pArr );
+        }
     }
     else if ( FormulaGrammar::isOOXML( meGrammar ) )
     {
         // Scan token array for missing args and rewrite if present.
         MissingConventionOOXML aConv;
         if (pArr->NeedsOoxmlRewrite())
+        {
             pArr = pArr->RewriteMissing( aConv );
+            maArrIterator = FormulaTokenArrayPlainIterator( *pArr );
+        }
     }
 
     // At least one character per token, plus some are references, some are
@@ -2090,7 +2106,7 @@ void FormulaCompiler::CreateStringFromTokenArray( OUStringBuffer& rBuffer )
 
     if ( pArr->IsRecalcModeForced() )
         rBuffer.append( '=');
-    const FormulaToken* t = pArr->First();
+    const FormulaToken* t = maArrIterator.First();
     while( t )
         t = CreateStringFromToken( rBuffer, t, true );
 
@@ -2098,6 +2114,8 @@ void FormulaCompiler::CreateStringFromTokenArray( OUStringBuffer& rBuffer )
     {
         delete pArr;
         pArr = pSaveArr;
+        maArrIterator = FormulaTokenArrayPlainIterator( *pArr );
+        maArrIterator.Jump(nSaveIndex);
     }
 }
 
@@ -2120,9 +2138,9 @@ const FormulaToken* FormulaCompiler::CreateStringFromToken( OUStringBuffer& rBuf
     {
         // AND, OR infix?
         if ( bAllowArrAdvance )
-            t = pArr->Next();
+            t = maArrIterator.Next();
         else
-            t = pArr->PeekNext();
+            t = maArrIterator.PeekNext();
         bNext = false;
         bSpaces = ( !t || t->GetOpCode() != ocOpen );
     }
@@ -2134,11 +2152,11 @@ const FormulaToken* FormulaCompiler::CreateStringFromToken( OUStringBuffer& rBuf
         bool bIntersectionOp = mxSymbols->isODFF();
         if (bIntersectionOp)
         {
-            const FormulaToken* p = pArr->PeekPrevNoSpaces();
+            const FormulaToken* p = maArrIterator.PeekPrevNoSpaces();
             bIntersectionOp = (p && p->GetOpCode() == ocColRowName);
             if (bIntersectionOp)
             {
-                p = pArr->PeekNextNoSpaces();
+                p = maArrIterator.PeekNextNoSpaces();
                 bIntersectionOp = (p && p->GetOpCode() == ocColRowName);
             }
         }
@@ -2208,13 +2226,13 @@ const FormulaToken* FormulaCompiler::CreateStringFromToken( OUStringBuffer& rBuf
                 {
                     // Suppress all TableRef related tokens, the resulting
                     // range was written by CreateStringFromIndex().
-                    const FormulaToken* const p = pArr->PeekNext();
+                    const FormulaToken* const p = maArrIterator.PeekNext();
                     if (p && p->GetOpCode() == ocTableRefOpen)
                     {
                         int nLevel = 0;
                         do
                         {
-                            t = pArr->Next();
+                            t = maArrIterator.Next();
                             if (!t)
                                 break;
 
@@ -2284,7 +2302,7 @@ const FormulaToken* FormulaCompiler::CreateStringFromToken( OUStringBuffer& rBuf
     if ( bAllowArrAdvance )
     {
         if( bNext )
-            t = pArr->Next();
+            t = maArrIterator.Next();
         return t;
     }
     return pTokenP;
@@ -2457,10 +2475,10 @@ OpCode FormulaCompiler::NextToken()
         {
             // Fake an intersection op as last op for the next round, but at
             // least roughly check if it could make sense at all.
-            FormulaToken* pPrev = pArr->PeekPrevNoSpaces();
+            FormulaToken* pPrev = maArrIterator.PeekPrevNoSpaces();
             if (pPrev && isPotentialRangeType( pPrev, false, false))
             {
-                FormulaToken* pNext = pArr->PeekNextNoSpaces();
+                FormulaToken* pNext = maArrIterator.PeekNextNoSpaces();
                 if (pNext && isPotentialRangeType( pNext, false, true))
                     eLastOp = ocIntersect;
                 else
@@ -2610,10 +2628,12 @@ void FormulaCompiler::PushTokenArray( FormulaTokenArray* pa, bool bTemp )
     FormulaArrayStack* p = new FormulaArrayStack;
     p->pNext      = pStack;
     p->pArr       = pArr;
+    p->nIndex     = maArrIterator.GetIndex();
     p->mpLastToken = mpLastToken;
     p->bTemp      = bTemp;
     pStack        = p;
     pArr          = pa;
+    maArrIterator = FormulaTokenArrayPlainIterator( *pArr );
 }
 
 } // namespace formula
diff --git a/formula/source/core/api/token.cxx b/formula/source/core/api/token.cxx
index 1e966f1a40f1..78c69ea7360a 100644
--- a/formula/source/core/api/token.cxx
+++ b/formula/source/core/api/token.cxx
@@ -456,134 +456,6 @@ bool FormulaTokenArray::Fill(
     }
     return bError;
 }
-FormulaToken* FormulaTokenArray::GetNextReference()
-{
-    while( nIndex < nLen )
-    {
-        FormulaToken* t = pCode[ nIndex++ ];
-        switch( t->GetType() )
-        {
-            case svSingleRef:
-            case svDoubleRef:
-            case svExternalSingleRef:
-            case svExternalDoubleRef:
-                return t;
-            default:
-            {
-                // added to avoid warnings
-            }
-        }
-    }
-    return nullptr;
-}
-
-FormulaToken* FormulaTokenArray::GetNextColRowName()
-{
-    while( nIndex < nLen )
-    {
-        FormulaToken* t = pCode[ nIndex++ ];
-        if ( t->GetOpCode() == ocColRowName )
-            return t;
-    }
-    return nullptr;
-}
-
-FormulaToken* FormulaTokenArray::GetNextReferenceRPN()
-{
-    while( nIndex < nRPN )
-    {
-        FormulaToken* t = pRPN[ nIndex++ ];
-        switch( t->GetType() )
-        {
-            case svSingleRef:
-            case svDoubleRef:
-            case svExternalSingleRef:
-            case svExternalDoubleRef:
-                return t;
-            default:
-            {
-                // added to avoid warnings
-            }
-        }
-    }
-    return nullptr;
-}
-
-FormulaToken* FormulaTokenArray::GetNextReferenceOrName()
-{
-    if( pCode )
-    {
-        while ( nIndex < nLen )
-        {
-            FormulaToken* t = pCode[ nIndex++ ];
-            switch( t->GetType() )
-            {
-                case svSingleRef:
-                case svDoubleRef:
-                case svIndex:
-                case svExternalSingleRef:
-                case svExternalDoubleRef:
-                case svExternalName:
-                    return t;
-                default:
-                {
-                    // added to avoid warnings
-                }
-             }
-         }
-     }
-    return nullptr;
-}
-
-FormulaToken* FormulaTokenArray::GetNextName()
-{
-    if( pCode )
-    {
-        while ( nIndex < nLen )
-        {
-            FormulaToken* t = pCode[ nIndex++ ];
-            if( t->GetType() == svIndex )
-                return t;
-        }
-    } // if( pCode )
-    return nullptr;
-}
-
-FormulaToken* FormulaTokenArray::Next()
-{
-    if( pCode && nIndex < nLen )
-        return pCode[ nIndex++ ];
-    else
-        return nullptr;
-}
-
-FormulaToken* FormulaTokenArray::NextNoSpaces()
-{
-    if( pCode )
-    {
-        while( (nIndex < nLen) && (pCode[ nIndex ]->GetOpCode() == ocSpaces) )
-            ++nIndex;
-        if( nIndex < nLen )
-            return pCode[ nIndex++ ];
-    }
-    return nullptr;
-}
-
-FormulaToken* FormulaTokenArray::NextRPN()
-{
-    if( pRPN && nIndex < nRPN )
-        return pRPN[ nIndex++ ];
-    else
-        return nullptr;
-}
-
-FormulaToken* FormulaTokenArray::PrevRPN()
-{
-    if( pRPN && nIndex )
-        return pRPN[ --nIndex ];
-    else
-        return nullptr;
-}
 
 void FormulaTokenArray::DelRPN()
 {
@@ -597,7 +469,7 @@ void FormulaTokenArray::DelRPN()
         delete [] pRPN;
     }
     pRPN = nullptr;
-    nRPN = nIndex = 0;
+    nRPN = 0;
 }
 
 FormulaToken* FormulaTokenArray::FirstToken() const
@@ -614,46 +486,6 @@ FormulaToken* FormulaTokenArray::PeekPrev( sal_uInt16 & nIdx )
     return nullptr;
 }
 
-FormulaToken* FormulaTokenArray::PeekNext()
-{
-    if( pCode && nIndex < nLen )
-        return pCode[ nIndex ];
-    else
-        return nullptr;
-}
-
-FormulaToken* FormulaTokenArray::PeekNextNoSpaces()
-{
-    if( pCode && nIndex < nLen )
-    {
-        sal_uInt16 j = nIndex;
-        while ( j < nLen && pCode[j]->GetOpCode() == ocSpaces )
-            j++;
-        if ( j < nLen )
-            return pCode[ j ];
-        else
-            return nullptr;
-    }
-    else
-        return nullptr;
-}
-
-FormulaToken* FormulaTokenArray::PeekPrevNoSpaces()
-{
-    if( pCode && nIndex > 1 )
-    {
-        sal_uInt16 j = nIndex - 2;
-        while ( pCode[j]->GetOpCode() == ocSpaces && j > 0 )
-            j--;
-        if ( j > 0 || pCode[j]->GetOpCode() != ocSpaces )
-            return pCode[ j ];
-        else
-            return nullptr;
-    }
-    else
-        return nullptr;
-}
-
 FormulaToken* FormulaTokenArray::FirstRPNToken() const
 {
     if (!pRPN || nRPN == 0)
@@ -737,7 +569,6 @@ FormulaTokenArray::FormulaTokenArray() :
     pRPN(nullptr),
     nLen(0),
     nRPN(0),
-    nIndex(0),
     nError(FormulaError::NONE),
     nMode(ScRecalcMode::NORMAL),
     bHyperLink(false),
@@ -761,7 +592,6 @@ void FormulaTokenArray::Assign( const FormulaTokenArray& r )
 {
     nLen   = r.nLen;
     nRPN   = r.nRPN;
-    nIndex = r.nIndex;
     nError = r.nError;
     nMode  = r.nMode;
     bHyperLink = r.bHyperLink;
@@ -828,7 +658,7 @@ void FormulaTokenArray::Clear()
     }
     pCode = nullptr; pRPN = nullptr;
     nError = FormulaError::NONE;
-    nLen = nIndex = nRPN = 0;
+    nLen = nRPN = 0;
     bHyperLink = false;
     mbFromRangeName = false;
     mbShareable = true;
@@ -924,13 +754,6 @@ sal_uInt16 FormulaTokenArray::RemoveToken( sal_uInt16 nOffset, sal_uInt16 nCount
         }
         nLen -= nCount;
 
-        if (nIndex >= nOffset)
-        {
-            if (nIndex < nStop)
-                nIndex = nOffset + 1;
-            else
-                nIndex -= nStop - nOffset;
-        }
         return nCount;
     }
     else
diff --git a/include/formula/FormulaCompiler.hxx b/include/formula/FormulaCompiler.hxx
index f6650201bba1..a9b65671e4cd 100644
--- a/include/formula/FormulaCompiler.hxx
+++ b/include/formula/FormulaCompiler.hxx
@@ -29,6 +29,7 @@
 #include <formula/grammar.hxx>
 #include <formula/opcode.hxx>
 #include <formula/token.hxx>
+#include <formula/tokenarray.hxx>
 #include <formula/types.hxx>
 #include <formula/paramclass.hxx>
 #include <rtl/ustrbuf.hxx>
@@ -53,12 +54,12 @@ enum class FormulaError : sal_uInt16;
 
 namespace formula
 {
-    class FormulaTokenArray;
 
 struct FormulaArrayStack
 {
     FormulaArrayStack*  pNext;
     FormulaTokenArray*  pArr;
+    sal_uInt16          nIndex;
     FormulaTokenRef     mpLastToken;
     bool bTemp;
 };
@@ -331,6 +332,7 @@ protected:
     FormulaTokenRef     pCurrentFactorToken;    // current factor token (of Factor() method)
     sal_uInt16          nCurrentFactorParam;    // current factor token's parameter, 1-based
     FormulaTokenArray*  pArr;
+    FormulaTokenArrayPlainIterator maArrIterator;
     FormulaTokenRef     mpLastToken;            // last token
 
     FormulaToken**      pCode;
@@ -416,6 +418,8 @@ private:
     mutable NonConstOpCodeMapPtr  mxSymbolsEnglish;   // English symbols
     mutable NonConstOpCodeMapPtr  mxSymbolsEnglishXL; // English Excel symbols (for VBA formula parsing)
     mutable NonConstOpCodeMapPtr  mxSymbolsOOXML;     // Excel OOXML symbols
+
+    static FormulaTokenArray smDummyTokenArray;
 };
 
 } // formula
diff --git a/include/formula/tokenarray.hxx b/include/formula/tokenarray.hxx
index 72cb0e5a400a..8a00c0287126 100644
--- a/include/formula/tokenarray.hxx
+++ b/include/formula/tokenarray.hxx
@@ -22,6 +22,7 @@
 
 #include <climits>
 #include <memory>
+#include <ostream>
 #include <type_traits>
 #include <unordered_set>
 #include <unordered_map>
@@ -123,7 +124,6 @@ protected:
     FormulaToken**  pRPN;                   // RPN array
     sal_uInt16      nLen;                   // Length of token array
     sal_uInt16      nRPN;                   // Length of RPN array
-    sal_uInt16      nIndex;                 // Current step index
     FormulaError    nError;                 // Error code
     ScRecalcMode    nMode;                  // Flags to indicate when to recalc this code
     bool            bHyperLink      :1;     // If HYPERLINK() occurs in the formula.
@@ -161,9 +161,7 @@ protected:
     /** Remove a sequence of tokens from pCode array, and pRPN array if the
         tokens are referenced there.
 
-        This' nLen and nRPN are adapted, as is nIndex if it points behind
-        nOffset. If nIndex points into the to be removed range
-        (nOffset < nIndex < nOffset+nCount) it is set to nOffset+1.
+        nLen and nRPN are adapted.
 
         @param  nOffset
                 Start offset into pCode.
@@ -205,24 +203,10 @@ public:
 
     void Clear();
     void DelRPN();
-    FormulaToken* First() { nIndex = 0; return Next(); }
     FormulaToken* FirstToken() const;
-    FormulaToken* Next();
-    FormulaToken* NextNoSpaces();
-    FormulaToken* GetNextName();
-    FormulaToken* GetNextReference();
-    FormulaToken* GetNextReferenceRPN();
-    FormulaToken* GetNextReferenceOrName();
-    FormulaToken* GetNextColRowName();
     /// Peek at nIdx-1 if not out of bounds, decrements nIdx if successful. Returns NULL if not.
     FormulaToken* PeekPrev( sal_uInt16 & nIdx );
-    FormulaToken* PeekNext();
-    FormulaToken* PeekPrevNoSpaces();    /// Only after Reset/First/Next/Last/Prev!
-    FormulaToken* PeekNextNoSpaces();    /// Only after Reset/First/Next/Last/Prev!
     FormulaToken* FirstRPNToken() const;
-    FormulaToken* NextRPN();
-    FormulaToken* LastRPN() { nIndex = nRPN; return PrevRPN(); }
-    FormulaToken* PrevRPN();
 
     bool HasReferences() const;
 
@@ -246,7 +230,6 @@ public:
     FormulaToken** GetCode()  const  { return pRPN; }
     sal_uInt16     GetLen() const     { return nLen; }
     sal_uInt16     GetCodeLen() const { return nRPN; }
-    void           Reset()            { nIndex = 0; }
     FormulaError   GetCodeError() const      { return nError; }
     void      SetCodeError( FormulaError n )  { nError = n; }
     void      SetHyperLink( bool bVal ) { bHyperLink = bVal; }
@@ -407,6 +390,22 @@ private:
     const FormulaToken* GetNonEndOfPathToken( short nIdx ) const;
 };
 
+// For use in SAL_INFO, SAL_WARN etc
+
+template<typename charT, typename traits>
+inline std::basic_ostream<charT, traits> & operator <<(std::basic_ostream<charT, traits> & stream, const FormulaTokenArray& point)
+{
+    stream <<
+        static_cast<const void*>(&point) <<
+        ":{nLen=" << point.GetLen() <<
+        ",nRPN=" << point.GetCodeLen() <<
+        ",pCode=" << static_cast<void*>(point.GetArray()) <<
+        ",pRPN=" << static_cast<void*>(point.GetCode()) <<
+        "}";
+
+    return stream;
+}
+
 class FORMULA_DLLPUBLIC FormulaTokenArrayPlainIterator
 {
     friend class FormulaCompiler;
diff --git a/sc/source/core/tool/compiler.cxx b/sc/source/core/tool/compiler.cxx
index 943c89dcc960..50775af00b57 100644
--- a/sc/source/core/tool/compiler.cxx
+++ b/sc/source/core/tool/compiler.cxx
@@ -4361,6 +4361,7 @@ ScTokenArray* ScCompiler::CompileString( const OUString& rFormula )
 
     ScTokenArray aArr;
     pArr = &aArr;
+    maArrIterator = FormulaTokenArrayPlainIterator(*pArr);
     aFormula = comphelper::string::strip(rFormula, ' ');
 
     nSrcPos = 0;
@@ -4645,6 +4646,7 @@ ScTokenArray* ScCompiler::CompileString( const OUString& rFormula )
     ScTokenArray* pNew = new ScTokenArray( aArr );
     pNew->GenHash();
     pArr = pNew;
+    maArrIterator = FormulaTokenArrayPlainIterator(*pArr);
 
     if (!maExternalFiles.empty())
     {
@@ -4675,6 +4677,7 @@ ScTokenArray* ScCompiler::CompileString( const OUString& rFormula, const OUStrin
             // remember pArr, in case a subsequent CompileTokenArray() is executed.
             ScTokenArray* pNew = new ScTokenArray( aTokenArray );
             pArr = pNew;
+            maArrIterator = FormulaTokenArrayPlainIterator(*pArr);
             return pNew;
         }
     }
@@ -4707,8 +4710,8 @@ bool ScCompiler::HandleRange()
             // or if not directly between ocSep/parenthesis,
             // e.g. SUM(...;(...;...)) no, SUM(...;(...)*3) yes,
             // in short: if it isn't a self-contained expression.
-            FormulaToken* p1 = pArr->PeekPrevNoSpaces();
-            FormulaToken* p2 = pArr->PeekNextNoSpaces();
+            FormulaToken* p1 = maArrIterator.PeekPrevNoSpaces();
+            FormulaToken* p2 = maArrIterator.PeekNextNoSpaces();
             OpCode eOp1 = (p1 ? p1->GetOpCode() : ocSep);
             OpCode eOp2 = (p2 ? p2->GetOpCode() : ocSep);
             bool bBorder1 = (eOp1 == ocSep || eOp1 == ocOpen);
@@ -4719,7 +4722,6 @@ bool ScCompiler::HandleRange()
                 pNew = new ScTokenArray();
                 pNew->AddOpCode( ocClose );
                 PushTokenArray( pNew, true );
-                pNew->Reset();
             }
             pNew = pRangeData->GetCode()->Clone();
             pNew->SetFromRangeName( true );
@@ -4737,13 +4739,12 @@ bool ScCompiler::HandleRange()
                 SetRelNameReference();
                 MoveRelWrap(pRangeData->GetMaxCol(), pRangeData->GetMaxRow());
             }
-            pNew->Reset();
+            maArrIterator.Reset();
             if ( bAddPair )
             {
                 pNew = new ScTokenArray();
                 pNew->AddOpCode( ocOpen );
                 PushTokenArray( pNew, true );
-                pNew->Reset();
             }
             return GetToken();
         }
@@ -4755,7 +4756,6 @@ bool ScCompiler::HandleRange()
         pNew = new ScTokenArray;
         pNew->Add( new FormulaErrorToken( FormulaError::NoName));
         PushTokenArray( pNew, true );
-        pNew->Reset();
         return GetToken();
     }
     return true;
@@ -4791,12 +4791,12 @@ bool ScCompiler::HandleExternalReference(const FormulaToken& _aToken)
 
             ScTokenArray* pNew = xNew->Clone();
             PushTokenArray( pNew, true);
-            if (pNew->GetNextReference() != nullptr)
+            if (FormulaTokenArrayPlainIterator(*pNew).GetNextReference() != nullptr)
             {
                 SetRelNameReference();
                 MoveRelWrap(MAXCOL, MAXROW);
             }
-            pNew->Reset();
+            maArrIterator.Reset();
             return GetToken();
         }
         default:
@@ -4808,8 +4808,8 @@ bool ScCompiler::HandleExternalReference(const FormulaToken& _aToken)
 
 void ScCompiler::AdjustSheetLocalNameRelReferences( SCTAB nDelta )
 {
-    pArr->Reset();
-    for (formula::FormulaToken* t = pArr->GetNextReference(); t; t = pArr->GetNextReference())
+    maArrIterator.Reset();
+    for (formula::FormulaToken* t = maArrIterator.GetNextReference(); t; t = maArrIterator.GetNextReference())
     {
         ScSingleRefData& rRef1 = *t->GetSingleRef();
         if (rRef1.IsTabRel())
@@ -4827,9 +4827,9 @@ void ScCompiler::AdjustSheetLocalNameRelReferences( SCTAB nDelta )
 
 void ScCompiler::SetRelNameReference()
 {
-    pArr->Reset();
-    for( formula::FormulaToken* t = pArr->GetNextReference(); t;
-                  t = pArr->GetNextReference() )
+    maArrIterator.Reset();
+    for( formula::FormulaToken* t = maArrIterator.GetNextReference(); t;
+                  t = maArrIterator.GetNextReference() )
     {
         ScSingleRefData& rRef1 = *t->GetSingleRef();
         if ( rRef1.IsColRel() || rRef1.IsRowRel() || rRef1.IsTabRel() )
@@ -4847,9 +4847,9 @@ void ScCompiler::SetRelNameReference()
 // don't call for other token arrays!
 void ScCompiler::MoveRelWrap( SCCOL nMaxCol, SCROW nMaxRow )
 {
-    pArr->Reset();
-    for( formula::FormulaToken* t = pArr->GetNextReference(); t;
-                  t = pArr->GetNextReference() )
+    maArrIterator.Reset();
+    for( formula::FormulaToken* t = maArrIterator.GetNextReference(); t;
+                  t = maArrIterator.GetNextReference() )
     {
         if ( t->GetType() == svSingleRef || t->GetType() == svExternalSingleRef )
             ScRefUpdate::MoveRelWrap( pDoc, aPos, nMaxCol, nMaxRow, SingleDoubleRefModifier( *t->GetSingleRef() ).Ref() );
@@ -4863,9 +4863,9 @@ void ScCompiler::MoveRelWrap( SCCOL nMaxCol, SCROW nMaxRow )
 void ScCompiler::MoveRelWrap( ScTokenArray& rArr, ScDocument* pDoc, const ScAddress& rPos,
                               SCCOL nMaxCol, SCROW nMaxRow )
 {
-    rArr.Reset();
-    for( formula::FormulaToken* t = rArr.GetNextReference(); t;
-                  t = rArr.GetNextReference() )
+    formula::FormulaTokenArrayPlainIterator aIter(rArr);
+    for( formula::FormulaToken* t = aIter.GetNextReference(); t;
+                  t = aIter.GetNextReference() )
     {
         if ( t->GetType() == svSingleRef || t->GetType() == svExternalSingleRef )
             ScRefUpdate::MoveRelWrap( pDoc, rPos, nMaxCol, nMaxRow, SingleDoubleRefModifier( *t->GetSingleRef() ).Ref() );
@@ -5031,7 +5031,7 @@ void ScCompiler::CreateStringFromSingleRef( OUStringBuffer& rBuffer, const Formu
                               GetSetupTabNames(), aRef, true, (pArr && pArr->IsFromRangeName()));
         }
     }
-    else if (pArr && (p = pArr->PeekPrevNoSpaces()) && p->GetOpCode() == ocTableRefOpen)
+    else if (pArr && (p = maArrIterator.PeekPrevNoSpaces()) && p->GetOpCode() == ocTableRefOpen)
     {
         OUString aStr;
         ScAddress aAbs = rRef.toAbs(aPos);
@@ -5351,8 +5351,8 @@ bool ScCompiler::HandleColRowName()
             bFound = true;
         else
         {
-            FormulaToken* p1 = pArr->PeekPrevNoSpaces();
-            FormulaToken* p2 = pArr->PeekNextNoSpaces();
+            FormulaToken* p1 = maArrIterator.PeekPrevNoSpaces();
+            FormulaToken* p2 = maArrIterator.PeekNextNoSpaces();
             // begin/end of a formula => single
             OpCode eOp1 = p1 ? p1->GetOpCode() : ocAdd;
             OpCode eOp2 = p2 ? p2->GetOpCode() : ocAdd;
@@ -5422,7 +5422,6 @@ bool ScCompiler::HandleColRowName()
                 }
             }
             PushTokenArray( pNew, true );
-            pNew->Reset();
             return GetToken();
         }
     }
@@ -5447,7 +5446,6 @@ bool ScCompiler::HandleDbData()
         ScTokenArray* pNew = new ScTokenArray();
         pNew->AddDoubleReference( aRefData );
         PushTokenArray( pNew, true );
-        pNew->Reset();
         return GetToken();
     }
     return true;
@@ -5455,7 +5453,7 @@ bool ScCompiler::HandleDbData()
 
 bool ScCompiler::GetTokenIfOpCode( OpCode eOp )
 {
-    const formula::FormulaToken* p = pArr->PeekNextNoSpaces();
+    const formula::FormulaToken* p = maArrIterator.PeekNextNoSpaces();
     if (p && p->GetOpCode() == eOp)
         return GetToken();
     return false;
@@ -5590,7 +5588,7 @@ bool ScCompiler::HandleTableRef()
             } eState = sOpen;
             do
             {
-                const formula::FormulaToken* p = pArr->PeekNextNoSpaces();
+                const formula::FormulaToken* p = maArrIterator.PeekNextNoSpaces();
                 if (!p)
                     eState = sStop;
                 else
@@ -5762,7 +5760,6 @@ bool ScCompiler::HandleTableRef()
                 SetError( FormulaError::Pair);
         }
         PushTokenArray( pNew, true );
-        pNew->Reset();
         return GetToken();
     }
     return true;
diff --git a/sc/source/core/tool/interpr4.cxx b/sc/source/core/tool/interpr4.cxx
index 37c9db979aec..6b5247b0889b 100644
--- a/sc/source/core/tool/interpr4.cxx
+++ b/sc/source/core/tool/interpr4.cxx
@@ -1296,7 +1296,8 @@ void ScInterpreter::GetExternalDoubleRef(
         return;
     }
 
-    formula::FormulaToken* pToken = pArray->First();
+    formula::FormulaTokenArrayPlainIterator aIter(*pArray);
+    formula::FormulaToken* pToken = aIter.First();
     if (pToken->GetType() == svError)
     {
         SetError( pToken->GetError());
@@ -1308,7 +1309,7 @@ void ScInterpreter::GetExternalDoubleRef(
         return;
     }
 
-    if (pArray->Next())
+    if (aIter.Next())
     {
         // Can't handle more than one matrix per parameter.
         SetError( FormulaError::IllegalArgument);


More information about the Libreoffice-commits mailing list