summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKohei Yoshida <kyoshida@novell.com>2011-05-09 22:54:59 -0400
committerMichael Meeks <michael.meeks@novell.com>2011-05-10 10:42:05 +0100
commita4c34eeb3f849574c2395a57e2ff2a11c78e687f (patch)
tree274e6f95d916f22736e81c9ed85a0c2a68b5f085
parentc831d4236f705d40b6bdd2280a15ccb56037c567 (diff)
fdo#36933: Fixed array comparison with external references.
-rw-r--r--sc/source/core/inc/interpre.hxx1
-rw-r--r--sc/source/core/tool/interpr1.cxx32
-rw-r--r--sc/source/core/tool/interpr4.cxx71
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 =