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@libreoffice.org>
Reviewed-by: Tor Lillqvist <tml@collabora.com>
This commit is contained in:
Tor Lillqvist
2017-06-16 00:18:57 +03:00
parent 468fc3847c
commit 5c81adc51a
6 changed files with 91 additions and 247 deletions

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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;

View File

@@ -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;

View File

@@ -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);