[Libreoffice-commits] core.git: 3 commits - formula/source include/formula sc/source

Eike Rathke erack at redhat.com
Thu Jan 5 17:24:11 UTC 2017


 formula/source/core/api/FormulaCompiler.cxx |   21 ++++++++
 include/formula/errorcodes.hxx              |   67 ++++++++++++++++++++++++++++
 sc/source/core/data/cellvalue.cxx           |    3 +
 sc/source/core/data/formulacell.cxx         |   13 +++++
 4 files changed, 103 insertions(+), 1 deletion(-)

New commits:
commit 6b89bcf85a911d043c9d93e843be12e6f23adedd
Author: Eike Rathke <erack at redhat.com>
Date:   Thu Jan 5 18:23:04 2017 +0100

    check "#ERRxxx!" constants for accepted error values, tdf#105024 follow-up
    
    Change-Id: I9a11695710baa2f4e022c8e07f01b962cfabe2e7

diff --git a/formula/source/core/api/FormulaCompiler.cxx b/formula/source/core/api/FormulaCompiler.cxx
index 9e23149..66c92fb 100644
--- a/formula/source/core/api/FormulaCompiler.cxx
+++ b/formula/source/core/api/FormulaCompiler.cxx
@@ -1192,7 +1192,7 @@ FormulaError FormulaCompiler::GetErrorConstant( const OUString& rName ) const
         if (rName.startsWithIgnoreAsciiCase("#ERR") && rName[rName.getLength()-1] == '!')
         {
             sal_uInt32 nErr = rName.copy( 4, rName.getLength() - 5).toUInt32();
-            if (0 < nErr && nErr <= SAL_MAX_UINT16)
+            if (0 < nErr && nErr <= SAL_MAX_UINT16 && isPublishedFormulaError(static_cast<FormulaError>(nErr)))
                 nError = static_cast<FormulaError>(nErr);
         }
     }
diff --git a/include/formula/errorcodes.hxx b/include/formula/errorcodes.hxx
index 329be0d..2af9b11 100644
--- a/include/formula/errorcodes.hxx
+++ b/include/formula/errorcodes.hxx
@@ -119,6 +119,73 @@ inline FormulaError GetDoubleErrorValue( double fVal )
     return (FormulaError)(nErr & 0x0000ffff);
 }
 
+/** Error values that are accepted as detailed "#ERRxxx!" constants.
+
+    Used in FormulaCompiler::GetErrorConstant() to prevent users from inventing
+    arbitrary values that already have or later might get a significant meaning.
+ */
+inline bool isPublishedFormulaError( FormulaError nErr )
+{
+    // Every value has to be handled explicitly, do not add a default case to
+    // let the compiler complain if a value is missing.
+    switch (nErr)
+    {
+        case FormulaError::NONE:
+            return false;
+
+        case FormulaError::IllegalChar:
+        case FormulaError::IllegalArgument:
+        case FormulaError::IllegalFPOperation:
+        case FormulaError::IllegalParameter:
+        case FormulaError::IllegalJump:
+        case FormulaError::Separator:
+        case FormulaError::Pair:
+        case FormulaError::PairExpected:
+        case FormulaError::OperatorExpected:
+        case FormulaError::VariableExpected:
+        case FormulaError::ParameterExpected:
+        case FormulaError::CodeOverflow:
+        case FormulaError::StringOverflow:
+        case FormulaError::StackOverflow:
+        case FormulaError::UnknownState:
+        case FormulaError::UnknownVariable:
+        case FormulaError::UnknownOpCode:
+        case FormulaError::UnknownStackVariable:
+        case FormulaError::NoValue:
+        case FormulaError::UnknownToken:
+        case FormulaError::NoCode:
+        case FormulaError::CircularReference:
+        case FormulaError::NoConvergence:
+        case FormulaError::NoRef:
+        case FormulaError::NoName:
+        case FormulaError::DoubleRef:
+            return true;
+
+        case FormulaError::TrackFromCircRef:
+        case FormulaError::CellNoValue:
+            return false;
+
+        case FormulaError::NoAddin:
+        case FormulaError::NoMacro:
+        case FormulaError::DivisionByZero:
+        case FormulaError::NestedArray:
+            return true;
+
+        case FormulaError::NotNumericString:
+        case FormulaError::JumpMatHasResult:
+        case FormulaError::ElementNaN:
+        case FormulaError::RetryCircular:
+            return false;
+
+        case FormulaError::MatrixSize:
+            return true;
+
+        case FormulaError::NotAvailable:
+            return false;
+    }
+    return false;
+}
+
 #endif // INCLUDED_FORMULA_ERRORCODES_HXX
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
commit 44021bd4018f4f97d9f0f6b6e1f0a256e8853537
Author: Eike Rathke <erack at redhat.com>
Date:   Thu Jan 5 16:37:07 2017 +0100

    check token array code errors when testing for equality, tdf#105024 related
    
    To not end up with a series of equal errors when importing individual error
    cells and attempting to group them.
    
    Change-Id: Idfcbb2e7077fc8799ef925c2c2e17188ac5e3b14

diff --git a/sc/source/core/data/cellvalue.cxx b/sc/source/core/data/cellvalue.cxx
index 147ad51..efe66f7 100644
--- a/sc/source/core/data/cellvalue.cxx
+++ b/sc/source/core/data/cellvalue.cxx
@@ -63,6 +63,9 @@ bool equalsFormulaCells( const ScFormulaCell* p1, const ScFormulaCell* p2 )
     if (pCode1->GetLen() != pCode2->GetLen())
         return false;
 
+    if (pCode1->GetCodeError() != pCode2->GetCodeError())
+        return false;
+
     sal_uInt16 n = pCode1->GetLen();
     formula::FormulaToken** ppToken1 = pCode1->GetArray();
     formula::FormulaToken** ppToken2 = pCode2->GetArray();
diff --git a/sc/source/core/data/formulacell.cxx b/sc/source/core/data/formulacell.cxx
index a9cb0e8..06fc6b1 100644
--- a/sc/source/core/data/formulacell.cxx
+++ b/sc/source/core/data/formulacell.cxx
@@ -3844,6 +3844,13 @@ ScFormulaCell::CompareState ScFormulaCell::CompareByTokenArray( ScFormulaCell& r
     if ( nThisLen != nOtherLen )
         return NotEqual;
 
+    // No tokens can be an error cell so check error code, otherwise we could
+    // end up with a series of equal error values instead of individual error
+    // values. Also if for any reason different errors are set even if all
+    // tokens are equal, the cells are not equal.
+    if (pCode->GetCodeError() != rOther.pCode->GetCodeError())
+        return NotEqual;
+
     bool bInvariant = true;
 
     // check we are basically the same function
@@ -3930,6 +3937,12 @@ ScFormulaCell::CompareState ScFormulaCell::CompareByTokenArray( ScFormulaCell& r
                     return NotEqual;
             }
             break;
+            case formula::svError:
+            {
+                if (pThisTok->GetError() != pOtherTok->GetError())
+                    return NotEqual;
+            }
+            break;
             default:
                 ;
         }
commit 857be5b2db4b2726306199bc279942f621bf55d8
Author: Eike Rathke <erack at redhat.com>
Date:   Thu Jan 5 16:32:24 2017 +0100

    Resolves: tdf#105024 generate and parse detailed "#ERRxxx!" error constants
    
    Change-Id: I4e5d98cdbbc2f3e7746cd3892f70151376bc5808

diff --git a/formula/source/core/api/FormulaCompiler.cxx b/formula/source/core/api/FormulaCompiler.cxx
index b0a2ada..9e23149 100644
--- a/formula/source/core/api/FormulaCompiler.cxx
+++ b/formula/source/core/api/FormulaCompiler.cxx
@@ -1185,6 +1185,17 @@ FormulaError FormulaCompiler::GetErrorConstant( const OUString& rName ) const
                 ;   // nothing
         }
     }
+    else
+    {
+        // Per convention recognize detailed "#ERRxxx!" constants, always
+        // untranslated.
+        if (rName.startsWithIgnoreAsciiCase("#ERR") && rName[rName.getLength()-1] == '!')
+        {
+            sal_uInt32 nErr = rName.copy( 4, rName.getLength() - 5).toUInt32();
+            if (0 < nErr && nErr <= SAL_MAX_UINT16)
+                nError = static_cast<FormulaError>(nErr);
+        }
+    }
     return nError;
 }
 
@@ -1203,7 +1214,6 @@ void FormulaCompiler::AppendErrorConstant( OUStringBuffer& rBuffer, FormulaError
     OpCode eOp;
     switch (nError)
     {
-        default:
         case FormulaError::NoCode:
             eOp = ocErrNull;
             break;
@@ -1225,6 +1235,15 @@ void FormulaCompiler::AppendErrorConstant( OUStringBuffer& rBuffer, FormulaError
         case FormulaError::NotAvailable:
             eOp = ocErrNA;
             break;
+        default:
+            {
+                // Per convention create detailed "#ERRxxx!" constants, always
+                // untranslated.
+                rBuffer.append("#ERR");
+                rBuffer.append(static_cast<sal_Int32>(nError));
+                rBuffer.append('!');
+                return;
+            }
     }
     rBuffer.append( mxSymbols->getSymbol( eOp));
 }


More information about the Libreoffice-commits mailing list