diff options
author | Eike Rathke [er] <eike.rathke@oracle.com> | 2011-03-04 14:43:09 +0100 |
---|---|---|
committer | Eike Rathke [er] <eike.rathke@oracle.com> | 2011-03-04 14:43:09 +0100 |
commit | 4f24ef15969c9c062f6ed60d0f2848608cee079e (patch) | |
tree | 9ffb4295d911a6aaffd6292744c78931255458af /formula/source | |
parent | cd0d6a5a6775f197fdb7e78b54c8133074a7a236 (diff) |
calc66: #i103331# make OFFSET with external references work again
+ Introduced FormulaSubroutineToken to hold a FormulaTokenArray.
* INDIRECT in case of external reference returns FormulaSubroutineToken
instead of directly pushing the token array to code and signalling its
presence to ScInterpreter::Interpret().
* ScInterpreter::ScExternalRef() checks if an external reference is used with
OFFSET and if so does not resolve it but pushes it so it can be handled
within OFFSET.
+ OFFSET recognizes external reference and creates an external reference of
the new area and returns that as subroutine to be resolved by
ScExternalRef().
* Interpret() pushes the subroutine to code and rememberes the token and array
for late destruction.
Diffstat (limited to 'formula/source')
-rw-r--r-- | formula/source/core/api/token.cxx | 67 |
1 files changed, 52 insertions, 15 deletions
diff --git a/formula/source/core/api/token.cxx b/formula/source/core/api/token.cxx index 3942712da6a4..b644d1cd8fb3 100644 --- a/formula/source/core/api/token.cxx +++ b/formula/source/core/api/token.cxx @@ -1265,15 +1265,7 @@ const FormulaToken* FormulaTokenIterator::First() const FormulaToken* FormulaTokenIterator::Next() { - const FormulaToken* t = NULL; - ++pCur->nPC; - if( pCur->nPC < pCur->pArr->nRPN && pCur->nPC < pCur->nStop ) - { - t = pCur->pArr->pRPN[ pCur->nPC ]; - // such an OpCode ends an IF() or CHOOSE() path - if( t->GetOpCode() == ocSep || t->GetOpCode() == ocClose ) - t = NULL; - } + const FormulaToken* t = GetNonEndOfPathToken( ++pCur->nPC ); if( !t && pCur->pNext ) { Pop(); @@ -1282,6 +1274,25 @@ const FormulaToken* FormulaTokenIterator::Next() return t; } +const FormulaToken* FormulaTokenIterator::PeekNextOperator() +{ + const FormulaToken* t = NULL; + short nIdx = pCur->nPC; + while (!t && ((t = GetNonEndOfPathToken( ++nIdx)) != NULL)) + { + if (t->GetOpCode() == ocPush) + t = NULL; // ignore operands + } + if (!t && pCur->pNext) + { + ImpTokenIterator* pHere = pCur; + pCur = pCur->pNext; + t = PeekNextOperator(); + pCur = pHere; + } + return t; +} + //! The nPC counts after a Push() are -1 void FormulaTokenIterator::Jump( short nStart, short nNext, short nStop ) @@ -1295,17 +1306,22 @@ void FormulaTokenIterator::Jump( short nStart, short nNext, short nStop ) } } -bool FormulaTokenIterator::IsEndOfPath() const +const FormulaToken* FormulaTokenIterator::GetNonEndOfPathToken( short nIdx ) const { - sal_uInt16 nTest = pCur->nPC + 1; - if( nTest < pCur->pArr->nRPN && nTest < pCur->nStop ) + if (nIdx < pCur->pArr->nRPN && nIdx < pCur->nStop) { - const FormulaToken* t = pCur->pArr->pRPN[ nTest ]; + const FormulaToken* t = pCur->pArr->pRPN[ nIdx ]; // such an OpCode ends an IF() or CHOOSE() path - return t->GetOpCode() == ocSep || t->GetOpCode() == ocClose; + return (t->GetOpCode() == ocSep || t->GetOpCode() == ocClose) ? NULL : t; } - return true; + return NULL; } + +bool FormulaTokenIterator::IsEndOfPath() const +{ + return GetNonEndOfPathToken( pCur->nPC + 1) != NULL; +} + // ----------------------------------------------------------------------------- // ========================================================================== // real implementations of virtual functions @@ -1367,6 +1383,27 @@ sal_Bool FormulaMissingToken::operator==( const FormulaToken& r ) const } +FormulaSubroutineToken::FormulaSubroutineToken( const FormulaSubroutineToken& r ) : + FormulaToken( r ), + mpArray( r.mpArray->Clone()) +{ +} +FormulaSubroutineToken::~FormulaSubroutineToken() +{ + delete mpArray; +} +const FormulaTokenArray* FormulaSubroutineToken::GetTokenArray() const +{ + return mpArray; +} +sal_Bool FormulaSubroutineToken::operator==( const FormulaToken& r ) const +{ + // Arrays don't equal.. + return FormulaToken::operator==( r ) && + (mpArray == static_cast<const FormulaSubroutineToken&>(r).mpArray); +} + + sal_Bool FormulaUnknownToken::operator==( const FormulaToken& r ) const { return FormulaToken::operator==( r ); |