Attached patch adds formula XOR to calc.
Possibly the function ought to be included in one or more arrays of functions that are or are
not known in Excel, Lotus, Qpro.
[...] However, you attached a patch for DATEDIF instead of XOR ;-)
This time the patch is the one that covers XOR.
Winfried
From 45326af955b020cc861148c7c1c95449dab858f4 Mon Sep 17 00:00:00 2001
From: Winfried Donkers <osc@dci-electronics.nl>
Date: Wed, 6 Jun 2012 16:33:38 +0200
Subject: [PATCH] fdo#50488 added calc formula XOR as in ODFF1.2
Change-Id: I89c3267d479d5f034ad25ff879d1df8f90b84a55
---
formula/inc/formula/compiler.hrc | 3 +-
formula/inc/formula/opcode.hxx | 1 +
formula/source/core/api/FormulaCompiler.cxx | 10 ++-
formula/source/core/api/token.cxx | 2 +-
formula/source/core/resource/core_resource.src | 5 +
sc/inc/helpids.h | 2 +-
sc/qa/unit/ucalc.cxx | 1 +
sc/source/core/inc/interpre.hxx | 1 +
sc/source/core/tool/interpr1.cxx | 105 ++++++++++++++++++++++++
sc/source/core/tool/interpr4.cxx | 1 +
sc/source/core/tool/parclass.cxx | 2 +
sc/source/filter/oox/formulabase.cxx | 2 +-
sc/source/ui/src/scfuncs.src | 24 ++++++
sc/source/ui/vba/vbawsfunction.cxx | 2 +-
sc/util/hidother.src | 1 +
15 files changed, 153 insertions(+), 9 deletions(-)
diff --git a/formula/inc/formula/compiler.hrc b/formula/inc/formula/compiler.hrc
index a2d4bb5..54ded84 100644
--- a/formula/inc/formula/compiler.hrc
+++ b/formula/inc/formula/compiler.hrc
@@ -89,7 +89,8 @@
#define SC_OPCODE_INTERSECT 54
#define SC_OPCODE_UNION 55
#define SC_OPCODE_RANGE 56
-#define SC_OPCODE_STOP_BIN_OP 57
+#define SC_OPCODE_XOR 57
+#define SC_OPCODE_STOP_BIN_OP 58
/* NOTE: binary and unary operators must be in sequence for compiler! */
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..e2de107 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:
@@ -1128,6 +1129,7 @@ void FormulaCompiler::Factor()
|| eOp == ocMacro
|| eOp == ocAnd
|| eOp == ocOr
+ || eOp == ocXor
|| eOp == ocBad
|| ( eOp >= ocInternalBegin && eOp <= ocInternalEnd )
|| (bCompileForFAP && ((eOp == ocIf) || (eOp == ocChose)))
@@ -1440,7 +1442,7 @@ OpCode FormulaCompiler::Expression()
return ocStop; //! generate token instead?
}
NotLine();
- while (pToken->GetOpCode() == ocAnd || pToken->GetOpCode() == ocOr)
+ while (pToken->GetOpCode() == ocAnd || pToken->GetOpCode() == ocOr || pToken->GetOpCode() ==
ocXor)
{
FormulaTokenRef p = pToken;
pToken->SetByte( 2 ); // 2 parameters!
@@ -1617,7 +1619,7 @@ FormulaToken* FormulaCompiler::CreateStringFromToken( rtl::OUStringBuffer&
rBuff
bool bSpaces = false;
FormulaToken* t = pTokenP;
OpCode eOp = t->GetOpCode();
- if( eOp >= ocAnd && eOp <= ocOr )
+ if( eOp >= ocAnd && eOp <= ocXor )
{
// AND, OR infix?
if ( bAllowArrAdvance )
@@ -1822,8 +1824,8 @@ OpCode FormulaCompiler::NextToken()
else
{
// Before an operator there must not be another operator, with the
- // exception of AND and OR.
- if ( eOp != ocAnd && eOp != ocOr &&
+ // exception of AND, OR and XOR.
+ if ( eOp != ocAnd && eOp != ocOr && eOp != ocXor &&
(SC_OPCODE_START_BIN_OP <= eOp && eOp < SC_OPCODE_STOP_BIN_OP )
&& (eLastOp == ocOpen || eLastOp == ocSep ||
(SC_OPCODE_START_BIN_OP <= eLastOp && eLastOp < SC_OPCODE_STOP_UN_OP)))
diff --git a/formula/source/core/api/token.cxx b/formula/source/core/api/token.cxx
index f426a31..fac4cbd 100644
--- a/formula/source/core/api/token.cxx
+++ b/formula/source/core/api/token.cxx
@@ -90,7 +90,7 @@ bool FormulaToken::IsFunction() const
|| (SC_OPCODE_START_2_PAR <= eOp && eOp < SC_OPCODE_STOP_2_PAR) // x parameters
(cByte==0 in
// FuncAutoPilot)
|| eOp == ocMacro || eOp == ocExternal // macros, AddIns
- || eOp == ocAnd || eOp == ocOr // former binary, now x parameters
+ || eOp == ocAnd || eOp == ocOr || eOp == ocXor // former binary, now x parameters
|| eOp == ocNot || eOp == ocNeg // unary but function
|| (eOp >= ocInternalBegin && eOp <= ocInternalEnd) // internal
));
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..e966bc3 100644
--- a/sc/inc/helpids.h
+++ b/sc/inc/helpids.h
@@ -88,7 +88,6 @@
#define HID_SC_FORM_ARGS "SC_HID_SC_FORM_ARGS"
#define HID_SCPAGE_SORT_FIELDS "SC_HID_SCPAGE_SORT_FIELDS"
#define HID_SCPAGE_SORT_OPTIONS "SC_HID_SCPAGE_SORT_OPTIONS"
-#define HID_SCPAGE_SORTKEY_FIELDS "SC_HID_SCPAGE_SORTKEY_FIELDS"
#define HID_SCPAGE_SUBT_OPTIONS "SC_HID_SCPAGE_SUBT_OPTIONS"
#define HID_SCPAGE_SUBT_GROUP "SC_HID_SCPAGE_SUBT_GROUP"
#define HID_SCPAGE_PROTECTION "SC_HID_SCPAGE_PROTECTION"
@@ -487,6 +486,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..400b73c 100644
--- a/sc/source/core/tool/interpr1.cxx
+++ b/sc/source/core/tool/interpr1.cxx
@@ -1385,6 +1385,111 @@ 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 = 0;
+ size_t nRefInList = 0;
+ while( nParamCount-- > 0)
+ {
+ if ( !nGlobalError )
+ {
+ switch ( GetStackType() )
+ {
+ case svDouble :
+ bHaveValue = true;
+ if ( PopDouble() != 0.0 )
+ nRes++;
+ break;
+ case svString :
+ Pop();
+ SetError( errNoValue );
+ break;
+ case svSingleRef :
+ {
+ ScAddress aAdr;
+ PopSingleRef( aAdr );
+ if ( !nGlobalError )
+ {
+ ScBaseCell* pCell = GetCell( aAdr );
+ if ( HasCellValueData( pCell ) )
+ {
+ bHaveValue = true;
+ if ( GetCellValue( aAdr, pCell ) != 0.0 )
+ nRes++;
+ }
+ // 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
+ {
+ if ( fVal != 0.0 )
+ nRes++;
+ } 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
+ if (fVal != 0.0)
+ nRes++;
+ }
+ // else: GetMatrix did set errIllegalParameter
+ }
+ break;
+ default:
+ Pop();
+ SetError( errIllegalParameter);
+ }
+ }
+ else
+ Pop();
+ }
+ if ( bHaveValue )
+ PushInt( nRes % 2 );
+ 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..ee2cc4b 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
@@ -498,6 +499,7 @@ void ScParameterClassification::GenerateDocumentation()
{
case ocAnd:
case ocOr:
+ case ocXor:
aToken.SetByte(1); // (r1)AND(r2) --> AND( r1, ...)
break;
default:
diff --git a/sc/source/filter/oox/formulabase.cxx b/sc/source/filter/oox/formulabase.cxx
index b80dbfa..a5276eb 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 ***
@@ -762,7 +763,6 @@ static const FunctionData saFuncTableOdf[] =
{ "SKEWP", 0, NOID, NOID, 1, MX, V, { RX },
FUNCFLAG_MACROCALLODF },
{ "UNICHAR", 0, NOID, NOID, 1, 1, V, { VR },
FUNCFLAG_MACROCALLODF },
{ "UNICODE", 0, NOID, NOID, 1, 1, V, { VR },
FUNCFLAG_MACROCALLODF },
- { "XOR", 0, NOID, NOID, 1, MX, V, { RX },
FUNCFLAG_MACROCALLODF }
};
// ----------------------------------------------------------------------------
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.