summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWinfried Donkers <osc@dci-electronics.nl>2012-06-09 12:43:30 +0200
committerEike Rathke <erack@redhat.com>2012-06-12 22:30:00 +0200
commit033cce3e0fbb72a9400836923be96c5036aaacb0 (patch)
tree9436b0e5e28152fc0dce036e89fa0722babebe46
parenta741932eb4e83148a341cfd5c6a30ff1878e3149 (diff)
fdo#50822 add function XOR to calc as in ODFF1.2
Change-Id: I994119c0520658775d07f776237d31a03f53ab52
-rw-r--r--formula/inc/formula/compiler.hrc5
-rw-r--r--formula/inc/formula/opcode.hxx1
-rw-r--r--formula/source/core/api/FormulaCompiler.cxx1
-rw-r--r--formula/source/core/resource/core_resource.src5
-rw-r--r--sc/inc/helpids.h1
-rw-r--r--sc/qa/unit/ucalc.cxx1
-rw-r--r--sc/source/core/inc/interpre.hxx1
-rw-r--r--sc/source/core/tool/interpr1.cxx101
-rw-r--r--sc/source/core/tool/interpr4.cxx1
-rw-r--r--sc/source/core/tool/parclass.cxx1
-rw-r--r--sc/source/filter/oox/formulabase.cxx1
-rw-r--r--sc/source/ui/src/scfuncs.src24
-rw-r--r--sc/source/ui/vba/vbawsfunction.cxx2
-rw-r--r--sc/util/hidother.src1
14 files changed, 143 insertions, 3 deletions
diff --git a/formula/inc/formula/compiler.hrc b/formula/inc/formula/compiler.hrc
index a2d4bb52f10f..4babe0ed4fe5 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 a1543ddcb427..16b12ece14a2 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 9e82422d1025..042e49b9f7e6 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 12592316e384..b4ea3457a44f 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 7c5955c240c4..e2f6e0612468 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 d37e3f15ba55..1db6294caec1 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 c92ad0c95a0e..de577ca9a99e 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 3d62b5140ba0..fd44da1336ec 100644
--- a/sc/source/core/tool/interpr1.cxx
+++ b/sc/source/core/tool/interpr1.cxx
@@ -1383,6 +1383,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 217dfa0a7f76..a6d169315926 100644
--- a/sc/source/core/tool/interpr4.cxx
+++ b/sc/source/core/tool/interpr4.cxx
@@ -3808,6 +3808,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 4d516e1ea125..03775bf34016 100644
--- a/sc/source/core/tool/parclass.cxx
+++ b/sc/source/core/tool/parclass.cxx
@@ -191,6 +191,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 b80dbfaaf7b2..381d74d1df54 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 53780de1be65..60f8fcac85f6 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 0692afb21a20..3a236b388386 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 85d36f913977..6a56a8188c6a 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; };