summaryrefslogtreecommitdiff
path: root/formula/source
diff options
context:
space:
mode:
authorEike Rathke [er] <eike.rathke@oracle.com>2011-03-04 14:43:09 +0100
committerEike Rathke [er] <eike.rathke@oracle.com>2011-03-04 14:43:09 +0100
commit4f24ef15969c9c062f6ed60d0f2848608cee079e (patch)
tree9ffb4295d911a6aaffd6292744c78931255458af /formula/source
parentcd0d6a5a6775f197fdb7e78b54c8133074a7a236 (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.cxx67
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 );