[Libreoffice-commits] core.git: Branch 'libreoffice-4-4' - formula/source include/formula sc/inc sc/source

Eike Rathke erack at redhat.com
Thu Nov 19 18:11:46 PST 2015


 formula/source/core/api/FormulaCompiler.cxx |   48 ++++++++++++++++++++++++++--
 include/formula/FormulaCompiler.hxx         |   29 +++++++++++-----
 sc/inc/compiler.hxx                         |    2 +
 sc/source/core/inc/interpre.hxx             |    4 +-
 sc/source/core/tool/compiler.cxx            |    8 ++++
 sc/source/core/tool/interpr4.cxx            |    2 -
 sc/source/core/tool/token.cxx               |    2 -
 7 files changed, 81 insertions(+), 14 deletions(-)

New commits:
commit 7ffceb55db60ab2cd5899b2a80583b5fb94bebcf
Author: Eike Rathke <erack at redhat.com>
Date:   Mon Nov 16 12:23:15 2015 +0100

    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.
    
    (cherry picked from commit 49257e1da7e371fdea0fac080116b0511789cac7)
    
    Conflicts:
    	formula/source/core/api/FormulaCompiler.cxx
    
    prevent ForceArray propagation on the same token, tdf#95670 follow-up
    
    This may happen if the last RPN token is put and the function has a
    ForceArray parameter but now again would be wrong if not all parameters
    are ForceArray.
    
    (cherry picked from commit b31b17e52b2b2b94999d68c4b2ed5c74ee7eed0a)
    
    890fb6b5b88337033cfcf2e8189371ee39461205
    
    Conflicts:
    	sc/source/core/inc/interpre.hxx
    
    -Werror,-Winconsistent-missing-override
    
    (cherry picked from commit 6edc492efd6fe2de15c1ae306b400ca054772ad1)
    Backported to SAL_OVERRIDE
    
    3bb2764b625d44f6e0cecbdde3363440faef63b5
    
    Change-Id: If188d45366279d9a7bf641edc7e4dd7095d6d035
    Reviewed-on: https://gerrit.libreoffice.org/19997
    Reviewed-by: Markus Mohrhard <markus.mohrhard at googlemail.com>
    Tested-by: Markus Mohrhard <markus.mohrhard at googlemail.com>

diff --git a/formula/source/core/api/FormulaCompiler.cxx b/formula/source/core/api/FormulaCompiler.cxx
index 5cb40fc..6b28048 100644
--- a/formula/source/core/api/FormulaCompiler.cxx
+++ b/formula/source/core/api/FormulaCompiler.cxx
@@ -527,6 +527,7 @@ void FormulaCompiler::OpCodeMap::putOpCode( const OUString & rStr, const OpCode
 
 FormulaCompiler::FormulaCompiler( FormulaTokenArray& rArr )
         :
+        nCurrentFactorParam(0),
         pArr( &rArr ),
         pCode( NULL ),
         pStack( NULL ),
@@ -545,6 +546,7 @@ FormulaCompiler::FormulaCompiler( FormulaTokenArray& rArr )
 
 FormulaCompiler::FormulaCompiler()
         :
+        nCurrentFactorParam(0),
         pArr( NULL ),
         pCode( NULL ),
         pStack( NULL ),
@@ -1165,6 +1167,7 @@ void FormulaCompiler::Factor()
         {   // range list  (A1;A2)  converted to  (A1~A2)
             pFacToken = mpToken;
             NextToken();
+            CheckSetForceArrayParameter( mpToken, 0);
             eOp = Expression();
             // Do not ignore error here, regardless of bIgnoreErrors, otherwise
             // errors like =(1;) would also result in display of =(1~)
@@ -1250,6 +1253,7 @@ void FormulaCompiler::Factor()
             if (eOp == ocOpen)
             {
                 NextToken();
+                CheckSetForceArrayParameter( mpToken, 0);
                 eOp = Expression();
             }
             else
@@ -1281,7 +1285,10 @@ void FormulaCompiler::Factor()
                 if (eOp == ocClose)
                     bNoParam = true;
                 else
+                {
+                    CheckSetForceArrayParameter( mpToken, 0);
                     eOp = Expression();
+                }
             }
             else if (eMyLastOp == ocBad)
             {
@@ -1298,8 +1305,9 @@ void FormulaCompiler::Factor()
                 nSepCount++;
                 while ((eOp == ocSep) && (!pArr->GetCodeError() || !mbStopOnError))
                 {
-                    nSepCount++;
                     NextToken();
+                    CheckSetForceArrayParameter( mpToken, nSepCount);
+                    nSepCount++;
                     eOp = Expression();
                 }
             }
@@ -1339,6 +1347,7 @@ void FormulaCompiler::Factor()
             if (eOp == ocOpen)
             {
                 NextToken();
+                CheckSetForceArrayParameter( mpToken, 0);
                 eOp = Expression();
             }
             else
@@ -1373,6 +1382,7 @@ void FormulaCompiler::Factor()
                 if ( ++nJumpCount <= nJumpMax )
                     pFacToken->GetJump()[nJumpCount] = pc-1;
                 NextToken();
+                CheckSetForceArrayParameter( mpToken, nJumpCount - 1);
                 eOp = Expression();
                 // ocSep or ocClose terminate the subexpression
                 PutCode( mpToken );
@@ -2082,7 +2092,7 @@ void FormulaCompiler::PutCode( FormulaTokenRef& p )
     }
     if (pArr->GetCodeError() && mbJumpCommandReorder)
         return;
-    ForceArrayOperator( p, pCurrentFactorToken);
+    ForceArrayOperator( p);
     p->IncRef();
     *pCode++ = p.get();
     pc++;
@@ -2133,6 +2143,40 @@ void FormulaCompiler::LocalizeString( OUString& /*rName*/ ) const
 {
 }
 
+bool FormulaCompiler::IsForceArrayParameter( const FormulaToken* /*pToken*/, sal_uInt16 /*nParam*/ ) const
+{
+    return false;
+}
+
+void FormulaCompiler::ForceArrayOperator( FormulaTokenRef& rCurr )
+{
+    if (!pCurrentFactorToken || (pCurrentFactorToken.get() == rCurr.get()))
+        return;
+
+    if (!(rCurr->GetOpCode() != ocPush && (rCurr->GetType() == svByte || rCurr->GetType() == svJump)))
+        return;
+
+    if (pCurrentFactorToken->HasForceArray())
+    {
+        rCurr->SetForceArray( true);
+        return;
+    }
+
+    if (nCurrentFactorParam && IsForceArrayParameter( pCurrentFactorToken.get(),
+                static_cast<sal_uInt8>(nCurrentFactorParam - 1)))
+        rCurr->SetForceArray( true);
+}
+
+void FormulaCompiler::CheckSetForceArrayParameter( FormulaTokenRef& rCurr, sal_uInt8 nParam )
+{
+    if (!pCurrentFactorToken)
+        return;
+
+    nCurrentFactorParam = nParam + 1;
+
+    ForceArrayOperator( rCurr);
+}
+
 void FormulaCompiler::PushTokenArray( FormulaTokenArray* pa, bool bTemp )
 {
     if ( bAutoCorrect && !pStack )
diff --git a/include/formula/FormulaCompiler.hxx b/include/formula/FormulaCompiler.hxx
index 101369d..002e08a 100644
--- a/include/formula/FormulaCompiler.hxx
+++ b/include/formula/FormulaCompiler.hxx
@@ -289,6 +289,10 @@ protected:
     virtual void CreateStringFromIndex(OUStringBuffer& rBuffer,FormulaToken* pTokenP) 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();
@@ -319,6 +323,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;
@@ -349,17 +354,18 @@ 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;
         // not implemented
         CurrentFactor( const CurrentFactor& );
@@ -367,15 +373,20 @@ private:
     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 )
             {
diff --git a/sc/inc/compiler.hxx b/sc/inc/compiler.hxx
index 6fb4b1b..9f8a7d7 100644
--- a/sc/inc/compiler.hxx
+++ b/sc/inc/compiler.hxx
@@ -462,6 +462,8 @@ private:
     virtual void CreateStringFromIndex(OUStringBuffer& rBuffer,formula::FormulaToken* _pTokenP) const SAL_OVERRIDE;
     virtual void LocalizeString( OUString& rName ) const SAL_OVERRIDE;   // modify rName - input: exact name
 
+    virtual bool IsForceArrayParameter( const formula::FormulaToken* pToken, sal_uInt16 nParam ) const SAL_OVERRIDE;
+
     /// Access the CharTable flags
     inline sal_uLong GetCharTableFlags( sal_Unicode c, sal_Unicode cLast )
         { return c < 128 ? pConv->getCharTableFlags(c, cLast) : 0; }
diff --git a/sc/source/core/inc/interpre.hxx b/sc/source/core/inc/interpre.hxx
index f1bceb1..2e0ae21 100644
--- a/sc/source/core/inc/interpre.hxx
+++ b/sc/source/core/inc/interpre.hxx
@@ -30,6 +30,7 @@
 #include "externalrefmgr.hxx"
 #include "calcconfig.hxx"
 #include "token.hxx"
+#include "parclass.hxx"
 
 #include <map>
 #include <vector>
@@ -898,7 +899,8 @@ inline void ScInterpreter::MatrixDoubleRefToMatrix()
 
 inline bool ScInterpreter::MatrixParameterConversion()
 {
-    if ( (bMatrixFormula || pCur->HasForceArray()) && !pJumpMatrix && sp > 0 )
+    if ( (bMatrixFormula || pCur->HasForceArray() || ScParameterClassification::HasForceArray( pCur->GetOpCode())) &&
+            !pJumpMatrix && sp > 0 )
         return ConvertMatrixParameters();
     return false;
 }
diff --git a/sc/source/core/tool/compiler.cxx b/sc/source/core/tool/compiler.cxx
index 04b7edc..2d64af8 100644
--- a/sc/source/core/tool/compiler.cxx
+++ b/sc/source/core/tool/compiler.cxx
@@ -4634,4 +4634,12 @@ FormulaTokenRef ScCompiler::ExtendRangeReference( FormulaToken & rTok1, FormulaT
     return extendRangeReference( rTok1, rTok2, aPos,bReuseDoubleRef );
 }
 
+bool ScCompiler::IsForceArrayParameter( const formula::FormulaToken* pToken, sal_uInt16 nParam ) const
+{
+    ScParameterClassification::Type eType = ScParameterClassification::GetParameterType( pToken, nParam);
+    return
+        eType == ScParameterClassification::ForceArray ||
+        eType == ScParameterClassification::ReferenceOrForceArray;
+}
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/core/tool/interpr4.cxx b/sc/source/core/tool/interpr4.cxx
index 6ebeed7..f2aa477 100644
--- a/sc/source/core/tool/interpr4.cxx
+++ b/sc/source/core/tool/interpr4.cxx
@@ -1661,7 +1661,7 @@ bool ScInterpreter::ConvertMatrixParameters()
                             // has ForceArray or ReferenceOrForceArray
                             // parameter *somewhere else*) pick a normal
                             // position dependent implicit intersection later.
-                            (eType != ScParameterClassification::Value || bMatrixFormula))
+                            (eType != ScParameterClassification::Value || bMatrixFormula || pCur->HasForceArray()))
                     {
                         SCCOL nCol1, nCol2;
                         SCROW nRow1, nRow2;
diff --git a/sc/source/core/tool/token.cxx b/sc/source/core/tool/token.cxx
index cfd2866..76769d6 100644
--- a/sc/source/core/tool/token.cxx
+++ b/sc/source/core/tool/token.cxx
@@ -201,7 +201,7 @@ void ScRawToken::SetOpCode( OpCode e )
         default:
             eType = svByte;
             sbyte.cByte = 0;
-            sbyte.bHasForceArray = ScParameterClassification::HasForceArray( eOp);
+            sbyte.bHasForceArray = false;
     }
 }
 


More information about the Libreoffice-commits mailing list