Date: prev next · Thread: first prev next last
2012 Archives by date, by thread · List index


Hi Eike,

Attached is the modified patch for function XOR, this time under its own bug.
I tested the patch, did an export to xls, reread the xls (XOR calls were not recgnised/calculated 
when importing), saved again as ods and reread that one (XOR calls were calculated correctly).
I think this has to do with XOR being in saFuncTableOdf[] (in 
core/sc/source/filter/oox/formulabase.cxx), which has the description "Functions defined by 
OpenFormula, but not supported by Calc or by Excel." and where XOR _is_ supported by Calc.

Winfried
From aee7748e018301b428c0d9ba02c058064a3de25d Mon Sep 17 00:00:00 2001
From: Winfried Donkers <osc@dci-electronics.nl>
Date: Sat, 9 Jun 2012 12:43:30 +0200
Subject: [PATCH] fdo#50822 add function XOR to calc as in ODFF1.2

Change-Id: I994119c0520658775d07f776237d31a03f53ab52
---
 formula/inc/formula/compiler.hrc               |    5 +-
 formula/inc/formula/opcode.hxx                 |    1 +
 formula/source/core/api/FormulaCompiler.cxx    |    1 +
 formula/source/core/resource/core_resource.src |    5 +
 sc/inc/helpids.h                               |    1 +
 sc/qa/unit/ucalc.cxx                           |    1 +
 sc/source/core/inc/interpre.hxx                |    1 +
 sc/source/core/tool/interpr1.cxx               |  101 ++++++++++++++++++++++++
 sc/source/core/tool/interpr4.cxx               |    1 +
 sc/source/core/tool/parclass.cxx               |    1 +
 sc/source/filter/oox/formulabase.cxx           |    1 +
 sc/source/ui/src/scfuncs.src                   |   24 ++++++
 sc/source/ui/vba/vbawsfunction.cxx             |    2 +-
 sc/util/hidother.src                           |    1 +
 14 files changed, 143 insertions(+), 3 deletions(-)

diff --git a/formula/inc/formula/compiler.hrc b/formula/inc/formula/compiler.hrc
index a2d4bb5..4babe0e 100644
--- a/formula/inc/formula/compiler.hrc
+++ b/formula/inc/formula/compiler.hrc
@@ -400,8 +400,9 @@
 #define SC_OPCODE_BITRSHIFT         398
 #define SC_OPCODE_BITLSHIFT         399
 #define SC_OPCODE_GET_DATEDIF       400
-#define SC_OPCODE_STOP_2_PAR        401
-#define SC_OPCODE_LAST_OPCODE_ID    401     /* last OpCode */
+#define SC_OPCODE_XOR               401
+#define SC_OPCODE_STOP_2_PAR        402
+#define SC_OPCODE_LAST_OPCODE_ID    402     /* last OpCode */
 
 /*** Internal ***/
 #define SC_OPCODE_INTERNAL_BEGIN   9999
diff --git a/formula/inc/formula/opcode.hxx b/formula/inc/formula/opcode.hxx
index a1543dd..16b12ec 100644
--- a/formula/inc/formula/opcode.hxx
+++ b/formula/inc/formula/opcode.hxx
@@ -89,6 +89,7 @@ enum OpCodeEnum
         ocGreaterEqual      = SC_OPCODE_GREATER_EQUAL,
         ocAnd               = SC_OPCODE_AND,
         ocOr                = SC_OPCODE_OR,
+        ocXor               = SC_OPCODE_XOR,
         ocIntersect         = SC_OPCODE_INTERSECT,
         ocUnion             = SC_OPCODE_UNION,
         ocRange             = SC_OPCODE_RANGE,
diff --git a/formula/source/core/api/FormulaCompiler.cxx 
b/formula/source/core/api/FormulaCompiler.cxx
index 9e82422..042e49b 100644
--- a/formula/source/core/api/FormulaCompiler.cxx
+++ b/formula/source/core/api/FormulaCompiler.cxx
@@ -76,6 +76,7 @@ short lcl_GetRetFormat( OpCode eOpCode )
         case ocGreaterEqual:
         case ocAnd:
         case ocOr:
+        case ocXor:
         case ocNot:
         case ocTrue:
         case ocFalse:
diff --git a/formula/source/core/resource/core_resource.src 
b/formula/source/core/resource/core_resource.src
index 1259231..b4ea345 100644
--- a/formula/source/core/resource/core_resource.src
+++ b/formula/source/core/resource/core_resource.src
@@ -56,6 +56,7 @@ Resource RID_STRLIST_FUNCTION_NAMES_ENGLISH_ODFF
     String SC_OPCODE_GREATER_EQUAL { Text = ">=" ; };
     String SC_OPCODE_AND { Text = "AND" ; };
     String SC_OPCODE_OR { Text = "OR" ; };
+    String SC_OPCODE_XOR { Text = "XOR" ; };
     String SC_OPCODE_INTERSECT { Text = "!" ; };
     String SC_OPCODE_UNION { Text = "~" ; };
     String SC_OPCODE_RANGE { Text = ":" ; };
@@ -731,6 +732,10 @@ Resource RID_STRLIST_FUNCTION_NAMES
     {
         Text [ en-US ] = "OR" ;
     };
+    String SC_OPCODE_XOR
+    {
+        Text [ en-US ] = "XOR" ;
+    };
     String SC_OPCODE_INTERSECT { Text = "!" ; };
     String SC_OPCODE_UNION { Text = "~" ; };
     String SC_OPCODE_RANGE { Text = ":" ; };
diff --git a/sc/inc/helpids.h b/sc/inc/helpids.h
index 7c5955c..e2f6e06 100644
--- a/sc/inc/helpids.h
+++ b/sc/inc/helpids.h
@@ -487,6 +487,7 @@
 #define HID_FUNC_WENN                                           "SC_HID_FUNC_WENN"
 #define HID_FUNC_ODER                                           "SC_HID_FUNC_ODER"
 #define HID_FUNC_UND                                            "SC_HID_FUNC_UND"
+#define HID_FUNC_XOR                                            "SC_HID_FUNC_XOR"
 
 #define HID_FUNC_ABS                                            "SC_HID_FUNC_ABS"
 #define HID_FUNC_POTENZ                                         "SC_HID_FUNC_POTENZ"
diff --git a/sc/qa/unit/ucalc.cxx b/sc/qa/unit/ucalc.cxx
index d37e3f1..1db6294 100644
--- a/sc/qa/unit/ucalc.cxx
+++ b/sc/qa/unit/ucalc.cxx
@@ -3276,6 +3276,7 @@ void Test::testFunctionLists()
         "NOT",
         "OR",
         "TRUE",
+        "XOR",
         0
     };
 
diff --git a/sc/source/core/inc/interpre.hxx b/sc/source/core/inc/interpre.hxx
index c92ad0c..de577ca 100644
--- a/sc/source/core/inc/interpre.hxx
+++ b/sc/source/core/inc/interpre.hxx
@@ -393,6 +393,7 @@ void ScLessEqual();
 void ScGreaterEqual();
 void ScAnd();
 void ScOr();
+void ScXor();
 void ScNot();
 void ScNeg();
 void ScPercentSign();
diff --git a/sc/source/core/tool/interpr1.cxx b/sc/source/core/tool/interpr1.cxx
index 34675c9..ccca6cd 100644
--- a/sc/source/core/tool/interpr1.cxx
+++ b/sc/source/core/tool/interpr1.cxx
@@ -1385,6 +1385,107 @@ void ScInterpreter::ScOr()
 }
 
 
+void ScInterpreter::ScXor()
+{
+    RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScXor" );
+
+    nFuncFmtType = NUMBERFORMAT_LOGICAL;
+    short nParamCount = GetByte();
+    if ( MustHaveParamCountMin( nParamCount, 1 ) )
+    {
+        bool bHaveValue = false;
+        short nRes = false;
+        size_t nRefInList = 0;
+        while( nParamCount-- > 0)
+        {
+            if ( !nGlobalError )
+            {
+                switch ( GetStackType() )
+                {
+                    case svDouble :
+                        bHaveValue = true;
+                        nRes ^= ( PopDouble() != 0.0 );
+                    break;
+                    case svString :
+                        Pop();
+                        SetError( errNoValue );
+                    break;
+                    case svSingleRef :
+                    {
+                        ScAddress aAdr;
+                        PopSingleRef( aAdr );
+                        if ( !nGlobalError )
+                        {
+                            ScBaseCell* pCell = GetCell( aAdr );
+                            if ( HasCellValueData( pCell ) )
+                            {
+                                bHaveValue = true;
+                                nRes ^= ( GetCellValue( aAdr, pCell ) != 0.0 );
+                            }
+                            // else: Xcl raises no error here
+                        }
+                    }
+                    break;
+                    case svDoubleRef:
+                    case svRefList:
+                    {
+                        ScRange aRange;
+                        PopDoubleRef( aRange, nParamCount, nRefInList);
+                        if ( !nGlobalError )
+                        {
+                            double fVal;
+                            sal_uInt16 nErr = 0;
+                            ScValueIterator aValIter( pDok, aRange );
+                            if ( aValIter.GetFirst( fVal, nErr ) )
+                            {
+                                bHaveValue = true;
+                                do
+                                {
+                                    nRes ^= ( fVal != 0.0 );
+                                } while ( (nErr == 0) &&
+                                    aValIter.GetNext( fVal, nErr ) );
+                            }
+                            SetError( nErr );
+                        }
+                    }
+                    break;
+                    case svExternalSingleRef:
+                    case svExternalDoubleRef:
+                    case svMatrix:
+                    {
+                        bHaveValue = true;
+                        ScMatrixRef pMat = GetMatrix();
+                        if ( pMat )
+                        {
+                            bHaveValue = true;
+                            double fVal = pMat->Or();
+                            sal_uInt16 nErr = GetDoubleErrorValue( fVal );
+                            if ( nErr )
+                            {
+                                SetError( nErr );
+                            }
+                            else
+                                nRes ^= ( fVal != 0.0 );
+                        }
+                        // else: GetMatrix did set errIllegalParameter
+                    }
+                    break;
+                    default:
+                        Pop();
+                        SetError( errIllegalParameter);
+                }
+            }
+            else
+                Pop();
+        }
+        if ( bHaveValue )
+            PushInt( nRes );
+        else
+            PushNoValue();
+    }
+}
+
+
 void ScInterpreter::ScNeg()
 {
     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScNeg" );
diff --git a/sc/source/core/tool/interpr4.cxx b/sc/source/core/tool/interpr4.cxx
index 4a10201..aeadfe9 100644
--- a/sc/source/core/tool/interpr4.cxx
+++ b/sc/source/core/tool/interpr4.cxx
@@ -3810,6 +3810,7 @@ StackVar ScInterpreter::Interpret()
                 case ocGreaterEqual     : ScGreaterEqual();             break;
                 case ocAnd              : ScAnd();                      break;
                 case ocOr               : ScOr();                       break;
+                case ocXor              : ScXor();                      break;
                 case ocIntersect        : ScIntersect();                break;
                 case ocRange            : ScRangeFunc();                break;
                 case ocUnion            : ScUnionFunc();                break;
diff --git a/sc/source/core/tool/parclass.cxx b/sc/source/core/tool/parclass.cxx
index e8509a3..f641b29 100644
--- a/sc/source/core/tool/parclass.cxx
+++ b/sc/source/core/tool/parclass.cxx
@@ -193,6 +193,7 @@ const ScParameterClassification::RawData ScParameterClassification::pRawData[] =
     { ocVarP,            {{ Reference                                            }, true }},
     { ocVarPA,           {{ Reference                                            }, true }},
     { ocVLookup,         {{ Value, Reference, Value, Value                       }, false }},
+    { ocXor,             {{ Reference                                            }, true }},
     { ocZTest,           {{ Reference, Value, Value                              }, false }},
     // Excel doubts:
     // ocT: Excel says (and handles) Reference, error? This means no position
diff --git a/sc/source/filter/oox/formulabase.cxx b/sc/source/filter/oox/formulabase.cxx
index b80dbfa..381d74d 100644
--- a/sc/source/filter/oox/formulabase.cxx
+++ b/sc/source/filter/oox/formulabase.cxx
@@ -669,6 +669,7 @@ static const FunctionData saFuncTableBiff5[] =
     { 0,                        "DATESTRING",           352,    352,    1,  1,  V, { VR }, 
FUNCFLAG_IMPORTONLY },   // not supported in Calc, missing in OOXML spec
     { 0,                        "NUMBERSTRING",         353,    353,    2,  2,  V, { VR }, 
FUNCFLAG_IMPORTONLY },   // not supported in Calc, missing in OOXML spec
     { "ROMAN",                  "ROMAN",                354,    354,    1,  2,  V, { VR }, 0 },
+    { "XOR",                    "XOR",                  355,    355,    1,  MX, V, { RX }, 0 },
 
     // *** EuroTool add-in ***
 
diff --git a/sc/source/ui/src/scfuncs.src b/sc/source/ui/src/scfuncs.src
index 53780de..60f8fca 100644
--- a/sc/source/ui/src/scfuncs.src
+++ b/sc/source/ui/src/scfuncs.src
@@ -2682,6 +2682,30 @@ Resource RID_SC_FUNCTION_DESCRIPTIONS1
             Text [ en-US ] = "Logical value 1, logical value 2,... are 1 to 30 conditions to be 
tested and which return either TRUE or FALSE." ;
         };
     };
+     // -=*# Resource for function XOR (EXKLUSIV ODER) #*=-
+    Resource SC_OPCODE_XOR
+    {
+        String 1 // Description
+        {
+            Text [ en-US ] = "Returns TRUE if one argument is TRUE, but not both." ;
+        };
+        ExtraData =
+        {
+            0;
+            ID_FUNCTION_GRP_LOGIC;
+            U2S( HID_FUNC_XOR );
+            VAR_ARGS;  0;
+            0;
+        };
+        String 2 // Name of Parameter 1
+        {
+            Text [ en-US ] = "Logical value " ;
+        };
+        String 3 // Description of Parameter 1
+        {
+            Text [ en-US ] = "Logical value 1, logical value 2, ... are 1 to 30 conditions to be 
tested and which returns either TRUE or FALSE." ;
+        };
+    };
      // -=*# Resource for function UND #*=-
     Resource SC_OPCODE_AND
     {
diff --git a/sc/source/ui/vba/vbawsfunction.cxx b/sc/source/ui/vba/vbawsfunction.cxx
index 0692afb..3a236b3 100644
--- a/sc/source/ui/vba/vbawsfunction.cxx
+++ b/sc/source/ui/vba/vbawsfunction.cxx
@@ -201,7 +201,7 @@ ScVbaWSFunction::invoke(const rtl::OUString& FunctionName, const uno::Sequence<
     if( (eOpCode == ocIsEmpty) || (eOpCode == ocIsString) || (eOpCode == ocIsNonString) || 
(eOpCode == ocIsLogical) ||
         (eOpCode == ocIsRef) || (eOpCode == ocIsValue) || (eOpCode == ocIsFormula) || (eOpCode == 
ocIsNA) ||
         (eOpCode == ocIsErr) || (eOpCode == ocIsError) || (eOpCode == ocIsEven) || (eOpCode == 
ocIsOdd) ||
-        (eOpCode == ocAnd) || (eOpCode == ocOr) || (eOpCode == ocNot) || (eOpCode == ocTrue) || 
(eOpCode == ocFalse) )
+        (eOpCode == ocAnd) || (eOpCode == ocOr) || (eOpCode == ocXor) || (eOpCode == ocNot) || 
(eOpCode == ocTrue) || (eOpCode == ocFalse) )
     {
         if( aRet.has< AnySeqSeq >() )
         {
diff --git a/sc/util/hidother.src b/sc/util/hidother.src
index 85d36f9..6a56a81 100644
--- a/sc/util/hidother.src
+++ b/sc/util/hidother.src
@@ -160,6 +160,7 @@ hidspecial HID_FUNC_WAHR         { HelpID = HID_FUNC_WAHR; };
 hidspecial HID_FUNC_WENN         { HelpID = HID_FUNC_WENN; };
 hidspecial HID_FUNC_ODER         { HelpID = HID_FUNC_ODER; };
 hidspecial HID_FUNC_UND      { HelpID = HID_FUNC_UND; };
+hidspecial HID_FUNC_XOR      { HelpID = HID_FUNC_XOR; };
 hidspecial HID_FUNC_ABS      { HelpID = HID_FUNC_ABS; };
 hidspecial HID_FUNC_POTENZ       { HelpID = HID_FUNC_POTENZ; };
 hidspecial HID_FUNC_ANZAHLLEEREZELLEN        { HelpID = HID_FUNC_ANZAHLLEEREZELLEN; };
-- 
1.7.7


Context


Privacy Policy | Impressum (Legal Info) | Copyright information: Unless otherwise specified, all text and images on this website are licensed under the Creative Commons Attribution-Share Alike 3.0 License. This does not include the source code of LibreOffice, which is licensed under the Mozilla Public License (MPLv2). "LibreOffice" and "The Document Foundation" are registered trademarks of their corresponding registered owners or are in actual use as trademarks in one or more countries. Their respective logos and icons are also subject to international copyright laws. Use thereof is explained in our trademark policy.