diff options
author | Kohei Yoshida <kyoshida@novell.com> | 2011-05-09 22:54:59 -0400 |
---|---|---|
committer | Michael Meeks <michael.meeks@novell.com> | 2011-05-10 10:42:05 +0100 |
commit | a4c34eeb3f849574c2395a57e2ff2a11c78e687f (patch) | |
tree | 274e6f95d916f22736e81c9ed85a0c2a68b5f085 | |
parent | c831d4236f705d40b6bdd2280a15ccb56037c567 (diff) |
fdo#36933: Fixed array comparison with external references.
-rw-r--r-- | sc/source/core/inc/interpre.hxx | 1 | ||||
-rw-r--r-- | sc/source/core/tool/interpr1.cxx | 32 | ||||
-rw-r--r-- | sc/source/core/tool/interpr4.cxx | 71 |
3 files changed, 88 insertions, 16 deletions
diff --git a/sc/source/core/inc/interpre.hxx b/sc/source/core/inc/interpre.hxx index ce59c16ffa20..7caee7518f8b 100644 --- a/sc/source/core/inc/interpre.hxx +++ b/sc/source/core/inc/interpre.hxx @@ -316,6 +316,7 @@ void PopExternalSingleRef(ScExternalRefCache::TokenRef& rToken, ScExternalRefCac void PopExternalDoubleRef(sal_uInt16& rFileId, String& rTabName, ScComplexRefData& rRef); void PopExternalDoubleRef(ScExternalRefCache::TokenArrayRef& rArray); void PopExternalDoubleRef(ScMatrixRef& rMat); +void GetExternalDoubleRef(sal_uInt16 nFileId, const String& rTabName, const ScComplexRefData& aData, ScExternalRefCache::TokenArrayRef& rArray); sal_Bool PopDoubleRefOrSingleRef( ScAddress& rAdr ); void PopDoubleRefPushMatrix(); // If MatrixFormula: convert formula::svDoubleRef to svMatrix, create JumpMatrix. diff --git a/sc/source/core/tool/interpr1.cxx b/sc/source/core/tool/interpr1.cxx index 41b5e27b2807..c4a8cdd346cd 100644 --- a/sc/source/core/tool/interpr1.cxx +++ b/sc/source/core/tool/interpr1.cxx @@ -810,6 +810,38 @@ double ScInterpreter::Compare() } } break; + case svExternalSingleRef: + { + ScMatrixRef pMat = GetMatrix(); + if (!pMat) + { + SetError( errIllegalParameter); + break; + } + + SCSIZE nC, nR; + pMat->GetDimensions(nC, nR); + if (!nC || !nR) + { + SetError( errIllegalParameter); + break; + } + if (pMat->IsEmpty(0, 0)) + aComp.bEmpty[i] = true; + else if (pMat->IsString(0, 0)) + { + *aComp.pVal[i] = pMat->GetString(0, 0); + aComp.bVal[i] = false; + } + else + { + aComp.nVal[i] = pMat->GetDouble(0, 0); + aComp.bVal[i] = true; + } + } + break; + case svExternalDoubleRef: + // TODO: Find out how to handle this... default: SetError( errIllegalParameter); break; diff --git a/sc/source/core/tool/interpr4.cxx b/sc/source/core/tool/interpr4.cxx index 551a1c2e94ab..bfe5b6b632ac 100644 --- a/sc/source/core/tool/interpr4.cxx +++ b/sc/source/core/tool/interpr4.cxx @@ -1519,6 +1519,28 @@ void ScInterpreter::PopExternalDoubleRef(ScExternalRefCache::TokenArrayRef& rArr if (nGlobalError) return; + GetExternalDoubleRef(nFileId, aTabName, aData, rArray); + if (nGlobalError) + return; +} + +void ScInterpreter::PopExternalDoubleRef(ScMatrixRef& rMat) +{ + ScExternalRefCache::TokenArrayRef pArray; + PopExternalDoubleRef(pArray); + if (nGlobalError) + return; + + // For now, we only support single range data for external + // references, which means the array should only contain a + // single matrix token. + ScToken* p = static_cast<ScToken*>(pArray->First()); + rMat = p->GetMatrix(); +} + +void ScInterpreter::GetExternalDoubleRef( + sal_uInt16 nFileId, const String& rTabName, const ScComplexRefData& rData, ScExternalRefCache::TokenArrayRef& rArray) +{ ScExternalRefManager* pRefMgr = pDok->GetExternalRefManager(); const String* pFile = pRefMgr->getExternalFileName(nFileId); if (!pFile) @@ -1526,18 +1548,19 @@ void ScInterpreter::PopExternalDoubleRef(ScExternalRefCache::TokenArrayRef& rArr SetError(errNoName); return; } - if (aData.Ref1.IsTabRel() || aData.Ref2.IsTabRel()) + if (rData.Ref1.IsTabRel() || rData.Ref2.IsTabRel()) { OSL_FAIL("ScCompiler::GetToken: external double reference must have an absolute table reference!"); SetError(errNoRef); return; } + ScComplexRefData aData(rData); aData.CalcAbsIfRel(aPos); ScRange aRange(aData.Ref1.nCol, aData.Ref1.nRow, aData.Ref1.nTab, aData.Ref2.nCol, aData.Ref2.nRow, aData.Ref2.nTab); ScExternalRefCache::TokenArrayRef pArray = pRefMgr->getDoubleRefTokens( - nFileId, aTabName, aRange, &aPos); + nFileId, rTabName, aRange, &aPos); if (!pArray) { @@ -1562,20 +1585,6 @@ void ScInterpreter::PopExternalDoubleRef(ScExternalRefCache::TokenArrayRef& rArr rArray = pArray; } -void ScInterpreter::PopExternalDoubleRef(ScMatrixRef& rMat) -{ - ScExternalRefCache::TokenArrayRef pArray; - PopExternalDoubleRef(pArray); - if (nGlobalError) - return; - - // For now, we only support single range data for external - // references, which means the array should only contain a - // single matrix token. - ScToken* p = static_cast<ScToken*>(pArray->First()); - rMat = p->GetMatrix(); -} - sal_Bool ScInterpreter::PopDoubleRefOrSingleRef( ScAddress& rAdr ) { RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::PopDoubleRefOrSingleRef" ); @@ -1643,6 +1652,7 @@ bool ScInterpreter::ConvertMatrixParameters() case svDouble: case svString: case svSingleRef: + case svExternalSingleRef: case svMissing: case svError: case svEmptyCell: @@ -1700,6 +1710,35 @@ bool ScInterpreter::ConvertMatrixParameters() } } break; + case svExternalDoubleRef: + { + ScParameterClassification::Type eType = + ScParameterClassification::GetParameterType( pCur, nParams - i); + if (eType == ScParameterClassification::Array) + { + sal_uInt16 nFileId = p->GetIndex(); + const String& rTabName = p->GetString(); + const ScComplexRefData& rRef = static_cast<ScToken*>(p)->GetDoubleRef(); + ScExternalRefCache::TokenArrayRef pArray; + GetExternalDoubleRef(nFileId, rTabName, rRef, pArray); + if (nGlobalError) + break; + + ScToken* pTemp = static_cast<ScToken*>(pArray->First()); + if (!pTemp) + break; + + ScMatrixRef pMat = pTemp->GetMatrix(); + if (pMat) + { + ScToken* pNew = new ScMatrixToken( pMat); + pNew->IncRef(); + pStack[ sp - i ] = pNew; + p->DecRef(); // p may be dead now! + } + } + } + break; case svRefList: { ScParameterClassification::Type eType = |