diff options
author | Kohei Yoshida <kohei.yoshida@gmail.com> | 2013-09-06 01:18:26 -0400 |
---|---|---|
committer | Kohei Yoshida <kohei.yoshida@gmail.com> | 2013-09-06 01:38:32 -0400 |
commit | 8e6b22b12322175e9aff643af45f275cb8c9cc5e (patch) | |
tree | 463016b5e8e8a001d398e3f2455213c4e9b90065 | |
parent | 7969bb659ef78ec6e1aaaf922757419795a823de (diff) |
Wrong place to apply implicit intersection. Do it at the very last.
Change-Id: I4b1e9d136d45f169ad1c1efee2275bab7dfe0f49
-rw-r--r-- | sc/inc/token.hxx | 7 | ||||
-rw-r--r-- | sc/inc/types.hxx | 2 | ||||
-rw-r--r-- | sc/source/core/data/types.cxx | 7 | ||||
-rw-r--r-- | sc/source/core/inc/interpre.hxx | 1 | ||||
-rw-r--r-- | sc/source/core/tool/interpr1.cxx | 121 | ||||
-rw-r--r-- | sc/source/core/tool/interpr4.cxx | 61 | ||||
-rw-r--r-- | sc/source/core/tool/token.cxx | 7 |
7 files changed, 85 insertions, 121 deletions
diff --git a/sc/inc/token.hxx b/sc/inc/token.hxx index 32cdf5ad1869..a852dd87b1fd 100644 --- a/sc/inc/token.hxx +++ b/sc/inc/token.hxx @@ -36,6 +36,12 @@ // Matrix token constants. #define MATRIX_TOKEN_HAS_RANGE 1 +namespace sc { + +struct RangeMatrix; + +} + class ScJumpMatrix; typedef ::std::vector< ScComplexRefData > ScRefList; @@ -190,6 +196,7 @@ class ScMatrixRangeToken : public ScToken ScComplexRefData maRef; public: ScMatrixRangeToken( const ScMatrixRef& p, const ScComplexRefData& rRef ); + ScMatrixRangeToken( const sc::RangeMatrix& rMat ); ScMatrixRangeToken( const ScMatrixRangeToken& r ); virtual sal_uInt8 GetByte() const; diff --git a/sc/inc/types.hxx b/sc/inc/types.hxx index f03ccc0149ec..045d6b128580 100644 --- a/sc/inc/types.hxx +++ b/sc/inc/types.hxx @@ -68,8 +68,10 @@ struct RangeMatrix ScMatrixRef mpMat; sal_Int32 mnCol1; sal_Int32 mnRow1; + sal_Int32 mnTab1; sal_Int32 mnCol2; sal_Int32 mnRow2; + sal_Int32 mnTab2; RangeMatrix(); diff --git a/sc/source/core/data/types.cxx b/sc/source/core/data/types.cxx index 566d088ffe29..b45a0b1467ae 100644 --- a/sc/source/core/data/types.cxx +++ b/sc/source/core/data/types.cxx @@ -12,11 +12,14 @@ namespace sc { -RangeMatrix::RangeMatrix() : mpMat(NULL), mnCol1(-1), mnRow1(-1), mnCol2(-1), mnRow2(-1) {} +RangeMatrix::RangeMatrix() : + mpMat(NULL), mnCol1(-1), mnRow1(-1), mnTab1(-1), mnCol2(-1), mnRow2(-1), mnTab2(-1) {} bool RangeMatrix::isRangeValid() const { - return mnCol1 >= 0 && mnRow1 >= 0 && mnCol2 >= 0 && mnRow2 >= 0 && mnCol1 <= mnCol2 && mnRow1 <= mnRow2; + return mnCol1 >= 0 && mnRow1 >= 0 && mnTab1 >=0 && + mnCol2 >= 0 && mnRow2 >= 0 && mnTab2 >= 0 && + mnCol1 <= mnCol2 && mnRow1 <= mnRow2 && mnTab1 <= mnTab2; } } diff --git a/sc/source/core/inc/interpre.hxx b/sc/source/core/inc/interpre.hxx index bb9f9194aafb..b615b34ba97a 100644 --- a/sc/source/core/inc/interpre.hxx +++ b/sc/source/core/inc/interpre.hxx @@ -319,6 +319,7 @@ void PushExternalSingleRef(sal_uInt16 nFileId, const String& rTabName, void PushExternalDoubleRef(sal_uInt16 nFileId, const String& rTabName, SCCOL nCol1, SCROW nRow1, SCTAB nTab1, SCCOL nCol2, SCROW nRow2, SCTAB nTab2); +void PushMatrix( const sc::RangeMatrix& rMat ); void PushMatrix(const ScMatrixRef& pMat); void PushError( sal_uInt16 nError ); /// Raw stack type without default replacements. diff --git a/sc/source/core/tool/interpr1.cxx b/sc/source/core/tool/interpr1.cxx index fb7b7dd2e99e..33eb3dae684d 100644 --- a/sc/source/core/tool/interpr1.cxx +++ b/sc/source/core/tool/interpr1.cxx @@ -1195,8 +1195,10 @@ sc::RangeMatrix ScInterpreter::CompareMat( ScCompareOptions* pOptions ) aRes.mnCol1 = aMat[i].mnCol1; aRes.mnRow1 = aMat[i].mnRow1; + aRes.mnTab1 = aMat[i].mnTab1; aRes.mnCol2 = aMat[i].mnCol2; aRes.mnRow2 = aMat[i].mnRow2; + aRes.mnTab2 = aMat[i].mnTab2; for (SCSIZE j = 0; j < nC; ++j) { @@ -1270,29 +1272,6 @@ ScMatrixRef ScInterpreter::QueryMat( const ScMatrixRef& pMat, ScCompareOptions& return pResultMatrix; } -namespace { - -double applyImplicitIntersection(const sc::RangeMatrix& rMat, const ScAddress& rPos) -{ - if (rMat.mnRow1 <= rPos.Row() && rPos.Row() <= rMat.mnRow2 && rMat.mnCol1 == rMat.mnCol2) - { - SCROW nOffset = rPos.Row() - rMat.mnRow1; - return rMat.mpMat->GetDouble(0, nOffset); - } - - if (rMat.mnCol1 <= rPos.Col() && rPos.Col() <= rMat.mnCol2 && rMat.mnRow1 == rMat.mnRow2) - { - SCROW nOffset = rPos.Col() - rMat.mnCol1; - return rMat.mpMat->GetDouble(nOffset, 0); - } - - double fVal; - rtl::math::setNan(&fVal); - return fVal; -} - -} - void ScInterpreter::ScEqual() { if ( GetStackType(1) == svMatrix || GetStackType(2) == svMatrix ) @@ -1304,22 +1283,8 @@ void ScInterpreter::ScEqual() return; } - if (aMat.isRangeValid()) - { - // This matrix represents a range reference. Apply implicit intersection. - double fVal = applyImplicitIntersection(aMat, aPos); - if (rtl::math::isNan(fVal)) - { - PushError(errCellNoValue); - return; - } - - PushInt(fVal == 0.0); - return; - } - aMat.mpMat->CompareEqual(); - PushMatrix(aMat.mpMat); + PushMatrix(aMat); } else PushInt( Compare() == 0 ); @@ -1337,22 +1302,8 @@ void ScInterpreter::ScNotEqual() return; } - if (aMat.isRangeValid()) - { - // This matrix represents a range reference. Apply implicit intersection. - double fVal = applyImplicitIntersection(aMat, aPos); - if (rtl::math::isNan(fVal)) - { - PushError(errCellNoValue); - return; - } - - PushInt(fVal != 0.0); - return; - } - aMat.mpMat->CompareNotEqual(); - PushMatrix(aMat.mpMat); + PushMatrix(aMat); } else PushInt( Compare() != 0 ); @@ -1370,22 +1321,8 @@ void ScInterpreter::ScLess() return; } - if (aMat.isRangeValid()) - { - // This matrix represents a range reference. Apply implicit intersection. - double fVal = applyImplicitIntersection(aMat, aPos); - if (rtl::math::isNan(fVal)) - { - PushError(errCellNoValue); - return; - } - - PushInt(fVal < 0.0); - return; - } - aMat.mpMat->CompareLess(); - PushMatrix(aMat.mpMat); + PushMatrix(aMat); } else PushInt( Compare() < 0 ); @@ -1403,22 +1340,8 @@ void ScInterpreter::ScGreater() return; } - if (aMat.isRangeValid()) - { - // This matrix represents a range reference. Apply implicit intersection. - double fVal = applyImplicitIntersection(aMat, aPos); - if (rtl::math::isNan(fVal)) - { - PushError(errCellNoValue); - return; - } - - PushInt(fVal > 0.0); - return; - } - aMat.mpMat->CompareGreater(); - PushMatrix(aMat.mpMat); + PushMatrix(aMat); } else PushInt( Compare() > 0 ); @@ -1436,22 +1359,8 @@ void ScInterpreter::ScLessEqual() return; } - if (aMat.isRangeValid()) - { - // This matrix represents a range reference. Apply implicit intersection. - double fVal = applyImplicitIntersection(aMat, aPos); - if (rtl::math::isNan(fVal)) - { - PushError(errCellNoValue); - return; - } - - PushInt(fVal <= 0.0); - return; - } - aMat.mpMat->CompareLessEqual(); - PushMatrix(aMat.mpMat); + PushMatrix(aMat); } else PushInt( Compare() <= 0 ); @@ -1469,22 +1378,8 @@ void ScInterpreter::ScGreaterEqual() return; } - if (aMat.isRangeValid()) - { - // This matrix represents a range reference. Apply implicit intersection. - double fVal = applyImplicitIntersection(aMat, aPos); - if (rtl::math::isNan(fVal)) - { - PushError(errCellNoValue); - return; - } - - PushInt(fVal >= 0.0); - return; - } - aMat.mpMat->CompareGreaterEqual(); - PushMatrix(aMat.mpMat); + PushMatrix(aMat); } else PushInt( Compare() >= 0 ); diff --git a/sc/source/core/tool/interpr4.cxx b/sc/source/core/tool/interpr4.cxx index 7beb5804575a..7288613fc160 100644 --- a/sc/source/core/tool/interpr4.cxx +++ b/sc/source/core/tool/interpr4.cxx @@ -1817,8 +1817,10 @@ sc::RangeMatrix ScInterpreter::PopRangeMatrix() { aRet.mnCol1 = rRef.Ref1.Col(); aRet.mnRow1 = rRef.Ref1.Row(); + aRet.mnTab1 = rRef.Ref1.Tab(); aRet.mnCol2 = rRef.Ref2.Col(); aRet.mnRow2 = rRef.Ref2.Row(); + aRet.mnTab2 = rRef.Ref2.Tab(); } } } @@ -1953,6 +1955,19 @@ void ScInterpreter::PushExternalDoubleRef( } } +void ScInterpreter::PushMatrix( const sc::RangeMatrix& rMat ) +{ + if (!rMat.isRangeValid()) + { + // Just push the matrix part only. + PushMatrix(rMat.mpMat); + return; + } + + rMat.mpMat->SetErrorInterpreter(NULL); + nGlobalError = 0; + PushTempTokenWithoutError(new ScMatrixRangeToken(rMat)); +} void ScInterpreter::PushMatrix(const ScMatrixRef& pMat) { @@ -3735,6 +3750,28 @@ void ScInterpreter::GlobalExit() DELETEZ(pGlobalStack); } +namespace { + +double applyImplicitIntersection(const sc::RangeMatrix& rMat, const ScAddress& rPos) +{ + if (rMat.mnRow1 <= rPos.Row() && rPos.Row() <= rMat.mnRow2 && rMat.mnCol1 == rMat.mnCol2) + { + SCROW nOffset = rPos.Row() - rMat.mnRow1; + return rMat.mpMat->GetDouble(0, nOffset); + } + + if (rMat.mnCol1 <= rPos.Col() && rPos.Col() <= rMat.mnCol2 && rMat.mnRow1 == rMat.mnRow2) + { + SCROW nOffset = rPos.Col() - rMat.mnCol1; + return rMat.mpMat->GetDouble(nOffset, 0); + } + + double fVal; + rtl::math::setNan(&fVal); + return fVal; +} + +} StackVar ScInterpreter::Interpret() { @@ -4315,17 +4352,29 @@ StackVar ScInterpreter::Interpret() } break; case svExternalDoubleRef: - case svMatrix : { ScMatrixRef xMat; - if (pCur->GetType() == svMatrix) - xMat = PopMatrix(); - else - PopExternalDoubleRef(xMat); - + PopExternalDoubleRef(xMat); QueryMatrixType(xMat, nRetTypeExpr, nRetIndexExpr); } break; + case svMatrix : + { + sc::RangeMatrix aMat = PopRangeMatrix(); + if (aMat.isRangeValid()) + { + // This matrix represents a range reference. Apply implicit intersection. + double fVal = applyImplicitIntersection(aMat, aPos); + if (rtl::math::isNan(fVal)) + PushError(errCellNoValue); + else + PushInt(fVal); + } + else + // This is a normal matrix. + QueryMatrixType(aMat.mpMat, nRetTypeExpr, nRetIndexExpr); + } + break; case svExternalSingleRef: { ScExternalRefCache::TokenRef pToken; diff --git a/sc/source/core/tool/token.cxx b/sc/source/core/tool/token.cxx index 9f5a7e6bf752..08455f597d01 100644 --- a/sc/source/core/tool/token.cxx +++ b/sc/source/core/tool/token.cxx @@ -38,6 +38,7 @@ #include "externalrefmgr.hxx" #include "document.hxx" #include "refupdatecontext.hxx" +#include "types.hxx" using ::std::vector; @@ -807,6 +808,12 @@ bool ScMatrixToken::operator==( const FormulaToken& r ) const ScMatrixRangeToken::ScMatrixRangeToken( const ScMatrixRef& p, const ScComplexRefData& rRef ) : ScToken(formula::svMatrix), mpMatrix(p), maRef(rRef) {} +ScMatrixRangeToken::ScMatrixRangeToken( const sc::RangeMatrix& rMat ) : + ScToken(formula::svMatrix), mpMatrix(rMat.mpMat) +{ + maRef.InitRange(rMat.mnCol1, rMat.mnRow1, rMat.mnTab1, rMat.mnCol2, rMat.mnRow2, rMat.mnTab2); +} + ScMatrixRangeToken::ScMatrixRangeToken( const ScMatrixRangeToken& r ) : ScToken(r), mpMatrix(r.mpMatrix), maRef(r.maRef) {} |