summaryrefslogtreecommitdiff
path: root/formula
diff options
context:
space:
mode:
authorEike Rathke <erack@erack.de>2011-08-12 17:48:37 +0200
committerEike Rathke <erack@erack.de>2011-08-14 00:12:45 +0200
commitbaca3632869b2b0b81e5a7dd83b189d3c8367652 (patch)
tree08d0a12349f5245b188f00ef0d40216c8cde0bdb /formula
parent7e8e85adbee73346403c364326544487677cd5c6 (diff)
fdo#37391 write and read [#REF!] in ODFF for reference errors
* write [#REF!] to ODFF when any part of the reference is invalid * read [#REF!] as reference error * display #REF! in UI + parse #REF! in UI + implemented error constants defined in ODFF as error tokens + parse error constants from ODFF and in UI * fixed SUM, AVERAGE, SUMSQ, PRODUCT to propagate error
Diffstat (limited to 'formula')
-rw-r--r--formula/inc/formula/FormulaCompiler.hxx6
-rw-r--r--formula/source/core/api/FormulaCompiler.cxx75
2 files changed, 81 insertions, 0 deletions
diff --git a/formula/inc/formula/FormulaCompiler.hxx b/formula/inc/formula/FormulaCompiler.hxx
index 9ff456beb4d2..e053c57751df 100644
--- a/formula/inc/formula/FormulaCompiler.hxx
+++ b/formula/inc/formula/FormulaCompiler.hxx
@@ -211,6 +211,9 @@ public:
const ::com::sun::star::sheet::FormulaOpCodeMapEntry > & rMapping,
bool bEnglish );
+ /** Get current OpCodeMap in effect. */
+ inline OpCodeMapPtr GetCurrentOpCodeMap() const { return mxSymbols; }
+
/** Get OpCode for English symbol.
Used in XFunctionAccess to create token array.
@param rName
@@ -272,6 +275,9 @@ protected:
virtual void LocalizeString( String& rName ); // modify rName - input: exact name
virtual sal_Bool IsImportingXML() const;
+ sal_uInt16 GetErrorConstant( const String& rName );
+ void AppendErrorConstant( rtl::OUStringBuffer& rBuffer, sal_uInt16 nError );
+
sal_Bool GetToken();
OpCode NextToken();
void PutCode( FormulaTokenRef& );
diff --git a/formula/source/core/api/FormulaCompiler.cxx b/formula/source/core/api/FormulaCompiler.cxx
index 8fd651225676..c1b4e5f9ae3b 100644
--- a/formula/source/core/api/FormulaCompiler.cxx
+++ b/formula/source/core/api/FormulaCompiler.cxx
@@ -825,6 +825,78 @@ void FormulaCompiler::OpCodeMap::copyFrom( const OpCodeMap& r )
// TODO: maybe copy the external maps too?
}
// -----------------------------------------------------------------------------
+
+sal_uInt16 FormulaCompiler::GetErrorConstant( const String& rName )
+{
+ sal_uInt16 nError = 0;
+ OpCodeHashMap::const_iterator iLook( mxSymbols->getHashMap()->find( rName));
+ if (iLook != mxSymbols->getHashMap()->end())
+ {
+ switch ((*iLook).second)
+ {
+ // Not all may make sense in a formula, but these we know as
+ // opcodes.
+ case ocErrNull:
+ nError = errNoCode;
+ break;
+ case ocErrDivZero:
+ nError = errDivisionByZero;
+ break;
+ case ocErrValue:
+ nError = errNoValue;
+ break;
+ case ocErrRef:
+ nError = errNoRef;
+ break;
+ case ocErrName:
+ nError = errNoName;
+ break;
+ case ocErrNum:
+ nError = errIllegalFPOperation;
+ break;
+ case ocErrNA:
+ nError = NOTAVAILABLE;
+ break;
+ default:
+ ; // nothing
+ }
+ }
+ return nError;
+}
+
+
+void FormulaCompiler::AppendErrorConstant( rtl::OUStringBuffer& rBuffer, sal_uInt16 nError )
+{
+ OpCode eOp;
+ switch (nError)
+ {
+ default:
+ case errNoCode:
+ eOp = ocErrNull;
+ break;
+ case errDivisionByZero:
+ eOp = ocErrDivZero;
+ break;
+ case errNoValue:
+ eOp = ocErrValue;
+ break;
+ case errNoRef:
+ eOp = ocErrRef;
+ break;
+ case errNoName:
+ eOp = ocErrName;
+ break;
+ case errIllegalFPOperation:
+ eOp = ocErrNum;
+ break;
+ case NOTAVAILABLE:
+ eOp = ocErrNA;
+ break;
+ }
+ rBuffer.append( mxSymbols->getSymbol( eOp));
+}
+
+// -----------------------------------------------------------------------------
sal_Int32 FormulaCompiler::OpCodeMap::getOpCodeUnknown()
{
static const sal_Int32 kOpCodeUnknown = -1;
@@ -1646,6 +1718,9 @@ FormulaToken* FormulaCompiler::CreateStringFromToken( rtl::OUStringBuffer& rBuff
rBuffer.append(aAddIn);
}
break;
+ case svError:
+ AppendErrorConstant( rBuffer, t->GetError());
+ break;
case svByte:
case svJump:
case svFAP: