Hi there, I'd like to have the attached patch committed for 3.4. It fixes
https://bugs.freedesktop.org/show_bug.cgi?id=36933 Per rule, I need to have one sign-off in order to commit this to the 3.4 branch. Review appreciated. Kohei -- Kohei Yoshida, LibreOffice hacker, Calc <kyosh...@novell.com>
>From b49cc01b9556a434c3c690df3bb6ddad5e0a7802 Mon Sep 17 00:00:00 2001 From: Kohei Yoshida <kyosh...@novell.com> Date: Mon, 9 May 2011 22:54:59 -0400 Subject: [PATCH] fdo#36933: Fixed array comparison with external references. --- sc/source/core/inc/interpre.hxx | 1 + sc/source/core/tool/interpr1.cxx | 32 +++++++++++++++++ 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 ce59c16..7caee75 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 8beb6f1..1999bff 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 551a1c2..bfe5b6b 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 = -- 1.7.3.4
_______________________________________________ LibreOffice mailing list LibreOffice@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/libreoffice