diff options
author | Eike Rathke <erack@redhat.com> | 2015-11-16 12:23:15 +0100 |
---|---|---|
committer | Eike Rathke <erack@redhat.com> | 2015-11-16 13:25:49 +0100 |
commit | 49257e1da7e371fdea0fac080116b0511789cac7 (patch) | |
tree | c959639884536a2bb035ee0fda819c7dada565c7 /include/formula | |
parent | c994ce8a1d292b02e4c53f7b4061f3bbb840f874 (diff) |
Resolves: tdf#95670 propagate ForceArray per parameter
Regression of b5cd11b4b02a85a83db77ba9d8d1763f0cd88cb1
It was always wrong to propagate ForceArray already if a function had a
ForceArray parameter *somewhere*, we need to do this per parameter
instead.
Change-Id: If188d45366279d9a7bf641edc7e4dd7095d6d035
Diffstat (limited to 'include/formula')
-rw-r--r-- | include/formula/FormulaCompiler.hxx | 29 |
1 files changed, 20 insertions, 9 deletions
diff --git a/include/formula/FormulaCompiler.hxx b/include/formula/FormulaCompiler.hxx index 8e5007e998f4..00e76faa45d7 100644 --- a/include/formula/FormulaCompiler.hxx +++ b/include/formula/FormulaCompiler.hxx @@ -293,6 +293,10 @@ protected: virtual void CreateStringFromIndex( OUStringBuffer& rBuffer, const FormulaToken* pToken ) const; virtual void LocalizeString( OUString& rName ) const; // modify rName - input: exact name + /** Whether parameter nParam (0-based) is forced to array for OpCode eOp. + Calc: ForceArray or ReferenceOrForceArray type. */ + virtual bool IsForceArrayParameter( const FormulaToken* pToken, sal_uInt16 nParam ) const; + void AppendErrorConstant( OUStringBuffer& rBuffer, sal_uInt16 nError ) const; bool GetToken(); @@ -323,6 +327,7 @@ protected: FormulaTokenRef mpToken; // current token FormulaTokenRef pCurrentFactorToken; // current factor token (of Factor() method) + sal_uInt16 nCurrentFactorParam; // current factor token's parameter, 1-based FormulaTokenArray* pArr; FormulaToken** pCode; @@ -353,32 +358,38 @@ private: void loadSymbols( sal_uInt16 nSymbols, FormulaGrammar::Grammar eGrammar, NonConstOpCodeMapPtr& rxMap, SeparatorType eSepType = SEMICOLON_BASE ) const; - static inline void ForceArrayOperator( FormulaTokenRef& rCurr, const FormulaTokenRef& rPrev ) - { - if ( rPrev && rPrev->HasForceArray() && rCurr->GetOpCode() != ocPush && - (rCurr->GetType() == svByte || rCurr->GetType() == svJump) && - !rCurr->HasForceArray() ) - rCurr->SetForceArray( true); - } + /** Check pCurrentFactorToken for nParam's (0-based) ForceArray types and + set ForceArray at rCurr if so. Set nParam+1 as 1-based + nCurrentFactorParam for subsequent ForceArrayOperator() calls. + */ + void CheckSetForceArrayParameter( FormulaTokenRef& rCurr, sal_uInt8 nParam ); + + void ForceArrayOperator( FormulaTokenRef& rCurr ); class CurrentFactor { FormulaTokenRef pPrevFac; + sal_uInt16 nPrevParam; FormulaCompiler* pCompiler; CurrentFactor( const CurrentFactor& ) = delete; CurrentFactor& operator=( const CurrentFactor& ) = delete; public: explicit CurrentFactor( FormulaCompiler* pComp ) : pPrevFac( pComp->pCurrentFactorToken ) + , nPrevParam( pComp->nCurrentFactorParam ) , pCompiler( pComp ) {} ~CurrentFactor() - { pCompiler->pCurrentFactorToken = pPrevFac; } + { + pCompiler->pCurrentFactorToken = pPrevFac; + pCompiler->nCurrentFactorParam = nPrevParam; + } // yes, this operator= may modify the RValue void operator=( FormulaTokenRef& r ) { - ForceArrayOperator( r, pPrevFac); + pCompiler->ForceArrayOperator( r ); pCompiler->pCurrentFactorToken = r; + pCompiler->nCurrentFactorParam = 0; } void operator=( FormulaToken* p ) { |