summaryrefslogtreecommitdiff
path: root/sc
diff options
context:
space:
mode:
authorEike Rathke <erack@redhat.com>2016-08-25 11:02:50 +0200
committerEike Rathke <erack@redhat.com>2016-08-25 10:20:26 +0000
commitdb8c3afe8c5a5756537d16cf0399e3b46876cc8b (patch)
treee43e25742e2c461e565adba3d8a69ecccd6c86ab /sc
parent9fda8f5ad61c11d72718a50a175b23cb43bfa9ab (diff)
let ScInterpreter::pStack contain const formula::FormulaToken*
For two reasons: * introduce a new PushTokenRef() to push an already existing token, which can be used in several places that currently unnecessarily copy-construct a new token to be pushed * prevent unwanted side effects in case a token on the stack would be fiddled with, which was possible but just by convention wasn't done Change-Id: I715d81bcba8bdb415af45e889e9f9db1e0ac4888 Reviewed-on: https://gerrit.libreoffice.org/28377 Reviewed-by: Eike Rathke <erack@redhat.com> Tested-by: Eike Rathke <erack@redhat.com> Tested-by: Jenkins <ci@libreoffice.org>
Diffstat (limited to 'sc')
-rw-r--r--sc/inc/column.hxx2
-rw-r--r--sc/inc/document.hxx2
-rw-r--r--sc/inc/scmatrix.hxx10
-rw-r--r--sc/inc/table.hxx2
-rw-r--r--sc/source/core/data/column2.cxx4
-rw-r--r--sc/source/core/data/documen8.cxx2
-rw-r--r--sc/source/core/data/table1.cxx2
-rw-r--r--sc/source/core/inc/interpre.hxx21
-rw-r--r--sc/source/core/inc/jumpmatrix.hxx2
-rw-r--r--sc/source/core/tool/formulagroup.cxx2
-rw-r--r--sc/source/core/tool/interpr1.cxx42
-rw-r--r--sc/source/core/tool/interpr2.cxx59
-rw-r--r--sc/source/core/tool/interpr4.cxx79
-rw-r--r--sc/source/core/tool/interpr5.cxx16
-rw-r--r--sc/source/core/tool/interpr6.cxx2
-rw-r--r--sc/source/core/tool/interpr8.cxx8
-rw-r--r--sc/source/core/tool/scmatrix.cxx9
17 files changed, 153 insertions, 111 deletions
diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx
index a73f7c4eed13..bb7a2b91b603 100644
--- a/sc/inc/column.hxx
+++ b/sc/inc/column.hxx
@@ -574,7 +574,7 @@ public:
void FillMatrix( ScMatrix& rMat, size_t nMatCol, SCROW nRow1, SCROW nRow2, svl::SharedStringPool* pPool = nullptr ) const;
formula::VectorRefArray FetchVectorRefArray( SCROW nRow1, SCROW nRow2 );
void SetFormulaResults( SCROW nRow, const double* pResults, size_t nLen );
- void SetFormulaResults( SCROW nRow, const formula::FormulaTokenRef* pResults, size_t nLen );
+ void SetFormulaResults( SCROW nRow, const formula::FormulaConstTokenRef* pResults, size_t nLen );
void SetNumberFormat( SCROW nRow, sal_uInt32 nNumberFormat );
diff --git a/sc/inc/document.hxx b/sc/inc/document.hxx
index b2f97534cc77..749eab291595 100644
--- a/sc/inc/document.hxx
+++ b/sc/inc/document.hxx
@@ -1983,7 +1983,7 @@ public:
*/
void SC_DLLPUBLIC SetFormulaResults( const ScAddress& rTopPos, const double* pResults, size_t nLen );
- void SC_DLLPUBLIC SetFormulaResults( const ScAddress& rTopPos, const formula::FormulaTokenRef* pResults, size_t nLen );
+ void SC_DLLPUBLIC SetFormulaResults( const ScAddress& rTopPos, const formula::FormulaConstTokenRef* pResults, size_t nLen );
/**
* Transfer a series of contiguous cell values from specified position to
diff --git a/sc/inc/scmatrix.hxx b/sc/inc/scmatrix.hxx
index 62cddee992ab..b565335844ff 100644
--- a/sc/inc/scmatrix.hxx
+++ b/sc/inc/scmatrix.hxx
@@ -113,7 +113,7 @@ struct ScMatrixValue
class SC_DLLPUBLIC ScMatrix
{
mutable size_t nRefCnt; // reference count
- bool mbCloneIfConst; // Whether the matrix is cloned with a CloneIfConst() call.
+ mutable bool mbCloneIfConst; // Whether the matrix is cloned with a CloneIfConst() call.
ScMatrix( const ScMatrix& ) = delete;
ScMatrix& operator=( const ScMatrix&) = delete;
@@ -219,9 +219,13 @@ public:
return _this_ matrix, to be assigned to a ScMatrixRef. */
ScMatrix* CloneIfConst();
- /** Set the matrix to (im)mutable for CloneIfConst(), only the interpreter
+ /** Set the matrix to mutable for CloneIfConst(), only the interpreter
should do this and know the consequences. */
- void SetImmutable( bool bVal );
+ void SetMutable();
+
+ /** Set the matrix to immutable for CloneIfConst(), only the interpreter
+ should do this and know the consequences. */
+ void SetImmutable() const;
/**
* Resize the matrix to specified new dimension.
diff --git a/sc/inc/table.hxx b/sc/inc/table.hxx
index bd6344657dfa..708e53537750 100644
--- a/sc/inc/table.hxx
+++ b/sc/inc/table.hxx
@@ -918,7 +918,7 @@ public:
void InterpretDirtyCells( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 );
void SetFormulaResults( SCCOL nCol, SCROW nRow, const double* pResults, size_t nLen );
- void SetFormulaResults( SCCOL nCol, SCROW nRow, const formula::FormulaTokenRef* pResults, size_t nLen );
+ void SetFormulaResults( SCCOL nCol, SCROW nRow, const formula::FormulaConstTokenRef* pResults, size_t nLen );
/**
* Either start all formula cells as listeners unconditionally, or start
diff --git a/sc/source/core/data/column2.cxx b/sc/source/core/data/column2.cxx
index cae1ff55e051..9faf724db50c 100644
--- a/sc/source/core/data/column2.cxx
+++ b/sc/source/core/data/column2.cxx
@@ -2752,7 +2752,7 @@ void ScColumn::SetFormulaResults( SCROW nRow, const double* pResults, size_t nLe
}
}
-void ScColumn::SetFormulaResults( SCROW nRow, const formula::FormulaTokenRef* pResults, size_t nLen )
+void ScColumn::SetFormulaResults( SCROW nRow, const formula::FormulaConstTokenRef* pResults, size_t nLen )
{
sc::CellStoreType::position_type aPos = maCells.position(nRow);
sc::CellStoreType::iterator it = aPos.first;
@@ -2768,7 +2768,7 @@ void ScColumn::SetFormulaResults( SCROW nRow, const formula::FormulaTokenRef* pR
sc::formula_block::iterator itCell = sc::formula_block::begin(*it->data);
std::advance(itCell, aPos.second);
- const formula::FormulaTokenRef* pResEnd = pResults + nLen;
+ const formula::FormulaConstTokenRef* pResEnd = pResults + nLen;
for (; pResults != pResEnd; ++pResults, ++itCell)
{
ScFormulaCell& rCell = **itCell;
diff --git a/sc/source/core/data/documen8.cxx b/sc/source/core/data/documen8.cxx
index a84c2d09a01e..ca158fdda762 100644
--- a/sc/source/core/data/documen8.cxx
+++ b/sc/source/core/data/documen8.cxx
@@ -419,7 +419,7 @@ void ScDocument::SetFormulaResults( const ScAddress& rTopPos, const double* pRes
}
void ScDocument::SetFormulaResults(
- const ScAddress& rTopPos, const formula::FormulaTokenRef* pResults, size_t nLen )
+ const ScAddress& rTopPos, const formula::FormulaConstTokenRef* pResults, size_t nLen )
{
ScTable* pTab = FetchTable(rTopPos.Tab());
if (!pTab)
diff --git a/sc/source/core/data/table1.cxx b/sc/source/core/data/table1.cxx
index feac2964b94e..f770c7e02d61 100644
--- a/sc/source/core/data/table1.cxx
+++ b/sc/source/core/data/table1.cxx
@@ -2257,7 +2257,7 @@ void ScTable::SetFormulaResults( SCCOL nCol, SCROW nRow, const double* pResults,
}
void ScTable::SetFormulaResults(
- SCCOL nCol, SCROW nRow, const formula::FormulaTokenRef* pResults, size_t nLen )
+ SCCOL nCol, SCROW nRow, const formula::FormulaConstTokenRef* pResults, size_t nLen )
{
if (!ValidCol(nCol))
return;
diff --git a/sc/source/core/inc/interpre.hxx b/sc/source/core/inc/interpre.hxx
index f1b8e0d4e11c..c6987f850b85 100644
--- a/sc/source/core/inc/interpre.hxx
+++ b/sc/source/core/inc/interpre.hxx
@@ -76,7 +76,7 @@ class ScTokenStack
{
public:
DECL_FIXEDMEMPOOL_NEWDEL( ScTokenStack )
- formula::FormulaToken* pPointer[ MAXSTACK ];
+ const formula::FormulaToken* pPointer[ MAXSTACK ];
};
enum ScIterFunc {
@@ -121,7 +121,7 @@ struct FormulaTokenRef_less
bool operator () ( const formula::FormulaConstTokenRef& r1, const formula::FormulaConstTokenRef& r2 ) const
{ return r1.get() < r2.get(); }
};
-typedef ::std::map< const formula::FormulaConstTokenRef, formula::FormulaTokenRef, FormulaTokenRef_less> ScTokenMatrixMap;
+typedef ::std::map< const formula::FormulaConstTokenRef, formula::FormulaConstTokenRef, FormulaTokenRef_less> ScTokenMatrixMap;
class ScInterpreter
{
@@ -187,7 +187,7 @@ private:
ScDocument* pDok;
sfx2::LinkManager* mpLinkManager;
svl::SharedStringPool& mrStrPool;
- formula::FormulaTokenRef xResult;
+ formula::FormulaConstTokenRef xResult;
ScJumpMatrix* pJumpMatrix; // currently active array condition, if any
ScTokenMatrixMap* pTokenMatrixMap; // map FormulaToken* to formula::FormulaTokenRef if in array condition
ScFormulaCell* pMyFormulaCell; // the cell of this formula expression
@@ -196,7 +196,7 @@ private:
const formula::FormulaToken*
pCur; // current token
ScTokenStack* pStackObj; // contains the stacks
- formula::FormulaToken** pStack; // the current stack
+ const formula::FormulaToken ** pStack; // the current stack
sal_uInt16 nGlobalError; // global (local to this formula expression) error
sal_uInt16 sp; // stack pointer
sal_uInt16 maxsp; // the maximal used stack pointer
@@ -262,7 +262,7 @@ void Push( formula::FormulaToken& r );
/** Does not substitute with formula::FormulaErrorToken in case nGlobalError is set.
Used to push RPN tokens or from within Push() or tokens that are already
explicit formula::FormulaErrorToken. Increments RefCount. */
-void PushWithoutError( formula::FormulaToken& r );
+void PushWithoutError( const formula::FormulaToken& r );
/** Clones the token to be pushed or substitutes with formula::FormulaErrorToken if
nGlobalError is set and the token passed is not formula::FormulaErrorToken. */
@@ -276,13 +276,18 @@ void PushTempToken( const formula::FormulaToken& );
deleted in case of an errStackOverflow or if substituted with formula::FormulaErrorToken! */
void PushTempToken( formula::FormulaToken* );
+/** Pushes the token or substitutes with formula::FormulaErrorToken in case
+ nGlobalError is set and the token passed is not formula::FormulaErrorToken.
+ Increments RefCount of the original token if not substituted. */
+void PushTokenRef( const formula::FormulaConstTokenRef& );
+
/** Does not substitute with formula::FormulaErrorToken in case nGlobalError is set.
Used to push tokens from within PushTempToken() or tokens that are already
explicit formula::FormulaErrorToken. Increments RefCount.
ATTENTION! The token had to be allocated with `new' and must not be used
after this call if no RefCount was set because possibly it gets immediately
decremented again and thus deleted in case of an errStackOverflow! */
-void PushTempTokenWithoutError( formula::FormulaToken* );
+void PushTempTokenWithoutError( const formula::FormulaToken* );
/** If nGlobalError is set push formula::FormulaErrorToken.
If nGlobalError is not set do nothing.
@@ -316,7 +321,7 @@ inline bool IfErrorPushError()
void PushCellResultToken( bool bDisplayEmptyAsString, const ScAddress & rAddress,
short * pRetTypeExpr, sal_uLong * pRetIndexExpr, bool bFinalResult = false );
-formula::FormulaTokenRef PopToken();
+formula::FormulaConstTokenRef PopToken();
void Pop();
void PopError();
double PopDouble();
@@ -976,7 +981,7 @@ public:
formula::StackVar GetResultType() const { return xResult->GetType(); }
svl::SharedString GetStringResult() const;
double GetNumResult() const { return xResult->GetDouble(); }
- const formula::FormulaTokenRef& GetResultToken() const { return xResult; }
+ const formula::FormulaConstTokenRef& GetResultToken() const { return xResult; }
short GetRetFormatType() const { return nRetFmtType; }
sal_uLong GetRetFormatIndex() const { return nRetFmtIndex; }
};
diff --git a/sc/source/core/inc/jumpmatrix.hxx b/sc/source/core/inc/jumpmatrix.hxx
index ed98e53f5ad6..4ef4f87b282a 100644
--- a/sc/source/core/inc/jumpmatrix.hxx
+++ b/sc/source/core/inc/jumpmatrix.hxx
@@ -27,7 +27,7 @@
#include "types.hxx"
#include "address.hxx"
-typedef ::std::vector< formula::FormulaToken*> ScTokenVec;
+typedef ::std::vector< const formula::FormulaToken*> ScTokenVec;
struct ScJumpMatrixEntry
{
diff --git a/sc/source/core/tool/formulagroup.cxx b/sc/source/core/tool/formulagroup.cxx
index 15ce590bfc6c..e165e0c317fe 100644
--- a/sc/source/core/tool/formulagroup.cxx
+++ b/sc/source/core/tool/formulagroup.cxx
@@ -158,7 +158,7 @@ bool FormulaGroupInterpreterSoftware::interpret(ScDocument& rDoc, const ScAddres
// the group.
ScAddress aTmpPos = rTopPos;
- std::vector<formula::FormulaTokenRef> aResults;
+ std::vector<formula::FormulaConstTokenRef> aResults;
aResults.reserve(xGroup->mnLength);
CachedTokensType aCachedTokens;
diff --git a/sc/source/core/tool/interpr1.cxx b/sc/source/core/tool/interpr1.cxx
index 52db34123cb1..85f443fa56c4 100644
--- a/sc/source/core/tool/interpr1.cxx
+++ b/sc/source/core/tool/interpr1.cxx
@@ -97,7 +97,7 @@ void ScInterpreter::ScIfJump()
PushIllegalParameter();
else
{
- FormulaTokenRef xNew;
+ FormulaConstTokenRef xNew;
ScTokenMatrixMap::const_iterator aMapIter;
// DoubleError handled by JumpMatrix
pMat->SetErrorInterpreter( nullptr);
@@ -108,8 +108,7 @@ void ScInterpreter::ScIfJump()
PushIllegalArgument();
return;
}
- else if (pTokenMatrixMap && ((aMapIter = pTokenMatrixMap->find(
- pCur)) != pTokenMatrixMap->end()))
+ else if (pTokenMatrixMap && ((aMapIter = pTokenMatrixMap->find( pCur)) != pTokenMatrixMap->end()))
xNew = (*aMapIter).second;
else
{
@@ -178,7 +177,7 @@ void ScInterpreter::ScIfJump()
PushIllegalArgument();
return;
}
- PushTempToken( xNew.get());
+ PushTokenRef( xNew);
// set endpoint of path for main code line
aCode.Jump( pJump[ nJumpCount ], pJump[ nJumpCount ] );
}
@@ -250,7 +249,7 @@ void ScInterpreter::ScIfError( bool bNAonly )
return;
}
- FormulaTokenRef xToken( pStack[ sp - 1 ] );
+ FormulaConstTokenRef xToken( pStack[ sp - 1 ] );
bool bError = false;
sal_uInt16 nOldGlobalError = nGlobalError;
nGlobalError = 0;
@@ -333,7 +332,7 @@ void ScInterpreter::ScIfError( bool bNAonly )
if (!bError)
break; // switch, we're done and have the result
- FormulaTokenRef xNew;
+ FormulaConstTokenRef xNew;
ScTokenMatrixMap::const_iterator aMapIter;
if (pTokenMatrixMap && ((aMapIter = pTokenMatrixMap->find( pCur)) != pTokenMatrixMap->end()))
{
@@ -380,7 +379,7 @@ void ScInterpreter::ScIfError( bool bNAonly )
GetTokenMatrixMap().insert( ScTokenMatrixMap::value_type( pCur, xNew ));
}
nGlobalError = nOldGlobalError;
- PushTempToken( xNew.get() );
+ PushTokenRef( xNew );
// set endpoint of path for main code line
aCode.Jump( pJump[ nJumpCount ], pJump[ nJumpCount ] );
return;
@@ -398,7 +397,7 @@ void ScInterpreter::ScIfError( bool bNAonly )
{
// no error, push 1st argument and continue
nGlobalError = nOldGlobalError;
- PushTempToken( xToken.get());
+ PushTokenRef( xToken);
aCode.Jump( pJump[ nJumpCount ], pJump[ nJumpCount ] );
}
}
@@ -420,7 +419,7 @@ void ScInterpreter::ScChooseJump()
PushIllegalParameter();
else
{
- FormulaTokenRef xNew;
+ FormulaConstTokenRef xNew;
ScTokenMatrixMap::const_iterator aMapIter;
// DoubleError handled by JumpMatrix
pMat->SetErrorInterpreter( nullptr);
@@ -479,7 +478,7 @@ void ScInterpreter::ScChooseJump()
}
if (xNew.get())
{
- PushTempToken( xNew.get());
+ PushTokenRef( xNew);
// set endpoint of path for main code line
aCode.Jump( pJump[ nJumpCount ], pJump[ nJumpCount ] );
bHaveJump = true;
@@ -768,8 +767,7 @@ bool ScInterpreter::JumpMatrix( short nStackLevel )
const ScTokenVec* pParams = pJumpMatrix->GetJumpParameters();
if ( pParams )
{
- for ( ScTokenVec::const_iterator i = pParams->begin();
- i != pParams->end(); ++i )
+ for ( ScTokenVec::const_iterator i = pParams->begin(); i != pParams->end(); ++i )
{
// This is not the current state of the interpreter, so
// push without error, and elements' errors are coded into
@@ -1814,7 +1812,7 @@ void ScInterpreter::ScIsEmpty()
{
case svEmptyCell:
{
- FormulaTokenRef p = PopToken();
+ FormulaConstTokenRef p = PopToken();
if (!static_cast<const ScEmptyCellToken*>(p.get())->IsInherited())
nRes = 1;
}
@@ -2478,7 +2476,7 @@ void ScInterpreter::ScIsRef()
break;
case svRefList :
{
- FormulaTokenRef x = PopToken();
+ FormulaConstTokenRef x = PopToken();
if ( !nGlobalError )
bRes = !x.get()->GetRefList()->empty();
}
@@ -7720,7 +7718,7 @@ void ScInterpreter::ScIndex()
bool bRowArray = false;
if (GetStackType() == svRefList)
{
- FormulaTokenRef xRef = PopToken();
+ FormulaConstTokenRef xRef = PopToken();
if (nGlobalError || !xRef)
{
PushIllegalParameter();
@@ -7805,21 +7803,21 @@ void ScInterpreter::ScAreas()
{
case svSingleRef:
{
- FormulaTokenRef xT = PopToken();
+ FormulaConstTokenRef xT = PopToken();
ValidateRef( *xT.get()->GetSingleRef());
++nCount;
}
break;
case svDoubleRef:
{
- FormulaTokenRef xT = PopToken();
+ FormulaConstTokenRef xT = PopToken();
ValidateRef( *xT.get()->GetDoubleRef());
++nCount;
}
break;
case svRefList:
{
- FormulaTokenRef xT = PopToken();
+ FormulaConstTokenRef xT = PopToken();
ValidateRef( *(xT.get()->GetRefList()));
nCount += xT.get()->GetRefList()->size();
}
@@ -8316,10 +8314,10 @@ void ScInterpreter::ScText()
break;
default:
{
- FormulaTokenRef xTok( PopToken());
+ FormulaConstTokenRef xTok( PopToken());
if (!nGlobalError)
{
- PushTempToken( xTok.get());
+ PushTokenRef( xTok);
// Temporarily override the ConvertStringToValue()
// error for GetCellValue() / GetCellValueOrZero()
sal_uInt16 nSErr = mnStringNoValueError;
@@ -8330,7 +8328,7 @@ void ScInterpreter::ScText()
{
// Not numeric.
nGlobalError = 0;
- PushTempToken( xTok.get());
+ PushTokenRef( xTok);
aStr = GetString();
bString = true;
}
@@ -8471,7 +8469,7 @@ sal_uInt16 ScInterpreter::GetErrorType()
{
case svRefList :
{
- FormulaTokenRef x = PopToken();
+ FormulaConstTokenRef x = PopToken();
if (nGlobalError)
nErr = nGlobalError;
else
diff --git a/sc/source/core/tool/interpr2.cxx b/sc/source/core/tool/interpr2.cxx
index 658119848879..b71d1babee59 100644
--- a/sc/source/core/tool/interpr2.cxx
+++ b/sc/source/core/tool/interpr2.cxx
@@ -1268,7 +1268,7 @@ void ScInterpreter::ScNPV()
{
double nVal = 0.0;
//We turn the stack upside down!
- FormulaToken* pTemp[ 31 ];
+ const FormulaToken* pTemp[ 31 ];
for( short i = 0; i < nParamCount; i++ )
pTemp[ i ] = pStack[ sp - i - 1 ];
memcpy( &pStack[ sp - nParamCount ], pTemp, nParamCount * sizeof( FormulaToken* ) );
@@ -2357,8 +2357,8 @@ void ScInterpreter::ScMod()
void ScInterpreter::ScIntersect()
{
- formula::FormulaTokenRef p2nd = PopToken();
- formula::FormulaTokenRef p1st = PopToken();
+ formula::FormulaConstTokenRef p2nd = PopToken();
+ formula::FormulaConstTokenRef p1st = PopToken();
if (nGlobalError || !p2nd || !p1st)
{
@@ -2375,14 +2375,14 @@ void ScInterpreter::ScIntersect()
return;
}
- formula::FormulaToken* x1 = p1st.get();
- formula::FormulaToken* x2 = p2nd.get();
+ const formula::FormulaToken* x1 = p1st.get();
+ const formula::FormulaToken* x2 = p2nd.get();
if (sv1 == svRefList || sv2 == svRefList)
{
// Now this is a bit nasty but it simplifies things, and having
// intersections with lists isn't too common, if at all..
// Convert a reference to list.
- formula::FormulaToken* xt[2] = { x1, x2 };
+ const formula::FormulaToken* xt[2] = { x1, x2 };
StackVar sv[2] = { sv1, sv2 };
for (size_t i=0; i<2; ++i)
{
@@ -2390,14 +2390,16 @@ void ScInterpreter::ScIntersect()
{
ScComplexRefData aRef;
aRef.Ref1 = aRef.Ref2 = *xt[i]->GetSingleRef();
- xt[i] = new ScRefListToken;
- xt[i]->GetRefList()->push_back( aRef);
+ formula::FormulaToken* p = new ScRefListToken;
+ p->GetRefList()->push_back( aRef);
+ xt[i] = p;
}
else if (sv[i] == svDoubleRef)
{
ScComplexRefData aRef = *xt[i]->GetDoubleRef();
- xt[i] = new ScRefListToken;
- xt[i]->GetRefList()->push_back( aRef);
+ formula::FormulaToken* p = new ScRefListToken;
+ p->GetRefList()->push_back( aRef);
+ xt[i] = p;
}
}
x1 = xt[0];
@@ -2445,11 +2447,11 @@ void ScInterpreter::ScIntersect()
PushTempToken( new ScDoubleRefToken( rRef));
}
else
- PushTempToken( xRes.get());
+ PushTokenRef( xRes);
}
else
{
- formula::FormulaToken* pt[2] = { x1, x2 };
+ const formula::FormulaToken* pt[2] = { x1, x2 };
StackVar sv[2] = { sv1, sv2 };
SCCOL nC1[2], nC2[2];
SCROW nR1[2], nR2[2];
@@ -2503,25 +2505,28 @@ void ScInterpreter::ScIntersect()
void ScInterpreter::ScRangeFunc()
{
- formula::FormulaTokenRef x2 = PopToken();
- formula::FormulaTokenRef x1 = PopToken();
+ formula::FormulaConstTokenRef x2 = PopToken();
+ formula::FormulaConstTokenRef x1 = PopToken();
if (nGlobalError || !x2 || !x1)
{
PushIllegalArgument();
return;
}
- FormulaTokenRef xRes = extendRangeReference( *x1, *x2, aPos, false);
+ // We explicitly tell extendRangeReference() to not reuse the token,
+ // casting const away spares two clones.
+ FormulaTokenRef xRes = extendRangeReference(
+ const_cast<FormulaToken&>(*x1), const_cast<FormulaToken&>(*x2), aPos, false);
if (!xRes)
PushIllegalArgument();
else
- PushTempToken( xRes.get());
+ PushTokenRef( xRes);
}
void ScInterpreter::ScUnionFunc()
{
- formula::FormulaTokenRef p2nd = PopToken();
- formula::FormulaTokenRef p1st = PopToken();
+ formula::FormulaConstTokenRef p2nd = PopToken();
+ formula::FormulaConstTokenRef p1st = PopToken();
if (nGlobalError || !p2nd || !p1st)
{
@@ -2538,25 +2543,25 @@ void ScInterpreter::ScUnionFunc()
return;
}
- formula::FormulaToken* x1 = p1st.get();
- formula::FormulaToken* x2 = p2nd.get();
+ const formula::FormulaToken* x1 = p1st.get();
+ const formula::FormulaToken* x2 = p2nd.get();
ScTokenRef xRes;
// Append to an existing RefList if there is one.
if (sv1 == svRefList)
{
- xRes = x1;
+ xRes = x1->Clone();
sv1 = svUnknown; // mark as handled
}
else if (sv2 == svRefList)
{
- xRes = x2;
+ xRes = x2->Clone();
sv2 = svUnknown; // mark as handled
}
else
xRes = new ScRefListToken;
ScRefList* pRes = xRes->GetRefList();
- formula::FormulaToken* pt[2] = { x1, x2 };
+ const formula::FormulaToken* pt[2] = { x1, x2 };
StackVar sv[2] = { sv1, sv2 };
for (size_t i=0; i<2; ++i)
{
@@ -2590,16 +2595,16 @@ void ScInterpreter::ScUnionFunc()
}
}
ValidateRef( *pRes); // set #REF! if needed
- PushTempToken( xRes.get());
+ PushTokenRef( xRes);
}
void ScInterpreter::ScCurrent()
{
- FormulaTokenRef xTok( PopToken());
+ FormulaConstTokenRef xTok( PopToken());
if (xTok)
{
- PushTempToken( xTok.get());
- PushTempToken( xTok.get());
+ PushTokenRef( xTok);
+ PushTokenRef( xTok);
}
else
PushError( errUnknownStackVariable);
diff --git a/sc/source/core/tool/interpr4.cxx b/sc/source/core/tool/interpr4.cxx
index 9b200d5cf494..5ff5cfaf909c 100644
--- a/sc/source/core/tool/interpr4.cxx
+++ b/sc/source/core/tool/interpr4.cxx
@@ -622,7 +622,7 @@ bool ScInterpreter::CreateCellArr(SCCOL nCol1, SCROW nRow1, SCTAB nTab1,
// Also releases a TempToken if appropriate.
-void ScInterpreter::PushWithoutError( FormulaToken& r )
+void ScInterpreter::PushWithoutError( const FormulaToken& r )
{
if ( sp >= MAXSTACK )
SetError( errStackOverflow );
@@ -689,7 +689,7 @@ void ScInterpreter::PushTempToken( FormulaToken* p )
}
}
-void ScInterpreter::PushTempTokenWithoutError( FormulaToken* p )
+void ScInterpreter::PushTempTokenWithoutError( const FormulaToken* p )
{
p->IncRef();
if ( sp >= MAXSTACK )
@@ -715,6 +715,26 @@ void ScInterpreter::PushTempToken( const FormulaToken& r )
PushTempTokenWithoutError( r.Clone());
}
+void ScInterpreter::PushTokenRef( const formula::FormulaConstTokenRef& x )
+{
+ if ( sp >= MAXSTACK )
+ {
+ SetError( errStackOverflow );
+ }
+ else
+ {
+ if (nGlobalError)
+ {
+ if (x->GetType() == svError && x->GetError() == nGlobalError)
+ PushTempTokenWithoutError( x.get());
+ else
+ PushTempTokenWithoutError( new FormulaErrorToken( nGlobalError));
+ }
+ else
+ PushTempTokenWithoutError( x.get());
+ }
+}
+
void ScInterpreter::PushCellResultToken( bool bDisplayEmptyAsString,
const ScAddress & rAddress, short * pRetTypeExpr, sal_uLong * pRetIndexExpr, bool bFinalResult )
{
@@ -794,12 +814,12 @@ void ScInterpreter::PopError()
SetError(errUnknownStackVariable);
}
-FormulaTokenRef ScInterpreter::PopToken()
+FormulaConstTokenRef ScInterpreter::PopToken()
{
if (sp)
{
sp--;
- FormulaToken* p = pStack[ sp ];
+ const FormulaToken* p = pStack[ sp ];
if (p->GetType() == svError)
nGlobalError = p->GetError();
return p;
@@ -816,7 +836,7 @@ double ScInterpreter::PopDouble()
if( sp )
{
--sp;
- FormulaToken* p = pStack[ sp ];
+ const FormulaToken* p = pStack[ sp ];
switch (p->GetType())
{
case svError:
@@ -848,7 +868,7 @@ svl::SharedString ScInterpreter::PopString()
if( sp )
{
--sp;
- FormulaToken* p = pStack[ sp ];
+ const FormulaToken* p = pStack[ sp ];
switch (p->GetType())
{
case svError:
@@ -933,7 +953,7 @@ void ScInterpreter::PopSingleRef(SCCOL& rCol, SCROW &rRow, SCTAB& rTab)
if( sp )
{
--sp;
- FormulaToken* p = pStack[ sp ];
+ const FormulaToken* p = pStack[ sp ];
switch (p->GetType())
{
case svError:
@@ -957,7 +977,7 @@ void ScInterpreter::PopSingleRef( ScAddress& rAdr )
if( sp )
{
--sp;
- FormulaToken* p = pStack[ sp ];
+ const FormulaToken* p = pStack[ sp ];
switch (p->GetType())
{
case svError:
@@ -1044,7 +1064,7 @@ void ScInterpreter::PopDoubleRef(SCCOL& rCol1, SCROW &rRow1, SCTAB& rTab1,
if( sp )
{
--sp;
- FormulaToken* p = pStack[ sp ];
+ const FormulaToken* p = pStack[ sp ];
switch (p->GetType())
{
case svError:
@@ -1083,7 +1103,7 @@ void ScInterpreter::PopDoubleRef( ScRange & rRange, short & rParam, size_t & rRe
{
if (sp)
{
- formula::FormulaToken* pToken = pStack[ sp-1 ];
+ const formula::FormulaToken* pToken = pStack[ sp-1 ];
switch (pToken->GetType())
{
case svError:
@@ -1128,7 +1148,7 @@ void ScInterpreter::PopDoubleRef( ScRange& rRange, bool bDontCheckForTableOp )
if( sp )
{
--sp;
- FormulaToken* p = pStack[ sp ];
+ const FormulaToken* p = pStack[ sp ];
switch (p->GetType())
{
case svError:
@@ -1154,7 +1174,7 @@ void ScInterpreter::PopExternalSingleRef(sal_uInt16& rFileId, OUString& rTabName
}
--sp;
- FormulaToken* p = pStack[sp];
+ const FormulaToken* p = pStack[sp];
StackVar eType = p->GetType();
if (eType == svError)
@@ -1233,7 +1253,7 @@ void ScInterpreter::PopExternalDoubleRef(sal_uInt16& rFileId, OUString& rTabName
}
--sp;
- FormulaToken* p = pStack[sp];
+ const FormulaToken* p = pStack[sp];
StackVar eType = p->GetType();
if (eType == svError)
@@ -1405,7 +1425,7 @@ bool ScInterpreter::ConvertMatrixParameters()
SCSIZE nJumpCols = 0, nJumpRows = 0;
for ( sal_uInt16 i=1; i <= nParams && i <= sp; ++i )
{
- FormulaToken* p = pStack[ sp - i ];
+ const FormulaToken* p = pStack[ sp - i ];
if ( p->GetOpCode() != ocPush && p->GetOpCode() != ocMissing)
{
OSL_FAIL( "ConvertMatrixParameters: not a push");
@@ -1428,7 +1448,7 @@ bool ScInterpreter::ConvertMatrixParameters()
if ( ScParameterClassification::GetParameterType( pCur, nParams - i)
== ScParameterClassification::Value )
{ // only if single value expected
- ScMatrixRef pMat = p->GetMatrix();
+ ScConstMatrixRef pMat = p->GetMatrix();
if ( !pMat )
SetError( errUnknownVariable);
else
@@ -1532,10 +1552,9 @@ bool ScInterpreter::ConvertMatrixParameters()
short nStart = nPC - 1; // restart on current code (-1)
short nNext = nPC; // next instruction after subroutine
short nStop = nPC + 1; // stop subroutine before reaching that
- FormulaTokenRef xNew;
+ FormulaConstTokenRef xNew;
ScTokenMatrixMap::const_iterator aMapIter;
- if (pTokenMatrixMap && ((aMapIter = pTokenMatrixMap->find( pCur)) !=
- pTokenMatrixMap->end()))
+ if (pTokenMatrixMap && ((aMapIter = pTokenMatrixMap->find( pCur)) != pTokenMatrixMap->end()))
xNew = (*aMapIter).second;
else
{
@@ -1545,15 +1564,14 @@ bool ScInterpreter::ConvertMatrixParameters()
ScTokenVec* pParams = new ScTokenVec( nParams);
for ( sal_uInt16 i=1; i <= nParams && sp > 0; ++i )
{
- FormulaToken* p = pStack[ --sp ];
+ const FormulaToken* p = pStack[ --sp ];
p->IncRef();
// store in reverse order such that a push may simply iterate
(*pParams)[ nParams - i ] = p;
}
pJumpMat->SetJumpParameters( pParams);
xNew = new ScJumpMatrixToken( pJumpMat );
- GetTokenMatrixMap().insert( ScTokenMatrixMap::value_type( pCur,
- xNew));
+ GetTokenMatrixMap().insert( ScTokenMatrixMap::value_type( pCur, xNew));
}
PushTempTokenWithoutError( xNew.get());
// set continuation point of path for main code line
@@ -1568,7 +1586,7 @@ ScMatrixRef ScInterpreter::PopMatrix()
if( sp )
{
--sp;
- FormulaToken* p = pStack[ sp ];
+ const FormulaToken* p = pStack[ sp ];
switch (p->GetType())
{
case svError:
@@ -1576,7 +1594,10 @@ ScMatrixRef ScInterpreter::PopMatrix()
break;
case svMatrix:
{
- ScMatrix* pMat = p->GetMatrix();
+ // ScMatrix itself maintains an im/mutable flag that should
+ // be obeyed where necessary.. so we can return ScMatrixRef
+ // here instead of ScConstMatrixRef.
+ ScMatrix* pMat = const_cast<FormulaToken*>(p)->GetMatrix();
if ( pMat )
pMat->SetErrorInterpreter( this);
else
@@ -1602,8 +1623,8 @@ sc::RangeMatrix ScInterpreter::PopRangeMatrix()
case svMatrix:
{
--sp;
- FormulaToken* p = pStack[sp];
- aRet.mpMat = p->GetMatrix();
+ const FormulaToken* p = pStack[sp];
+ aRet.mpMat = const_cast<FormulaToken*>(p)->GetMatrix();
if (aRet.mpMat)
{
aRet.mpMat->SetErrorInterpreter(this);
@@ -1906,7 +1927,7 @@ StackVar ScInterpreter::GetStackType( sal_uInt8 nParam )
void ScInterpreter::ReverseStack( sal_uInt8 nParamCount )
{
//reverse order of parameter stack
- FormulaToken* p;
+ const FormulaToken* p;
assert( sp >= nParamCount && " less stack elements than parameters");
short nStackParams = std::min<short>( sp, nParamCount);
for ( short i = 0; i < short( nStackParams / 2 ); i++ )
@@ -3879,7 +3900,7 @@ StackVar ScInterpreter::Interpret()
if ( nStackBase > sp )
nStackBase = sp; // underflow?!?
sp = nStackBase;
- PushTempToken( (*aTokenMatrixMapIter).second.get());
+ PushTokenRef( (*aTokenMatrixMapIter).second);
}
else
{
@@ -4572,7 +4593,7 @@ StackVar ScInterpreter::Interpret()
xResult = new FormulaErrorToken( errUnknownStackVariable);
// release tokens in expression stack
- FormulaToken** p = pStack;
+ const FormulaToken** p = pStack;
while( maxsp-- )
(*p++)->DecRef();
@@ -4580,7 +4601,7 @@ StackVar ScInterpreter::Interpret()
if (eType == svMatrix)
// Results are immutable in case they would be reused as input for new
// interpreters.
- xResult.get()->GetMatrix()->SetImmutable( true);
+ xResult.get()->GetMatrix()->SetImmutable();
return eType;
}
diff --git a/sc/source/core/tool/interpr5.cxx b/sc/source/core/tool/interpr5.cxx
index 2c357dbb99cf..5321791e4eb6 100644
--- a/sc/source/core/tool/interpr5.cxx
+++ b/sc/source/core/tool/interpr5.cxx
@@ -326,7 +326,7 @@ ScMatrixRef ScInterpreter::GetNewMat(SCSIZE nC, SCSIZE nR, bool bEmpty)
pMat->SetErrorInterpreter( this);
// A temporary matrix is mutable and ScMatrix::CloneIfConst() returns the
// very matrix.
- pMat->SetImmutable( false);
+ pMat->SetMutable();
SCSIZE nCols, nRows;
pMat->GetDimensions( nCols, nRows);
if ( nCols != nC || nRows != nR )
@@ -358,10 +358,15 @@ ScMatrixRef ScInterpreter::CreateMatrixFromDoubleRef( const FormulaToken* pToken
}
ScTokenMatrixMap::const_iterator aIter;
- if (pTokenMatrixMap && ((aIter = pTokenMatrixMap->find( pToken))
- != pTokenMatrixMap->end()))
+ if (pTokenMatrixMap && ((aIter = pTokenMatrixMap->find( pToken)) != pTokenMatrixMap->end()))
{
- return (*aIter).second.get()->GetMatrix();
+ /* XXX casting const away here is ugly; ScMatrixToken (to which the
+ * result of this function usually is assigned) should not be forced to
+ * carry a ScConstMatrixRef though.
+ * TODO: a matrix already stored in pTokenMatrixMap should be
+ * read-only and have a copy-on-write mechanism. Previously all tokens
+ * were modifiable so we're already better than before ... */
+ return const_cast<FormulaToken*>((*aIter).second.get())->GetMatrix();
}
ScMatrixRef pMat = GetNewMat( nMatCols, nMatRows, true);
@@ -371,8 +376,7 @@ ScMatrixRef ScInterpreter::CreateMatrixFromDoubleRef( const FormulaToken* pToken
pDok->FillMatrix(*pMat, nTab1, nCol1, nRow1, nCol2, nRow2);
if (pTokenMatrixMap)
- pTokenMatrixMap->insert( ScTokenMatrixMap::value_type(
- pToken, new ScMatrixToken( pMat)));
+ pTokenMatrixMap->insert( ScTokenMatrixMap::value_type( pToken, new ScMatrixToken( pMat)));
return pMat;
}
diff --git a/sc/source/core/tool/interpr6.cxx b/sc/source/core/tool/interpr6.cxx
index 78d6f47c2589..c46606891c95 100644
--- a/sc/source/core/tool/interpr6.cxx
+++ b/sc/source/core/tool/interpr6.cxx
@@ -915,7 +915,7 @@ void ScInterpreter::ScRawSubtract()
return;
// Fish the 1st parameter from the stack and push it on top.
- FormulaToken* p = pStack[ sp - nParamCount ];
+ const FormulaToken* p = pStack[ sp - nParamCount ];
PushWithoutError( *p );
// Obtain the minuend.
double fRes = GetDouble();
diff --git a/sc/source/core/tool/interpr8.cxx b/sc/source/core/tool/interpr8.cxx
index 972b125267c0..d219c6e4692f 100644
--- a/sc/source/core/tool/interpr8.cxx
+++ b/sc/source/core/tool/interpr8.cxx
@@ -1895,7 +1895,7 @@ void ScInterpreter::ScIfs_MS()
}
//push result :
- FormulaTokenRef xToken( PopToken() );
+ FormulaConstTokenRef xToken( PopToken() );
if ( xToken )
{
// Remove unused arguments of IFS from the stack before pushing the result.
@@ -1904,7 +1904,7 @@ void ScInterpreter::ScIfs_MS()
Pop();
nParamCount--;
}
- PushTempToken( xToken.get() );
+ PushTokenRef( xToken );
}
else
PushError( errUnknownStackVariable );
@@ -2006,7 +2006,7 @@ void ScInterpreter::ScSwitch_MS()
}
// push result
- FormulaTokenRef xToken( PopToken() );
+ FormulaConstTokenRef xToken( PopToken() );
if ( xToken )
{
// Remove unused arguments of SWITCH from the stack before pushing the result.
@@ -2015,7 +2015,7 @@ void ScInterpreter::ScSwitch_MS()
Pop();
nParamCount--;
}
- PushTempToken( xToken.get() );
+ PushTokenRef( xToken );
}
else
PushError( errUnknownStackVariable );
diff --git a/sc/source/core/tool/scmatrix.cxx b/sc/source/core/tool/scmatrix.cxx
index 5e19a6c6a32a..3b035c2c868b 100644
--- a/sc/source/core/tool/scmatrix.cxx
+++ b/sc/source/core/tool/scmatrix.cxx
@@ -2696,9 +2696,14 @@ ScMatrix* ScMatrix::CloneIfConst()
return mbCloneIfConst ? Clone() : this;
}
-void ScMatrix::SetImmutable( bool bVal )
+void ScMatrix::SetMutable()
{
- mbCloneIfConst = bVal;
+ mbCloneIfConst = false;
+}
+
+void ScMatrix::SetImmutable() const
+{
+ mbCloneIfConst = true;
}
void ScFullMatrix::Resize( SCSIZE nC, SCSIZE nR)