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:
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
|
@@ -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);
|
||||
|
Reference in New Issue
Block a user