summaryrefslogtreecommitdiff
path: root/sc
diff options
context:
space:
mode:
authorKurt Zenker <kz@openoffice.org>2009-09-11 18:55:06 +0000
committerKurt Zenker <kz@openoffice.org>2009-09-11 18:55:06 +0000
commit6c08543a370b759d495b0f4a593b1f7cd329de64 (patch)
tree7e33d6f928c03c1201008de2f38907b7dcd63a1c /sc
parent921ff4b99a018c4d45c6d8d810fc96130c1b3a70 (diff)
CWS-TOOLING: integrate CWS odff06
2009-09-10 18:58:49 +0200 dr r276042 : #i104954# excel export: fixed broken handling of unary operators 2009-09-06 19:30:43 +0200 er r275861 : warnings 2009-09-05 19:48:41 +0200 er r275849 : warnings; wntmsci12 tries to be too smart 2009-09-05 19:37:47 +0200 er r275848 : warnings 2009-09-03 22:45:42 +0200 er r275776 : #i5658# GetCellValueOrZero: missed the formula cell case 2009-09-03 14:28:41 +0200 er r275752 : #i90759# better description of ZTEST 2009-09-03 03:34:03 +0200 er r275739 : warnings 2009-09-03 03:31:19 +0200 er r275738 : warnings 2009-09-03 03:16:46 +0200 er r275737 : warnings 2009-09-03 03:11:42 +0200 er r275736 : CELLTYPE_DESTROYED only if DBG_UTIL 2009-09-03 03:06:31 +0200 er r275735 : warnings 2009-09-03 03:00:30 +0200 er r275734 : warnings 2009-09-03 02:32:35 +0200 er r275733 : fix broken rebase merge 2009-09-02 22:27:53 +0200 er r275730 : CWS-TOOLING: rebase CWS odff06 to trunk@275331 (milestone: DEV300:m56) 2009-09-02 14:45:05 +0200 er r275712 : #i5658# calculate with string operands as long as they unambiguously represent an integer or ISO 8601 date and/or time value 2009-08-29 22:05:31 +0200 er r275559 : #i99140# CONVERT_ADD new conversions as per ODFF; patch from <lvyue>, slightly changed 2009-08-25 13:23:59 +0200 er r275349 : #i90759# rewording of ZTEST description 2009-08-21 00:10:22 +0200 er r275204 : #i82007# correct description of POWER and parameters; patch from <regina> 2009-08-20 23:58:20 +0200 er r275203 : #i74704# B correct calculation for SP arguments 0 and 1; patch from <regina> 2009-08-20 22:58:57 +0200 er r275201 : #i90759# ZTEST correct calculation using the 3rd parameter sigma 2009-08-14 17:55:45 +0200 er r275000 : #i81214# LOOKUP with single values, data arrays and result arrays; based on a patch from <lvyue> 2009-08-11 00:47:48 +0200 er r274845 : unxlngi6 compiler warnings 2009-08-11 00:43:06 +0200 er r274844 : unxlngi6 compiler warnings 2009-08-10 23:59:05 +0200 er r274843 : #91351# make HYPERLINK accept and return numeric values, propagate errors 2009-07-08 18:46:00 +0200 dr r273846 : #i102022# export 3D refs to cond. formats and data validation 2009-07-02 17:59:40 +0200 dr r273667 : #i102702# adapt changes from sc/source/filter/excel 2009-07-02 15:20:37 +0200 dr r273656 : #i102702# reimplementation of formula token class export 2009-07-02 14:41:02 +0200 er r273653 : a surrogate with value 0x10000 is also valid (ran into when testing #i99900# Calc's UNICHAR function), and Unicode ends at 0x10ffff 2009-07-01 00:10:16 +0200 er r273536 : #i99900# iterateCodePoints: check index against string length to avoid assertion; caught this when testing Calc's new UNICHAR function, with the result of a surrogate pair forming one character. 2009-07-01 00:03:57 +0200 er r273535 : #i99900# new UNICODE and UNICHAR functions; patch from <tanchengbiao> 2009-06-15 16:42:06 +0200 er r272999 : merge patch from #i102701 2009-06-15 11:15:16 +0200 dr r272970 : #i102702# in BIFF, the SKIP flag may be missing for the tAttrSkip token 2009-06-11 13:27:46 +0200 er r272867 : CWS-TOOLING: rebase CWS odff06 to trunk@272827 (milestone: DEV300:m50) 2009-04-30 18:28:02 +0200 er r271423 : #i94618# on status bar, ignore error of cell for COUNT and COUNTA if selection; patch from <kohei> 2009-04-30 13:58:44 +0200 er r271413 : get rid of that ugly mail address thingie in RTL_LOGFILE_CONTEXT_AUTHOR introduced by CWS frmdlg ... 2009-04-30 12:32:44 +0200 er r271411 : #i94618# do not display error of cell for COUNT and COUNTA status bar functions 2009-04-30 01:32:38 +0200 er r271399 : #i101316# improve accuracy of STDEV on equal values; patch from <regina> 2009-04-30 01:18:54 +0200 er r271398 : #i97605# improve accuracy of ASINH and ACOSH; patch from <regina> 2009-04-30 00:46:00 +0200 er r271397 : #i59153# improve accuracy of MOD; patch from <regina> 2009-04-30 00:29:43 +0200 er r271396 : #i69069# improve accuracy of NORMSDIST and POISSON; patch from <regina> 2009-04-29 23:53:28 +0200 er r271395 : #i100119# NORMDIST and LOGNORMDIST optional parameters, plus improvement in accuracy also of NORMSDIST (part of i69069); patch from <regina> 2009-04-28 18:22:07 +0200 er r271337 : #i97052# REPLACE with no length of text to be removed simply inserts new text; patch from <lvyue>, slightly modified 2009-03-24 17:29:36 +0100 er r269982 : #i97091# moved implementation of erf() and erfc() from scaddins to sal to provide C99 functions for compilers lacking it
Diffstat (limited to 'sc')
-rw-r--r--sc/source/core/inc/interpre.hxx16
-rw-r--r--sc/source/core/inc/parclass.hxx11
-rw-r--r--sc/source/core/tool/interpr1.cxx565
-rw-r--r--sc/source/core/tool/interpr2.cxx281
-rw-r--r--sc/source/core/tool/interpr3.cxx315
-rw-r--r--sc/source/core/tool/interpr4.cxx397
-rw-r--r--sc/source/core/tool/interpr5.cxx82
-rw-r--r--sc/source/core/tool/interpr6.cxx12
-rw-r--r--sc/source/core/tool/parclass.cxx263
-rw-r--r--sc/source/filter/excel/xeformula.cxx2032
-rw-r--r--sc/source/filter/excel/xlformula.cxx569
-rw-r--r--sc/source/filter/inc/xlformula.hxx173
-rw-r--r--sc/source/ui/inc/tabvwsh.hxx2
-rw-r--r--sc/source/ui/src/scfuncs.src42
-rw-r--r--sc/source/ui/view/cellsh.cxx12
-rw-r--r--sc/source/ui/view/tabvwsha.cxx16
16 files changed, 2790 insertions, 1998 deletions
diff --git a/sc/source/core/inc/interpre.hxx b/sc/source/core/inc/interpre.hxx
index 9fcf743c1e85..659884dfd5de 100644
--- a/sc/source/core/inc/interpre.hxx
+++ b/sc/source/core/inc/interpre.hxx
@@ -193,6 +193,7 @@ void ReplaceCell( ScAddress& ); // for TableOp
void ReplaceCell( SCCOL& rCol, SCROW& rRow, SCTAB& rTab ); // for TableOp
BOOL IsTableOpInRange( const ScRange& );
ULONG GetCellNumberFormat( const ScAddress&, const ScBaseCell* );
+double ConvertStringToValue( const String& );
double GetCellValue( const ScAddress&, const ScBaseCell* );
double GetCellValueOrZero( const ScAddress&, const ScBaseCell* );
double GetValueCellValue( const ScAddress&, const ScValueCell* );
@@ -453,6 +454,8 @@ void ScClean();
void ScChar();
void ScJis();
void ScAsc();
+void ScUnicode();
+void ScUnichar();
void ScMin( BOOL bTextAsZero = FALSE );
void ScMax( BOOL bTextAsZero = FALSE );
double IterateParameters( ScIterFunc, BOOL bTextAsZero = FALSE );
@@ -542,7 +545,17 @@ void ScSpewFunc();
void ScGame();
//----------------Funktionen in interpr2.cxx---------------
-double GetDate(INT16 nYear, INT16 nMonth, INT16 nDay);
+
+/** Obtain the date serial number for a given date.
+ @param bStrict
+ If FALSE, nYear < 100 takes the two-digit year setting into account,
+ and rollover of invalid calendar dates takes place, e.g. 1999-02-31 =>
+ 1999-03-03.
+ If TRUE, the date passed must be a valid Gregorian calendar date. No
+ two-digit expanding or rollover is done.
+ */
+double GetDateSerial( INT16 nYear, INT16 nMonth, INT16 nDay, bool bStrict );
+
void ScGetActDate();
void ScGetActTime();
void ScGetYear();
@@ -682,6 +695,7 @@ void ScNoName();
void ScBadName();
// Statistik:
double phi(double x);
+double integralPhi(double x);
double taylor(double* pPolynom, USHORT nMax, double x);
double gauss(double x);
double gaussinv(double x);
diff --git a/sc/source/core/inc/parclass.hxx b/sc/source/core/inc/parclass.hxx
index be66587b4c0e..c72bcece7f19 100644
--- a/sc/source/core/inc/parclass.hxx
+++ b/sc/source/core/inc/parclass.hxx
@@ -72,7 +72,14 @@ public:
/** Area reference must be converted to array in any case, and must
also be propagated to subsequent operators and functions being part
of a parameter of this function. */
- ForceArray
+ ForceArray,
+
+ /** Area reference is not converted to array, but ForceArray must be
+ propagated to subsequent operators and functions being part of a
+ parameter of this function. Used with functions that treat
+ references separately from arrays, but need the forced array
+ calculation of parameters that are not references.*/
+ ReferenceOrForceArray
};
/// MUST be called once before any other method.
@@ -87,7 +94,7 @@ public:
USHORT nParameter);
/** Whether OpCode has a parameter of type
- ForceArray. */
+ ForceArray or ReferenceOrForceArray. */
static inline bool HasForceArray( OpCode eOp)
{
return 0 <= (short)eOp &&
diff --git a/sc/source/core/tool/interpr1.cxx b/sc/source/core/tool/interpr1.cxx
index 1145fe2ed3c4..9c604d9a07e4 100644
--- a/sc/source/core/tool/interpr1.cxx
+++ b/sc/source/core/tool/interpr1.cxx
@@ -45,6 +45,7 @@
#include <sfx2/printer.hxx>
#include <unotools/collatorwrapper.hxx>
#include <unotools/transliterationwrapper.hxx>
+#include <rtl/ustring.hxx>
#include <rtl/logfile.hxx>
#include "interpre.hxx"
@@ -89,7 +90,7 @@ using namespace formula;
void ScInterpreter::ScIfJump()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScIfJump" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScIfJump" );
const short* pJump = pCur->GetJump();
short nJumpCount = pJump[ 0 ];
MatrixDoubleRefToMatrix();
@@ -219,7 +220,7 @@ void ScInterpreter::ScIfJump()
void ScInterpreter::ScChoseJump()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScChoseJump" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScChoseJump" );
// We have to set a jump, if there was none chosen because of an error set
// it to endpoint.
bool bHaveJump = false;
@@ -350,7 +351,7 @@ void lcl_AdjustJumpMatrix( ScJumpMatrix* pJumpM, ScMatrixRef& pResMat, SCSIZE nP
bool ScInterpreter::JumpMatrix( short nStackLevel )
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::JumpMatrix" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::JumpMatrix" );
pJumpMatrix = static_cast<ScToken*>(pStack[sp-nStackLevel])->GetJumpMatrix();
ScMatrixRef pResMat = pJumpMatrix->GetResultMatrix();
SCSIZE nC, nR;
@@ -642,7 +643,7 @@ ScCompareOptions::ScCompareOptions( ScDocument* pDoc, const ScQueryEntry& rEntry
double ScInterpreter::CompareFunc( const ScCompare& rComp, ScCompareOptions* pOptions )
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::CompareFunc" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::CompareFunc" );
// Keep DoubleError if encountered
// #i40539# if bEmpty is set, bVal/nVal are uninitialized
if ( !rComp.bEmpty[0] && rComp.bVal[0] && !::rtl::math::isFinite( rComp.nVal[0]))
@@ -771,7 +772,7 @@ double ScInterpreter::CompareFunc( const ScCompare& rComp, ScCompareOptions* pOp
double ScInterpreter::Compare()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::Compare" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::Compare" );
String aVal1, aVal2;
ScCompare aComp( &aVal1, &aVal2 );
for( short i = 1; i >= 0; i-- )
@@ -825,7 +826,7 @@ double ScInterpreter::Compare()
ScMatrixRef ScInterpreter::CompareMat( ScCompareOptions* pOptions )
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::CompareMat" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::CompareMat" );
String aVal1, aVal2;
ScCompare aComp( &aVal1, &aVal2 );
ScMatrixRef pMat[2];
@@ -1002,7 +1003,7 @@ ScMatrixRef ScInterpreter::QueryMat( ScMatrix* pMat, ScCompareOptions& rOptions
void ScInterpreter::ScEqual()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScEqual" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScEqual" );
if ( GetStackType(1) == svMatrix || GetStackType(2) == svMatrix )
{
ScMatrixRef pMat = CompareMat();
@@ -1021,7 +1022,7 @@ void ScInterpreter::ScEqual()
void ScInterpreter::ScNotEqual()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScNotEqual" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScNotEqual" );
if ( GetStackType(1) == svMatrix || GetStackType(2) == svMatrix )
{
ScMatrixRef pMat = CompareMat();
@@ -1040,7 +1041,7 @@ void ScInterpreter::ScNotEqual()
void ScInterpreter::ScLess()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScLess" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScLess" );
if ( GetStackType(1) == svMatrix || GetStackType(2) == svMatrix )
{
ScMatrixRef pMat = CompareMat();
@@ -1059,7 +1060,7 @@ void ScInterpreter::ScLess()
void ScInterpreter::ScGreater()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScGreater" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScGreater" );
if ( GetStackType(1) == svMatrix || GetStackType(2) == svMatrix )
{
ScMatrixRef pMat = CompareMat();
@@ -1078,7 +1079,7 @@ void ScInterpreter::ScGreater()
void ScInterpreter::ScLessEqual()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScLessEqual" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScLessEqual" );
if ( GetStackType(1) == svMatrix || GetStackType(2) == svMatrix )
{
ScMatrixRef pMat = CompareMat();
@@ -1097,7 +1098,7 @@ void ScInterpreter::ScLessEqual()
void ScInterpreter::ScGreaterEqual()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScGreaterEqual" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScGreaterEqual" );
if ( GetStackType(1) == svMatrix || GetStackType(2) == svMatrix )
{
ScMatrixRef pMat = CompareMat();
@@ -1116,7 +1117,7 @@ void ScInterpreter::ScGreaterEqual()
void ScInterpreter::ScAnd()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScAnd" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScAnd" );
nFuncFmtType = NUMBERFORMAT_LOGICAL;
short nParamCount = GetByte();
if ( MustHaveParamCountMin( nParamCount, 1 ) )
@@ -1214,7 +1215,7 @@ void ScInterpreter::ScAnd()
void ScInterpreter::ScOr()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScOr" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScOr" );
nFuncFmtType = NUMBERFORMAT_LOGICAL;
short nParamCount = GetByte();
if ( MustHaveParamCountMin( nParamCount, 1 ) )
@@ -1313,7 +1314,7 @@ void ScInterpreter::ScOr()
void ScInterpreter::ScNeg()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScNeg" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScNeg" );
// Simple negation doesn't change current format type to number, keep
// current type.
nFuncFmtType = nCurFmtType;
@@ -1355,7 +1356,7 @@ void ScInterpreter::ScNeg()
void ScInterpreter::ScPercentSign()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScPercentSign" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScPercentSign" );
nFuncFmtType = NUMBERFORMAT_PERCENT;
const FormulaToken* pSaveCur = pCur;
BYTE nSavePar = cPar;
@@ -1371,7 +1372,7 @@ void ScInterpreter::ScPercentSign()
void ScInterpreter::ScNot()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScNot" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScNot" );
nFuncFmtType = NUMBERFORMAT_LOGICAL;
switch ( GetStackType() )
{
@@ -1411,21 +1412,21 @@ void ScInterpreter::ScNot()
void ScInterpreter::ScPi()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScPi" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScPi" );
PushDouble(F_PI);
}
void ScInterpreter::ScRandom()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScRandom" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScRandom" );
PushDouble((double)rand() / ((double)RAND_MAX+1.0));
}
void ScInterpreter::ScTrue()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScTrue" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScTrue" );
nFuncFmtType = NUMBERFORMAT_LOGICAL;
PushInt(1);
}
@@ -1433,7 +1434,7 @@ void ScInterpreter::ScTrue()
void ScInterpreter::ScFalse()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScFalse" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScFalse" );
nFuncFmtType = NUMBERFORMAT_LOGICAL;
PushInt(0);
}
@@ -1441,124 +1442,121 @@ void ScInterpreter::ScFalse()
void ScInterpreter::ScDeg()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScDeg" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScDeg" );
PushDouble((GetDouble() / F_PI) * 180.0);
}
void ScInterpreter::ScRad()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScRad" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScRad" );
PushDouble(GetDouble() * (F_PI / 180));
}
void ScInterpreter::ScSin()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScSin" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScSin" );
PushDouble(::rtl::math::sin(GetDouble()));
}
void ScInterpreter::ScCos()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScCos" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScCos" );
PushDouble(::rtl::math::cos(GetDouble()));
}
void ScInterpreter::ScTan()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScTan" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScTan" );
PushDouble(::rtl::math::tan(GetDouble()));
}
void ScInterpreter::ScCot()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScCot" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScCot" );
PushDouble(1.0 / ::rtl::math::tan(GetDouble()));
}
void ScInterpreter::ScArcSin()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScArcSin" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScArcSin" );
PushDouble(asin(GetDouble()));
}
void ScInterpreter::ScArcCos()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScArcCos" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScArcCos" );
PushDouble(acos(GetDouble()));
}
void ScInterpreter::ScArcTan()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScArcTan" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScArcTan" );
PushDouble(atan(GetDouble()));
}
void ScInterpreter::ScArcCot()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScArcCot" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScArcCot" );
PushDouble((F_PI2) - atan(GetDouble()));
}
void ScInterpreter::ScSinHyp()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScSinHyp" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScSinHyp" );
PushDouble(sinh(GetDouble()));
}
void ScInterpreter::ScCosHyp()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScCosHyp" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScCosHyp" );
PushDouble(cosh(GetDouble()));
}
void ScInterpreter::ScTanHyp()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScTanHyp" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScTanHyp" );
PushDouble(tanh(GetDouble()));
}
void ScInterpreter::ScCotHyp()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScCotHyp" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScCotHyp" );
PushDouble(1.0 / tanh(GetDouble()));
}
void ScInterpreter::ScArcSinHyp()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScArcSinHyp" );
- double nVal = GetDouble();
- PushDouble(log(nVal + sqrt((nVal * nVal) + 1.0)));
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScArcSinHyp" );
+ PushDouble( ::rtl::math::asinh( GetDouble()));
}
-
void ScInterpreter::ScArcCosHyp()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScArcCosHyp" );
- double nVal = GetDouble();
- if (nVal < 1.0)
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScArcCosHyp" );
+ double fVal = GetDouble();
+ if (fVal < 1.0)
PushIllegalArgument();
else
- PushDouble(log(nVal + sqrt((nVal * nVal) - 1.0)));
+ PushDouble( ::rtl::math::acosh( fVal));
}
-
void ScInterpreter::ScArcTanHyp()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScArcTanHyp" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScArcTanHyp" );
double fVal = GetDouble();
if (fabs(fVal) >= 1.0)
PushIllegalArgument();
@@ -1569,7 +1567,7 @@ void ScInterpreter::ScArcTanHyp()
void ScInterpreter::ScArcCotHyp()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScArcCotHyp" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScArcCotHyp" );
double nVal = GetDouble();
if (fabs(nVal) <= 1.0)
PushIllegalArgument();
@@ -1580,14 +1578,14 @@ void ScInterpreter::ScArcCotHyp()
void ScInterpreter::ScExp()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScExp" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScExp" );
PushDouble(exp(GetDouble()));
}
void ScInterpreter::ScSqrt()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScSqrt" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScSqrt" );
double fVal = GetDouble();
if (fVal >= 0.0)
PushDouble(sqrt(fVal));
@@ -1598,7 +1596,7 @@ void ScInterpreter::ScSqrt()
void ScInterpreter::ScIsEmpty()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScIsEmpty" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScIsEmpty" );
short nRes = 0;
nFuncFmtType = NUMBERFORMAT_LOGICAL;
switch ( GetRawStackType() )
@@ -1653,7 +1651,7 @@ void ScInterpreter::ScIsEmpty()
short ScInterpreter::IsString()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::IsString" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::IsString" );
nFuncFmtType = NUMBERFORMAT_LOGICAL;
short nRes = 0;
switch ( GetRawStackType() )
@@ -1714,21 +1712,21 @@ short ScInterpreter::IsString()
void ScInterpreter::ScIsString()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScIsString" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScIsString" );
PushInt( IsString() );
}
void ScInterpreter::ScIsNonString()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScIsNonString" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScIsNonString" );
PushInt( !IsString() );
}
void ScInterpreter::ScIsLogical()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScIsLogical" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScIsLogical" );
short nRes = 0;
switch ( GetStackType() )
{
@@ -1767,7 +1765,7 @@ void ScInterpreter::ScIsLogical()
void ScInterpreter::ScType()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScType" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScType" );
short nType = 0;
switch ( GetStackType() )
{
@@ -2065,7 +2063,7 @@ void ScInterpreter::ScCell()
void ScInterpreter::ScIsRef()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScCell" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScCell" );
nFuncFmtType = NUMBERFORMAT_LOGICAL;
short nRes = 0;
switch ( GetStackType() )
@@ -2103,7 +2101,7 @@ void ScInterpreter::ScIsRef()
void ScInterpreter::ScIsValue()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScIsValue" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScIsValue" );
nFuncFmtType = NUMBERFORMAT_LOGICAL;
short nRes = 0;
switch ( GetRawStackType() )
@@ -2167,7 +2165,7 @@ void ScInterpreter::ScIsValue()
void ScInterpreter::ScIsFormula()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScIsFormula" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScIsFormula" );
nFuncFmtType = NUMBERFORMAT_LOGICAL;
short nRes = 0;
switch ( GetStackType() )
@@ -2191,7 +2189,7 @@ void ScInterpreter::ScIsFormula()
void ScInterpreter::ScFormula()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScFormula" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScFormula" );
String aFormula;
switch ( GetStackType() )
{
@@ -2223,7 +2221,7 @@ void ScInterpreter::ScFormula()
void ScInterpreter::ScIsNV()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScIsNV" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScIsNV" );
nFuncFmtType = NUMBERFORMAT_LOGICAL;
short nRes = 0;
switch ( GetStackType() )
@@ -2272,7 +2270,7 @@ void ScInterpreter::ScIsNV()
void ScInterpreter::ScIsErr()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScIsErr" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScIsErr" );
nFuncFmtType = NUMBERFORMAT_LOGICAL;
short nRes = 0;
switch ( GetStackType() )
@@ -2327,7 +2325,7 @@ void ScInterpreter::ScIsErr()
void ScInterpreter::ScIsError()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScIsError" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScIsError" );
nFuncFmtType = NUMBERFORMAT_LOGICAL;
short nRes = 0;
switch ( GetStackType() )
@@ -2379,7 +2377,7 @@ void ScInterpreter::ScIsError()
short ScInterpreter::IsEven()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::IsEven" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::IsEven" );
nFuncFmtType = NUMBERFORMAT_LOGICAL;
short nRes = 0;
double fVal = 0.0;
@@ -2462,21 +2460,21 @@ short ScInterpreter::IsEven()
void ScInterpreter::ScIsEven()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScIsEven" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScIsEven" );
PushInt( IsEven() );
}
void ScInterpreter::ScIsOdd()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScIsOdd" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScIsOdd" );
PushInt( !IsEven() );
}
void ScInterpreter::ScN()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScN" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScN" );
USHORT nErr = nGlobalError;
nGlobalError = 0;
double fVal;
@@ -2515,7 +2513,7 @@ void ScInterpreter::ScTrim()
void ScInterpreter::ScUpper()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScTrim" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScTrim" );
String aString = GetString();
ScGlobal::pCharClass->toUpper(aString);
PushString(aString);
@@ -2524,7 +2522,7 @@ void ScInterpreter::ScUpper()
void ScInterpreter::ScPropper()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScPropper" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScPropper" );
//2do: what to do with I18N-CJK ?!?
String aStr( GetString() );
const xub_StrLen nLen = aStr.Len();
@@ -2557,7 +2555,7 @@ void ScInterpreter::ScPropper()
void ScInterpreter::ScLower()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScLower" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScLower" );
String aString( GetString() );
ScGlobal::pCharClass->toLower(aString);
PushString(aString);
@@ -2566,7 +2564,7 @@ void ScInterpreter::ScLower()
void ScInterpreter::ScLen()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScLen" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScLen" );
String aStr( GetString() );
PushDouble( aStr.Len() );
}
@@ -2574,7 +2572,7 @@ void ScInterpreter::ScLen()
void ScInterpreter::ScT()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScT" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScT" );
switch ( GetStackType() )
{
case svDoubleRef :
@@ -2629,7 +2627,7 @@ void ScInterpreter::ScT()
void ScInterpreter::ScValue()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScValue" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScValue" );
String aInputString;
double fVal;
@@ -2711,7 +2709,7 @@ inline BOOL lcl_ScInterpreter_IsPrintable( sal_Unicode c )
void ScInterpreter::ScClean()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScClean" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScClean" );
String aStr( GetString() );
for ( xub_StrLen i = 0; i < aStr.Len(); i++ )
{
@@ -2724,7 +2722,7 @@ void ScInterpreter::ScClean()
void ScInterpreter::ScCode()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScCode" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScCode" );
//2do: make it full range unicode?
const String& rStr = GetString();
PushInt( (sal_uChar) ByteString::ConvertFromUnicode( rStr.GetChar(0), gsl_getSystemTextEncoding() ) );
@@ -2733,7 +2731,7 @@ void ScInterpreter::ScCode()
void ScInterpreter::ScChar()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScChar" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScChar" );
//2do: make it full range unicode?
double fVal = GetDouble();
if (fVal < 0.0 || fVal >= 256.0)
@@ -2793,7 +2791,7 @@ static ::rtl::OUString lcl_convertIntoFullWidth( const ::rtl::OUString & rStr )
*/
void ScInterpreter::ScJis()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScJis" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScJis" );
if (MustHaveParamCount( GetByte(), 1))
PushString( lcl_convertIntoFullWidth( GetString()));
}
@@ -2807,15 +2805,48 @@ void ScInterpreter::ScJis()
*/
void ScInterpreter::ScAsc()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScAsc" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScAsc" );
if (MustHaveParamCount( GetByte(), 1))
PushString( lcl_convertIntoHalfWidth( GetString()));
}
+void ScInterpreter::ScUnicode()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScUnicode" );
+ if ( MustHaveParamCount( GetByte(), 1 ) )
+ {
+ const rtl::OUString& rStr = GetString();
+ if (rStr.getLength() <= 0)
+ PushIllegalParameter();
+ else
+ {
+ sal_Int32 i = 0;
+ PushDouble( rStr.iterateCodePoints(&i) );
+ }
+ }
+}
+
+void ScInterpreter::ScUnichar()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScUnichar" );
+ if ( MustHaveParamCount( GetByte(), 1 ) )
+ {
+ double dVal = ::rtl::math::approxFloor( GetDouble() );
+ if ((dVal < 0x000000) || (dVal > 0x10FFFF))
+ PushIllegalArgument();
+ else
+ {
+ sal_uInt32 nCodePoint = static_cast<sal_uInt32>( dVal );
+ rtl::OUString aStr( &nCodePoint, 1 );
+ PushString( aStr );
+ }
+ }
+}
+
void ScInterpreter::ScMin( BOOL bTextAsZero )
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScMin" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScMin" );
short nParamCount = GetByte();
if (!MustHaveParamCountMin( nParamCount, 1))
return;
@@ -2940,7 +2971,7 @@ void ScInterpreter::ScMin( BOOL bTextAsZero )
void ScInterpreter::ScMax( BOOL bTextAsZero )
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScMax" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScMax" );
short nParamCount = GetByte();
if (!MustHaveParamCountMin( nParamCount, 1))
return;
@@ -3065,7 +3096,7 @@ void ScInterpreter::ScMax( BOOL bTextAsZero )
double ScInterpreter::IterateParameters( ScIterFunc eFunc, BOOL bTextAsZero )
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::IterateParameters" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::IterateParameters" );
short nParamCount = GetByte();
double fRes = ( eFunc == ifPRODUCT ) ? 1.0 : 0.0;
double fVal = 0.0;
@@ -3377,42 +3408,42 @@ double ScInterpreter::IterateParameters( ScIterFunc eFunc, BOOL bTextAsZero )
void ScInterpreter::ScSumSQ()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScSumSQ" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScSumSQ" );
PushDouble( IterateParameters( ifSUMSQ ) );
}
void ScInterpreter::ScSum()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScSum" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScSum" );
PushDouble( IterateParameters( ifSUM ) );
}
void ScInterpreter::ScProduct()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScProduct" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScProduct" );
PushDouble( IterateParameters( ifPRODUCT ) );
}
void ScInterpreter::ScAverage( BOOL bTextAsZero )
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScAverage" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScAverage" );
PushDouble( IterateParameters( ifAVERAGE, bTextAsZero ) );
}
void ScInterpreter::ScCount()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScCount" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScCount" );
PushDouble( IterateParameters( ifCOUNT ) );
}
void ScInterpreter::ScCount2()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScCount2" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScCount2" );
PushDouble( IterateParameters( ifCOUNT2 ) );
}
@@ -3420,7 +3451,7 @@ void ScInterpreter::ScCount2()
void ScInterpreter::GetStVarParams( double& rVal, double& rValCount,
BOOL bTextAsZero )
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::GetStVarParams" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::GetStVarParams" );
short nParamCount = GetByte();
std::vector<double> values;
@@ -3529,15 +3560,14 @@ void ScInterpreter::GetStVarParams( double& rVal, double& rValCount,
::std::vector<double>::size_type n = values.size();
vMean = fSum / n;
for (::std::vector<double>::size_type i = 0; i < n; i++)
- vSum += (values[i] - vMean) * (values[i] - vMean);
-
+ vSum += ::rtl::math::approxSub( values[i], vMean) * ::rtl::math::approxSub( values[i], vMean);
rVal = vSum;
}
void ScInterpreter::ScVar( BOOL bTextAsZero )
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScVar" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScVar" );
double nVal;
double nValCount;
GetStVarParams( nVal, nValCount, bTextAsZero );
@@ -3551,7 +3581,7 @@ void ScInterpreter::ScVar( BOOL bTextAsZero )
void ScInterpreter::ScVarP( BOOL bTextAsZero )
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScVarP" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScVarP" );
double nVal;
double nValCount;
GetStVarParams( nVal, nValCount, bTextAsZero );
@@ -3562,7 +3592,7 @@ void ScInterpreter::ScVarP( BOOL bTextAsZero )
void ScInterpreter::ScStDev( BOOL bTextAsZero )
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScStDev" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScStDev" );
double nVal;
double nValCount;
GetStVarParams( nVal, nValCount, bTextAsZero );
@@ -3575,7 +3605,7 @@ void ScInterpreter::ScStDev( BOOL bTextAsZero )
void ScInterpreter::ScStDevP( BOOL bTextAsZero )
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScStDevP" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScStDevP" );
double nVal;
double nValCount;
GetStVarParams( nVal, nValCount, bTextAsZero );
@@ -3605,7 +3635,7 @@ void ScInterpreter::ScStDevP( BOOL bTextAsZero )
void ScInterpreter::ScColumns()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScColumns" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScColumns" );
BYTE nParamCount = GetByte();
ULONG nVal = 0;
SCCOL nCol1;
@@ -3649,7 +3679,7 @@ void ScInterpreter::ScColumns()
void ScInterpreter::ScRows()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScRows" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScRows" );
BYTE nParamCount = GetByte();
ULONG nVal = 0;
SCCOL nCol1;
@@ -3692,7 +3722,7 @@ void ScInterpreter::ScRows()
void ScInterpreter::ScTables()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScTables" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScTables" );
BYTE nParamCount = GetByte();
ULONG nVal;
if ( nParamCount == 0 )
@@ -3734,7 +3764,7 @@ void ScInterpreter::ScTables()
void ScInterpreter::ScColumn()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScColumn" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScColumn" );
BYTE nParamCount = GetByte();
if ( MustHaveParamCount( nParamCount, 0, 1 ) )
{
@@ -3810,7 +3840,7 @@ void ScInterpreter::ScColumn()
void ScInterpreter::ScRow()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScRow" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScRow" );
BYTE nParamCount = GetByte();
if ( MustHaveParamCount( nParamCount, 0, 1 ) )
{
@@ -3885,7 +3915,7 @@ void ScInterpreter::ScRow()
void ScInterpreter::ScTable()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScTable" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScTable" );
BYTE nParamCount = GetByte();
if ( MustHaveParamCount( nParamCount, 0, 1 ) )
{
@@ -4034,7 +4064,7 @@ static void lcl_GetLastMatch( SCSIZE& rIndex, const ScMatrix& rMat,
void ScInterpreter::ScMatch()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScMatch" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScMatch" );
ScMatrixRef pMatSrc = NULL;
BYTE nParamCount = GetByte();
@@ -4293,7 +4323,7 @@ void ScInterpreter::ScMatch()
void ScInterpreter::ScCountEmptyCells()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScCountEmptyCells" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScCountEmptyCells" );
if ( MustHaveParamCount( GetByte(), 1 ) )
{
ULONG nMaxCount = 0, nCount = 0;
@@ -4346,7 +4376,7 @@ void ScInterpreter::ScCountEmptyCells()
void ScInterpreter::ScCountIf()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScCountIf" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScCountIf" );
if ( MustHaveParamCount( GetByte(), 2 ) )
{
String rString;
@@ -4538,7 +4568,7 @@ void ScInterpreter::ScCountIf()
void ScInterpreter::ScSumIf()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScSumIf" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScSumIf" );
BYTE nParamCount = GetByte();
if ( MustHaveParamCount( nParamCount, 2, 3 ) )
{
@@ -4905,7 +4935,7 @@ void ScInterpreter::ScSumIf()
void ScInterpreter::ScLookup()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScLookup" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScLookup" );
BYTE nParamCount = GetByte();
if ( !MustHaveParamCount( nParamCount, 2, 3 ) )
return ;
@@ -4917,9 +4947,16 @@ void ScInterpreter::ScLookup()
SCSIZE nLenMajor = 0; // length of major direction
bool bVertical = true; // whether to lookup vertically or horizontally
+ // The third parameter, result array, for double, string and single reference.
+ double fResVal = 0.0;
+ String aResStr;
+ ScAddress aResAdr;
+ StackVar eResArrayType = svUnknown;
+
if (nParamCount == 3)
{
- switch (GetStackType())
+ eResArrayType = GetStackType();
+ switch (eResArrayType)
{
case svDoubleRef:
{
@@ -4953,16 +4990,32 @@ void ScInterpreter::ScLookup()
}
}
break;
+ case svDouble:
+ fResVal = GetDouble();
+ break;
+ case svString:
+ aResStr = GetString();
+ break;
+ case svSingleRef:
+ PopSingleRef( aResAdr );
+ break;
default:
PushIllegalParameter();
return;
}
}
+ // For double, string and single reference.
+ double fDataVal = 0.0;
+ String aDataStr;
+ ScAddress aDataAdr;
+ bool bValueData = false;
+
// Get the data-result range and also determine whether this is vertical
// lookup or horizontal lookup.
- switch (GetStackType())
+ StackVar eDataArrayType = GetStackType();
+ switch (eDataArrayType)
{
case svDoubleRef:
{
@@ -4992,15 +5045,43 @@ void ScInterpreter::ScLookup()
nLenMajor = bVertical ? nR : nC;
}
break;
+ case svDouble:
+ {
+ fDataVal = GetDouble();
+ bValueData = true;
+ }
+ break;
+ case svString:
+ {
+ aDataStr = GetString();
+ }
+ break;
+ case svSingleRef:
+ {
+ PopSingleRef( aDataAdr );
+ const ScBaseCell* pDataCell = GetCell( aDataAdr );
+ if (HasCellEmptyData( pDataCell))
+ {
+ // Empty cells aren't found anywhere, bail out early.
+ SetError( NOTAVAILABLE);
+ }
+ else if (HasCellValueData( pDataCell))
+ {
+ fDataVal = GetCellValue( aDataAdr, pDataCell );
+ bValueData = true;
+ }
+ else
+ GetCellString( aDataStr, pDataCell );
+ }
+ break;
default:
- PushIllegalParameter();
- return;
+ SetError( errIllegalParameter);
}
if (nGlobalError)
{
- PushIllegalParameter();
+ PushError( nGlobalError);
return;
}
@@ -5011,6 +5092,84 @@ void ScInterpreter::ScLookup()
if ( !FillEntry(rEntry) )
return;
+ if ( eDataArrayType == svDouble || eDataArrayType == svString ||
+ eDataArrayType == svSingleRef )
+ {
+ // Delta position for a single value is always 0.
+
+ // Found if data <= query, but not if query is string and found data is
+ // numeric or vice versa. This is how Excel does it but doesn't
+ // document it.
+
+ bool bFound = false;
+ if ( bValueData )
+ {
+ if ( rEntry.bQueryByString )
+ bFound = false;
+ else
+ bFound = (fDataVal <= rEntry.nVal);
+ }
+ else
+ {
+ if ( !rEntry.bQueryByString )
+ bFound = false;
+ else
+ bFound = (ScGlobal::pCollator->compareString( aDataStr, *rEntry.pStr) <= 0);
+ }
+
+ if (!bFound)
+ {
+ PushNA();
+ return;
+ }
+
+ if (pResMat)
+ {
+ if (pResMat->IsValue( 0 ))
+ PushDouble(pResMat->GetDouble( 0 ));
+ else
+ PushString(pResMat->GetString( 0 ));
+ }
+ else if (nParamCount == 3)
+ {
+ switch (eResArrayType)
+ {
+ case svDouble:
+ PushDouble( fResVal );
+ break;
+ case svString:
+ PushString( aResStr );
+ break;
+ case svDoubleRef:
+ aResAdr.Set( nResCol1, nResRow1, nResTab);
+ // fallthru
+ case svSingleRef:
+ PushCellResultToken( true, aResAdr, NULL, NULL);
+ break;
+ default:
+ DBG_ERRORFILE( "ScInterpreter::ScLookup: unhandled eResArrayType, single value data");
+ }
+ }
+ else
+ {
+ switch (eDataArrayType)
+ {
+ case svDouble:
+ PushDouble( fDataVal );
+ break;
+ case svString:
+ PushString( aDataStr );
+ break;
+ case svSingleRef:
+ PushCellResultToken( true, aDataAdr, NULL, NULL);
+ break;
+ default:
+ DBG_ERRORFILE( "ScInterpreter::ScLookup: unhandled eDataArrayType, single value data");
+ }
+ }
+ return;
+ }
+
// Now, perform the search to compute the delta position (nDelta).
if (pDataMat)
@@ -5096,6 +5255,20 @@ void ScInterpreter::ScLookup()
bFound = true;
}
+ // With 0-9 < A-Z, if query is numeric and data found is string, or
+ // vice versa, the (yet another undocumented) Excel behavior is to
+ // return #N/A instead.
+
+ if (bFound)
+ {
+ SCCOLROW i = nDelta;
+ SCSIZE n = pDataMat->GetElementCount();
+ if (static_cast<SCSIZE>(i) >= n)
+ i = static_cast<SCCOLROW>(n);
+ if (bool(rEntry.bQueryByString) == bool(pDataMat->IsValue(i)))
+ bFound = false;
+ }
+
if (!bFound)
{
PushNA();
@@ -5208,35 +5381,69 @@ void ScInterpreter::ScLookup()
}
else if (nParamCount == 3)
{
- // Use the result array vector. Note that the result array is assumed
- // to be a vector (i.e. 1-dimensinoal array).
-
- ScAddress aAdr;
- aAdr.SetTab(nResTab);
- bool bResVertical = (nResRow2 - nResRow1) > 0;
- if (bResVertical)
+ switch (eResArrayType)
{
- SCROW nTempRow = static_cast<SCROW>(nResRow1 + nDelta);
- if (nTempRow > MAXROW)
+ case svDoubleRef:
{
- PushDouble(0);
- return;
+ // Use the result array vector. Note that the result array is assumed
+ // to be a vector (i.e. 1-dimensinoal array).
+
+ ScAddress aAdr;
+ aAdr.SetTab(nResTab);
+ bool bResVertical = (nResRow2 - nResRow1) > 0;
+ if (bResVertical)
+ {
+ SCROW nTempRow = static_cast<SCROW>(nResRow1 + nDelta);
+ if (nTempRow > MAXROW)
+ {
+ PushDouble(0);
+ return;
+ }
+ aAdr.SetCol(nResCol1);
+ aAdr.SetRow(nTempRow);
+ }
+ else
+ {
+ SCCOL nTempCol = static_cast<SCCOL>(nResCol1 + nDelta);
+ if (nTempCol > MAXCOL)
+ {
+ PushDouble(0);
+ return;
+ }
+ aAdr.SetCol(nTempCol);
+ aAdr.SetRow(nResRow1);
+ }
+ PushCellResultToken( true, aAdr, NULL, NULL);
}
- aAdr.SetCol(nResCol1);
- aAdr.SetRow(nTempRow);
- }
- else
- {
- SCCOL nTempCol = static_cast<SCCOL>(nResCol1 + nDelta);
- if (nTempCol > MAXCOL)
+ break;
+ case svDouble:
+ case svString:
+ case svSingleRef:
{
- PushDouble(0);
- return;
+ if (nDelta != 0)
+ PushNA();
+ else
+ {
+ switch (eResArrayType)
+ {
+ case svDouble:
+ PushDouble( fResVal );
+ break;
+ case svString:
+ PushString( aResStr );
+ break;
+ case svSingleRef:
+ PushCellResultToken( true, aResAdr, NULL, NULL);
+ break;
+ default:
+ ; // nothing
+ }
+ }
}
- aAdr.SetCol(nTempCol);
- aAdr.SetRow(nResRow1);
+ break;
+ default:
+ DBG_ERRORFILE( "ScInterpreter::ScLookup: unhandled eResArrayType, range search");
}
- PushCellResultToken(true, aAdr, NULL, NULL);
}
else
{
@@ -5274,12 +5481,12 @@ void ScInterpreter::ScLookup()
void ScInterpreter::ScHLookup()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScHLookup" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScHLookup" );
CalculateLookup(TRUE);
}
void ScInterpreter::CalculateLookup(BOOL HLookup)
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::CalculateLookup" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::CalculateLookup" );
BYTE nParamCount = GetByte();
if ( MustHaveParamCount( nParamCount, 3, 4 ) )
{
@@ -5503,7 +5710,7 @@ void ScInterpreter::CalculateLookup(BOOL HLookup)
bool ScInterpreter::FillEntry(ScQueryEntry& rEntry)
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::FillEntry" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::FillEntry" );
switch ( GetStackType() )
{
case svDouble:
@@ -5567,7 +5774,7 @@ bool ScInterpreter::FillEntry(ScQueryEntry& rEntry)
}
void ScInterpreter::ScVLookup()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScVLookup" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScVLookup" );
CalculateLookup(FALSE);
}
@@ -5577,7 +5784,7 @@ void ScInterpreter::ScVLookup()
void ScInterpreter::ScSubTotal()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScSubTotal" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScSubTotal" );
BYTE nParamCount = GetByte();
if ( MustHaveParamCountMin( nParamCount, 2 ) )
{
@@ -5622,7 +5829,7 @@ void ScInterpreter::ScSubTotal()
BOOL ScInterpreter::GetDBParams(SCTAB& rTab, ScQueryParam& rParam,
BOOL& rMissingField )
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::GetDBParams" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::GetDBParams" );
BOOL bRet = FALSE;
BOOL bAllowMissingField = FALSE;
if ( rMissingField )
@@ -5791,7 +5998,7 @@ BOOL ScInterpreter::GetDBParams(SCTAB& rTab, ScQueryParam& rParam,
void ScInterpreter::DBIterator( ScIterFunc eFunc )
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::DBIterator" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::DBIterator" );
SCTAB nTab1;
double nErg = 0.0;
double fMem = 0.0;
@@ -5854,14 +6061,14 @@ void ScInterpreter::DBIterator( ScIterFunc eFunc )
void ScInterpreter::ScDBSum()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScDBSum" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScDBSum" );
DBIterator( ifSUM );
}
void ScInterpreter::ScDBCount()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScDBCount" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScDBCount" );
SCTAB nTab;
ScQueryParam aQueryParam;
BOOL bMissingField = TRUE;
@@ -5910,7 +6117,7 @@ void ScInterpreter::ScDBCount()
void ScInterpreter::ScDBCount2()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScDBCount2" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScDBCount2" );
SCTAB nTab;
ScQueryParam aQueryParam;
BOOL bMissingField = TRUE;
@@ -5934,35 +6141,35 @@ void ScInterpreter::ScDBCount2()
void ScInterpreter::ScDBAverage()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScDBAverage" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScDBAverage" );
DBIterator( ifAVERAGE );
}
void ScInterpreter::ScDBMax()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScDBMax" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScDBMax" );
DBIterator( ifMAX );
}
void ScInterpreter::ScDBMin()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScDBMin" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScDBMin" );
DBIterator( ifMIN );
}
void ScInterpreter::ScDBProduct()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScDBProduct" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScDBProduct" );
DBIterator( ifPRODUCT );
}
void ScInterpreter::GetDBStVarParams( double& rVal, double& rValCount )
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::GetDBStVarParams" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::GetDBStVarParams" );
std::vector<double> values;
double vSum = 0.0;
double vMean = 0.0;
@@ -6003,7 +6210,7 @@ void ScInterpreter::GetDBStVarParams( double& rVal, double& rValCount )
void ScInterpreter::ScDBStdDev()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScDBStdDev" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScDBStdDev" );
double fVal, fCount;
GetDBStVarParams( fVal, fCount );
PushDouble( sqrt(fVal/(fCount-1)));
@@ -6012,7 +6219,7 @@ void ScInterpreter::ScDBStdDev()
void ScInterpreter::ScDBStdDevP()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScDBStdDevP" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScDBStdDevP" );
double fVal, fCount;
GetDBStVarParams( fVal, fCount );
PushDouble( sqrt(fVal/fCount));
@@ -6021,7 +6228,7 @@ void ScInterpreter::ScDBStdDevP()
void ScInterpreter::ScDBVar()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScDBVar" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScDBVar" );
double fVal, fCount;
GetDBStVarParams( fVal, fCount );
PushDouble(fVal/(fCount-1));
@@ -6030,7 +6237,7 @@ void ScInterpreter::ScDBVar()
void ScInterpreter::ScDBVarP()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScDBVarP" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScDBVarP" );
double fVal, fCount;
GetDBStVarParams( fVal, fCount );
PushDouble(fVal/fCount);
@@ -6085,7 +6292,7 @@ ScTokenArray* lcl_CreateExternalRefTokenArray( const ScAddress& rPos, ScDocument
void ScInterpreter::ScIndirect()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScIndirect" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScIndirect" );
BYTE nParamCount = GetByte();
if ( MustHaveParamCount( nParamCount, 1, 2 ) )
{
@@ -6194,7 +6401,7 @@ void ScInterpreter::ScIndirect()
void ScInterpreter::ScAddressFunc()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScAddressFunc" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScAddressFunc" );
String sTabStr;
BYTE nParamCount = GetByte();
@@ -6269,7 +6476,7 @@ void ScInterpreter::ScAddressFunc()
void ScInterpreter::ScOffset()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScOffset" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScOffset" );
BYTE nParamCount = GetByte();
if ( MustHaveParamCount( nParamCount, 3, 5 ) )
{
@@ -6345,7 +6552,7 @@ void ScInterpreter::ScOffset()
void ScInterpreter::ScIndex()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScIndex" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScIndex" );
BYTE nParamCount = GetByte();
if ( MustHaveParamCount( nParamCount, 1, 4 ) )
{
@@ -6551,7 +6758,7 @@ void ScInterpreter::ScIndex()
void ScInterpreter::ScMultiArea()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScMultiArea" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScMultiArea" );
// Legacy support, convert to RefList
BYTE nParamCount = GetByte();
if (MustHaveParamCountMin( nParamCount, 1))
@@ -6566,7 +6773,7 @@ void ScInterpreter::ScMultiArea()
void ScInterpreter::ScAreas()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScAreas" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScAreas" );
BYTE nParamCount = GetByte();
if (MustHaveParamCount( nParamCount, 1))
{
@@ -6604,7 +6811,7 @@ void ScInterpreter::ScAreas()
void ScInterpreter::ScCurrency()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScCurrency" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScCurrency" );
BYTE nParamCount = GetByte();
if ( MustHaveParamCount( nParamCount, 1, 2 ) )
{
@@ -6665,17 +6872,25 @@ void ScInterpreter::ScCurrency()
void ScInterpreter::ScReplace()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScReplace" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScReplace" );
if ( MustHaveParamCount( GetByte(), 4 ) )
{
String aNewStr( GetString() );
- short nCount = (short) GetDouble();
- short nPos = (short) GetDouble();
+ double fCount = ::rtl::math::approxFloor( GetDouble());
+ double fPos = ::rtl::math::approxFloor( GetDouble());
String aOldStr( GetString() );
- if( nPos < 1 || nCount < 1 )
+ if (fPos < 1.0 || fPos > static_cast<double>(STRING_MAXLEN)
+ || fCount < 0.0 || fCount > static_cast<double>(STRING_MAXLEN))
PushIllegalArgument();
else
{
+ xub_StrLen nCount = static_cast<xub_StrLen>(fCount);
+ xub_StrLen nPos = static_cast<xub_StrLen>(fPos);
+ xub_StrLen nLen = aOldStr.Len();
+ if (nPos > nLen + 1)
+ nPos = nLen + 1;
+ if (nCount > nLen - nPos + 1)
+ nCount = nLen - nPos + 1;
aOldStr.Erase( nPos-1, nCount );
if ( CheckStringResultLen( aOldStr, aNewStr ) )
aOldStr.Insert( aNewStr, nPos-1 );
@@ -6687,7 +6902,7 @@ void ScInterpreter::ScReplace()
void ScInterpreter::ScFixed()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScFixed" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScFixed" );
BYTE nParamCount = GetByte();
if ( MustHaveParamCount( nParamCount, 1, 3 ) )
{
@@ -6747,7 +6962,7 @@ void ScInterpreter::ScFixed()
void ScInterpreter::ScFind()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScFind" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScFind" );
BYTE nParamCount = GetByte();
if ( MustHaveParamCount( nParamCount, 2, 3 ) )
{
@@ -6773,7 +6988,7 @@ void ScInterpreter::ScFind()
void ScInterpreter::ScExact()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScExact" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScExact" );
nFuncFmtType = NUMBERFORMAT_LOGICAL;
if ( MustHaveParamCount( GetByte(), 2 ) )
{
@@ -6786,7 +7001,7 @@ void ScInterpreter::ScExact()
void ScInterpreter::ScLeft()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScLeft" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScLeft" );
BYTE nParamCount = GetByte();
if ( MustHaveParamCount( nParamCount, 1, 2 ) )
{
@@ -6813,7 +7028,7 @@ void ScInterpreter::ScLeft()
void ScInterpreter::ScRight()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScRight" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScRight" );
BYTE nParamCount = GetByte();
if ( MustHaveParamCount( nParamCount, 1, 2 ) )
{
@@ -6841,7 +7056,7 @@ void ScInterpreter::ScRight()
void ScInterpreter::ScSearch()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScSearch" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScSearch" );
double fAnz;
BYTE nParamCount = GetByte();
if ( MustHaveParamCount( nParamCount, 2, 3 ) )
@@ -6882,7 +7097,7 @@ void ScInterpreter::ScSearch()
void ScInterpreter::ScMid()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScMid" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScMid" );
if ( MustHaveParamCount( GetByte(), 3 ) )
{
double fAnz = ::rtl::math::approxFloor(GetDouble());
@@ -6898,7 +7113,7 @@ void ScInterpreter::ScMid()
void ScInterpreter::ScText()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScText" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScText" );
if ( MustHaveParamCount( GetByte(), 2 ) )
{
String sFormatString = GetString();
@@ -6924,7 +7139,7 @@ void ScInterpreter::ScText()
void ScInterpreter::ScSubstitute()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScSubstitute" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScSubstitute" );
BYTE nParamCount = GetByte();
if ( MustHaveParamCount( nParamCount, 3, 4 ) )
{
@@ -6979,7 +7194,7 @@ void ScInterpreter::ScSubstitute()
void ScInterpreter::ScRept()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScRept" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScRept" );
if ( MustHaveParamCount( GetByte(), 2 ) )
{
double fAnz = ::rtl::math::approxFloor(GetDouble());
@@ -7012,7 +7227,7 @@ void ScInterpreter::ScRept()
void ScInterpreter::ScConcat()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScConcat" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScConcat" );
BYTE nParamCount = GetByte();
String aRes;
while( nParamCount-- > 0)
@@ -7026,7 +7241,7 @@ void ScInterpreter::ScConcat()
void ScInterpreter::ScErrorType()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScErrorType" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScErrorType" );
USHORT nErr;
USHORT nOldError = nGlobalError;
nGlobalError = 0;
@@ -7108,7 +7323,7 @@ void ScInterpreter::ScErrorType()
BOOL ScInterpreter::MayBeRegExp( const String& rStr, const ScDocument* pDoc )
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::MayBeRegExp" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::MayBeRegExp" );
if ( pDoc && !pDoc->GetDocOptions().IsFormulaRegexEnabled() )
return FALSE;
if ( !rStr.Len() || (rStr.Len() == 1 && rStr.GetChar(0) != '.') )
@@ -7178,7 +7393,7 @@ static struct LookupCacheDebugCounter
bool ScInterpreter::LookupQueryWithCache( ScAddress & o_rResultPos,
const ScQueryParam & rParam ) const
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::LookupQueryWithCache" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::LookupQueryWithCache" );
bool bFound = false;
const ScQueryEntry& rEntry = rParam.GetEntry(0);
bool bColumnsMatch = (rParam.nCol1 == rEntry.nField);
diff --git a/sc/source/core/tool/interpr2.cxx b/sc/source/core/tool/interpr2.cxx
index d4d938d482ed..fc0f085706c5 100644
--- a/sc/source/core/tool/interpr2.cxx
+++ b/sc/source/core/tool/interpr2.cxx
@@ -69,24 +69,33 @@ using namespace formula;
// Datum und Zeit
//-----------------------------------------------------------------------------
-double ScInterpreter::GetDate(INT16 nYear, INT16 nMonth, INT16 nDay)
+double ScInterpreter::GetDateSerial( INT16 nYear, INT16 nMonth, INT16 nDay, bool bStrict )
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::GetDate" );
- if ( nYear < 100 )
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::GetDateSerial" );
+ if ( nYear < 100 && !bStrict )
nYear = pFormatter->ExpandTwoDigitYear( nYear );
- INT16 nY, nM;
- if (nMonth > 0)
- {
- nY = nYear + (nMonth-1) / 12;
- nM = ((nMonth-1) % 12) + 1;
- }
+ // Do not use a default Date ctor here because it asks system time with a
+ // performance penalty.
+ INT16 nY, nM, nD;
+ if (bStrict)
+ nY = nYear, nM = nMonth, nD = nDay;
else
{
- nY = nYear + (nMonth-12) / 12;
- nM = 12 - (-nMonth) % 12;
+ if (nMonth > 0)
+ {
+ nY = nYear + (nMonth-1) / 12;
+ nM = ((nMonth-1) % 12) + 1;
+ }
+ else
+ {
+ nY = nYear + (nMonth-12) / 12;
+ nM = 12 - (-nMonth) % 12;
+ }
+ nD = 1;
}
- Date aDate(1, nM, nY);
- aDate += nDay - 1;
+ Date aDate( nD, nM, nY);
+ if (!bStrict)
+ aDate += nDay - 1;
if (aDate.IsValid())
return (double) (aDate - *(pFormatter->GetNullDate()));
else
@@ -102,7 +111,7 @@ double ScInterpreter::GetDate(INT16 nYear, INT16 nMonth, INT16 nDay)
void ScInterpreter::ScGetActDate()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScGetActDate" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScGetActDate" );
nFuncFmtType = NUMBERFORMAT_DATE;
Date aActDate;
long nDiff = aActDate - *(pFormatter->GetNullDate());
@@ -111,7 +120,7 @@ void ScInterpreter::ScGetActDate()
void ScInterpreter::ScGetActTime()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScGetActTime" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScGetActTime" );
nFuncFmtType = NUMBERFORMAT_DATETIME;
Date aActDate;
long nDiff = aActDate - *(pFormatter->GetNullDate());
@@ -125,7 +134,7 @@ void ScInterpreter::ScGetActTime()
void ScInterpreter::ScGetYear()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScGetYear" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScGetYear" );
Date aDate = *(pFormatter->GetNullDate());
aDate += (long) ::rtl::math::approxFloor(GetDouble());
PushDouble( (double) aDate.GetYear() );
@@ -133,7 +142,7 @@ void ScInterpreter::ScGetYear()
void ScInterpreter::ScGetMonth()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScGetMonth" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScGetMonth" );
Date aDate = *(pFormatter->GetNullDate());
aDate += (long) ::rtl::math::approxFloor(GetDouble());
PushDouble( (double) aDate.GetMonth() );
@@ -141,7 +150,7 @@ void ScInterpreter::ScGetMonth()
void ScInterpreter::ScGetDay()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScGetDay" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScGetDay" );
Date aDate = *(pFormatter->GetNullDate());
aDate += (long)::rtl::math::approxFloor(GetDouble());
PushDouble((double) aDate.GetDay());
@@ -149,7 +158,7 @@ void ScInterpreter::ScGetDay()
void ScInterpreter::ScGetMin()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScGetMin" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScGetMin" );
double fTime = GetDouble();
fTime -= ::rtl::math::approxFloor(fTime); // Datumsanteil weg
long nVal = (long)::rtl::math::approxFloor(fTime*D_TIMEFACTOR+0.5) % 3600;
@@ -158,7 +167,7 @@ void ScInterpreter::ScGetMin()
void ScInterpreter::ScGetSec()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScGetSec" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScGetSec" );
double fTime = GetDouble();
fTime -= ::rtl::math::approxFloor(fTime); // Datumsanteil weg
long nVal = (long)::rtl::math::approxFloor(fTime*D_TIMEFACTOR+0.5) % 60;
@@ -167,7 +176,7 @@ void ScInterpreter::ScGetSec()
void ScInterpreter::ScGetHour()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScGetHour" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScGetHour" );
double fTime = GetDouble();
fTime -= ::rtl::math::approxFloor(fTime); // Datumsanteil weg
long nVal = (long)::rtl::math::approxFloor(fTime*D_TIMEFACTOR+0.5) / 3600;
@@ -176,7 +185,7 @@ void ScInterpreter::ScGetHour()
void ScInterpreter::ScGetDateValue()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScGetDateValue" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScGetDateValue" );
String aInputString = GetString();
sal_uInt32 nFIndex = 0; // damit default Land/Spr.
double fVal;
@@ -194,7 +203,7 @@ void ScInterpreter::ScGetDateValue()
void ScInterpreter::ScGetDayOfWeek()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScGetDayOfWeek" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScGetDayOfWeek" );
BYTE nParamCount = GetByte();
if ( MustHaveParamCount( nParamCount, 1, 2 ) )
{
@@ -222,7 +231,7 @@ void ScInterpreter::ScGetDayOfWeek()
void ScInterpreter::ScGetWeekOfYear()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScGetWeekOfYear" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScGetWeekOfYear" );
if ( MustHaveParamCount( GetByte(), 2 ) )
{
short nFlag = (short) ::rtl::math::approxFloor(GetDouble());
@@ -235,7 +244,7 @@ void ScInterpreter::ScGetWeekOfYear()
void ScInterpreter::ScEasterSunday()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScEasterSunday" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScEasterSunday" );
nFuncFmtType = NUMBERFORMAT_DATE;
if ( MustHaveParamCount( GetByte(), 1 ) )
{
@@ -260,13 +269,13 @@ void ScInterpreter::ScEasterSunday()
O = H + L - 7 * M + 114;
nDay = sal::static_int_cast<INT16>( O % 31 + 1 );
nMonth = sal::static_int_cast<INT16>( int(O / 31) );
- PushDouble( GetDate( nYear, nMonth, nDay ) );
+ PushDouble( GetDateSerial( nYear, nMonth, nDay, true ) );
}
}
void ScInterpreter::ScGetDate()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScGetDate" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScGetDate" );
nFuncFmtType = NUMBERFORMAT_DATE;
if ( MustHaveParamCount( GetByte(), 3 ) )
{
@@ -277,14 +286,14 @@ void ScInterpreter::ScGetDate()
PushIllegalArgument();
else
{
- PushDouble(GetDate(nYear, nMonth, nDay));
+ PushDouble(GetDateSerial(nYear, nMonth, nDay, false));
}
}
}
void ScInterpreter::ScGetTime()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScGetTime" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScGetTime" );
nFuncFmtType = NUMBERFORMAT_TIME;
if ( MustHaveParamCount( GetByte(), 3 ) )
{
@@ -297,7 +306,7 @@ void ScInterpreter::ScGetTime()
void ScInterpreter::ScGetDiffDate()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScGetDiffDate" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScGetDiffDate" );
if ( MustHaveParamCount( GetByte(), 2 ) )
{
double nDate2 = GetDouble();
@@ -308,7 +317,7 @@ void ScInterpreter::ScGetDiffDate()
void ScInterpreter::ScGetDiffDate360()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScGetDiffDate360" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScGetDiffDate360" );
/* Implementation follows
* http://www.bondmarkets.com/eCommerce/SMD_Fields_030802.pdf
* Appendix B: Day-Count Bases, there are 7 different ways to calculate the
@@ -403,7 +412,7 @@ void ScInterpreter::ScGetDiffDate360()
void ScInterpreter::ScGetTimeValue()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScGetTimeValue" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScGetTimeValue" );
String aInputString = GetString();
sal_uInt32 nFIndex = 0; // damit default Land/Spr.
double fVal;
@@ -425,7 +434,7 @@ void ScInterpreter::ScGetTimeValue()
void ScInterpreter::ScPlusMinus()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScPlusMinus" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScPlusMinus" );
double nVal = GetDouble();
short n = 0;
if (nVal < 0.0)
@@ -437,20 +446,20 @@ void ScInterpreter::ScPlusMinus()
void ScInterpreter::ScAbs()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScAbs" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScAbs" );
PushDouble(fabs(GetDouble()));
}
void ScInterpreter::ScInt()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScInt" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScInt" );
PushDouble(::rtl::math::approxFloor(GetDouble()));
}
void ScInterpreter::RoundNumber( rtl_math_RoundingMode eMode )
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::RoundNumber" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::RoundNumber" );
BYTE nParamCount = GetByte();
if ( MustHaveParamCount( nParamCount, 1, 2 ) )
{
@@ -471,25 +480,25 @@ void ScInterpreter::RoundNumber( rtl_math_RoundingMode eMode )
void ScInterpreter::ScRound()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScRound" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScRound" );
RoundNumber( rtl_math_RoundingMode_Corrected );
}
void ScInterpreter::ScRoundDown()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScRoundDown" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScRoundDown" );
RoundNumber( rtl_math_RoundingMode_Down );
}
void ScInterpreter::ScRoundUp()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScRoundUp" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScRoundUp" );
RoundNumber( rtl_math_RoundingMode_Up );
}
void ScInterpreter::ScCeil()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScCeil" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScCeil" );
BYTE nParamCount = GetByte();
if ( MustHaveParamCount( nParamCount, 2, 3 ) )
{
@@ -512,7 +521,7 @@ void ScInterpreter::ScCeil()
void ScInterpreter::ScFloor()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScFloor" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScFloor" );
BYTE nParamCount = GetByte();
if ( MustHaveParamCount( nParamCount, 2, 3 ) )
{
@@ -535,7 +544,7 @@ void ScInterpreter::ScFloor()
void ScInterpreter::ScEven()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScEven" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScEven" );
double fVal = GetDouble();
if (fVal < 0.0)
PushDouble(::rtl::math::approxFloor(fVal/2.0) * 2.0);
@@ -545,7 +554,7 @@ void ScInterpreter::ScEven()
void ScInterpreter::ScOdd()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScOdd" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScOdd" );
double fVal = GetDouble();
if (fVal >= 0.0)
{
@@ -564,7 +573,7 @@ void ScInterpreter::ScOdd()
void ScInterpreter::ScArcTan2()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScArcTan2" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScArcTan2" );
if ( MustHaveParamCount( GetByte(), 2 ) )
{
double nVal2 = GetDouble();
@@ -575,7 +584,7 @@ void ScInterpreter::ScArcTan2()
void ScInterpreter::ScLog()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScLog" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScLog" );
BYTE nParamCount = GetByte();
if ( MustHaveParamCount( nParamCount, 1, 2 ) )
{
@@ -594,7 +603,7 @@ void ScInterpreter::ScLog()
void ScInterpreter::ScLn()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScLn" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScLn" );
double fVal = GetDouble();
if (fVal > 0.0)
PushDouble(log(fVal));
@@ -604,7 +613,7 @@ void ScInterpreter::ScLn()
void ScInterpreter::ScLog10()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScLog10" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScLog10" );
double fVal = GetDouble();
if (fVal > 0.0)
PushDouble(log10(fVal));
@@ -614,7 +623,7 @@ void ScInterpreter::ScLog10()
void ScInterpreter::ScNPV()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScNPV" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScNPV" );
nFuncFmtType = NUMBERFORMAT_CURRENCY;
short nParamCount = GetByte();
if ( MustHaveParamCount( nParamCount, 2, 31 ) )
@@ -682,7 +691,7 @@ void ScInterpreter::ScNPV()
void ScInterpreter::ScIRR()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScIRR" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScIRR" );
double fSchaetzwert;
nFuncFmtType = NUMBERFORMAT_PERCENT;
BYTE nParamCount = GetByte();
@@ -825,7 +834,7 @@ void ScInterpreter::ScISPMT()
double ScInterpreter::ScGetBw(double fZins, double fZzr, double fRmz,
double fZw, double fF)
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScMIRR" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScMIRR" );
double fBw;
if (fZins == 0.0)
fBw = fZw + fRmz * fZzr;
@@ -841,7 +850,7 @@ double ScInterpreter::ScGetBw(double fZins, double fZzr, double fRmz,
void ScInterpreter::ScBW()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScBW" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScBW" );
nFuncFmtType = NUMBERFORMAT_CURRENCY;
double nRmz, nZzr, nZins, nZw = 0, nFlag = 0;
BYTE nParamCount = GetByte();
@@ -859,7 +868,7 @@ void ScInterpreter::ScBW()
void ScInterpreter::ScDIA()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScDIA" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScDIA" );
nFuncFmtType = NUMBERFORMAT_CURRENCY;
if ( MustHaveParamCount( GetByte(), 4 ) )
{
@@ -876,7 +885,7 @@ void ScInterpreter::ScDIA()
double ScInterpreter::ScGetGDA(double fWert, double fRest, double fDauer,
double fPeriode, double fFaktor)
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScGetGDA" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScGetGDA" );
double fGda, fZins, fAlterWert, fNeuerWert;
fZins = fFaktor / fDauer;
if (fZins >= 1.0)
@@ -902,7 +911,7 @@ double ScInterpreter::ScGetGDA(double fWert, double fRest, double fDauer,
void ScInterpreter::ScGDA()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScGDA" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScGDA" );
nFuncFmtType = NUMBERFORMAT_CURRENCY;
BYTE nParamCount = GetByte();
if ( MustHaveParamCount( nParamCount, 4, 5 ) )
@@ -926,7 +935,7 @@ void ScInterpreter::ScGDA()
void ScInterpreter::ScGDA2()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScGDA2" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScGDA2" );
nFuncFmtType = NUMBERFORMAT_CURRENCY;
BYTE nParamCount = GetByte();
if ( !MustHaveParamCount( nParamCount, 4, 5 ) )
@@ -973,7 +982,7 @@ void ScInterpreter::ScGDA2()
double ScInterpreter::ScInterVDB(double fWert,double fRest,double fDauer,
double fDauer1,double fPeriode,double fFaktor)
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScInterVDB" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScInterVDB" );
double fVdb=0;
double fIntEnd = ::rtl::math::approxCeil(fPeriode);
ULONG nLoopEnd = (ULONG) fIntEnd;
@@ -1024,7 +1033,7 @@ inline double DblMin( double a, double b )
void ScInterpreter::ScVDB()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScVDB" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScVDB" );
nFuncFmtType = NUMBERFORMAT_CURRENCY;
BYTE nParamCount = GetByte();
if ( MustHaveParamCount( nParamCount, 5, 7 ) )
@@ -1101,7 +1110,7 @@ void ScInterpreter::ScVDB()
void ScInterpreter::ScLaufz()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScLaufz" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScLaufz" );
if ( MustHaveParamCount( GetByte(), 3 ) )
{
double nZukunft = GetDouble();
@@ -1113,7 +1122,7 @@ void ScInterpreter::ScLaufz()
void ScInterpreter::ScLIA()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScLIA" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScLIA" );
nFuncFmtType = NUMBERFORMAT_CURRENCY;
if ( MustHaveParamCount( GetByte(), 3 ) )
{
@@ -1127,7 +1136,7 @@ void ScInterpreter::ScLIA()
double ScInterpreter::ScGetRmz(double fZins, double fZzr, double fBw,
double fZw, double fF)
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScGetRmz" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScGetRmz" );
double fRmz;
if (fZins == 0.0)
fRmz = (fBw + fZw) / fZzr;
@@ -1146,7 +1155,7 @@ double ScInterpreter::ScGetRmz(double fZins, double fZzr, double fBw,
void ScInterpreter::ScRMZ()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScRMZ" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScRMZ" );
double nZins, nZzr, nBw, nZw = 0, nFlag = 0;
nFuncFmtType = NUMBERFORMAT_CURRENCY;
BYTE nParamCount = GetByte();
@@ -1164,7 +1173,7 @@ void ScInterpreter::ScRMZ()
void ScInterpreter::ScZGZ()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScZGZ" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScZGZ" );
nFuncFmtType = NUMBERFORMAT_PERCENT;
if ( MustHaveParamCount( GetByte(), 3 ) )
{
@@ -1178,7 +1187,7 @@ void ScInterpreter::ScZGZ()
double ScInterpreter::ScGetZw(double fZins, double fZzr, double fRmz,
double fBw, double fF)
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScGetZw" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScGetZw" );
double fZw;
if (fZins == 0.0)
fZw = fBw + fRmz * fZzr;
@@ -1195,7 +1204,7 @@ double ScInterpreter::ScGetZw(double fZins, double fZzr, double fRmz,
void ScInterpreter::ScZW()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScZW" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScZW" );
double nZins, nZzr, nRmz, nBw = 0, nFlag = 0;
nFuncFmtType = NUMBERFORMAT_CURRENCY;
BYTE nParamCount = GetByte();
@@ -1213,7 +1222,7 @@ void ScInterpreter::ScZW()
void ScInterpreter::ScZZR()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScZZR" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScZZR" );
double nZins, nRmz, nBw, nZw = 0, nFlag = 0;
BYTE nParamCount = GetByte();
if ( !MustHaveParamCount( nParamCount, 3, 5 ) )
@@ -1237,7 +1246,7 @@ void ScInterpreter::ScZZR()
bool ScInterpreter::RateIteration( double fNper, double fPayment, double fPv,
double fFv, double fPayType, double & fGuess )
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::RateIteration" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::RateIteration" );
// See also #i15090#
// Newton-Raphson method: x(i+1) = x(i) - f(x(i)) / f'(x(i))
// This solution handles integer and non-integer values of Nper different.
@@ -1331,7 +1340,7 @@ bool ScInterpreter::RateIteration( double fNper, double fPayment, double fPv,
// In Calc UI it is the function RATE(Nper;Pmt;Pv;Fv;Type;Guess)
void ScInterpreter::ScZins()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScZins" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScZins" );
double fPv, fPayment, fNper;
// defaults for missing arguments, see ODFF spec
double fFv = 0, fPayType = 0, fGuess = 0.1;
@@ -1366,7 +1375,7 @@ void ScInterpreter::ScZins()
double ScInterpreter::ScGetZinsZ(double fZins, double fZr, double fZzr, double fBw,
double fZw, double fF, double& fRmz)
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScGetZinsZ" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScGetZinsZ" );
fRmz = ScGetRmz(fZins, fZzr, fBw, fZw, fF); // fuer kapz auch bei fZr == 1
double fZinsZ;
nFuncFmtType = NUMBERFORMAT_CURRENCY;
@@ -1389,7 +1398,7 @@ double ScInterpreter::ScGetZinsZ(double fZins, double fZr, double fZzr, double f
void ScInterpreter::ScZinsZ()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScZinsZ" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScZinsZ" );
double nZins, nZr, nRmz, nZzr, nBw, nZw = 0, nFlag = 0;
nFuncFmtType = NUMBERFORMAT_CURRENCY;
BYTE nParamCount = GetByte();
@@ -1411,7 +1420,7 @@ void ScInterpreter::ScZinsZ()
void ScInterpreter::ScKapz()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScKapz" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScKapz" );
double nZins, nZr, nZzr, nBw, nZw = 0, nFlag = 0, nRmz, nZinsz;
nFuncFmtType = NUMBERFORMAT_CURRENCY;
BYTE nParamCount = GetByte();
@@ -1436,7 +1445,7 @@ void ScInterpreter::ScKapz()
void ScInterpreter::ScKumZinsZ()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScKumZinsZ" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScKumZinsZ" );
nFuncFmtType = NUMBERFORMAT_CURRENCY;
if ( MustHaveParamCount( GetByte(), 6 ) )
{
@@ -1477,7 +1486,7 @@ void ScInterpreter::ScKumZinsZ()
void ScInterpreter::ScKumKapZ()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScKumKapZ" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScKumKapZ" );
nFuncFmtType = NUMBERFORMAT_CURRENCY;
if ( MustHaveParamCount( GetByte(), 6 ) )
{
@@ -1519,7 +1528,7 @@ void ScInterpreter::ScKumKapZ()
void ScInterpreter::ScEffektiv()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScEffektiv" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScEffektiv" );
nFuncFmtType = NUMBERFORMAT_PERCENT;
if ( MustHaveParamCount( GetByte(), 2 ) )
{
@@ -1537,7 +1546,7 @@ void ScInterpreter::ScEffektiv()
void ScInterpreter::ScNominal()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScNominal" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScNominal" );
nFuncFmtType = NUMBERFORMAT_PERCENT;
if ( MustHaveParamCount( GetByte(), 2 ) )
{
@@ -1555,13 +1564,24 @@ void ScInterpreter::ScNominal()
void ScInterpreter::ScMod()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScMod" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScMod" );
if ( MustHaveParamCount( GetByte(), 2 ) )
{
- double nVal2 = GetDouble();
- double nVal1 = GetDouble();
- PushDouble( ::rtl::math::approxSub( nVal1,
- ::rtl::math::approxFloor(nVal1 / nVal2) * nVal2));
+ double fVal2 = GetDouble(); // Denominator
+ double fVal1 = GetDouble(); // Numerator
+ if (fVal2 == floor(fVal2)) // a pure integral number stored in double
+ {
+ double fResult = fmod(fVal1,fVal2);
+ if ( (fResult != 0.0) &&
+ ((fVal1 > 0.0 && fVal2 < 0.0) || (fVal1 < 0.0 && fVal2 > 0.0)))
+ fResult += fVal2 ;
+ PushDouble( fResult );
+ }
+ else
+ {
+ PushDouble( ::rtl::math::approxSub( fVal1,
+ ::rtl::math::approxFloor(fVal1 / fVal2) * fVal2));
+ }
}
}
@@ -1582,7 +1602,7 @@ void ScInterpreter::ScMod()
*/
void ScInterpreter::ScBackSolver()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScBackSolver" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScBackSolver" );
if ( MustHaveParamCount( GetByte(), 3 ) )
{
BOOL bDoneIteration = FALSE;
@@ -1786,7 +1806,7 @@ void ScInterpreter::ScBackSolver()
void ScInterpreter::ScIntersect()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScIntersect" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScIntersect" );
formula::FormulaTokenRef p2nd = PopToken();
formula::FormulaTokenRef p1st = PopToken();
@@ -1934,7 +1954,7 @@ void ScInterpreter::ScIntersect()
void ScInterpreter::ScRangeFunc()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScRangeFunc" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScRangeFunc" );
formula::FormulaTokenRef x2 = PopToken();
formula::FormulaTokenRef x1 = PopToken();
@@ -1953,7 +1973,7 @@ void ScInterpreter::ScRangeFunc()
void ScInterpreter::ScUnionFunc()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScUnionFunc" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScUnionFunc" );
formula::FormulaTokenRef p2nd = PopToken();
formula::FormulaTokenRef p1st = PopToken();
@@ -2031,7 +2051,7 @@ void ScInterpreter::ScUnionFunc()
void ScInterpreter::ScCurrent()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScCurrent" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScCurrent" );
FormulaTokenRef xTok( PopToken());
if (xTok)
{
@@ -2044,7 +2064,7 @@ void ScInterpreter::ScCurrent()
void ScInterpreter::ScStyle()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScStyle" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScStyle" );
BYTE nParamCount = GetByte();
if (nParamCount >= 1 && nParamCount <= 3)
{
@@ -2105,7 +2125,7 @@ ScDdeLink* lcl_GetDdeLink( SvxLinkManager* pLinkMgr,
void ScInterpreter::ScDde()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScDde" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScDde" );
// Applikation, Datei, Bereich
// Application, Topic, Item
@@ -2471,7 +2491,7 @@ void ScInterpreter::ScRoman()
BOOL lcl_GetArabicValue( sal_Unicode cChar, USHORT& rnValue, BOOL& rbIsDec )
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScBase" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScBase" );
switch( cChar )
{
case 'M': rnValue = 1000; rbIsDec = TRUE; break;
@@ -2489,7 +2509,7 @@ BOOL lcl_GetArabicValue( sal_Unicode cChar, USHORT& rnValue, BOOL& rbIsDec )
void ScInterpreter::ScArabic()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScArabic" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScArabic" );
String aRoman( GetString() );
if( nGlobalError )
PushError( nGlobalError);
@@ -2546,18 +2566,89 @@ void ScInterpreter::ScArabic()
void ScInterpreter::ScHyperLink()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScHyperLink" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScHyperLink" );
BYTE nParamCount = GetByte();
if ( MustHaveParamCount( nParamCount, 1, 2 ) )
{
- String aCellText = GetString();
- ScMatrixRef pResMat = GetNewMat(1,2);
- pResMat->PutString(aCellText,0);
- pResMat->PutString((nParamCount == 2) ? GetString() : aCellText, 1);
+ double fVal = 0.0;
+ String aStr;
+ ScMatValType nResultType = SC_MATVAL_STRING;
+
+ if ( nParamCount == 2 )
+ {
+ switch ( GetStackType() )
+ {
+ case svDouble:
+ fVal = GetDouble();
+ nResultType = SC_MATVAL_VALUE;
+ break;
+ case svString:
+ aStr = GetString();
+ break;
+ case svSingleRef:
+ case svDoubleRef:
+ {
+ ScAddress aAdr;
+ if ( !PopDoubleRefOrSingleRef( aAdr ) )
+ break;
+ ScBaseCell* pCell = GetCell( aAdr );
+ if (HasCellEmptyData( pCell))
+ nResultType = SC_MATVAL_EMPTY;
+ else
+ {
+ USHORT nErr = GetCellErrCode( pCell );
+ if (nErr)
+ SetError( nErr);
+ else if (HasCellValueData( pCell))
+ {
+ fVal = GetCellValue( aAdr, pCell );
+ nResultType = SC_MATVAL_VALUE;
+ }
+ else
+ GetCellString( aStr, pCell );
+ }
+ }
+ break;
+ case svMatrix:
+ nResultType = GetDoubleOrStringFromMatrix( fVal, aStr);
+ break;
+ case svMissing:
+ case svEmptyCell:
+ Pop();
+ // mimic xcl
+ fVal = 0.0;
+ nResultType = SC_MATVAL_VALUE;
+ break;
+ default:
+ PopError();
+ SetError( errIllegalArgument);
+ }
+ }
+ String aUrl = GetString();
+ ScMatrixRef pResMat = GetNewMat( 1, 2);
+ if (nGlobalError)
+ {
+ fVal = CreateDoubleError( nGlobalError);
+ nResultType = SC_MATVAL_VALUE;
+ }
+ if (nParamCount == 2 || nGlobalError)
+ {
+ if (ScMatrix::IsValueType( nResultType))
+ pResMat->PutDouble( fVal, 0);
+ else if (ScMatrix::IsRealStringType( nResultType))
+ pResMat->PutString( aStr, 0);
+ else // EmptyType, EmptyPathType, mimic xcl
+ pResMat->PutDouble( 0.0, 0 );
+ }
+ else
+ pResMat->PutString( aUrl, 0 );
+ pResMat->PutString( aUrl, 1 );
bMatrixFormula = true;
PushMatrix(pResMat);
}
}
+
+
BOOL lclConvertMoney( const String& aSearchUnit, double& rfRate, int& rnDec )
{
struct ConvertInfo
@@ -2782,7 +2873,7 @@ void lclAppendBlock( ByteString& rText, sal_Int32 nValue )
void ScInterpreter::ScBahtText()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScBahtText" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScBahtText" );
BYTE nParamCount = GetByte();
if ( MustHaveParamCount( nParamCount, 1 ) )
{
@@ -2851,7 +2942,7 @@ void ScInterpreter::ScBahtText()
void ScInterpreter::ScGetPivotData()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScGetPivotData" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScGetPivotData" );
BYTE nParamCount = GetByte();
if ( MustHaveParamCount( nParamCount, 2, 30 ) )
diff --git a/sc/source/core/tool/interpr3.cxx b/sc/source/core/tool/interpr3.cxx
index e7435c4a1546..4d4a59509fca 100644
--- a/sc/source/core/tool/interpr3.cxx
+++ b/sc/source/core/tool/interpr3.cxx
@@ -188,13 +188,13 @@ double lcl_IterateInverse( const ScDistFunc& rFunction, double fAx, double fBx,
void ScInterpreter::ScNoName()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScNoName" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScNoName" );
PushError(errNoName);
}
void ScInterpreter::ScBadName()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScBadName" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScBadName" );
short nParamCount = GetByte();
while (nParamCount-- > 0)
{
@@ -205,13 +205,18 @@ void ScInterpreter::ScBadName()
double ScInterpreter::phi(double x)
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::phi" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::phi" );
return 0.39894228040143268 * exp(-(x * x) / 2.0);
}
+double ScInterpreter::integralPhi(double x)
+{ // Using gauss(x)+0.5 has severe cancellation errors for x<-4
+ return 0.5 * ::rtl::math::erfc(-x * 0.7071067811865475); // * 1/sqrt(2)
+}
+
double ScInterpreter::taylor(double* pPolynom, USHORT nMax, double x)
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::taylor" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::taylor" );
double nVal = pPolynom[nMax];
for (short i = nMax-1; i >= 0; i--)
{
@@ -222,7 +227,7 @@ double ScInterpreter::taylor(double* pPolynom, USHORT nMax, double x)
double ScInterpreter::gauss(double x)
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::gauss" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::gauss" );
double t0[] =
{ 0.39894228040143268, -0.06649038006690545, 0.00997355701003582,
-0.00118732821548045, 0.00011543468761616, -0.00000944465625950,
@@ -270,7 +275,7 @@ double ScInterpreter::gauss(double x)
double ScInterpreter::gaussinv(double x)
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::gaussinv" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::gaussinv" );
double q,t,z;
q=x-0.5;
@@ -442,7 +447,7 @@ double ScInterpreter::gaussinv(double x)
double ScInterpreter::Fakultaet(double x)
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::Fakultaet" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::Fakultaet" );
x = ::rtl::math::approxFloor(x);
if (x < 0.0)
return 0.0;
@@ -468,7 +473,7 @@ double ScInterpreter::Fakultaet(double x)
double ScInterpreter::BinomKoeff(double n, double k)
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::BinomKoeff" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::BinomKoeff" );
double nVal = 0.0;
k = ::rtl::math::approxFloor(k);
if (n < k)
@@ -606,7 +611,7 @@ double lcl_GetLogGammaHelper(double fZ)
/** You must ensure non integer arguments for fZ<1 */
double ScInterpreter::GetGamma(double fZ)
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::GetGamma" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::GetGamma" );
const double fLogPi = log(F_PI);
const double fLogDblMax = log( ::std::numeric_limits<double>::max());
@@ -652,7 +657,7 @@ double ScInterpreter::GetGamma(double fZ)
/** You must ensure fZ>0 */
double ScInterpreter::GetLogGamma(double fZ)
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::GetLogGamma" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::GetLogGamma" );
if (fZ >= fMaxGammaArgument)
return lcl_GetLogGammaHelper(fZ);
if (fZ >= 1.0)
@@ -664,7 +669,7 @@ double ScInterpreter::GetLogGamma(double fZ)
double ScInterpreter::GetFDist(double x, double fF1, double fF2)
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::GetFDist" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::GetFDist" );
double arg = fF2/(fF2+fF1*x);
double alpha = fF2/2.0;
double beta = fF1/2.0;
@@ -678,7 +683,7 @@ double ScInterpreter::GetFDist(double x, double fF1, double fF2)
double ScInterpreter::GetTDist(double T, double fDF)
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::GetTDist" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::GetTDist" );
return 0.5 * GetBetaDist(fDF/(fDF+T*T), fDF/2.0, 0.5);
/*
USHORT DF = (USHORT) fDF;
@@ -717,7 +722,7 @@ double ScInterpreter::GetTDist(double T, double fDF)
/** You must ensure fDF>0.0 */
double ScInterpreter::GetChiDist(double fX, double fDF)
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::GetChiDist" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::GetChiDist" );
if (fX <= 0.0)
return 1.0; // see ODFF
else
@@ -730,7 +735,7 @@ double ScInterpreter::GetChiDist(double fX, double fDF)
/** You must ensure fDF>0.0 */
double ScInterpreter::GetChiSqDistCDF(double fX, double fDF)
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::GetChiSqDistCDF" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::GetChiSqDistCDF" );
if (fX <= 0.0)
return 0.0; // see ODFF
else
@@ -801,7 +806,7 @@ void ScInterpreter::ScChiSqDist()
void ScInterpreter::ScGamma()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScGamma" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScGamma" );
double x = GetDouble();
double fResult;
if (x <= 0.0 && x == ::rtl::math::approxFloor(x))
@@ -821,7 +826,7 @@ void ScInterpreter::ScGamma()
void ScInterpreter::ScLogGamma()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScLogGamma" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScLogGamma" );
double x = GetDouble();
if (x > 0.0) // constraint from ODFF
PushDouble( GetLogGamma(x));
@@ -1125,19 +1130,19 @@ double ScInterpreter::GetBetaDist(double fXin, double fAlpha, double fBeta)
void ScInterpreter::ScPhi()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScPhi" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScPhi" );
PushDouble(phi(GetDouble()));
}
void ScInterpreter::ScGauss()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScGauss" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScGauss" );
PushDouble(gauss(GetDouble()));
}
void ScInterpreter::ScFisher()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScFisher" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScFisher" );
double fVal = GetDouble();
if (fabs(fVal) >= 1.0)
PushIllegalArgument();
@@ -1147,13 +1152,13 @@ void ScInterpreter::ScFisher()
void ScInterpreter::ScFisherInv()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScFisherInv" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScFisherInv" );
PushDouble( tanh( GetDouble()));
}
void ScInterpreter::ScFact()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScFact" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScFact" );
double nVal = GetDouble();
if (nVal < 0.0)
PushIllegalArgument();
@@ -1163,7 +1168,7 @@ void ScInterpreter::ScFact()
void ScInterpreter::ScKombin()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScKombin" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScKombin" );
if ( MustHaveParamCount( GetByte(), 2 ) )
{
double k = ::rtl::math::approxFloor(GetDouble());
@@ -1177,7 +1182,7 @@ void ScInterpreter::ScKombin()
void ScInterpreter::ScKombin2()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScKombin2" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScKombin2" );
if ( MustHaveParamCount( GetByte(), 2 ) )
{
double k = ::rtl::math::approxFloor(GetDouble());
@@ -1191,7 +1196,7 @@ void ScInterpreter::ScKombin2()
void ScInterpreter::ScVariationen()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScVariationen" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScVariationen" );
if ( MustHaveParamCount( GetByte(), 2 ) )
{
double k = ::rtl::math::approxFloor(GetDouble());
@@ -1212,7 +1217,7 @@ void ScInterpreter::ScVariationen()
void ScInterpreter::ScVariationen2()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScVariationen2" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScVariationen2" );
if ( MustHaveParamCount( GetByte(), 2 ) )
{
double k = ::rtl::math::approxFloor(GetDouble());
@@ -1226,7 +1231,7 @@ void ScInterpreter::ScVariationen2()
void ScInterpreter::ScB()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScB" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScB" );
BYTE nParamCount = GetByte();
if ( !MustHaveParamCount( nParamCount, 3, 4 ) )
return ;
@@ -1279,8 +1284,8 @@ void ScInterpreter::ScB()
// double nVal = fabs(gauss(xs / Varianz) - gauss(xe / Varianz));
// PushDouble(nVal);
// }
- if (xe <= n && xs <= xe &&
- p < 1.0 && p > 0.0 && n >= 0.0 && xs >= 0.0 )
+ bool bIsValidX = ( 0.0 <= xs && xs <= xe && xe <= n);
+ if ( bIsValidX && 0.0 < p && p < 1.0 )
{
double q = 1.0 - p;
double fFactor = pow(q, n);
@@ -1342,13 +1347,25 @@ void ScInterpreter::ScB()
}
}
else
- PushIllegalArgument();
+ {
+ if ( bIsValidX ) // not(0<p<1)
+ {
+ if ( p == 0.0 )
+ PushDouble( (xs == 0.0) ? 1.0 : 0.0 );
+ else if ( p == 1.0 )
+ PushDouble( (xe == n) ? 1.0 : 0.0 );
+ else
+ PushIllegalArgument();
+ }
+ else
+ PushIllegalArgument();
+ }
}
}
void ScInterpreter::ScBinomDist()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScBinomDist" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScBinomDist" );
if ( MustHaveParamCount( GetByte(), 4 ) )
{
double kum = GetDouble(); // 0 oder 1
@@ -1429,7 +1446,7 @@ void ScInterpreter::ScBinomDist()
void ScInterpreter::ScCritBinom()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScCritBinom" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScCritBinom" );
if ( MustHaveParamCount( GetByte(), 3 ) )
{
double alpha = GetDouble(); // alpha
@@ -1477,7 +1494,7 @@ void ScInterpreter::ScCritBinom()
void ScInterpreter::ScNegBinomDist()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScNegBinomDist" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScNegBinomDist" );
if ( MustHaveParamCount( GetByte(), 3 ) )
{
double p = GetDouble(); // p
@@ -1498,52 +1515,65 @@ void ScInterpreter::ScNegBinomDist()
void ScInterpreter::ScNormDist()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScNormDist" );
- if ( MustHaveParamCount( GetByte(), 4 ) )
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScNormDist" );
+ BYTE nParamCount = GetByte();
+ if ( !MustHaveParamCount( nParamCount, 3, 4))
+ return;
+ bool bCumulative = nParamCount == 4 ? GetBool() : true;
+ double sigma = GetDouble(); // standard deviation
+ double mue = GetDouble(); // mean
+ double x = GetDouble(); // x
+ if (sigma <= 0.0)
{
- double kum = GetDouble(); // 0 oder 1
- double sigma = GetDouble(); // Stdabw
- double mue = GetDouble(); // Mittelwert
- double x = GetDouble(); // x
- if (sigma < 0.0)
- PushError( errIllegalArgument);
- else if (sigma == 0.0)
- PushError( errDivisionByZero);
- else if (kum == 0.0) // Dichte
- PushDouble(phi((x-mue)/sigma)/sigma);
- else // Verteilung
- PushDouble(0.5 + gauss((x-mue)/sigma));
+ PushIllegalArgument();
+ return;
}
+ if (bCumulative)
+ PushDouble(integralPhi((x-mue)/sigma));
+ else
+ PushDouble(phi((x-mue)/sigma)/sigma);
}
-void ScInterpreter::ScLogNormDist()
+void ScInterpreter::ScLogNormDist() //expanded, see #i100119#
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScLogNormDist" );
- if ( MustHaveParamCount( GetByte(), 3 ) )
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScLogNormDist" );
+ BYTE nParamCount = GetByte();
+ if ( !MustHaveParamCount( nParamCount, 1, 4))
+ return;
+ bool bCumulative = nParamCount == 4 ? GetBool() : true; // cumulative
+ double sigma = nParamCount >= 3 ? GetDouble() : 1.0; // standard deviation
+ double mue = nParamCount >= 2 ? GetDouble() : 0.0; // mean
+ double x = GetDouble(); // x
+ if (sigma <= 0.0)
{
- double sigma = GetDouble(); // Stdabw
- double mue = GetDouble(); // Mittelwert
- double x = GetDouble(); // x
- if (sigma < 0.0)
- PushError( errIllegalArgument);
- else if (sigma == 0.0)
- PushError( errDivisionByZero);
- else if (x <= 0.0)
+ PushIllegalArgument();
+ return;
+ }
+ if (bCumulative)
+ { // cumulative
+ if (x <= 0.0)
+ PushDouble(0.0);
+ else
+ PushDouble(integralPhi((log(x)-mue)/sigma));
+ }
+ else
+ { // density
+ if (x <= 0.0)
PushIllegalArgument();
else
- PushDouble(0.5 + gauss((log(x)-mue)/sigma));
+ PushDouble(phi((log(x)-mue)/sigma)/sigma/x);
}
}
void ScInterpreter::ScStdNormDist()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScStdNormDist" );
- PushDouble(0.5 + gauss(GetDouble()));
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScStdNormDist" );
+ PushDouble(integralPhi(GetDouble()));
}
void ScInterpreter::ScExpDist()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScExpDist" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScExpDist" );
if ( MustHaveParamCount( GetByte(), 3 ) )
{
double kum = GetDouble(); // 0 oder 1
@@ -1570,7 +1600,7 @@ void ScInterpreter::ScExpDist()
void ScInterpreter::ScTDist()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScTDist" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScTDist" );
if ( !MustHaveParamCount( GetByte(), 3 ) )
return;
double fFlag = ::rtl::math::approxFloor(GetDouble());
@@ -1590,7 +1620,7 @@ void ScInterpreter::ScTDist()
void ScInterpreter::ScFDist()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScFDist" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScFDist" );
if ( !MustHaveParamCount( GetByte(), 3 ) )
return;
double fF2 = ::rtl::math::approxFloor(GetDouble());
@@ -1606,7 +1636,7 @@ void ScInterpreter::ScFDist()
void ScInterpreter::ScChiDist()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScChiDist" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScChiDist" );
double fResult;
if ( !MustHaveParamCount( GetByte(), 2 ) )
return;
@@ -1628,7 +1658,7 @@ void ScInterpreter::ScChiDist()
void ScInterpreter::ScWeibull()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScWeibull" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScWeibull" );
if ( MustHaveParamCount( GetByte(), 4 ) )
{
double kum = GetDouble(); // 0 oder 1
@@ -1647,43 +1677,61 @@ void ScInterpreter::ScWeibull()
void ScInterpreter::ScPoissonDist()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScPoissonDist" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScPoissonDist" );
BYTE nParamCount = GetByte();
if ( MustHaveParamCount( nParamCount, 2, 3 ) )
{
- double kum = (nParamCount == 3 ? GetDouble() : 1); // 0 oder 1
- double lambda = GetDouble(); // Mittelwert
- double x = ::rtl::math::approxFloor(GetDouble()); // x
+ bool bCumulative = (nParamCount == 3 ? GetBool() : true); // default cumulative
+ double lambda = GetDouble(); // Mean
+ double x = ::rtl::math::approxFloor(GetDouble()); // discrete distribution
if (lambda < 0.0 || x < 0.0)
PushIllegalArgument();
- else if (kum == 0.0) // Dichte
+ else if (!bCumulative) // Probability mass function
{
if (lambda == 0.0)
PushInt(0);
else
{
- double fPoissonVar = 1.0;
- for ( double f = 0.0; f < x; ++f )
- fPoissonVar *= lambda / ( f + 1.0 );
- PushDouble( fPoissonVar*exp( -lambda ) );
+ if (lambda >712) // underflow in exp(-lambda)
+ { // accuracy 11 Digits
+ PushDouble( exp(x*log(lambda)-lambda-GetLogGamma(x+1.0)));
+ }
+ else
+ {
+ double fPoissonVar = 1.0;
+ for ( double f = 0.0; f < x; ++f )
+ fPoissonVar *= lambda / ( f + 1.0 );
+ PushDouble( fPoissonVar * exp( -lambda ) );
+ }
}
}
- else // Verteilung
+ else // Cumulative distribution function
{
if (lambda == 0.0)
PushInt(1);
else
{
- double sum = 1.0;
- double fFak = 1.0;
- ULONG nEnd = (ULONG) x;
- for (ULONG i = 1; i <= nEnd; i++)
+ if (lambda > 712 ) // underflow in exp(-lambda)
+ { // accuracy 12 Digits
+ PushDouble(GetUpRegIGamma(x+1.0,lambda));
+ }
+ else
{
- fFak *= (double)i;
- sum += pow( lambda, (double)i ) / fFak;
+ if (x >= 936.0) // result is always undistinghable from 1
+ PushDouble (1.0);
+ else
+ {
+ double fSummand = exp(-lambda);
+ double fSum = fSummand;
+ int nEnd = sal::static_int_cast<int>( x );
+ for (int i = 1; i <= nEnd; i++)
+ {
+ fSummand = (fSummand * lambda)/(double)i;
+ fSum += fSummand;
+ }
+ PushDouble(fSum);
+ }
}
- sum *= exp(-lambda);
- PushDouble(sum);
}
}
}
@@ -1716,7 +1764,7 @@ void lcl_PutFactorialElements( ::std::vector< double >& cn, double fLower, doubl
*/
void ScInterpreter::ScHypGeomDist()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScHypGeomDist" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScHypGeomDist" );
const size_t nMaxArraySize = 500000; // arbitrary max array size
if ( !MustHaveParamCount( GetByte(), 4 ) )
@@ -1931,7 +1979,7 @@ void ScInterpreter::ScHypGeomDist()
void ScInterpreter::ScGammaDist()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScGammaDist" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScGammaDist" );
BYTE nParamCount = GetByte();
if ( !MustHaveParamCount( nParamCount, 3, 4 ) )
return;
@@ -1956,7 +2004,7 @@ void ScInterpreter::ScGammaDist()
void ScInterpreter::ScNormInv()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScNormInv" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScNormInv" );
if ( MustHaveParamCount( GetByte(), 3 ) )
{
double sigma = GetDouble();
@@ -1973,7 +2021,7 @@ void ScInterpreter::ScNormInv()
void ScInterpreter::ScSNormInv()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScSNormInv" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScSNormInv" );
double x = GetDouble();
if (x < 0.0 || x > 1.0)
PushIllegalArgument();
@@ -1985,7 +2033,7 @@ void ScInterpreter::ScSNormInv()
void ScInterpreter::ScLogNormInv()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScLogNormInv" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScLogNormInv" );
if ( MustHaveParamCount( GetByte(), 3 ) )
{
double sigma = GetDouble(); // Stdabw
@@ -2012,7 +2060,7 @@ public:
void ScInterpreter::ScGammaInv()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScGammaInv" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScGammaInv" );
if ( !MustHaveParamCount( GetByte(), 3 ) )
return;
double fBeta = GetDouble();
@@ -2051,7 +2099,7 @@ public:
void ScInterpreter::ScBetaInv()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScBetaInv" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScBetaInv" );
BYTE nParamCount = GetByte();
if ( !MustHaveParamCount( nParamCount, 3, 5 ) )
return;
@@ -2105,7 +2153,7 @@ public:
void ScInterpreter::ScTInv()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScTInv" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScTInv" );
if ( !MustHaveParamCount( GetByte(), 2 ) )
return;
double fDF = ::rtl::math::approxFloor(GetDouble());
@@ -2138,7 +2186,7 @@ public:
void ScInterpreter::ScFInv()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScFInv" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScFInv" );
if ( !MustHaveParamCount( GetByte(), 3 ) )
return;
double fF2 = ::rtl::math::approxFloor(GetDouble());
@@ -2172,7 +2220,7 @@ public:
void ScInterpreter::ScChiInv()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScChiInv" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScChiInv" );
if ( !MustHaveParamCount( GetByte(), 2 ) )
return;
double fDF = ::rtl::math::approxFloor(GetDouble());
@@ -2228,7 +2276,7 @@ void ScInterpreter::ScChiSqInv()
void ScInterpreter::ScConfidence()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScConfidence" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScConfidence" );
if ( MustHaveParamCount( GetByte(), 3 ) )
{
double n = ::rtl::math::approxFloor(GetDouble());
@@ -2243,7 +2291,7 @@ void ScInterpreter::ScConfidence()
void ScInterpreter::ScZTest()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScZTest" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScZTest" );
BYTE nParamCount = GetByte();
if ( !MustHaveParamCount( nParamCount, 2, 3 ) )
return;
@@ -2352,9 +2400,12 @@ void ScInterpreter::ScZTest()
{
mue = fSum/rValCount;
if (nParamCount != 3)
+ {
sigma = (fSumSqr - fSum*fSum/rValCount)/(rValCount-1.0);
-
- PushDouble(0.5 - gauss((mue-x)/sqrt(sigma/rValCount)));
+ PushDouble(0.5 - gauss((mue-x)/sqrt(sigma/rValCount)));
+ }
+ else
+ PushDouble(0.5 - gauss((mue-x)*sqrt(rValCount)/sigma));
}
}
bool ScInterpreter::CalculateTest(BOOL _bTemplin
@@ -2362,7 +2413,7 @@ bool ScInterpreter::CalculateTest(BOOL _bTemplin
,const ScMatrixRef& pMat1,const ScMatrixRef& pMat2
,double& fT,double& fF)
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::CalculateTest" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::CalculateTest" );
double fCount1 = 0.0;
double fCount2 = 0.0;
double fSum1 = 0.0;
@@ -2430,7 +2481,7 @@ bool ScInterpreter::CalculateTest(BOOL _bTemplin
}
void ScInterpreter::ScTTest()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScTTest" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScTTest" );
if ( !MustHaveParamCount( GetByte(), 4 ) )
return;
double fTyp = ::rtl::math::approxFloor(GetDouble());
@@ -2510,7 +2561,7 @@ void ScInterpreter::ScTTest()
void ScInterpreter::ScFTest()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScFTest" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScFTest" );
if ( !MustHaveParamCount( GetByte(), 2 ) )
return;
ScMatrixRef pMat2 = GetMatrix();
@@ -2589,7 +2640,7 @@ void ScInterpreter::ScFTest()
void ScInterpreter::ScChiTest()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScChiTest" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScChiTest" );
if ( !MustHaveParamCount( GetByte(), 2 ) )
return;
ScMatrixRef pMat2 = GetMatrix();
@@ -2662,7 +2713,7 @@ void ScInterpreter::ScChiTest()
void ScInterpreter::ScKurt()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScKurt" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScKurt" );
double fSum,fCount,vSum;
std::vector<double> values;
if ( !CalculateSkew(fSum,fCount,vSum,values) )
@@ -2704,7 +2755,7 @@ void ScInterpreter::ScKurt()
void ScInterpreter::ScHarMean()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScHarMean" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScHarMean" );
short nParamCount = GetByte();
double nVal = 0.0;
double nValCount = 0.0;
@@ -2824,7 +2875,7 @@ void ScInterpreter::ScHarMean()
void ScInterpreter::ScGeoMean()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScGeoMean" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScGeoMean" );
short nParamCount = GetByte();
double nVal = 0.0;
double nValCount = 0.0;
@@ -2945,7 +2996,7 @@ void ScInterpreter::ScGeoMean()
void ScInterpreter::ScStandard()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScStandard" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScStandard" );
if ( MustHaveParamCount( GetByte(), 3 ) )
{
double sigma = GetDouble();
@@ -2961,7 +3012,7 @@ void ScInterpreter::ScStandard()
}
bool ScInterpreter::CalculateSkew(double& fSum,double& fCount,double& vSum,std::vector<double>& values)
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::CalculateSkew" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::CalculateSkew" );
short nParamCount = GetByte();
if ( !MustHaveParamCountMin( nParamCount, 1 ) )
return false;
@@ -3066,7 +3117,7 @@ bool ScInterpreter::CalculateSkew(double& fSum,double& fCount,double& vSum,std::
void ScInterpreter::ScSkew()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScSkew" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScSkew" );
double fSum,fCount,vSum;
std::vector<double> values;
if ( !CalculateSkew(fSum,fCount,vSum,values) )
@@ -3123,7 +3174,7 @@ double ScInterpreter::GetMedian( vector<double> & rArray )
void ScInterpreter::ScMedian()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScMedian" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScMedian" );
BYTE nParamCount = GetByte();
if ( !MustHaveParamCountMin( nParamCount, 1 ) )
return;
@@ -3165,7 +3216,7 @@ double ScInterpreter::GetPercentile( vector<double> & rArray, double fPercentile
void ScInterpreter::ScPercentile()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScPercentile" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScPercentile" );
if ( !MustHaveParamCount( GetByte(), 2 ) )
return;
double alpha = GetDouble();
@@ -3181,7 +3232,7 @@ void ScInterpreter::ScPercentile()
void ScInterpreter::ScQuartile()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScQuartile" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScQuartile" );
if ( !MustHaveParamCount( GetByte(), 2 ) )
return;
double fFlag = ::rtl::math::approxFloor(GetDouble());
@@ -3197,7 +3248,7 @@ void ScInterpreter::ScQuartile()
void ScInterpreter::ScModalValue()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScModalValue" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScModalValue" );
BYTE nParamCount = GetByte();
if ( !MustHaveParamCountMin( nParamCount, 1 ) )
return;
@@ -3243,7 +3294,7 @@ void ScInterpreter::ScModalValue()
void ScInterpreter::CalculateSmallLarge(BOOL bSmall)
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::CalculateSmallLarge" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::CalculateSmallLarge" );
if ( !MustHaveParamCount( GetByte(), 2 ) )
return;
double f = ::rtl::math::approxFloor(GetDouble());
@@ -3274,19 +3325,19 @@ void ScInterpreter::CalculateSmallLarge(BOOL bSmall)
void ScInterpreter::ScLarge()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScLarge" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScLarge" );
CalculateSmallLarge(FALSE);
}
void ScInterpreter::ScSmall()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScSmall" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScSmall" );
CalculateSmallLarge(TRUE);
}
void ScInterpreter::ScPercentrank()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScPercentrank" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScPercentrank" );
BYTE nParamCount = GetByte();
if ( !MustHaveParamCount( nParamCount, 2 ) )
return;
@@ -3361,7 +3412,7 @@ void ScInterpreter::ScPercentrank()
void ScInterpreter::ScTrimMean()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScTrimMean" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScTrimMean" );
if ( !MustHaveParamCount( GetByte(), 2 ) )
return;
double alpha = GetDouble();
@@ -3391,7 +3442,7 @@ void ScInterpreter::ScTrimMean()
void ScInterpreter::GetNumberSequenceArray( BYTE nParamCount, vector<double>& rArray )
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::GetSortArray" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::GetSortArray" );
ScAddress aAdr;
ScRange aRange;
short nParam = nParamCount;
@@ -3537,7 +3588,7 @@ static void lcl_QuickSort( long nLo, long nHi, vector<double>& rSortArray, vecto
void ScInterpreter::QuickSort( vector<double>& rSortArray, vector<long>* pIndexOrder )
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::QuickSort" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::QuickSort" );
long n = static_cast<long>(rSortArray.size());
if (pIndexOrder)
@@ -3565,7 +3616,7 @@ void ScInterpreter::QuickSort( vector<double>& rSortArray, vector<long>* pIndexO
void ScInterpreter::ScRank()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScRank" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScRank" );
BYTE nParamCount = GetByte();
if ( !MustHaveParamCount( nParamCount, 2, 3 ) )
return;
@@ -3685,7 +3736,7 @@ void ScInterpreter::ScRank()
void ScInterpreter::ScAveDev()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScAveDev" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScAveDev" );
BYTE nParamCount = GetByte();
if ( !MustHaveParamCountMin( nParamCount, 1 ) )
return;
@@ -3840,7 +3891,7 @@ void ScInterpreter::ScAveDev()
void ScInterpreter::ScDevSq()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScDevSq" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScDevSq" );
double nVal;
double nValCount;
GetStVarParams(nVal, nValCount);
@@ -3849,7 +3900,7 @@ void ScInterpreter::ScDevSq()
void ScInterpreter::ScProbability()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScProbability" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScProbability" );
BYTE nParamCount = GetByte();
if ( !MustHaveParamCount( nParamCount, 3, 4 ) )
return;
@@ -3913,25 +3964,25 @@ void ScInterpreter::ScProbability()
void ScInterpreter::ScCorrel()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScCorrel" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScCorrel" );
// This is identical to ScPearson()
ScPearson();
}
void ScInterpreter::ScCovar()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScCovar" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScCovar" );
CalculatePearsonCovar(FALSE,FALSE);
}
void ScInterpreter::ScPearson()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScPearson" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScPearson" );
CalculatePearsonCovar(TRUE,FALSE);
}
void ScInterpreter::CalculatePearsonCovar(BOOL _bPearson,BOOL _bStexy)
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::CalculatePearsonCovar" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::CalculatePearsonCovar" );
if ( !MustHaveParamCount( GetByte(), 2 ) )
return;
ScMatrixRef pMat1 = GetMatrix();
@@ -4017,7 +4068,7 @@ void ScInterpreter::CalculatePearsonCovar(BOOL _bPearson,BOOL _bStexy)
void ScInterpreter::ScRSQ()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScRSQ" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScRSQ" );
// Same as ScPearson()*ScPearson()
ScPearson();
if (!nGlobalError)
@@ -4039,12 +4090,12 @@ void ScInterpreter::ScRSQ()
void ScInterpreter::ScSTEXY()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScSTEXY" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScSTEXY" );
CalculatePearsonCovar(TRUE,TRUE);
}
void ScInterpreter::CalculateSlopeIntercept(BOOL bSlope)
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::CalculateSlopeIntercept" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::CalculateSlopeIntercept" );
if ( !MustHaveParamCount( GetByte(), 2 ) )
return;
ScMatrixRef pMat1 = GetMatrix();
@@ -4116,19 +4167,19 @@ void ScInterpreter::CalculateSlopeIntercept(BOOL bSlope)
void ScInterpreter::ScSlope()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScSlope" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScSlope" );
CalculateSlopeIntercept(TRUE);
}
void ScInterpreter::ScIntercept()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScIntercept" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScIntercept" );
CalculateSlopeIntercept(FALSE);
}
void ScInterpreter::ScForecast()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScForecast" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScForecast" );
if ( !MustHaveParamCount( GetByte(), 3 ) )
return;
ScMatrixRef pMat1 = GetMatrix();
diff --git a/sc/source/core/tool/interpr4.cxx b/sc/source/core/tool/interpr4.cxx
index a73fe62998a6..a5644985206f 100644
--- a/sc/source/core/tool/interpr4.cxx
+++ b/sc/source/core/tool/interpr4.cxx
@@ -99,7 +99,7 @@ ScSpew ScInterpreter::theSpew;
void ScInterpreter::ReplaceCell( ScAddress& rPos )
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ReplaceCell" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ReplaceCell" );
ScInterpreterTableOpParams* pTOp = pDok->aTableOpList.First();
while (pTOp)
{
@@ -121,7 +121,7 @@ void ScInterpreter::ReplaceCell( ScAddress& rPos )
void ScInterpreter::ReplaceCell( SCCOL& rCol, SCROW& rRow, SCTAB& rTab )
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ReplaceCell" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ReplaceCell" );
ScAddress aCellPos( rCol, rRow, rTab );
ScInterpreterTableOpParams* pTOp = pDok->aTableOpList.First();
while (pTOp)
@@ -148,7 +148,7 @@ void ScInterpreter::ReplaceCell( SCCOL& rCol, SCROW& rRow, SCTAB& rTab )
BOOL ScInterpreter::IsTableOpInRange( const ScRange& rRange )
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::IsTableOpInRange" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::IsTableOpInRange" );
if ( rRange.aStart == rRange.aEnd )
return FALSE; // not considered to be a range in TableOp sense
@@ -168,7 +168,7 @@ BOOL ScInterpreter::IsTableOpInRange( const ScRange& rRange )
ULONG ScInterpreter::GetCellNumberFormat( const ScAddress& rPos, const ScBaseCell* pCell)
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::GetCellNumberFormat" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::GetCellNumberFormat" );
ULONG nFormat;
USHORT nErr;
if ( pCell )
@@ -193,10 +193,10 @@ ULONG ScInterpreter::GetCellNumberFormat( const ScAddress& rPos, const ScBaseCel
}
-// nur ValueCell, Formelzellen speichern das Ergebnis bereits gerundet
+/// Only ValueCell, formula cells already store the result rounded.
double ScInterpreter::GetValueCellValue( const ScAddress& rPos, const ScValueCell* pCell )
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::GetValueCellValue" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::GetValueCellValue" );
double fVal = pCell->GetValue();
if ( bCalcAsShown && fVal != 0.0 )
{
@@ -207,9 +207,207 @@ double ScInterpreter::GetValueCellValue( const ScAddress& rPos, const ScValueCel
}
+/** Convert string content to numeric value.
+
+ Converted are only integer numbers including exponent, and ISO 8601 dates
+ and times in their extended formats with separators. Anything else,
+ especially fractional numeric values with decimal separators or dates other
+ than ISO 8601 would be locale dependent and is a no-no. Leading and
+ trailing blanks are ignored.
+
+ The following ISO 8601 formats are converted:
+
+ CCYY-MM-DD
+ CCYY-MM-DDThh:mm
+ CCYY-MM-DDThh:mm:ss
+ CCYY-MM-DDThh:mm:ss,s
+ CCYY-MM-DDThh:mm:ss.s
+ hh:mm
+ hh:mm:ss
+ hh:mm:ss,s
+ hh:mm:ss.s
+
+ The century CC may not be omitted and the two-digit year setting is not
+ taken into account. Instead of the T date and time separator exactly one
+ blank may be used.
+
+ If a date is given, it must be a valid Gregorian calendar date. In this
+ case the optional time must be in the range 00:00 to 23:59:59.99999...
+ If only time is given, it may have any value for hours, taking elapsed time
+ into account; minutes and seconds are limited to the value 59 as well.
+ */
+
+double ScInterpreter::ConvertStringToValue( const String& rStr )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ConvertStringToValue" );
+ double fValue = 0.0;
+ ::rtl::OUString aStr( rStr);
+ rtl_math_ConversionStatus eStatus;
+ sal_Int32 nParseEnd;
+ // Decimal and group separator 0 => only integer and possibly exponent,
+ // stops at first non-digit non-sign.
+ fValue = ::rtl::math::stringToDouble( aStr, 0, 0, &eStatus, &nParseEnd);
+ sal_Int32 nLen;
+ if (eStatus == rtl_math_ConversionStatus_Ok && nParseEnd < (nLen = aStr.getLength()))
+ {
+ // Not at string end, check for trailing blanks or switch to date or
+ // time parsing or bail out.
+ const sal_Unicode* const pStart = aStr.getStr();
+ const sal_Unicode* p = pStart + nParseEnd;
+ const sal_Unicode* const pStop = pStart + nLen;
+ switch (*p++)
+ {
+ case ' ':
+ while (p < pStop && *p == ' ')
+ ++p;
+ if (p < pStop)
+ SetError( errNoValue);
+ break;
+ case '-':
+ case ':':
+ {
+ bool bDate = (*(p-1) == '-');
+ enum State { year = 0, month, day, hour, minute, second, fraction, done, blank, stop };
+ sal_Int32 nUnit[done] = {0,0,0,0,0,0,0};
+ const sal_Int32 nLimit[done] = {0,12,31,0,59,59,0};
+ State eState = (bDate ? month : minute);
+ nCurFmtType = (bDate ? NUMBERFORMAT_DATE : NUMBERFORMAT_TIME);
+ nUnit[eState-1] = aStr.copy( 0, nParseEnd).toInt32();
+ const sal_Unicode* pLastStart = p;
+ // Ensure there's no preceding sign. Negative dates
+ // currently aren't handled correctly. Also discard
+ // +CCYY-MM-DD
+ p = pStart;
+ while (p < pStop && *p == ' ')
+ ++p;
+ if (p < pStop && !CharClass::isAsciiDigit(*p))
+ SetError( errNoValue);
+ p = pLastStart;
+ while (p < pStop && !nGlobalError && eState < blank)
+ {
+ if (eState == minute)
+ nCurFmtType |= NUMBERFORMAT_TIME;
+ if (CharClass::isAsciiDigit(*p))
+ {
+ // Maximum 2 digits per unit, except fractions.
+ if (p - pLastStart >= 2 && eState != fraction)
+ SetError( errNoValue);
+ }
+ else if (p > pLastStart)
+ {
+ // We had at least one digit.
+ if (eState < done)
+ {
+ nUnit[eState] = aStr.copy( pLastStart - pStart, p - pLastStart).toInt32();
+ if (nLimit[eState] && nLimit[eState] < nUnit[eState])
+ SetError( errNoValue);
+ }
+ pLastStart = p + 1; // hypothetical next start
+ // Delimiters must match, a trailing delimiter
+ // yields an invalid date/time.
+ switch (eState)
+ {
+ case month:
+ // Month must be followed by separator and
+ // day, no trailing blanks.
+ if (*p != '-' || (p+1 == pStop))
+ SetError( errNoValue);
+ break;
+ case day:
+ if ((*p != 'T' || (p+1 == pStop)) && *p != ' ')
+ SetError( errNoValue);
+ // Take one blank as a valid delimiter
+ // between date and time.
+ break;
+ case hour:
+ // Hour must be followed by separator and
+ // minute, no trailing blanks.
+ if (*p != ':' || (p+1 == pStop))
+ SetError( errNoValue);
+ break;
+ case minute:
+ if ((*p != ':' || (p+1 == pStop)) && *p != ' ')
+ SetError( errNoValue);
+ if (*p == ' ')
+ eState = done;
+ break;
+ case second:
+ if (((*p != ',' && *p != '.') || (p+1 == pStop)) && *p != ' ')
+ SetError( errNoValue);
+ if (*p == ' ')
+ eState = done;
+ break;
+ case fraction:
+ eState = done;
+ break;
+ case year:
+ case done:
+ case blank:
+ case stop:
+ SetError( errNoValue);
+ break;
+ }
+ eState = static_cast<State>(eState + 1);
+ }
+ else
+ SetError( errNoValue);
+ ++p;
+ }
+ if (eState == blank)
+ {
+ while (p < pStop && *p == ' ')
+ ++p;
+ if (p < pStop)
+ SetError( errNoValue);
+ eState = stop;
+ }
+
+ // Month without day, or hour without minute.
+ if (eState == month || (eState == day && p <= pLastStart) ||
+ eState == hour || (eState == minute && p <= pLastStart))
+ SetError( errNoValue);
+
+ if (!nGlobalError)
+ {
+ // Catch the very last unit at end of string.
+ if (p > pLastStart && eState < done)
+ {
+ nUnit[eState] = aStr.copy( pLastStart - pStart, p - pLastStart).toInt32();
+ if (nLimit[eState] && nLimit[eState] < nUnit[eState])
+ SetError( errNoValue);
+ }
+ if (bDate && nUnit[hour] > 23)
+ SetError( errNoValue);
+ if (!nGlobalError)
+ {
+ if (bDate && nUnit[day] == 0)
+ nUnit[day] = 1;
+ double fFraction = (nUnit[fraction] <= 0 ? 0.0 :
+ ::rtl::math::pow10Exp( nUnit[fraction],
+ static_cast<int>( -ceil( log10( static_cast<double>( nUnit[fraction]))))));
+ fValue = (bDate ? GetDateSerial(
+ sal::static_int_cast<INT16>(nUnit[year]),
+ sal::static_int_cast<INT16>(nUnit[month]),
+ sal::static_int_cast<INT16>(nUnit[day]),
+ true) : 0.0);
+ fValue += ((nUnit[hour] * 3600) + (nUnit[minute] * 60) + nUnit[second] + fFraction) / 86400.0;
+ }
+ }
+ }
+ break;
+ default:
+ SetError( errNoValue);
+ }
+ if (nGlobalError)
+ fValue = 0.0;
+ }
+ return fValue;
+}
+
+
double ScInterpreter::GetCellValue( const ScAddress& rPos, const ScBaseCell* pCell )
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::GetCellValue" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::GetCellValue" );
USHORT nErr = nGlobalError;
nGlobalError = 0;
double nVal = GetCellValueOrZero( rPos, pCell );
@@ -221,8 +419,8 @@ double ScInterpreter::GetCellValue( const ScAddress& rPos, const ScBaseCell* pCe
double ScInterpreter::GetCellValueOrZero( const ScAddress& rPos, const ScBaseCell* pCell )
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::GetCellValueOrZero" );
- double fValue;
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::GetCellValueOrZero" );
+ double fValue = 0.0;
if (pCell)
{
CellType eType = pCell->GetCellType();
@@ -242,8 +440,9 @@ double ScInterpreter::GetCellValueOrZero( const ScAddress& rPos, const ScBaseCel
}
else
{
- SetError(errCellNoValue);
- fValue = 0.0;
+ String aStr;
+ pFCell->GetString( aStr );
+ fValue = ConvertStringToValue( aStr );
}
}
else
@@ -264,26 +463,28 @@ double ScInterpreter::GetCellValueOrZero( const ScAddress& rPos, const ScBaseCel
break;
case CELLTYPE_STRING:
case CELLTYPE_EDIT:
-#if 0
-// Xcl does it, but SUM(A1:A2) differs from A1+A2. No good.
{
+ // SUM(A1:A2) differs from A1+A2. No good. But people insist on
+ // it ... #i5658#
String aStr;
if ( eType == CELLTYPE_STRING )
((ScStringCell*)pCell)->GetString( aStr );
else
((ScEditCell*)pCell)->GetString( aStr );
- sal_uInt32 nFIndex = 0; // damit default Land/Spr.
- if ( !pFormatter->IsNumberFormat( aStr, nFIndex, fValue ) )
- {
- SetError(errNoValue);
- fValue = 0.0;
- }
+ fValue = ConvertStringToValue( aStr );
}
break;
+ case CELLTYPE_NONE:
+ case CELLTYPE_NOTE:
+ fValue = 0.0; // empty or broadcaster cell
+ break;
+ case CELLTYPE_SYMBOLS:
+#if DBG_UTIL
+ case CELLTYPE_DESTROYED:
#endif
- default:
SetError(errCellNoValue);
fValue = 0.0;
+ break;
}
}
else
@@ -294,7 +495,7 @@ double ScInterpreter::GetCellValueOrZero( const ScAddress& rPos, const ScBaseCel
void ScInterpreter::GetCellString( String& rStr, const ScBaseCell* pCell )
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::GetCellString" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::GetCellString" );
USHORT nErr = 0;
if (pCell)
{
@@ -345,7 +546,7 @@ void ScInterpreter::GetCellString( String& rStr, const ScBaseCell* pCell )
BOOL ScInterpreter::CreateDoubleArr(SCCOL nCol1, SCROW nRow1, SCTAB nTab1,
SCCOL nCol2, SCROW nRow2, SCTAB nTab2, BYTE* pCellArr)
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::CreateDoubleArr" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::CreateDoubleArr" );
#if SC_ROWLIMIT_MORE_THAN_64K
#error row limit 64k
#endif
@@ -426,7 +627,7 @@ BOOL ScInterpreter::CreateStringArr(SCCOL nCol1, SCROW nRow1, SCTAB nTab1,
SCCOL nCol2, SCROW nRow2, SCTAB nTab2,
BYTE* pCellArr)
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::CreateStringArr" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::CreateStringArr" );
#if SC_ROWLIMIT_MORE_THAN_64K
#error row limit 64k
#endif
@@ -521,7 +722,7 @@ BOOL ScInterpreter::CreateCellArr(SCCOL nCol1, SCROW nRow1, SCTAB nTab1,
SCCOL nCol2, SCROW nRow2, SCTAB nTab2,
BYTE* pCellArr)
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::CreateCellArr" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::CreateCellArr" );
#if SC_ROWLIMIT_MORE_THAN_64K
#error row limit 64k
#endif
@@ -642,7 +843,7 @@ BOOL ScInterpreter::CreateCellArr(SCCOL nCol1, SCROW nRow1, SCTAB nTab1,
void ScInterpreter::PushWithoutError( FormulaToken& r )
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::PushWithoutError" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::PushWithoutError" );
if ( sp >= MAXSTACK )
SetError( errStackOverflow );
else
@@ -660,7 +861,7 @@ void ScInterpreter::PushWithoutError( FormulaToken& r )
void ScInterpreter::Push( FormulaToken& r )
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::Push" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::Push" );
if ( sp >= MAXSTACK )
SetError( errStackOverflow );
else
@@ -683,7 +884,7 @@ void ScInterpreter::Push( FormulaToken& r )
void ScInterpreter::PushTempToken( FormulaToken* p )
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::PushTempToken" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::PushTempToken" );
if ( sp >= MAXSTACK )
{
SetError( errStackOverflow );
@@ -716,7 +917,7 @@ void ScInterpreter::PushTempToken( FormulaToken* p )
void ScInterpreter::PushTempTokenWithoutError( FormulaToken* p )
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::PushTempTokenWithoutError" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::PushTempTokenWithoutError" );
p->IncRef();
if ( sp >= MAXSTACK )
{
@@ -738,7 +939,7 @@ void ScInterpreter::PushTempTokenWithoutError( FormulaToken* p )
void ScInterpreter::PushTempToken( const FormulaToken& r )
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::PushTempToken" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::PushTempToken" );
if (!IfErrorPushError())
PushTempTokenWithoutError( r.Clone());
}
@@ -747,7 +948,7 @@ void ScInterpreter::PushTempToken( const FormulaToken& r )
void ScInterpreter::PushCellResultToken( bool bDisplayEmptyAsString,
const ScAddress & rAddress, short * pRetTypeExpr, ULONG * pRetIndexExpr )
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::PushCellResultToken" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::PushCellResultToken" );
ScBaseCell* pCell = pDok->GetCell( rAddress);
if (!pCell || pCell->HasEmptyData())
{
@@ -792,7 +993,7 @@ void ScInterpreter::PushCellResultToken( bool bDisplayEmptyAsString,
void ScInterpreter::Pop()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::Pop" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::Pop" );
if( sp )
sp--;
else
@@ -804,7 +1005,7 @@ void ScInterpreter::Pop()
void ScInterpreter::PopError()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::PopError" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::PopError" );
if( sp )
{
sp--;
@@ -818,7 +1019,7 @@ void ScInterpreter::PopError()
FormulaTokenRef ScInterpreter::PopToken()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::PopToken" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::PopToken" );
if (sp)
{
sp--;
@@ -835,7 +1036,7 @@ FormulaTokenRef ScInterpreter::PopToken()
double ScInterpreter::PopDouble()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::PopDouble" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::PopDouble" );
nCurFmtType = NUMBERFORMAT_NUMBER;
nCurFmtIndex = 0;
if( sp )
@@ -864,7 +1065,7 @@ double ScInterpreter::PopDouble()
const String& ScInterpreter::PopString()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::PopString" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::PopString" );
nCurFmtType = NUMBERFORMAT_TEXT;
nCurFmtIndex = 0;
if( sp )
@@ -893,7 +1094,7 @@ const String& ScInterpreter::PopString()
void ScInterpreter::ValidateRef( const ScSingleRefData & rRef )
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ValidateRef" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ValidateRef" );
SCCOL nCol;
SCROW nRow;
SCTAB nTab;
@@ -903,7 +1104,7 @@ void ScInterpreter::ValidateRef( const ScSingleRefData & rRef )
void ScInterpreter::ValidateRef( const ScComplexRefData & rRef )
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ValidateRef" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ValidateRef" );
ValidateRef( rRef.Ref1);
ValidateRef( rRef.Ref2);
}
@@ -911,7 +1112,7 @@ void ScInterpreter::ValidateRef( const ScComplexRefData & rRef )
void ScInterpreter::ValidateRef( const ScRefList & rRefList )
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ValidateRef" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ValidateRef" );
ScRefList::const_iterator it( rRefList.begin());
ScRefList::const_iterator end( rRefList.end());
for ( ; it != end; ++it)
@@ -924,7 +1125,7 @@ void ScInterpreter::ValidateRef( const ScRefList & rRefList )
void ScInterpreter::SingleRefToVars( const ScSingleRefData & rRef,
SCCOL & rCol, SCROW & rRow, SCTAB & rTab )
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::SingleRefToVars" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::SingleRefToVars" );
if ( rRef.IsColRel() )
rCol = aPos.Col() + rRef.nRelCol;
else
@@ -948,7 +1149,7 @@ void ScInterpreter::SingleRefToVars( const ScSingleRefData & rRef,
void ScInterpreter::PopSingleRef(SCCOL& rCol, SCROW &rRow, SCTAB& rTab)
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::PopSingleRef" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::PopSingleRef" );
if( sp )
{
--sp;
@@ -974,7 +1175,7 @@ void ScInterpreter::PopSingleRef(SCCOL& rCol, SCROW &rRow, SCTAB& rTab)
void ScInterpreter::PopSingleRef( ScAddress& rAdr )
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::PopSingleRef" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::PopSingleRef" );
if( sp )
{
--sp;
@@ -1009,7 +1210,7 @@ void ScInterpreter::DoubleRefToVars( const ScToken* p,
SCCOL& rCol2, SCROW &rRow2, SCTAB& rTab2,
BOOL bDontCheckForTableOp )
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::DoubleRefToVars" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::DoubleRefToVars" );
const ScComplexRefData& rCRef = p->GetDoubleRef();
SingleRefToVars( rCRef.Ref1, rCol1, rRow1, rTab1);
SingleRefToVars( rCRef.Ref2, rCol2, rRow2, rTab2);
@@ -1026,7 +1227,7 @@ void ScInterpreter::PopDoubleRef(SCCOL& rCol1, SCROW &rRow1, SCTAB& rTab1,
SCCOL& rCol2, SCROW &rRow2, SCTAB& rTab2,
BOOL bDontCheckForTableOp )
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::PopDoubleRef" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::PopDoubleRef" );
if( sp )
{
--sp;
@@ -1052,7 +1253,7 @@ void ScInterpreter::PopDoubleRef(SCCOL& rCol1, SCROW &rRow1, SCTAB& rTab1,
void ScInterpreter::DoubleRefToRange( const ScComplexRefData & rCRef,
ScRange & rRange, BOOL bDontCheckForTableOp )
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::DoubleRefToRange" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::DoubleRefToRange" );
SCCOL nCol;
SCROW nRow;
SCTAB nTab;
@@ -1070,7 +1271,7 @@ void ScInterpreter::DoubleRefToRange( const ScComplexRefData & rCRef,
void ScInterpreter::PopDoubleRef( ScRange & rRange, short & rParam, size_t & rRefInList )
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::PopDoubleRef" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::PopDoubleRef" );
if (sp)
{
formula::FormulaToken* pToken = pStack[ sp-1 ];
@@ -1117,7 +1318,7 @@ void ScInterpreter::PopDoubleRef( ScRange & rRange, short & rParam, size_t & rRe
void ScInterpreter::PopDoubleRef( ScRange& rRange, BOOL bDontCheckForTableOp )
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::PopDoubleRef" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::PopDoubleRef" );
if( sp )
{
--sp;
@@ -1141,7 +1342,7 @@ void ScInterpreter::PopDoubleRef( ScRange& rRange, BOOL bDontCheckForTableOp )
BOOL ScInterpreter::PopDoubleRefOrSingleRef( ScAddress& rAdr )
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::PopDoubleRefOrSingleRef" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::PopDoubleRefOrSingleRef" );
switch ( GetStackType() )
{
case svDoubleRef :
@@ -1167,7 +1368,7 @@ BOOL ScInterpreter::PopDoubleRefOrSingleRef( ScAddress& rAdr )
void ScInterpreter::PopDoubleRefPushMatrix()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::PopDoubleRefPushMatrix" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::PopDoubleRefPushMatrix" );
if ( GetStackType() == svDoubleRef )
{
ScMatrixRef pMat = GetMatrix();
@@ -1183,14 +1384,14 @@ void ScInterpreter::PopDoubleRefPushMatrix()
ScTokenMatrixMap* ScInterpreter::CreateTokenMatrixMap()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::CreateTokenMatrixMap" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::CreateTokenMatrixMap" );
return new ScTokenMatrixMap;
}
bool ScInterpreter::ConvertMatrixParameters()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ConvertMatrixParameters" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ConvertMatrixParameters" );
USHORT nParams = pCur->GetParamCount();
DBG_ASSERT( nParams <= sp, "ConvertMatrixParameters: stack/param count mismatch");
SCSIZE nJumpCols = 0, nJumpRows = 0;
@@ -1237,7 +1438,8 @@ bool ScInterpreter::ConvertMatrixParameters()
{
ScParameterClassification::Type eType =
ScParameterClassification::GetParameterType( pCur, nParams - i);
- if ( eType != ScParameterClassification::Reference )
+ if ( eType != ScParameterClassification::Reference &&
+ eType != ScParameterClassification::ReferenceOrForceArray)
{
SCCOL nCol1, nCol2;
SCROW nRow1, nRow2;
@@ -1268,7 +1470,8 @@ bool ScInterpreter::ConvertMatrixParameters()
{
ScParameterClassification::Type eType =
ScParameterClassification::GetParameterType( pCur, nParams - i);
- if ( eType != ScParameterClassification::Reference )
+ if ( eType != ScParameterClassification::Reference &&
+ eType != ScParameterClassification::ReferenceOrForceArray)
{
// can't convert to matrix
SetError( errNoValue);
@@ -1320,7 +1523,7 @@ bool ScInterpreter::ConvertMatrixParameters()
ScMatrixRef ScInterpreter::PopMatrix()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::PopMatrix" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::PopMatrix" );
if( sp )
{
--sp;
@@ -1351,7 +1554,7 @@ ScMatrixRef ScInterpreter::PopMatrix()
void ScInterpreter::PushDouble(double nVal)
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::PushDouble" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::PushDouble" );
TreatDoubleError( nVal );
if (!IfErrorPushError())
PushTempTokenWithoutError( new FormulaDoubleToken( nVal ) );
@@ -1360,7 +1563,7 @@ void ScInterpreter::PushDouble(double nVal)
void ScInterpreter::PushInt(int nVal)
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::PushInt" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::PushInt" );
if (!IfErrorPushError())
PushTempTokenWithoutError( new FormulaDoubleToken( nVal ) );
}
@@ -1368,7 +1571,7 @@ void ScInterpreter::PushInt(int nVal)
void ScInterpreter::PushStringBuffer( const sal_Unicode* pString )
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::PushStringBuffer" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::PushStringBuffer" );
if ( pString )
PushString( String( pString ) );
else
@@ -1378,7 +1581,7 @@ void ScInterpreter::PushStringBuffer( const sal_Unicode* pString )
void ScInterpreter::PushString( const String& rString )
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::PushString" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::PushString" );
if (!IfErrorPushError())
PushTempTokenWithoutError( new FormulaStringToken( rString ) );
}
@@ -1386,7 +1589,7 @@ void ScInterpreter::PushString( const String& rString )
void ScInterpreter::PushSingleRef(SCCOL nCol, SCROW nRow, SCTAB nTab)
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::PushSingleRef" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::PushSingleRef" );
if (!IfErrorPushError())
{
ScSingleRefData aRef;
@@ -1402,7 +1605,7 @@ void ScInterpreter::PushSingleRef(SCCOL nCol, SCROW nRow, SCTAB nTab)
void ScInterpreter::PushDoubleRef(SCCOL nCol1, SCROW nRow1, SCTAB nTab1,
SCCOL nCol2, SCROW nRow2, SCTAB nTab2)
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::PushDoubleRef" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::PushDoubleRef" );
if (!IfErrorPushError())
{
ScComplexRefData aRef;
@@ -1420,7 +1623,7 @@ void ScInterpreter::PushDoubleRef(SCCOL nCol1, SCROW nRow1, SCTAB nTab1,
void ScInterpreter::PushMatrix(ScMatrix* pMat)
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::PushMatrix" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::PushMatrix" );
pMat->SetErrorInterpreter( NULL);
// No if (!IfErrorPushError()) because ScMatrix stores errors itself,
// but with notifying ScInterpreter via nGlobalError, substituting it would
@@ -1433,56 +1636,56 @@ void ScInterpreter::PushMatrix(ScMatrix* pMat)
void ScInterpreter::PushError( USHORT nError )
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::PushError" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::PushError" );
SetError( nError ); // only sets error if not already set
PushTempTokenWithoutError( new FormulaErrorToken( nGlobalError));
}
void ScInterpreter::PushParameterExpected()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::PushParameterExpected" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::PushParameterExpected" );
PushError( errParameterExpected);
}
void ScInterpreter::PushIllegalParameter()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::PushIllegalParameter" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::PushIllegalParameter" );
PushError( errIllegalParameter);
}
void ScInterpreter::PushIllegalArgument()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::PushIllegalArgument" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::PushIllegalArgument" );
PushError( errIllegalArgument);
}
void ScInterpreter::PushNA()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::PushNA" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::PushNA" );
PushError( NOTAVAILABLE);
}
void ScInterpreter::PushNoValue()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::PushNoValue" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::PushNoValue" );
PushError( errNoValue);
}
BOOL ScInterpreter::IsMissing()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::IsMissing" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::IsMissing" );
return sp && pStack[sp - 1]->GetType() == svMissing;
}
StackVar ScInterpreter::GetRawStackType()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::GetRawStackType" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::GetRawStackType" );
StackVar eRes;
if( sp )
{
@@ -1499,7 +1702,7 @@ StackVar ScInterpreter::GetRawStackType()
StackVar ScInterpreter::GetStackType()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::GetStackType" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::GetStackType" );
StackVar eRes;
if( sp )
{
@@ -1518,7 +1721,7 @@ StackVar ScInterpreter::GetStackType()
StackVar ScInterpreter::GetStackType( BYTE nParam )
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::GetStackType" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::GetStackType" );
StackVar eRes;
if( sp > nParam-1 )
{
@@ -1534,7 +1737,7 @@ StackVar ScInterpreter::GetStackType( BYTE nParam )
BOOL ScInterpreter::DoubleRefToPosSingleRef( const ScRange& rRange, ScAddress& rAdr )
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::DoubleRefToPosSingleRef" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::DoubleRefToPosSingleRef" );
// Check for a singleton first - no implicit intersection for them.
if( rRange.aStart == rRange.aEnd )
{
@@ -1623,7 +1826,7 @@ BOOL ScInterpreter::DoubleRefToPosSingleRef( const ScRange& rRange, ScAddress& r
double ScInterpreter::GetDouble()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::GetDouble" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::GetDouble" );
double nVal;
switch( GetRawStackType() )
{
@@ -1631,15 +1834,7 @@ double ScInterpreter::GetDouble()
nVal = PopDouble();
break;
case svString:
- {
- String aStr(PopString());
- sal_uInt32 nFIndex = 0; // damit default Land/Spr.
- if(!pFormatter->IsNumberFormat( aStr, nFIndex, nVal ) )
- {
- SetError( errIllegalArgument); //! fit to ScN()
- nVal = 0.0;
- }
- }
+ nVal = ConvertStringToValue( PopString());
break;
case svSingleRef:
{
@@ -1707,7 +1902,7 @@ double ScInterpreter::GetDouble()
double ScInterpreter::GetDoubleWithDefault(double nDefault)
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::GetDoubleWithDefault" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::GetDoubleWithDefault" );
bool bMissing = IsMissing();
double nResultVal = GetDouble();
if ( bMissing )
@@ -1718,7 +1913,7 @@ double ScInterpreter::GetDoubleWithDefault(double nDefault)
const String& ScInterpreter::GetString()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::GetString" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::GetString" );
switch (GetRawStackType())
{
case svError:
@@ -1809,7 +2004,7 @@ const String& ScInterpreter::GetString()
ScMatValType ScInterpreter::GetDoubleOrStringFromMatrix( double& rDouble,
String& rString )
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::GetDoubleOrStringFromMatrix" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::GetDoubleOrStringFromMatrix" );
ScMatValType nMatValType = SC_MATVAL_EMPTY;
switch ( GetStackType() )
{
@@ -1859,7 +2054,7 @@ ScMatValType ScInterpreter::GetDoubleOrStringFromMatrix( double& rDouble,
void ScInterpreter::ScDBGet()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScDBGet" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScDBGet" );
SCTAB nTab;
ScQueryParam aQueryParam;
BOOL bMissingField = FALSE;
@@ -1937,7 +2132,7 @@ void ScInterpreter::ScDBGet()
void ScInterpreter::ScExternal()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScExternal" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScExternal" );
USHORT nIndex;
BYTE nParamCount = GetByte();
String aUnoName;
@@ -2484,14 +2679,14 @@ void ScInterpreter::ScExternal()
void ScInterpreter::ScMissing()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScMissing" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScMissing" );
PushTempToken( new FormulaMissingToken );
}
void ScInterpreter::ScMacro()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScMacro" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScMacro" );
SbxBase::ResetError();
BYTE nParamCount = GetByte();
@@ -2720,7 +2915,7 @@ void ScInterpreter::ScMacro()
BOOL ScInterpreter::SetSbxVariable( SbxVariable* pVar, const ScAddress& rPos )
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::SetSbxVariable" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::SetSbxVariable" );
BOOL bOk = TRUE;
ScBaseCell* pCell = pDok->GetCell( rPos );
if (pCell)
@@ -2778,7 +2973,7 @@ BOOL ScInterpreter::SetSbxVariable( SbxVariable* pVar, const ScAddress& rPos )
void ScInterpreter::ScTableOp()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScTableOp" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScTableOp" );
BYTE nParamCount = GetByte();
if (nParamCount != 3 && nParamCount != 5)
{
@@ -2874,7 +3069,7 @@ void ScInterpreter::ScTableOp()
void ScInterpreter::ScErrCell()
{
-RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScErrCell" );
+RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScErrCell" );
double fErrNum = GetDouble();
PushError((USHORT) fErrNum);
}
@@ -2882,7 +3077,7 @@ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter
void ScInterpreter::ScDBArea()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScDBArea" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScDBArea" );
ScDBData* pDBData = pDok->GetDBCollection()->FindIndex( pCur->GetIndex());
if (pDBData)
{
@@ -2904,7 +3099,7 @@ void ScInterpreter::ScDBArea()
void ScInterpreter::ScColRowNameAuto()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScColRowNameAuto" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScColRowNameAuto" );
ScComplexRefData aRefData( static_cast<const ScToken*>(pCur)->GetDoubleRef() );
aRefData.CalcAbsIfRel( aPos );
if ( aRefData.Valid() )
@@ -3065,7 +3260,7 @@ void ScInterpreter::ScExternalRef()
void ScInterpreter::ScAnswer()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScAnswer" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScAnswer" );
String aStr( GetString() );
if( aStr.EqualsIgnoreCaseAscii( "Das Leben, das Universum und der ganze Rest" ) )
{
@@ -3079,7 +3274,7 @@ void ScInterpreter::ScAnswer()
void ScInterpreter::ScCalcTeam()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScCalcTeam" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScCalcTeam" );
static BOOL bShown = FALSE;
if( !bShown )
{
@@ -3097,7 +3292,7 @@ void ScInterpreter::ScCalcTeam()
void ScInterpreter::ScSpewFunc()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScSpewFunc" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScSpewFunc" );
BOOL bRefresh = FALSE;
BOOL bClear = FALSE;
// Stack aufraeumen
@@ -3145,7 +3340,7 @@ extern "C" { static void SAL_CALL thisModule() {} }
void ScInterpreter::ScGame()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScGame" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScGame" );
enum GameType {
SC_GAME_NONE,
SC_GAME_ONCE,
@@ -3374,7 +3569,7 @@ ScInterpreter::ScInterpreter( ScFormulaCell* pCell, ScDocument* pDoc,
pFormatter( pDoc->GetFormatTable() ),
bCalcAsShown( pDoc->GetDocOptions().IsCalcAsShown() )
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScTTT" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScTTT" );
// pStack = new ScToken*[ MAXSTACK ];
BYTE cMatFlag = pMyFormulaCell->GetMatrixFlag();
@@ -3408,7 +3603,7 @@ ScInterpreter::~ScInterpreter()
void ScInterpreter::GlobalExit() // static
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::GlobalExit" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::GlobalExit" );
DBG_ASSERT(!bGlobalStackInUse, "wer benutzt noch den TokenStack?");
DELETEZ(pGlobalStack);
}
@@ -3416,7 +3611,7 @@ void ScInterpreter::GlobalExit() // static
StackVar ScInterpreter::Interpret()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::Interpret" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::Interpret" );
short nRetTypeExpr = NUMBERFORMAT_UNDEFINED;
ULONG nRetIndexExpr = 0;
USHORT nErrorFunction = 0;
@@ -3803,6 +3998,8 @@ StackVar ScInterpreter::Interpret()
case ocGetPivotData : ScGetPivotData(); break;
case ocJis : ScJis(); break;
case ocAsc : ScAsc(); break;
+ case ocUnicode : ScUnicode(); break;
+ case ocUnichar : ScUnichar(); break;
case ocAnswer : ScAnswer(); break;
case ocTeam : ScCalcTeam(); break;
case ocTTT : ScTTT(); break;
diff --git a/sc/source/core/tool/interpr5.cxx b/sc/source/core/tool/interpr5.cxx
index 5fb45755eb7c..7da4778bfe1a 100644
--- a/sc/source/core/tool/interpr5.cxx
+++ b/sc/source/core/tool/interpr5.cxx
@@ -106,7 +106,7 @@ const double fInvEpsilon = 1.0E-7;
double ScInterpreter::ScGetGCD(double fx, double fy)
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::div" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::div" );
// By ODFF definition GCD(0,a) => a. This is also vital for the code in
// ScGCD() to work correctly with a preset fy=0.0
if (fy == 0.0)
@@ -128,7 +128,7 @@ double ScInterpreter::ScGetGCD(double fx, double fy)
void ScInterpreter::ScGCD()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScGCD" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScGCD" );
short nParamCount = GetByte();
if ( MustHaveParamCountMin( nParamCount, 1 ) )
{
@@ -310,7 +310,7 @@ void ScInterpreter:: ScLCM()
ScMatrixRef ScInterpreter::GetNewMat(SCSIZE nC, SCSIZE nR)
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::GetNewMat" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::GetNewMat" );
ScMatrix* pMat = new ScMatrix( nC, nR);
pMat->SetErrorInterpreter( this);
SCSIZE nCols, nRows;
@@ -328,7 +328,7 @@ ScMatrixRef ScInterpreter::CreateMatrixFromDoubleRef( const FormulaToken* pToken
SCCOL nCol1, SCROW nRow1, SCTAB nTab1,
SCCOL nCol2, SCROW nRow2, SCTAB nTab2 )
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::CreateMatrixFromDoubleRef" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::CreateMatrixFromDoubleRef" );
ScMatrixRef pMat = NULL;
if (nTab1 == nTab2 && !nGlobalError)
{
@@ -449,7 +449,7 @@ ScMatrixRef ScInterpreter::CreateMatrixFromDoubleRef( const FormulaToken* pToken
ScMatrixRef ScInterpreter::GetMatrix()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::GetMatrix" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::GetMatrix" );
ScMatrixRef pMat = NULL;
switch (GetRawStackType())
{
@@ -532,7 +532,7 @@ ScMatrixRef ScInterpreter::GetMatrix()
void ScInterpreter::ScMatValue()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScMatValue" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScMatValue" );
if ( MustHaveParamCount( GetByte(), 3 ) )
{
// 0 to count-1
@@ -604,7 +604,7 @@ void ScInterpreter::ScMatValue()
}
void ScInterpreter::CalculateMatrixValue(const ScMatrix* pMat,SCSIZE nC,SCSIZE nR)
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::CalculateMatrixValue" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::CalculateMatrixValue" );
if (pMat)
{
SCSIZE nCl, nRw;
@@ -628,7 +628,7 @@ void ScInterpreter::CalculateMatrixValue(const ScMatrix* pMat,SCSIZE nC,SCSIZE n
void ScInterpreter::ScEMat()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScEMat" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScEMat" );
if ( MustHaveParamCount( GetByte(), 1 ) )
{
SCSIZE nDim = static_cast<SCSIZE>(::rtl::math::approxFloor(GetDouble()));
@@ -650,7 +650,7 @@ void ScInterpreter::ScEMat()
void ScInterpreter::MEMat(ScMatrix* mM, SCSIZE n)
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::MEMat" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::MEMat" );
mM->FillDouble(0.0, 0, 0, n-1, n-1);
for (SCSIZE i = 0; i < n; i++)
mM->PutDouble(1.0, i, i);
@@ -660,7 +660,7 @@ void ScInterpreter::MFastMult(ScMatrix* pA, ScMatrix* pB, ScMatrix* pR,
SCSIZE n, SCSIZE m, SCSIZE l)
// Multipliziert n x m Mat a mit m x l Mat b nach Mat r
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::MFastMult" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::MFastMult" );
double sum;
for (SCSIZE i = 0; i < n; i++)
{
@@ -830,7 +830,7 @@ static void lcl_LUP_solve( const ScMatrix* mLU, const SCSIZE n,
void ScInterpreter::ScMatDet()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScMatDet" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScMatDet" );
if ( MustHaveParamCount( GetByte(), 1 ) )
{
ScMatrixRef pMat = GetMatrix();
@@ -877,7 +877,7 @@ void ScInterpreter::ScMatDet()
void ScInterpreter::ScMatInv()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScMatInv" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScMatInv" );
if ( MustHaveParamCount( GetByte(), 1 ) )
{
ScMatrixRef pMat = GetMatrix();
@@ -979,7 +979,7 @@ void ScInterpreter::ScMatInv()
void ScInterpreter::ScMatMult()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScMatMult" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScMatMult" );
if ( MustHaveParamCount( GetByte(), 2 ) )
{
ScMatrixRef pMat2 = GetMatrix();
@@ -1029,7 +1029,7 @@ void ScInterpreter::ScMatMult()
void ScInterpreter::ScMatTrans()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScMatTrans" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScMatTrans" );
if ( MustHaveParamCount( GetByte(), 1 ) )
{
ScMatrixRef pMat = GetMatrix();
@@ -1102,7 +1102,7 @@ ScMatrixRef lcl_MatrixCalculation(const _Function& _pOperation,ScMatrix* pMat1,
ScMatrixRef ScInterpreter::MatConcat(ScMatrix* pMat1, ScMatrix* pMat2)
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::MatConcat" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::MatConcat" );
SCSIZE nC1, nC2, nMinC;
SCSIZE nR1, nR2, nMinR;
SCSIZE i, j;
@@ -1166,12 +1166,12 @@ void lcl_GetDiffDateTimeFmtType( short& nFuncFmt, short nFmt1, short nFmt2 )
void ScInterpreter::ScAdd()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScAdd" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScAdd" );
CalculateAddSub(FALSE);
}
void ScInterpreter::CalculateAddSub(BOOL _bSub)
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::CalculateAddSub" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::CalculateAddSub" );
ScMatrixRef pMat1 = NULL;
ScMatrixRef pMat2 = NULL;
double fVal1 = 0.0, fVal2 = 0.0;
@@ -1306,7 +1306,7 @@ void ScInterpreter::CalculateAddSub(BOOL _bSub)
void ScInterpreter::ScAmpersand()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScAmpersand" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScAmpersand" );
ScMatrixRef pMat1 = NULL;
ScMatrixRef pMat2 = NULL;
String sStr1, sStr2;
@@ -1398,13 +1398,13 @@ void ScInterpreter::ScAmpersand()
void ScInterpreter::ScSub()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScSub" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScSub" );
CalculateAddSub(TRUE);
}
void ScInterpreter::ScMul()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScMul" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScMul" );
ScMatrixRef pMat1 = NULL;
ScMatrixRef pMat2 = NULL;
double fVal1 = 0.0, fVal2 = 0.0;
@@ -1483,7 +1483,7 @@ void ScInterpreter::ScMul()
void ScInterpreter::ScDiv()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScDiv" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScDiv" );
ScMatrixRef pMat1 = NULL;
ScMatrixRef pMat2 = NULL;
double fVal1 = 0.0, fVal2 = 0.0;
@@ -1574,14 +1574,14 @@ void ScInterpreter::ScDiv()
void ScInterpreter::ScPower()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScPower" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScPower" );
if ( MustHaveParamCount( GetByte(), 2 ) )
ScPow();
}
void ScInterpreter::ScPow()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScPow" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScPow" );
ScMatrixRef pMat1 = NULL;
ScMatrixRef pMat2 = NULL;
double fVal1 = 0.0, fVal2 = 0.0;
@@ -1649,7 +1649,7 @@ void ScInterpreter::ScPow()
void ScInterpreter::ScSumProduct()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScSumProduct" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScSumProduct" );
BYTE nParamCount = GetByte();
if ( !MustHaveParamCount( nParamCount, 1, 30 ) )
return;
@@ -1703,12 +1703,12 @@ void ScInterpreter::ScSumProduct()
void ScInterpreter::ScSumX2MY2()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScSumX2MY2" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScSumX2MY2" );
CalculateSumX2MY2SumX2DY2(FALSE);
}
void ScInterpreter::CalculateSumX2MY2SumX2DY2(BOOL _bSumX2DY2)
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::CalculateSumX2MY2SumX2DY2" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::CalculateSumX2MY2SumX2DY2" );
if ( !MustHaveParamCount( GetByte(), 2 ) )
return;
@@ -1749,13 +1749,13 @@ void ScInterpreter::CalculateSumX2MY2SumX2DY2(BOOL _bSumX2DY2)
void ScInterpreter::ScSumX2DY2()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScSumX2DY2" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScSumX2DY2" );
CalculateSumX2MY2SumX2DY2(TRUE);
}
void ScInterpreter::ScSumXMY2()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScSumXMY2" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScSumXMY2" );
if ( !MustHaveParamCount( GetByte(), 2 ) )
return;
@@ -1799,7 +1799,7 @@ void ScInterpreter::ScSumXMY2()
void ScInterpreter::ScFrequency()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScFrequency" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScFrequency" );
if ( !MustHaveParamCount( GetByte(), 2 ) )
return;
@@ -1959,7 +1959,7 @@ BOOL ScInterpreter::RGetVariances( ScMatrix* pV, ScMatrix* pX,
// -----------------------------------------------------------------------------
void ScInterpreter::Calculate(ScMatrixRef& pResMat,ScMatrixRef& pE,ScMatrixRef& pQ,ScMatrixRef& pV,ScMatrixRef& pMatX,BOOL bConstant,SCSIZE N,SCSIZE M,BYTE nCase)
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::RGetVariances" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::RGetVariances" );
// pE[0] := Sigma i=1...n (Yi)
// pE[k] := Sigma i=1...n (Xki*Yi)
// pE[M+1] := Sigma i=1...n (Yi**2)
@@ -2053,7 +2053,7 @@ void ScInterpreter::Calculate(ScMatrixRef& pResMat,ScMatrixRef& pE,ScMatrixRef&
void ScInterpreter::ScRGP()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScRGP" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScRGP" );
CalulateRGPRKP(FALSE);
}
bool ScInterpreter::CheckMatrix(BOOL _bLOG,BOOL _bTrendGrowth,BYTE& nCase,SCSIZE& nCX,SCSIZE& nCY,SCSIZE& nRX,SCSIZE& nRY,SCSIZE& M,SCSIZE& N,ScMatrixRef& pMatX,ScMatrixRef& pMatY)
@@ -2154,7 +2154,7 @@ bool ScInterpreter::CheckMatrix(BOOL _bLOG,BOOL _bTrendGrowth,BYTE& nCase,SCSIZE
}
void ScInterpreter::CalulateRGPRKP(BOOL _bRKP)
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::CheckMatrix" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::CheckMatrix" );
BYTE nParamCount = GetByte();
if ( !MustHaveParamCount( nParamCount, 1, 4 ) )
return;
@@ -2353,13 +2353,13 @@ void ScInterpreter::CalulateRGPRKP(BOOL _bRKP)
void ScInterpreter::ScRKP()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScRKP" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScRKP" );
CalulateRGPRKP(TRUE);
}
// -----------------------------------------------------------------------------
bool ScInterpreter::Calculate4(BOOL _bExp,ScMatrixRef& pResMat,ScMatrixRef& pQ,BOOL bConstant,SCSIZE N,SCSIZE M)
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::Calculate4" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::Calculate4" );
pQ->PutDouble((double)N, 0, 0);
if (bConstant)
{
@@ -2412,7 +2412,7 @@ bool ScInterpreter::Calculate4(BOOL _bExp,ScMatrixRef& pResMat,ScMatrixRef& pQ,B
ScMatrixRef ScInterpreter::Calculate2(const BOOL bConstant,const SCSIZE M ,const SCSIZE N,ScMatrixRef& pMatX,ScMatrixRef& pMatY,BYTE nCase)
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::Calculate2" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::Calculate2" );
SCSIZE i, j, k;
ScMatrixRef pQ = GetNewMat(M+1, M+2);
ScMatrixRef pE = GetNewMat(M+2, 1);
@@ -2511,7 +2511,7 @@ ScMatrixRef ScInterpreter::Calculate2(const BOOL bConstant,const SCSIZE M ,const
}
bool ScInterpreter::Calculate3(const SCSIZE M ,ScMatrixRef& pQ)
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::Calculate3" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::Calculate3" );
SCSIZE S, L;
for (S = 1; S < M+1; S++)
{
@@ -2550,12 +2550,12 @@ bool ScInterpreter::Calculate3(const SCSIZE M ,ScMatrixRef& pQ)
void ScInterpreter::ScTrend()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScTrend" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScTrend" );
CalculateTrendGrowth(FALSE);
}
void ScInterpreter::CalculateTrendGrowth(BOOL _bGrowth)
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::CalculateTrendGrowth" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::CalculateTrendGrowth" );
BYTE nParamCount = GetByte();
if ( !MustHaveParamCount( nParamCount, 1, 4 ) )
return;
@@ -2716,13 +2716,13 @@ void ScInterpreter::CalculateTrendGrowth(BOOL _bGrowth)
void ScInterpreter::ScGrowth()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScGrowth" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScGrowth" );
CalculateTrendGrowth(TRUE);
}
void ScInterpreter::ScMatRef()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScMatRef" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScMatRef" );
// Falls Deltarefs drin sind...
Push( (FormulaToken&)*pCur );
ScAddress aAdr;
@@ -2792,7 +2792,7 @@ void ScInterpreter::ScMatRef()
void ScInterpreter::ScInfo()
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScInfo" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScInfo" );
if( MustHaveParamCount( GetByte(), 1 ) )
{
String aStr = GetString();
diff --git a/sc/source/core/tool/interpr6.cxx b/sc/source/core/tool/interpr6.cxx
index 118b5f0ece68..e8b69a4e6eda 100644
--- a/sc/source/core/tool/interpr6.cxx
+++ b/sc/source/core/tool/interpr6.cxx
@@ -48,7 +48,7 @@ double const fHalfMachEps = 0.5 * ::std::numeric_limits<double>::epsilon();
uses continued fraction with odd items */
double ScInterpreter::GetGammaContFraction( double fA, double fX )
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::GetGammaContFraction" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::GetGammaContFraction" );
double const fBigInv = ::std::numeric_limits<double>::epsilon();
double const fBig = 1.0/fBigInv;
@@ -105,7 +105,7 @@ double ScInterpreter::GetGammaContFraction( double fA, double fX )
uses power series */
double ScInterpreter::GetGammaSeries( double fA, double fX )
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::GetGammaSeries" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::GetGammaSeries" );
double fDenomfactor = fA;
double fSummand = 1.0/fA;
double fSum = fSummand;
@@ -129,7 +129,7 @@ double ScInterpreter::GetGammaSeries( double fA, double fX )
/** You must ensure fA>0.0 && fX>0.0) */
double ScInterpreter::GetLowRegIGamma( double fA, double fX )
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::GetLowRegIGamma" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::GetLowRegIGamma" );
double fLnFactor = fA * log(fX) - fX - GetLogGamma(fA);
double fFactor = exp(fLnFactor); // Do we need more accuracy than exp(ln()) has?
if (fX>fA+1.0) // includes fX>1.0; 1-GetUpRegIGamma, continued fraction
@@ -141,7 +141,7 @@ double ScInterpreter::GetLowRegIGamma( double fA, double fX )
/** You must ensure fA>0.0 && fX>0.0) */
double ScInterpreter::GetUpRegIGamma( double fA, double fX )
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::GetUpRegIGamma" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::GetUpRegIGamma" );
double fLnFactor= fA*log(fX)-fX-GetLogGamma(fA);
double fFactor = exp(fLnFactor); //Do I need more accuracy than exp(ln()) has?;
@@ -156,7 +156,7 @@ double ScInterpreter::GetUpRegIGamma( double fA, double fX )
You must ensure fAlpha>0.0 and fLambda>0.0 */
double ScInterpreter::GetGammaDistPDF( double fX, double fAlpha, double fLambda )
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::GetGammaDistPDF" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::GetGammaDistPDF" );
if (fX <= 0.0)
return 0.0; // see ODFF
else
@@ -194,7 +194,7 @@ double ScInterpreter::GetGammaDistPDF( double fX, double fAlpha, double fLambda
You must ensure fAlpha>0.0 and fLambda>0.0 */
double ScInterpreter::GetGammaDist( double fX, double fAlpha, double fLambda )
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::GetGammaDist" );
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::GetGammaDist" );
if (fX <= 0.0)
return 0.0;
else
diff --git a/sc/source/core/tool/parclass.cxx b/sc/source/core/tool/parclass.cxx
index 634c6adbb5cf..5f2094d2f0f7 100644
--- a/sc/source/core/tool/parclass.cxx
+++ b/sc/source/core/tool/parclass.cxx
@@ -64,138 +64,138 @@ const ScParameterClassification::RawData ScParameterClassification::pRawData[] =
// IF() and CHOOSE() are somewhat special, since the ScJumpMatrix is
// created inside those functions and ConvertMatrixParameters() is not
// called for them.
- { ocIf, {{ Array, Reference, Reference }, false }},
- { ocChose, {{ Array, Reference }, true }},
+ { ocIf, {{ Array, Reference, Reference }, false }},
+ { ocChose, {{ Array, Reference }, true }},
// Other specials.
- { ocOpen, {{ Bounds }, false }},
- { ocClose, {{ Bounds }, false }},
- { ocSep, {{ Bounds }, false }},
- { ocNoName, {{ Bounds }, false }},
- { ocErrCell, {{ Bounds }, false }},
- { ocStop, {{ Bounds }, false }},
- { ocUnion, {{ Reference, Reference }, false }},
- { ocRange, {{ Reference, Reference }, false }},
+ { ocOpen, {{ Bounds }, false }},
+ { ocClose, {{ Bounds }, false }},
+ { ocSep, {{ Bounds }, false }},
+ { ocNoName, {{ Bounds }, false }},
+ { ocErrCell, {{ Bounds }, false }},
+ { ocStop, {{ Bounds }, false }},
+ { ocUnion, {{ Reference, Reference }, false }},
+ { ocRange, {{ Reference, Reference }, false }},
// Functions with Value parameters only but not in resource.
- { ocBackSolver, {{ Value, Value, Value }, false }},
- { ocTableOp, {{ Value, Value, Value, Value, Value }, false }},
+ { ocBackSolver, {{ Value, Value, Value }, false }},
+ { ocTableOp, {{ Value, Value, Value, Value, Value }, false }},
// Operators and functions.
- { ocAdd, {{ Array, Array }, false }},
- { ocAmpersand, {{ Array, Array }, false }},
- { ocAnd, {{ Reference }, true }},
- { ocAreas, {{ Reference }, false }},
- { ocAveDev, {{ Reference }, true }},
- { ocAverage, {{ Reference }, true }},
- { ocAverageA, {{ Reference }, true }},
- { ocCell, {{ Value, Reference }, false }},
- { ocColumn, {{ Reference }, false }},
- { ocColumns, {{ Reference }, true }},
- { ocCorrel, {{ ForceArray, ForceArray }, false }},
- { ocCount, {{ Reference }, true }},
- { ocCount2, {{ Reference }, true }},
- { ocCountEmptyCells, {{ Reference }, false }},
- { ocCountIf, {{ Reference, Value }, false }},
- { ocCovar, {{ ForceArray, ForceArray }, false }},
- { ocDBAverage, {{ Reference, Reference, Reference }, false }},
- { ocDBCount, {{ Reference, Reference, Reference }, false }},
- { ocDBCount2, {{ Reference, Reference, Reference }, false }},
- { ocDBGet, {{ Reference, Reference, Reference }, false }},
- { ocDBMax, {{ Reference, Reference, Reference }, false }},
- { ocDBMin, {{ Reference, Reference, Reference }, false }},
- { ocDBProduct, {{ Reference, Reference, Reference }, false }},
- { ocDBStdDev, {{ Reference, Reference, Reference }, false }},
- { ocDBStdDevP, {{ Reference, Reference, Reference }, false }},
- { ocDBSum, {{ Reference, Reference, Reference }, false }},
- { ocDBVar, {{ Reference, Reference, Reference }, false }},
- { ocDBVarP, {{ Reference, Reference, Reference }, false }},
- { ocDevSq, {{ Reference }, true }},
- { ocDiv, {{ Array, Array }, false }},
- { ocEqual, {{ Array, Array }, false }},
- { ocForecast, {{ Value, ForceArray, ForceArray }, false }},
- { ocFrequency, {{ Reference, Reference }, false }},
- { ocFTest, {{ ForceArray, ForceArray }, false }},
- { ocGeoMean, {{ Reference }, true }},
- { ocGCD, {{ Reference }, true }},
- { ocGreater, {{ Array, Array }, false }},
- { ocGreaterEqual, {{ Array, Array }, false }},
- { ocGrowth, {{ Reference, Reference, Reference, Value }, false }},
- { ocHarMean, {{ Reference }, true }},
- { ocHLookup, {{ Value, Reference, Value, Value }, false }},
- { ocIRR, {{ Reference, Value }, false }},
- { ocIndex, {{ Reference, Value, Value, Value }, false }},
- { ocIntercept, {{ ForceArray, ForceArray }, false }},
- { ocIntersect, {{ Reference, Reference }, false }},
- { ocIsRef, {{ Reference }, false }},
- { ocLCM, {{ Reference }, true }},
- { ocKurt, {{ Reference }, true }},
- { ocLarge, {{ Reference, Value }, false }},
- { ocLess, {{ Array, Array }, false }},
- { ocLessEqual, {{ Array, Array }, false }},
- { ocLookup, {{ Value, Reference, Reference }, false }},
- { ocMatch, {{ Value, Reference, Reference }, false }},
- { ocMatDet, {{ ForceArray }, false }},
- { ocMatInv, {{ ForceArray }, false }},
- { ocMatMult, {{ ForceArray, ForceArray }, false }},
- { ocMatTrans, {{ Array }, false }}, // strange, but Xcl doesn't force MatTrans array
- { ocMatValue, {{ Reference, Value, Value }, false }},
- { ocMax, {{ Reference }, true }},
- { ocMaxA, {{ Reference }, true }},
- { ocMedian, {{ Reference }, true }},
- { ocMin, {{ Reference }, true }},
- { ocMinA, {{ Reference }, true }},
- { ocMIRR, {{ Reference, Value, Value }, false }},
- { ocModalValue, {{ ForceArray }, true }},
- { ocMul, {{ Array, Array }, false }},
- { ocMultiArea, {{ Reference }, true }},
- { ocN, {{ Reference }, false }},
- { ocNPV, {{ Value, Reference }, true }},
- { ocNeg, {{ Array }, false }},
- { ocNegSub, {{ Array }, false }},
- { ocNot, {{ Array }, false }},
- { ocNotEqual, {{ Array, Array }, false }},
- { ocOffset, {{ Reference, Value, Value, Value, Value }, false }},
- { ocOr, {{ Reference }, true }},
- { ocPearson, {{ ForceArray, ForceArray }, false }},
- { ocPercentile, {{ Reference, Value }, false }},
- { ocPercentrank, {{ Reference, Value }, false }},
- { ocPow, {{ Array, Array }, false }},
- { ocPower, {{ Array, Array }, false }},
- { ocProb, {{ ForceArray, ForceArray, Value, Value }, false }},
- { ocProduct, {{ Reference }, true }},
- { ocQuartile, {{ Reference, Value }, false }},
- { ocRank, {{ Value, Reference, Value }, false }},
- { ocRGP, {{ Reference, Reference, Value, Value }, false }},
- { ocRKP, {{ Reference, Reference, Value, Value }, false }},
- { ocRow, {{ Reference }, false }},
- { ocRows, {{ Reference }, true }},
- { ocRSQ, {{ ForceArray, ForceArray }, false }},
- { ocSchiefe, {{ Reference }, true }},
- { ocSlope, {{ ForceArray, ForceArray }, false }},
- { ocSmall, {{ Reference, Value }, false }},
- { ocStDev, {{ Reference }, true }},
- { ocStDevA, {{ Reference }, true }},
- { ocStDevP, {{ Reference }, true }},
- { ocStDevPA, {{ Reference }, true }},
- { ocSTEYX, {{ ForceArray, ForceArray }, false }},
- { ocSub, {{ Array, Array }, false }},
- { ocSubTotal, {{ Value, Reference }, true }},
- { ocSum, {{ Reference }, true }},
- { ocSumIf, {{ Reference, Value, Reference }, false }},
- { ocSumProduct, {{ ForceArray }, true }},
- { ocSumSQ, {{ Reference }, true }},
- { ocSumX2MY2, {{ ForceArray, ForceArray }, false }},
- { ocSumX2DY2, {{ ForceArray, ForceArray }, false }},
- { ocSumXMY2, {{ ForceArray, ForceArray }, false }},
- { ocTable, {{ Reference }, false }},
- { ocTables, {{ Reference }, true }},
- { ocTrend, {{ Reference, Reference, Reference, Value }, false }},
- { ocTrimMean, {{ Reference, Value }, false }},
- { ocTTest, {{ ForceArray, ForceArray, Value, Value }, false }},
- { ocVar, {{ Reference }, true }},
- { ocVarA, {{ Reference }, true }},
- { ocVarP, {{ Reference }, true }},
- { ocVarPA, {{ Reference }, true }},
- { ocVLookup, {{ Value, Reference, Value, Value }, false }},
- { ocZTest, {{ Reference, Value, Value }, false }},
+ { ocAdd, {{ Array, Array }, false }},
+ { ocAmpersand, {{ Array, Array }, false }},
+ { ocAnd, {{ Reference }, true }},
+ { ocAreas, {{ Reference }, false }},
+ { ocAveDev, {{ Reference }, true }},
+ { ocAverage, {{ Reference }, true }},
+ { ocAverageA, {{ Reference }, true }},
+ { ocCell, {{ Value, Reference }, false }},
+ { ocColumn, {{ Reference }, false }},
+ { ocColumns, {{ Reference }, true }},
+ { ocCorrel, {{ ForceArray, ForceArray }, false }},
+ { ocCount, {{ Reference }, true }},
+ { ocCount2, {{ Reference }, true }},
+ { ocCountEmptyCells, {{ Reference }, false }},
+ { ocCountIf, {{ Reference, Value }, false }},
+ { ocCovar, {{ ForceArray, ForceArray }, false }},
+ { ocDBAverage, {{ Reference, Reference, Reference }, false }},
+ { ocDBCount, {{ Reference, Reference, Reference }, false }},
+ { ocDBCount2, {{ Reference, Reference, Reference }, false }},
+ { ocDBGet, {{ Reference, Reference, Reference }, false }},
+ { ocDBMax, {{ Reference, Reference, Reference }, false }},
+ { ocDBMin, {{ Reference, Reference, Reference }, false }},
+ { ocDBProduct, {{ Reference, Reference, Reference }, false }},
+ { ocDBStdDev, {{ Reference, Reference, Reference }, false }},
+ { ocDBStdDevP, {{ Reference, Reference, Reference }, false }},
+ { ocDBSum, {{ Reference, Reference, Reference }, false }},
+ { ocDBVar, {{ Reference, Reference, Reference }, false }},
+ { ocDBVarP, {{ Reference, Reference, Reference }, false }},
+ { ocDevSq, {{ Reference }, true }},
+ { ocDiv, {{ Array, Array }, false }},
+ { ocEqual, {{ Array, Array }, false }},
+ { ocForecast, {{ Value, ForceArray, ForceArray }, false }},
+ { ocFrequency, {{ Reference, Reference }, false }},
+ { ocFTest, {{ ForceArray, ForceArray }, false }},
+ { ocGeoMean, {{ Reference }, true }},
+ { ocGCD, {{ Reference }, true }},
+ { ocGreater, {{ Array, Array }, false }},
+ { ocGreaterEqual, {{ Array, Array }, false }},
+ { ocGrowth, {{ Reference, Reference, Reference, Value }, false }},
+ { ocHarMean, {{ Reference }, true }},
+ { ocHLookup, {{ Value, Reference, Value, Value }, false }},
+ { ocIRR, {{ Reference, Value }, false }},
+ { ocIndex, {{ Reference, Value, Value, Value }, false }},
+ { ocIntercept, {{ ForceArray, ForceArray }, false }},
+ { ocIntersect, {{ Reference, Reference }, false }},
+ { ocIsRef, {{ Reference }, false }},
+ { ocLCM, {{ Reference }, true }},
+ { ocKurt, {{ Reference }, true }},
+ { ocLarge, {{ Reference, Value }, false }},
+ { ocLess, {{ Array, Array }, false }},
+ { ocLessEqual, {{ Array, Array }, false }},
+ { ocLookup, {{ Value, ReferenceOrForceArray, ReferenceOrForceArray }, false }},
+ { ocMatch, {{ Value, Reference, Reference }, false }},
+ { ocMatDet, {{ ForceArray }, false }},
+ { ocMatInv, {{ ForceArray }, false }},
+ { ocMatMult, {{ ForceArray, ForceArray }, false }},
+ { ocMatTrans, {{ Array }, false }}, // strange, but Xcl doesn't force MatTrans array
+ { ocMatValue, {{ Reference, Value, Value }, false }},
+ { ocMax, {{ Reference }, true }},
+ { ocMaxA, {{ Reference }, true }},
+ { ocMedian, {{ Reference }, true }},
+ { ocMin, {{ Reference }, true }},
+ { ocMinA, {{ Reference }, true }},
+ { ocMIRR, {{ Reference, Value, Value }, false }},
+ { ocModalValue, {{ ForceArray }, true }},
+ { ocMul, {{ Array, Array }, false }},
+ { ocMultiArea, {{ Reference }, true }},
+ { ocN, {{ Reference }, false }},
+ { ocNPV, {{ Value, Reference }, true }},
+ { ocNeg, {{ Array }, false }},
+ { ocNegSub, {{ Array }, false }},
+ { ocNot, {{ Array }, false }},
+ { ocNotEqual, {{ Array, Array }, false }},
+ { ocOffset, {{ Reference, Value, Value, Value, Value }, false }},
+ { ocOr, {{ Reference }, true }},
+ { ocPearson, {{ ForceArray, ForceArray }, false }},
+ { ocPercentile, {{ Reference, Value }, false }},
+ { ocPercentrank, {{ Reference, Value }, false }},
+ { ocPow, {{ Array, Array }, false }},
+ { ocPower, {{ Array, Array }, false }},
+ { ocProb, {{ ForceArray, ForceArray, Value, Value }, false }},
+ { ocProduct, {{ Reference }, true }},
+ { ocQuartile, {{ Reference, Value }, false }},
+ { ocRank, {{ Value, Reference, Value }, false }},
+ { ocRGP, {{ Reference, Reference, Value, Value }, false }},
+ { ocRKP, {{ Reference, Reference, Value, Value }, false }},
+ { ocRow, {{ Reference }, false }},
+ { ocRows, {{ Reference }, true }},
+ { ocRSQ, {{ ForceArray, ForceArray }, false }},
+ { ocSchiefe, {{ Reference }, true }},
+ { ocSlope, {{ ForceArray, ForceArray }, false }},
+ { ocSmall, {{ Reference, Value }, false }},
+ { ocStDev, {{ Reference }, true }},
+ { ocStDevA, {{ Reference }, true }},
+ { ocStDevP, {{ Reference }, true }},
+ { ocStDevPA, {{ Reference }, true }},
+ { ocSTEYX, {{ ForceArray, ForceArray }, false }},
+ { ocSub, {{ Array, Array }, false }},
+ { ocSubTotal, {{ Value, Reference }, true }},
+ { ocSum, {{ Reference }, true }},
+ { ocSumIf, {{ Reference, Value, Reference }, false }},
+ { ocSumProduct, {{ ForceArray }, true }},
+ { ocSumSQ, {{ Reference }, true }},
+ { ocSumX2MY2, {{ ForceArray, ForceArray }, false }},
+ { ocSumX2DY2, {{ ForceArray, ForceArray }, false }},
+ { ocSumXMY2, {{ ForceArray, ForceArray }, false }},
+ { ocTable, {{ Reference }, false }},
+ { ocTables, {{ Reference }, true }},
+ { ocTrend, {{ Reference, Reference, Reference, Value }, false }},
+ { ocTrimMean, {{ Reference, Value }, false }},
+ { ocTTest, {{ ForceArray, ForceArray, Value, Value }, false }},
+ { ocVar, {{ Reference }, true }},
+ { ocVarA, {{ Reference }, true }},
+ { ocVarP, {{ Reference }, true }},
+ { ocVarPA, {{ Reference }, true }},
+ { ocVLookup, {{ Value, Reference, Value, Value }, false }},
+ { ocZTest, {{ Reference, Value, Value }, false }},
// Excel doubts:
// ocT: Excel says (and handles) Reference, error? This means no position
// dependent SingleRef if DoubleRef, and no array calculation, just the
@@ -265,7 +265,7 @@ void ScParameterClassification::Init()
}
for ( size_t j=0; j < CommonData::nMaxParams; ++j )
{
- if ( pRun->aData.nParam[j] == ForceArray )
+ if ( pRun->aData.nParam[j] == ForceArray || pRun->aData.nParam[j] == ReferenceOrForceArray )
{
pRun->bHasForceArray = true;
break; // for
@@ -537,6 +537,9 @@ void ScParameterClassification::GenerateDocumentation()
case ForceArray :
aStr += " ForceArray";
break;
+ case ReferenceOrForceArray :
+ aStr += " ReferenceOrForceArray";
+ break;
case Bounds :
aStr += " (Bounds, classification error?)";
break;
diff --git a/sc/source/filter/excel/xeformula.cxx b/sc/source/filter/excel/xeformula.cxx
index 457c31d4ab04..ef15b16030cf 100644
--- a/sc/source/filter/excel/xeformula.cxx
+++ b/sc/source/filter/excel/xeformula.cxx
@@ -31,25 +31,29 @@
// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_sc.hxx"
+// XXX xelink.hxx MUST be included before xeformula.hxx because of the
+// redifinition of the CREATE_OUSTRING() macro, which is in oox/helper.hxx
+// (indirectly included via xelink.hxx) and ../inc/ftools.hxx (indirectly
+// included via xeformula.hxx) that does an undef first. Ugly.
+#include "xelink.hxx"
+#include "xeformula.hxx"
+
#include <list>
#include <map>
+#include <memory>
+#include "addincol.hxx"
#include "compiler.hxx"
+#include "document.hxx"
+#include "externalrefmgr.hxx"
#include "rangelst.hxx"
-#include "addincol.hxx"
-#include "xestream.hxx"
-#include "xehelper.hxx"
-#include "xelink.hxx"
-#include "xename.hxx"
-#include "xeformula.hxx"
#include "token.hxx"
#include "tokenarray.hxx"
+#include "xehelper.hxx"
+#include "xename.hxx"
+#include "xestream.hxx"
-#include "document.hxx"
-#include "externalrefmgr.hxx"
-
-#include <memory>
+using namespace ::formula;
-using namespace formula;
// External reference log =====================================================
XclExpRefLogEntry::XclExpRefLogEntry() :
@@ -63,90 +67,60 @@ XclExpRefLogEntry::XclExpRefLogEntry() :
// Formula compiler ===========================================================
-/** Type of token class handling. */
-enum XclExpTokenClassType
-{
- EXC_CLASSTYPE_CELL, /// Cell formula, shared formula.
- EXC_CLASSTYPE_ARRAY, /// Array formula, conditional formatting, data validation.
- EXC_CLASSTYPE_NAME /// Defined name, range list.
-};
+namespace {
-/** Type of the link manager to be used. */
-enum XclExpLinkMgrType
+/** Wrapper structure for a processed Calc formula token with additional
+ settings (whitespaces). */
+struct XclExpScToken
{
- EXC_LINKMGRTYPE_NONE, /// No link manager, 2D references only.
- EXC_LINKMGRTYPE_LOCAL, /// Local (per-sheet) link manager.
- EXC_LINKMGRTYPE_GLOBAL /// Global link manager.
+ const FormulaToken* mpScToken; /// Currently processed Calc token.
+ sal_uInt8 mnSpaces; /// Number of spaces before the Calc token.
+
+ inline explicit XclExpScToken() : mpScToken( 0 ), mnSpaces( 0 ) {}
+ inline bool Is() const { return mpScToken != 0; }
+ inline StackVar GetType() const { return mpScToken ? mpScToken->GetType() : static_cast< StackVar >( svUnknown ); }
+ inline OpCode GetOpCode() const { return mpScToken ? mpScToken->GetOpCode() : static_cast< OpCode >( ocNone ); }
};
// ----------------------------------------------------------------------------
-/** Configuration data of the formula compiler. */
-struct XclExpCompConfig
+/** Effective token class conversion types. */
+enum XclExpClassConv
{
- XclFormulaType meType; /// Type of the formula to be created.
- XclExpTokenClassType meClassType; /// Token class handling type.
- XclExpLinkMgrType meLinkMgrType; /// Link manager to be used.
- bool mbFromCell; /// True = Any kind of cell formula (cell, array, shared).
- bool mb3DRefOnly; /// True = Only 3D references allowed (e.g. names).
- bool mbAllowArrays; /// True = Allow inline arrays.
+ EXC_CLASSCONV_ORG, /// Keep original class of the token.
+ EXC_CLASSCONV_VAL, /// Convert ARR tokens to VAL class (REF remains uncahnged).
+ EXC_CLASSCONV_ARR /// Convert VAL tokens to ARR class (REF remains uncahnged).
};
// ----------------------------------------------------------------------------
-/** Working data of the formula compiler. Used to push onto a stack for recursive calls. */
-struct XclExpCompData
+/** Token class conversion and position of a token in the token array. */
+struct XclExpTokenConvInfo
{
- typedef ::std::list< const ScMatrix* > ScMatrixList;
- typedef ScfRef< ScMatrixList > ScMatrixListRef;
- typedef ScfRef< ScTokenArray > ScTokenArrayRef;
-
- XclExpCompConfig maCfg; /// Configuration for current formula type.
- ScfUInt8Vec maTokVec; /// Byte vector containing token data.
- ScTokenArrayRef mxOwnScTokArr; /// Own clone of a Calc token array.
- XclTokenArrayIterator maTokArrIt; /// Iterator in Calc token array.
- XclExpLinkManager* mpLinkMgr; /// Link manager for current context (local/global).
- XclExpRefLog* mpRefLog; /// Log for external references.
- ScMatrixListRef mxInlineArr; /// List of inline arrays (in reverse order)
-
- const ScAddress* mpScBasePos; /// Current cell position of the formula.
-
- // processing data during compilation
- sal_uInt16 mnLastTokPos; /// Position of last appended Excel token ID.
- sal_uInt8 mnLastDefClass; /// Default class of last appended Excel token ID.
- sal_uInt8 mnRefExpClass; /// New class for VAL parameters, if REF is expected.
- sal_uInt8 mnValExpClass; /// New class for all parameters, if VAL is expected.
- sal_uInt8 mnArrExpClass; /// New class for all parameters, if ARR is expected.
- bool mbStopAtSep; /// True = Stop subexpression creation at an ocSep token.
- bool mbVolatile; /// True = Formula contains volatile function.
- bool mbIsArrExp; /// True = ARR class is expected somewhere before.
- bool mbOk; /// Current state of the compiler.
-
- explicit XclExpCompData();
+ sal_uInt16 mnTokPos; /// Position of the token in the token array.
+ XclFuncParamConv meConv; /// Token class conversion type.
+ bool mbValType; /// Data type (false = REFTYPE, true = VALTYPE).
};
-XclExpCompData::XclExpCompData() :
- mpLinkMgr( 0 ),
- mpRefLog( 0 ),
- mpScBasePos( 0 ),
- mbOk( false )
+/** Vector of token position and conversion for all operands of an operator,
+ or for all parameters of a function. */
+struct XclExpOperandList : public ::std::vector< XclExpTokenConvInfo >
{
-}
-
-// ----------------------------------------------------------------------------
+ inline explicit XclExpOperandList() { reserve( 2 ); }
+ void AppendOperand( sal_uInt16 nTokPos, XclFuncParamConv eConv, bool bValType );
+};
-/** Working data for a processed Calc formula token. */
-struct XclExpTokenData
+void XclExpOperandList::AppendOperand( sal_uInt16 nTokPos, XclFuncParamConv eConv, bool bValType )
{
- const formula::FormulaToken*
- mpScToken; /// Currently processed Calc token.
- sal_uInt8 mnSpaces; /// Number of spaces before the Calc token.
+ resize( size() + 1 );
+ XclExpTokenConvInfo& rConvInfo = back();
+ rConvInfo.mnTokPos = nTokPos;
+ rConvInfo.meConv = eConv;
+ rConvInfo.mbValType = bValType;
+}
- inline explicit XclExpTokenData() : mpScToken( 0 ), mnSpaces( 0 ) {}
- inline bool Is() const { return mpScToken != 0; }
- inline formula::StackVar GetType() const { return mpScToken ? mpScToken->GetType() : static_cast< formula::StackVar >( svUnknown ); }
- inline OpCode GetOpCode() const { return mpScToken ? mpScToken->GetOpCode() : static_cast< OpCode >( ocNone ); }
-};
+typedef ScfRef< XclExpOperandList > XclExpOperandListRef;
+typedef ::std::vector< XclExpOperandListRef > XclExpOperandListVector;
// ----------------------------------------------------------------------------
@@ -175,87 +149,168 @@ class XclExpFuncData
{
public:
explicit XclExpFuncData(
- const XclExpTokenData& rTokData,
+ const XclExpScToken& rTokData,
const XclFunctionInfo& rFuncInfo,
- const XclExpExtFuncData& rExtFuncData,
- sal_uInt8 nExpRetClass );
+ const XclExpExtFuncData& rExtFuncData );
- inline const formula::FormulaToken& GetScToken() const { return *mrTokData.mpScToken; }
+ inline const FormulaToken& GetScToken() const { return *mrTokData.mpScToken; }
inline OpCode GetOpCode() const { return mrFuncInfo.meOpCode; }
inline sal_uInt16 GetXclFuncIdx() const { return mrFuncInfo.mnXclFunc; }
inline bool IsVolatile() const { return mrFuncInfo.IsVolatile(); }
+ inline bool IsFixedParamCount() const { return mrFuncInfo.IsFixedParamCount(); }
inline bool IsMacroFunc() const { return mrFuncInfo.IsMacroFunc(); }
inline sal_uInt8 GetSpaces() const { return mrTokData.mnSpaces; }
inline const XclExpExtFuncData& GetExtFuncData() const { return maExtFuncData; }
-
inline sal_uInt8 GetReturnClass() const { return mrFuncInfo.mnRetClass; }
- inline sal_uInt8 GetExpReturnClass() const { return mnExpRetClass; }
- inline sal_uInt8 GetExpParamClass() const { return mrFuncInfo.mpnParamClass[ mnClassIdx ]; }
- void IncExpParamClassIdx();
+ const XclFuncParamInfo& GetParamInfo() const;
+ bool IsCalcOnlyParam() const;
+ bool IsExcelOnlyParam() const;
+ void IncParamInfoIdx();
inline sal_uInt8 GetMinParamCount() const { return mrFuncInfo.mnMinParamCount; }
inline sal_uInt8 GetMaxParamCount() const { return mrFuncInfo.mnMaxParamCount; }
- inline sal_uInt8 GetParamCount() const { return mnParamCount; }
- inline void IncParamCount() { ++mnParamCount; }
+ inline sal_uInt8 GetParamCount() const { return static_cast< sal_uInt8 >( mxOperands->size() ); }
+ void FinishParam( sal_uInt16 nTokPos );
+ inline XclExpOperandListRef GetOperandList() const { return mxOperands; }
inline ScfUInt16Vec& GetAttrPosVec() { return maAttrPosVec; }
inline void AppendAttrPos( sal_uInt16 nPos ) { maAttrPosVec.push_back( nPos ); }
private:
ScfUInt16Vec maAttrPosVec; /// Token array positions of tAttr tokens.
- const XclExpTokenData& mrTokData; /// Data about processed function name token.
+ const XclExpScToken& mrTokData; /// Data about processed function name token.
const XclFunctionInfo& mrFuncInfo; /// Constant data about processed function.
XclExpExtFuncData maExtFuncData; /// Data for external functions (macro, add-in).
- sal_uInt8 mnExpRetClass; /// Expected token class for return value.
- sal_uInt8 mnClassIdx; /// Index into expected parameter class array of mrFuncInfo.
- sal_uInt8 mnParamCount; /// Current number of parameters of a function.
+ XclExpOperandListRef mxOperands; /// Class conversion and position of all parameters.
+ const XclFuncParamInfo* mpParamInfo; /// Information for current parameter.
};
-XclExpFuncData::XclExpFuncData(
- const XclExpTokenData& rTokData, const XclFunctionInfo& rFuncInfo,
- const XclExpExtFuncData& rExtFuncData, sal_uInt8 nExpRetClass ) :
+XclExpFuncData::XclExpFuncData( const XclExpScToken& rTokData,
+ const XclFunctionInfo& rFuncInfo, const XclExpExtFuncData& rExtFuncData ) :
mrTokData( rTokData ),
mrFuncInfo( rFuncInfo ),
maExtFuncData( rExtFuncData ),
- mnExpRetClass( nExpRetClass ),
- mnClassIdx( 0 ),
- mnParamCount( 0 )
+ mxOperands( new XclExpOperandList ),
+ mpParamInfo( rFuncInfo.mpParamInfos )
{
DBG_ASSERT( mrTokData.mpScToken, "XclExpFuncData::XclExpFuncData - missing core token" );
// set name of an add-in function
- if( !maExtFuncData.maFuncName.Len() && dynamic_cast< const formula::FormulaExternalToken* >( mrTokData.mpScToken ) )
+ if( (maExtFuncData.maFuncName.Len() == 0) && dynamic_cast< const FormulaExternalToken* >( mrTokData.mpScToken ) )
maExtFuncData.Set( GetScToken().GetExternal(), true, false );
}
-void XclExpFuncData::IncExpParamClassIdx()
+const XclFuncParamInfo& XclExpFuncData::GetParamInfo() const
{
- if( (mnClassIdx + 1 < EXC_FUNCINFO_CLASSCOUNT) && (mrFuncInfo.mpnParamClass[ mnClassIdx + 1 ] != EXC_TOKCLASS_NONE) )
- ++mnClassIdx;
+ static const XclFuncParamInfo saInvalidInfo = { EXC_PARAM_NONE, EXC_PARAMCONV_ORG, false };
+ return mpParamInfo ? *mpParamInfo : saInvalidInfo;
}
-// reference handling ---------------------------------------------------------
-
-namespace {
+bool XclExpFuncData::IsCalcOnlyParam() const
+{
+ return mpParamInfo && (mpParamInfo->meValid == EXC_PARAM_CALCONLY);
+}
-inline bool lclIsRefRel2D( const ScSingleRefData& rRefData )
+bool XclExpFuncData::IsExcelOnlyParam() const
{
- return rRefData.IsColRel() || rRefData.IsRowRel();
+ return mpParamInfo && (mpParamInfo->meValid == EXC_PARAM_EXCELONLY);
}
-inline bool lclIsRefDel2D( const ScSingleRefData& rRefData )
+void XclExpFuncData::IncParamInfoIdx()
{
- return rRefData.IsColDeleted() || rRefData.IsRowDeleted();
+ if( mpParamInfo )
+ {
+ // move pointer to next entry, if something explicit follows
+ if( (static_cast<size_t>(mpParamInfo - mrFuncInfo.mpParamInfos + 1) < EXC_FUNCINFO_PARAMINFO_COUNT) && (mpParamInfo[ 1 ].meValid != EXC_PARAM_NONE) )
+ ++mpParamInfo;
+ // if last parameter type is 'Excel-only' or 'Calc-only', do not repeat it
+ else if( IsExcelOnlyParam() || IsCalcOnlyParam() )
+ mpParamInfo = 0;
+ // otherwise: repeat last parameter class
+ }
}
-inline bool lclIsRefRel2D( const ScComplexRefData& rRefData )
+void XclExpFuncData::FinishParam( sal_uInt16 nTokPos )
{
- return lclIsRefRel2D( rRefData.Ref1 ) || lclIsRefRel2D( rRefData.Ref2 );
+ // write token class conversion info for this parameter
+ const XclFuncParamInfo& rParamInfo = GetParamInfo();
+ mxOperands->AppendOperand( nTokPos, rParamInfo.meConv, rParamInfo.mbValType );
+ // move to next parameter info structure
+ IncParamInfoIdx();
}
-inline bool lclIsRefDel2D( const ScComplexRefData& rRefData )
+// compiler configuration -----------------------------------------------------
+
+/** Type of token class handling. */
+enum XclExpFmlaClassType
{
- return lclIsRefDel2D( rRefData.Ref1 ) || lclIsRefDel2D( rRefData.Ref2 );
+ EXC_CLASSTYPE_CELL, /// Cell formula, shared formula.
+ EXC_CLASSTYPE_ARRAY, /// Array formula, conditional formatting, data validation.
+ EXC_CLASSTYPE_NAME /// Defined name, range list.
+};
+
+/** Configuration data of the formula compiler. */
+struct XclExpCompConfig
+{
+ XclFormulaType meType; /// Type of the formula to be created.
+ XclExpFmlaClassType meClassType; /// Token class handling type.
+ bool mbLocalLinkMgr; /// True = local (per-sheet) link manager, false = global.
+ bool mbFromCell; /// True = Any kind of cell formula (cell, array, shared).
+ bool mb3DRefOnly; /// True = Only 3D references allowed (e.g. names).
+ bool mbAllowArrays; /// True = Allow inline arrays.
+};
+
+/** The table containing configuration data for all formula types. */
+static const XclExpCompConfig spConfigTable[] =
+{
+ // formula type token class type lclLM inCell 3dOnly allowArray
+ { EXC_FMLATYPE_CELL, EXC_CLASSTYPE_CELL, true, true, false, true },
+ { EXC_FMLATYPE_SHARED, EXC_CLASSTYPE_CELL, true, true, false, true },
+ { EXC_FMLATYPE_MATRIX, EXC_CLASSTYPE_ARRAY, true, true, false, true },
+ { EXC_FMLATYPE_CONDFMT, EXC_CLASSTYPE_ARRAY, true, false, false, false },
+ { EXC_FMLATYPE_DATAVAL, EXC_CLASSTYPE_ARRAY, true, false, false, false },
+ { EXC_FMLATYPE_NAME, EXC_CLASSTYPE_NAME, false, false, true, true },
+ { EXC_FMLATYPE_CHART, EXC_CLASSTYPE_NAME, true, false, true, true },
+ { EXC_FMLATYPE_CONTROL, EXC_CLASSTYPE_NAME, true, false, false, false },
+ { EXC_FMLATYPE_WQUERY, EXC_CLASSTYPE_NAME, true, false, true, false },
+ { EXC_FMLATYPE_LISTVAL, EXC_CLASSTYPE_NAME, true, false, false, false }
+};
+
+// ----------------------------------------------------------------------------
+
+/** Working data of the formula compiler. Used to push onto a stack for recursive calls. */
+struct XclExpCompData
+{
+ typedef ScfRef< ScTokenArray > ScTokenArrayRef;
+
+ const XclExpCompConfig& mrCfg; /// Configuration for current formula type.
+ ScTokenArrayRef mxOwnScTokArr; /// Own clone of a Calc token array.
+ XclTokenArrayIterator maTokArrIt; /// Iterator in Calc token array.
+ XclExpLinkManager* mpLinkMgr; /// Link manager for current context (local/global).
+ XclExpRefLog* mpRefLog; /// Log for external references.
+ const ScAddress* mpScBasePos; /// Current cell position of the formula.
+
+ ScfUInt8Vec maTokVec; /// Byte vector containing token data.
+ ScfUInt8Vec maExtDataVec; /// Byte vector containing extended data (arrays, stacked NLRs).
+ XclExpOperandListVector maOpListVec; /// Formula structure, maps operators to their operands.
+ ScfUInt16Vec maOpPosStack; /// Stack with positions of operand tokens waiting for an operator.
+ bool mbStopAtSep; /// True = Stop subexpression creation at an ocSep token.
+ bool mbVolatile; /// True = Formula contains volatile function.
+ bool mbOk; /// Current state of the compiler.
+
+ explicit XclExpCompData( const XclExpCompConfig* pCfg );
+};
+
+XclExpCompData::XclExpCompData( const XclExpCompConfig* pCfg ) :
+ mrCfg( pCfg ? *pCfg : spConfigTable[ 0 ] ),
+ mpLinkMgr( 0 ),
+ mpRefLog( 0 ),
+ mpScBasePos( 0 ),
+ mbStopAtSep( false ),
+ mbVolatile( false ),
+ mbOk( pCfg != 0 )
+{
+ DBG_ASSERT( pCfg, "XclExpFmlaCompImpl::Init - unknown formula type" );
}
} // namespace
@@ -263,7 +318,7 @@ inline bool lclIsRefDel2D( const ScComplexRefData& rRefData )
// ----------------------------------------------------------------------------
/** Implementation class of the export formula compiler. */
-class XclExpFmlaCompImpl : protected XclExpRoot, protected XclTokenArrayHelper, private XclExpCompData
+class XclExpFmlaCompImpl : protected XclExpRoot, protected XclTokenArrayHelper
{
public:
explicit XclExpFmlaCompImpl( const XclExpRoot& rRoot );
@@ -285,64 +340,64 @@ public:
// ------------------------------------------------------------------------
private:
const XclExpCompConfig* GetConfigForType( XclFormulaType eType ) const;
- inline sal_uInt16 GetSize() const { return static_cast< sal_uInt16 >( maTokVec.size() ); }
+ inline sal_uInt16 GetSize() const { return static_cast< sal_uInt16 >( mxData->maTokVec.size() ); }
- void EnterRecursive();
void Init( XclFormulaType eType );
void Init( XclFormulaType eType, const ScTokenArray& rScTokArr,
const ScAddress* pScBasePos, XclExpRefLog* pRefLog );
- void LeaveRecursive();
- void FinalizeFormula( ScfUInt8Vec & rExtensionTokens );
- void AppendInlineArrays( ScfUInt8Vec & rExtensionTokens );
- XclTokenArrayRef CreateTokenArray( ScfUInt8Vec* pExtensionTokens = NULL );
+ void RecalcTokenClasses();
+ void RecalcTokenClass( const XclExpTokenConvInfo& rConvInfo, XclFuncParamConv ePrevConv, XclExpClassConv ePrevClassConv, bool bWasRefClass );
+
+ void FinalizeFormula();
+ XclTokenArrayRef CreateTokenArray();
// compiler ---------------------------------------------------------------
- // XclExpTokenData: pass-by-value and return-by-value is intended
-
- const formula::FormulaToken* GetNextRawToken();
- const formula::FormulaToken* PeekNextRawToken( bool bSkipSpaces ) const;
-
- bool GetNextToken( XclExpTokenData& rTokData );
- XclExpTokenData GetNextToken();
-
- XclExpTokenData Expression( XclExpTokenData aTokData, sal_uInt8 nExpClass, bool bInParentheses, bool bStopAtSep );
- XclExpTokenData SkipExpression( XclExpTokenData aTokData, bool bStopAtSep );
-
- XclExpTokenData OrTerm( XclExpTokenData aTokData, sal_uInt8 nExpClass, bool bInParentheses );
- XclExpTokenData AndTerm( XclExpTokenData aTokData, sal_uInt8 nExpClass, bool bInParentheses );
- XclExpTokenData CompareTerm( XclExpTokenData aTokData, sal_uInt8 nExpClass, bool bInParentheses );
- XclExpTokenData ConcatTerm( XclExpTokenData aTokData, sal_uInt8 nExpClass, bool bInParentheses );
- XclExpTokenData AddSubTerm( XclExpTokenData aTokData, sal_uInt8 nExpClass, bool bInParentheses );
- XclExpTokenData MulDivTerm( XclExpTokenData aTokData, sal_uInt8 nExpClass, bool bInParentheses );
- XclExpTokenData PowTerm( XclExpTokenData aTokData, sal_uInt8 nExpClass, bool bInParentheses );
- XclExpTokenData UnaryPostTerm( XclExpTokenData aTokData, sal_uInt8 nExpClass, bool bInParentheses );
- XclExpTokenData UnaryPreTerm( XclExpTokenData aTokData, sal_uInt8 nExpClass, bool bInParentheses );
- XclExpTokenData ListTerm( XclExpTokenData aTokData, sal_uInt8 nExpClass, bool bInParentheses );
- XclExpTokenData IntersectTerm( XclExpTokenData aTokData, sal_uInt8 nExpClass, bool& rbHasRefOp );
- XclExpTokenData RangeTerm( XclExpTokenData aTokData, sal_uInt8 nExpClass, bool& rbHasRefOp );
- XclExpTokenData Factor( XclExpTokenData aTokData, sal_uInt8 nExpClass );
+ // XclExpScToken: pass-by-value and return-by-value is intended
+
+ const FormulaToken* GetNextRawToken();
+ const FormulaToken* PeekNextRawToken( bool bSkipSpaces ) const;
+
+ bool GetNextToken( XclExpScToken& rTokData );
+ XclExpScToken GetNextToken();
+
+ XclExpScToken Expression( XclExpScToken aTokData, bool bInParentheses, bool bStopAtSep );
+ XclExpScToken SkipExpression( XclExpScToken aTokData, bool bStopAtSep );
+
+ XclExpScToken OrTerm( XclExpScToken aTokData, bool bInParentheses );
+ XclExpScToken AndTerm( XclExpScToken aTokData, bool bInParentheses );
+ XclExpScToken CompareTerm( XclExpScToken aTokData, bool bInParentheses );
+ XclExpScToken ConcatTerm( XclExpScToken aTokData, bool bInParentheses );
+ XclExpScToken AddSubTerm( XclExpScToken aTokData, bool bInParentheses );
+ XclExpScToken MulDivTerm( XclExpScToken aTokData, bool bInParentheses );
+ XclExpScToken PowTerm( XclExpScToken aTokData, bool bInParentheses );
+ XclExpScToken UnaryPostTerm( XclExpScToken aTokData, bool bInParentheses );
+ XclExpScToken UnaryPreTerm( XclExpScToken aTokData, bool bInParentheses );
+ XclExpScToken ListTerm( XclExpScToken aTokData, bool bInParentheses );
+ XclExpScToken IntersectTerm( XclExpScToken aTokData, bool& rbHasRefOp );
+ XclExpScToken RangeTerm( XclExpScToken aTokData, bool& rbHasRefOp );
+ XclExpScToken Factor( XclExpScToken aTokData );
// formula structure ------------------------------------------------------
- void ProcessDouble( const XclExpTokenData& rTokData );
- void ProcessString( const XclExpTokenData& rTokData );
- void ProcessError( const XclExpTokenData& rTokData );
- void ProcessMissing( const XclExpTokenData& rTokData );
- void ProcessBad( const XclExpTokenData& rTokData );
- void ProcessParentheses( const XclExpTokenData& rTokData, sal_uInt8 nExpClass );
- void ProcessBoolean( const XclExpTokenData& rTokData );
- void ProcessDdeLink( const XclExpTokenData& rTokData, sal_uInt8 nExpClass );
- void ProcessExternal( const XclExpTokenData& rTokData, sal_uInt8 nExpClass );
- void ProcessExternalName( const XclExpTokenData& rTokData, sal_uInt8 nExpClass );
-
- void ProcessFunction( const XclExpTokenData& rTokData, sal_uInt8 nExpClass );
+ void ProcessDouble( const XclExpScToken& rTokData );
+ void ProcessString( const XclExpScToken& rTokData );
+ void ProcessError( const XclExpScToken& rTokData );
+ void ProcessMissing( const XclExpScToken& rTokData );
+ void ProcessBad( const XclExpScToken& rTokData );
+ void ProcessParentheses( const XclExpScToken& rTokData );
+ void ProcessBoolean( const XclExpScToken& rTokData );
+ void ProcessDdeLink( const XclExpScToken& rTokData );
+ void ProcessExternal( const XclExpScToken& rTokData );
+ void ProcessMatrix( const XclExpScToken& rTokData );
+
+ void ProcessFunction( const XclExpScToken& rTokData );
void PrepareFunction( XclExpFuncData& rFuncData );
void FinishFunction( XclExpFuncData& rFuncData, sal_uInt8 nCloseSpaces );
void FinishIfFunction( XclExpFuncData& rFuncData );
void FinishChooseFunction( XclExpFuncData& rFuncData );
- XclExpTokenData ProcessParam( XclExpTokenData aTokData, XclExpFuncData& rFuncData );
+ XclExpScToken ProcessParam( XclExpScToken aTokData, XclExpFuncData& rFuncData );
void PrepareParam( XclExpFuncData& rFuncData );
void FinishParam( XclExpFuncData& rFuncData );
void AppendDefaultParam( XclExpFuncData& rFuncData );
@@ -360,28 +415,20 @@ private:
bool bNatLangRef ) const;
XclExpRefLogEntry* GetNewRefLogEntry();
- void ProcessCellRef( const XclExpTokenData& rTokData, sal_uInt8 nExpClass );
- void ProcessRangeRef( const XclExpTokenData& rTokData, sal_uInt8 nExpClass );
- void ProcessMatrix( const XclExpTokenData& rTokData, sal_uInt8 nExpClass );
- void ProcessDefinedName( const XclExpTokenData& rTokData, sal_uInt8 nExpClass );
- void ProcessDatabaseArea( const XclExpTokenData& rTokData, sal_uInt8 nExpClass );
-
- // token identifiers ------------------------------------------------------
-
- void SetReplaceTokenClasses();
- void SetArrExpFlag( bool bIsArrExp );
- void UpdateArrExpFlag( sal_uInt8 nParamExpClass, sal_uInt8 nFuncRetClass );
-
- void AdjustTokenClass( sal_uInt8& rnTokenId, sal_uInt8 nExpClass );
- void AdjustLastTokenClass( sal_uInt8 nExpClass );
- void AdjustLastTokenClassForEastereggOp();
-
- void AppendOpTokenId( sal_uInt8 nTokenId, sal_uInt8 nExpClass, sal_uInt8 nSpaces = 0 );
-//UNUSED2008-05 void AppendFuncTokenId( sal_uInt16 nXclFuncIdx, sal_uInt8 nRetClass, sal_uInt8 nExpRetClass, sal_uInt8 nSpaces = 0 );
- void AppendVarFuncTokenId( sal_uInt16 nXclFuncIdx, sal_uInt8 nRetClass, sal_uInt8 nExpRetClass, sal_uInt8 nParamCount, sal_uInt8 nSpaces = 0 );
+ void ProcessCellRef( const XclExpScToken& rTokData );
+ void ProcessRangeRef( const XclExpScToken& rTokData );
+ void ProcessExternalCellRef( const XclExpScToken& rTokData );
+ void ProcessExternalRangeRef( const XclExpScToken& rTokData );
+ void ProcessDefinedName( const XclExpScToken& rTokData );
+ void ProcessExternalName( const XclExpScToken& rTokData );
+ void ProcessDatabaseArea( const XclExpScToken& rTokData );
// token vector -----------------------------------------------------------
+ void PushOperandPos( sal_uInt16 nTokPos );
+ void PushOperatorPos( sal_uInt16 nTokPos, const XclExpOperandListRef& rxOperands );
+ sal_uInt16 PopOperandPos();
+
void Append( sal_uInt8 nData );
void Append( sal_uInt8 nData, size_t nCount );
void Append( sal_uInt16 nData );
@@ -393,21 +440,30 @@ private:
void AppendRange( const XclRange& rXclRange );
void AppendSpaceToken( sal_uInt8 nType, sal_uInt8 nCount );
+
+ void AppendOperandTokenId( sal_uInt8 nTokenId, sal_uInt8 nSpaces = 0 );
void AppendIntToken( sal_uInt16 nValue, sal_uInt8 nSpaces = 0 );
void AppendNumToken( double fValue, sal_uInt8 nSpaces = 0 );
void AppendBoolToken( bool bValue, sal_uInt8 nSpaces = 0 );
void AppendErrorToken( sal_uInt8 nErrCode, sal_uInt8 nSpaces = 0 );
void AppendMissingToken( sal_uInt8 nSpaces = 0 );
- void AppendNameToken( sal_uInt16 nNameIdx, sal_uInt8 nExpClass, sal_uInt8 nSpaces = 0 );
- void AppendMissingNameToken( const String& rName, sal_uInt8 nExpClass, sal_uInt8 nSpaces = 0 );
- void AppendNameXToken( sal_uInt16 nExtSheet, sal_uInt16 nExtName, sal_uInt8 nExpClass, sal_uInt8 nSpaces = 0 );
- void AppendMacroCallToken( const XclExpExtFuncData& rExtFuncData, sal_uInt8 nExpClass, sal_uInt8 nSpaces = 0 );
- void AppendAddInFuncToken( const XclExpExtFuncData& rExtFuncData, sal_uInt8 nExpClass, sal_uInt8 nSpaces = 0 );
- void AppendEuroToolFuncToken( const XclExpExtFuncData& rExtFuncData, sal_uInt8 nExpClass, sal_uInt8 nSpaces = 0 );
+ void AppendNameToken( sal_uInt16 nNameIdx, sal_uInt8 nSpaces = 0 );
+ void AppendMissingNameToken( const String& rName, sal_uInt8 nSpaces = 0 );
+ void AppendNameXToken( sal_uInt16 nExtSheet, sal_uInt16 nExtName, sal_uInt8 nSpaces = 0 );
+ void AppendMacroCallToken( const XclExpExtFuncData& rExtFuncData, sal_uInt8 nSpaces = 0 );
+ void AppendAddInCallToken( const XclExpExtFuncData& rExtFuncData, sal_uInt8 nSpaces = 0 );
+ void AppendEuroToolCallToken( const XclExpExtFuncData& rExtFuncData, sal_uInt8 nSpaces = 0 );
+
+ void AppendOperatorTokenId( sal_uInt8 nTokenId, const XclExpOperandListRef& rxOperands, sal_uInt8 nSpaces = 0 );
+ void AppendUnaryOperatorToken( sal_uInt8 nTokenId, sal_uInt8 nSpaces = 0 );
+ void AppendBinaryOperatorToken( sal_uInt8 nTokenId, bool bValType, sal_uInt8 nSpaces = 0 );
+ void AppendLogicalOperatorToken( sal_uInt16 nXclFuncIdx, sal_uInt8 nOpCount );
+ void AppendFuncToken( const XclExpFuncData& rFuncData );
+
void AppendParenToken( sal_uInt8 nOpenSpaces = 0, sal_uInt8 nCloseSpaces = 0 );
void AppendJumpToken( XclExpFuncData& rFuncData, sal_uInt8 nAttrType );
- void Insert( sal_uInt16 nInsertPos, sal_uInt16 nInsertSize );
+ void InsertZeros( sal_uInt16 nInsertPos, sal_uInt16 nInsertSize );
void Overwrite( sal_uInt16 nWriteToPos, sal_uInt16 nOffset );
void UpdateAttrGoto( sal_uInt16 nAttrPos );
@@ -415,14 +471,23 @@ private:
bool IsSpaceToken( sal_uInt16 nPos ) const;
void RemoveTrailingParen();
+ void AppendExt( sal_uInt8 nData );
+ void AppendExt( sal_uInt8 nData, size_t nCount );
+ void AppendExt( sal_uInt16 nData );
+ void AppendExt( sal_uInt32 nData );
+ void AppendExt( double fData );
+ void AppendExt( const String& rString );
+
// ------------------------------------------------------------------------
private:
typedef ::std::map< XclFormulaType, XclExpCompConfig > XclExpCompConfigMap;
- typedef ::std::list< XclExpCompData > XclExpCompDataList;
+ typedef ScfRef< XclExpCompData > XclExpCompDataRef;
+ typedef ::std::vector< XclExpCompDataRef > XclExpCompDataVector;
XclExpCompConfigMap maCfgMap; /// Compiler configuration map for all formula types.
XclFunctionProvider maFuncProv; /// Excel function data provider.
- XclExpCompDataList maCompDataList; /// List for working data, when compiler is called recursively.
+ XclExpCompDataRef mxData; /// Working data for current formula.
+ XclExpCompDataVector maDataStack; /// Stack for working data, when compiler is called recursively.
const XclBiff meBiff; /// Cached BIFF version to save GetBiff() calls.
const SCsCOL mnMaxAbsCol; /// Maximum column index.
const SCsROW mnMaxAbsRow; /// Maximum row index.
@@ -430,31 +495,8 @@ private:
const SCsROW mnMaxScRow; /// Maximum row index in Calc itself.
const sal_uInt16 mnMaxColMask; /// Mask to delete invalid bits in column fields.
const sal_uInt16 mnMaxRowMask; /// Mask to delete invalid bits in row fields.
- bool mbRunning; /// true = compiler already running (for recursive calls).
-};
-
-// ----------------------------------------------------------------------------
-
-namespace {
-
-/** The table containing configuration data for all formula types. */
-static const XclExpCompConfig spConfigTable[] =
-{
- // formula type token class type link manager type inCell 3dOnly allowArray
- { EXC_FMLATYPE_CELL, EXC_CLASSTYPE_CELL, EXC_LINKMGRTYPE_LOCAL, true, false, true },
- { EXC_FMLATYPE_SHARED, EXC_CLASSTYPE_CELL, EXC_LINKMGRTYPE_LOCAL, true, false, true },
- { EXC_FMLATYPE_MATRIX, EXC_CLASSTYPE_ARRAY, EXC_LINKMGRTYPE_LOCAL, true, false, true },
- { EXC_FMLATYPE_CONDFMT, EXC_CLASSTYPE_ARRAY, EXC_LINKMGRTYPE_NONE, false, false, false },
- { EXC_FMLATYPE_DATAVAL, EXC_CLASSTYPE_ARRAY, EXC_LINKMGRTYPE_NONE, false, false, false },
- { EXC_FMLATYPE_NAME, EXC_CLASSTYPE_NAME, EXC_LINKMGRTYPE_GLOBAL, false, true, true },
- { EXC_FMLATYPE_CHART, EXC_CLASSTYPE_NAME, EXC_LINKMGRTYPE_LOCAL, false, true, true },
- { EXC_FMLATYPE_CONTROL, EXC_CLASSTYPE_NAME, EXC_LINKMGRTYPE_LOCAL, false, false, false },
- { EXC_FMLATYPE_WQUERY, EXC_CLASSTYPE_NAME, EXC_LINKMGRTYPE_LOCAL, false, true, false },
- { EXC_FMLATYPE_LISTVAL, EXC_CLASSTYPE_NAME, EXC_LINKMGRTYPE_NONE, false, false, false }
};
-} // namespace
-
// ----------------------------------------------------------------------------
XclExpFmlaCompImpl::XclExpFmlaCompImpl( const XclExpRoot& rRoot ) :
@@ -466,8 +508,7 @@ XclExpFmlaCompImpl::XclExpFmlaCompImpl( const XclExpRoot& rRoot ) :
mnMaxScCol( static_cast< SCsCOL >( rRoot.GetScMaxPos().Col() ) ),
mnMaxScRow( static_cast< SCsROW >( rRoot.GetScMaxPos().Row() ) ),
mnMaxColMask( static_cast< sal_uInt16 >( rRoot.GetXclMaxPos().Col() ) ),
- mnMaxRowMask( static_cast< sal_uInt16 >( rRoot.GetXclMaxPos().Row() ) ),
- mbRunning( false )
+ mnMaxRowMask( static_cast< sal_uInt16 >( rRoot.GetXclMaxPos().Row() ) )
{
// build the configuration map
for( const XclExpCompConfig* pEntry = spConfigTable; pEntry != STATIC_TABLE_END( spConfigTable ); ++pEntry )
@@ -481,9 +522,9 @@ XclTokenArrayRef XclExpFmlaCompImpl::CreateFormula( XclFormulaType eType,
Init( eType, rScTokArr, pScBasePos, pRefLog );
// start compilation, if initialization didn't fail
- if( mbOk )
+ if( mxData->mbOk )
{
- XclExpTokenData aTokData( GetNextToken() );
+ XclExpScToken aTokData( GetNextToken() );
USHORT nScError = rScTokArr.GetCodeError();
if( (nScError != 0) && (!aTokData.Is() || (aTokData.GetOpCode() == ocStop)) )
{
@@ -492,29 +533,28 @@ XclTokenArrayRef XclExpFmlaCompImpl::CreateFormula( XclFormulaType eType,
}
else if( aTokData.Is() )
{
- // expected class is VAL in cell and array formulas, and REF in names
- sal_uInt8 nExpClass = (maCfg.meClassType == EXC_CLASSTYPE_NAME) ? EXC_TOKCLASS_REF : EXC_TOKCLASS_VAL;
- aTokData = Expression( aTokData, nExpClass, false, false );
+ aTokData = Expression( aTokData, false, false );
}
else
{
DBG_ERRORFILE( "XclExpFmlaCompImpl::CreateFormula - empty token array" );
- mbOk = false;
+ mxData->mbOk = false;
}
- if( mbOk )
+ if( mxData->mbOk )
{
// #i44907# auto-generated SUBTOTAL formula cells have trailing ocStop token
- mbOk = !aTokData.Is() || (aTokData.GetOpCode() == ocStop);
- DBG_ASSERT( mbOk, "XclExpFmlaCompImpl::CreateFormula - unknown garbage behind formula" );
+ mxData->mbOk = !aTokData.Is() || (aTokData.GetOpCode() == ocStop);
+ DBG_ASSERT( mxData->mbOk, "XclExpFmlaCompImpl::CreateFormula - unknown garbage behind formula" );
}
}
- // finalizing, e.g. add tAttrVolatile token, and storing any inline arrays
- ScfUInt8Vec aExtensionTokens;
- FinalizeFormula( aExtensionTokens );
+ // finalize (add tAttrVolatile token, calculate all token classes)
+ RecalcTokenClasses();
+ FinalizeFormula();
- return CreateTokenArray( &aExtensionTokens );
+ // leave recursive call, create and return the final token array
+ return CreateTokenArray();
}
XclTokenArrayRef XclExpFmlaCompImpl::CreateErrorFormula( sal_uInt8 nErrCode )
@@ -527,7 +567,7 @@ XclTokenArrayRef XclExpFmlaCompImpl::CreateErrorFormula( sal_uInt8 nErrCode )
XclTokenArrayRef XclExpFmlaCompImpl::CreateSpecialRefFormula( sal_uInt8 nTokenId, const XclAddress& rXclPos )
{
Init( EXC_FMLATYPE_NAME );
- AppendOpTokenId( nTokenId, EXC_TOKCLASS_NONE );
+ AppendOperandTokenId( nTokenId );
Append( rXclPos.mnRow );
Append( rXclPos.mnCol ); // do not use AppendAddress(), we always need 16-bit column here
return CreateTokenArray();
@@ -536,7 +576,7 @@ XclTokenArrayRef XclExpFmlaCompImpl::CreateSpecialRefFormula( sal_uInt8 nTokenId
XclTokenArrayRef XclExpFmlaCompImpl::CreateNameXFormula( sal_uInt16 nExtSheet, sal_uInt16 nExtName )
{
Init( EXC_FMLATYPE_NAME );
- AppendNameXToken( nExtSheet, nExtName, EXC_TOKCLASS_NONE );
+ AppendNameXToken( nExtSheet, nExtName );
return CreateTokenArray();
}
@@ -555,47 +595,13 @@ const XclExpCompConfig* XclExpFmlaCompImpl::GetConfigForType( XclFormulaType eTy
return (aIt == maCfgMap.end()) ? 0 : &aIt->second;
}
-void XclExpFmlaCompImpl::EnterRecursive()
-{
- if( mbRunning )
- // compiler invoked recursively - store old working data
- maCompDataList.push_back( static_cast< const XclExpCompData& >( *this ) );
- else
- mbRunning = true;
-}
-
void XclExpFmlaCompImpl::Init( XclFormulaType eType )
{
// compiler invoked recursively? - store old working data
- EnterRecursive();
-
- // compiler configuration
- const XclExpCompConfig* pCfg = GetConfigForType( eType );
- mbOk = pCfg != 0;
- DBG_ASSERT( mbOk, "XclExpFmlaCompImpl::Init - unknown formula type" );
- if( mbOk )
- {
- // copy config data to own member
- maCfg = *pCfg;
-
- // reset per-formula data
- maTokVec.clear();
- mxOwnScTokArr.reset();
- maTokArrIt.Init();
- mpLinkMgr = 0;
- mpRefLog = 0;
- mxInlineArr.reset();
-
- mpScBasePos = 0;
-
- // init processing data used during compilation
- mnLastTokPos = SAL_MAX_UINT16;
- mnLastDefClass = EXC_TOKCLASS_NONE;
- mbStopAtSep = false;
- mbVolatile = false;
- mbIsArrExp = false;
- SetReplaceTokenClasses(); // initializes the token class variables for AdjustTokenClass()
- }
+ if( mxData.get() )
+ maDataStack.push_back( mxData );
+ // new compiler working data structure
+ mxData.reset( new XclExpCompData( GetConfigForType( eType ) ) );
}
void XclExpFmlaCompImpl::Init( XclFormulaType eType, const ScTokenArray& rScTokArr,
@@ -605,199 +611,222 @@ void XclExpFmlaCompImpl::Init( XclFormulaType eType, const ScTokenArray& rScTokA
Init( eType );
// special initialization
- if( mbOk ) switch( maCfg.meType )
+ if( mxData->mbOk ) switch( mxData->mrCfg.meType )
{
case EXC_FMLATYPE_CELL:
case EXC_FMLATYPE_MATRIX:
case EXC_FMLATYPE_CHART:
- mbOk = pScBasePos != 0;
- DBG_ASSERT( mbOk, "XclExpFmlaCompImpl::Init - missing cell address" );
- mpScBasePos = pScBasePos;
+ mxData->mbOk = pScBasePos != 0;
+ DBG_ASSERT( mxData->mbOk, "XclExpFmlaCompImpl::Init - missing cell address" );
+ mxData->mpScBasePos = pScBasePos;
break;
case EXC_FMLATYPE_SHARED:
- mbOk = pScBasePos != 0;
- DBG_ASSERT( mbOk, "XclExpFmlaCompImpl::Init - missing cell address" );
+ mxData->mbOk = pScBasePos != 0;
+ DBG_ASSERT( mxData->mbOk, "XclExpFmlaCompImpl::Init - missing cell address" );
// clone the passed token array, convert references relative to current cell position
- mxOwnScTokArr.reset( rScTokArr.Clone() );
- ScCompiler::MoveRelWrap( *mxOwnScTokArr, GetDocPtr(), *pScBasePos, MAXCOL, MAXROW );
- // don't remember pScBasePos in mpScBasePos, shared formulas use real relative refs
+ mxData->mxOwnScTokArr.reset( rScTokArr.Clone() );
+ ScCompiler::MoveRelWrap( *mxData->mxOwnScTokArr, GetDocPtr(), *pScBasePos, MAXCOL, MAXROW );
+ // don't remember pScBasePos in mxData->mpScBasePos, shared formulas use real relative refs
break;
default:;
}
- if( mbOk )
+ if( mxData->mbOk )
{
// link manager to be used
- switch( maCfg.meLinkMgrType )
- {
- case EXC_LINKMGRTYPE_NONE: mpLinkMgr = 0; break;
- case EXC_LINKMGRTYPE_LOCAL: mpLinkMgr = &GetLocalLinkManager(); break;
- case EXC_LINKMGRTYPE_GLOBAL: mpLinkMgr = &GetGlobalLinkManager(); break;
- }
+ mxData->mpLinkMgr = mxData->mrCfg.mbLocalLinkMgr ? &GetLocalLinkManager() : &GetGlobalLinkManager();
// token array iterator (use cloned token array if present)
- maTokArrIt.Init( mxOwnScTokArr.is() ? *mxOwnScTokArr : rScTokArr, false );
- mpRefLog = pRefLog;
+ mxData->maTokArrIt.Init( mxData->mxOwnScTokArr.is() ? *mxData->mxOwnScTokArr : rScTokArr, false );
+ mxData->mpRefLog = pRefLog;
}
}
-void XclExpFmlaCompImpl::LeaveRecursive()
+void XclExpFmlaCompImpl::RecalcTokenClasses()
{
- mbRunning = !maCompDataList.empty();
- if( mbRunning )
+ if( mxData->mbOk )
{
- // compiler invoked recursively - restore old working data
- static_cast< XclExpCompData& >( *this ) = maCompDataList.back();
- maCompDataList.pop_back();
+ mxData->mbOk = mxData->maOpPosStack.size() == 1;
+ DBG_ASSERT( mxData->mbOk, "XclExpFmlaCompImpl::RecalcTokenClasses - position of root token expected on stack" );
+ if( mxData->mbOk )
+ {
+ /* Cell and array formulas start with VAL conversion and VALTYPE
+ parameter type, defined names start with ARR conversion and
+ REFTYPE parameter type for the root token. */
+ XclExpOperandList aOperands;
+ bool bNameFmla = mxData->mrCfg.meClassType == EXC_CLASSTYPE_NAME;
+ XclFuncParamConv eParamConv = bNameFmla ? EXC_PARAMCONV_ARR : EXC_PARAMCONV_VAL;
+ XclExpClassConv eClassConv = bNameFmla ? EXC_CLASSCONV_ARR : EXC_CLASSCONV_VAL;
+ XclExpTokenConvInfo aConvInfo = { PopOperandPos(), eParamConv, !bNameFmla };
+ RecalcTokenClass( aConvInfo, eParamConv, eClassConv, bNameFmla );
+ }
+
+ // clear operand vectors (calls to the expensive InsertZeros() may follow)
+ mxData->maOpListVec.clear();
+ mxData->maOpPosStack.clear();
}
}
-void XclExpFmlaCompImpl::AppendInlineArrays( ScfUInt8Vec& rExtensionTokens )
+void XclExpFmlaCompImpl::RecalcTokenClass( const XclExpTokenConvInfo& rConvInfo,
+ XclFuncParamConv ePrevConv, XclExpClassConv ePrevClassConv, bool bWasRefClass )
{
- // The const_cast is needed, otherwise MS and Sun compilers can't promote
- // the non-const iterators obtained via ScMatrixList* to const iterators.
- const ScMatrixList* pList = const_cast< const ScMatrixList* >( mxInlineArr.get() );
- for( ScMatrixList::const_reverse_iterator aIt = pList->rbegin(), aEnd = pList->rend(); aIt != aEnd ; ++aIt )
- {
- const ScMatrix* pMatrix = *aIt;
- SCSIZE nC, nMaxC, nR, nMaxR;
+ DBG_ASSERT( rConvInfo.mnTokPos < GetSize(), "XclExpFmlaCompImpl::RecalcTokenClass - invalid token position" );
+ sal_uInt8& rnTokenId = mxData->maTokVec[ rConvInfo.mnTokPos ];
+ sal_uInt8 nTokClass = GetTokenClass( rnTokenId );
- pMatrix->GetDimensions( nMaxC, nMaxR );
+ // REF tokens in VALTYPE parameters behave like VAL tokens
+ if( rConvInfo.mbValType && (nTokClass == EXC_TOKCLASS_REF) )
+ ChangeTokenClass( rnTokenId, nTokClass = EXC_TOKCLASS_VAL );
- if( meBiff == EXC_BIFF8 )
- {
- rExtensionTokens.push_back( sal::static_int_cast<sal_uInt8>( nMaxC - 1 ) );
- rExtensionTokens.resize( rExtensionTokens.size() + 2 );
- ShortToSVBT16( static_cast< USHORT >( nMaxR - 1 ), &*(rExtensionTokens.end() - 2) );
- }
- else
- {
- rExtensionTokens.push_back( static_cast< sal_uInt8 >( (nMaxC == 256) ? 0 : nMaxC ) );
- rExtensionTokens.resize( rExtensionTokens.size() + 2 );
- ShortToSVBT16( static_cast< USHORT >( nMaxR ), &*(rExtensionTokens.end() - 2) );
- }
+ // replace RPO conversion of operator with parent conversion
+ XclFuncParamConv eConv = (rConvInfo.meConv == EXC_PARAMCONV_RPO) ? ePrevConv : rConvInfo.meConv;
- for( nR = 0 ; nR < nMaxR ; nR++)
- {
- for( nC = 0 ; nC < nMaxC ; nC++)
+ // find the effective token class conversion to be performed for this token
+ XclExpClassConv eClassConv = EXC_CLASSCONV_ORG;
+ switch( eConv )
+ {
+ case EXC_PARAMCONV_ORG:
+ // conversion is forced independent of parent conversion
+ eClassConv = EXC_CLASSCONV_ORG;
+ break;
+ case EXC_PARAMCONV_VAL:
+ // conversion is forced independent of parent conversion
+ eClassConv = EXC_CLASSCONV_VAL;
+ break;
+ case EXC_PARAMCONV_ARR:
+ // conversion is forced independent of parent conversion
+ eClassConv = EXC_CLASSCONV_ARR;
+ break;
+ case EXC_PARAMCONV_RPT:
+ switch( ePrevConv )
{
- if( pMatrix->IsValue( nC, nR ) )
- {
- ScMatValType nType;
- const ScMatrixValue* pVal = pMatrix->Get( nC, nR, nType);
-
- if( nType == SC_MATVAL_BOOLEAN )
- {
- rExtensionTokens.push_back( EXC_CACHEDVAL_BOOL );
-
- rExtensionTokens.resize( rExtensionTokens.size() + 8 );
- const bool bVal = ! ::rtl::math::approxEqual( pVal->fVal, 0. );
- UInt32ToSVBT32( bVal ? 1 : 0, &*(rExtensionTokens.end() - 8) );
- UInt32ToSVBT32( 0, &*(rExtensionTokens.end() - 4) );
- }
- else
- {
- USHORT nErr = pVal->GetError();
- if( nErr )
- {
- rExtensionTokens.push_back( EXC_CACHEDVAL_ERROR );
-
- rExtensionTokens.resize( rExtensionTokens.size() + 8 );
- UInt32ToSVBT32( XclTools::GetXclErrorCode ( nErr ),
- &*(rExtensionTokens.end() - 8) );
- UInt32ToSVBT32( 0, &*(rExtensionTokens.end() - 4) );
- }
- else
- {
- rExtensionTokens.push_back( EXC_CACHEDVAL_DOUBLE );
-
- const double nVal = pMatrix->GetDouble( nC, nR );
- rExtensionTokens.resize( rExtensionTokens.size() + 8 );
- DoubleToSVBT64( nVal, &*(rExtensionTokens.end() - 8) );
- }
- }
- }
- else if( pMatrix->IsEmpty( nC, nR ) )
- {
- rExtensionTokens.push_back( EXC_CACHEDVAL_EMPTY );
-
- rExtensionTokens.resize( rExtensionTokens.size() + 8 );
- UInt32ToSVBT32( 0, &*(rExtensionTokens.end() - 8) );
- UInt32ToSVBT32( 0, &*(rExtensionTokens.end() - 4) );
- }
- else if( pMatrix->IsString( nC, nR ) )
- {
- rExtensionTokens.push_back( EXC_CACHEDVAL_STRING );
-
- const String & rString = pMatrix->GetString( nC, nR );
- XclExpStringRef xXclStr = XclExpStringHelper::CreateString(
- GetRoot(), rString,
- ((meBiff == EXC_BIFF8) ? EXC_STR_DEFAULT : EXC_STR_8BITLENGTH),
- EXC_TOK_STR_MAXLEN );
- size_t nSize = rExtensionTokens.size();
- rExtensionTokens.resize( nSize + xXclStr->GetSize() );
- xXclStr->WriteToMem( &rExtensionTokens[ nSize ] );
- }
-
+ case EXC_PARAMCONV_ORG:
+ case EXC_PARAMCONV_VAL:
+ case EXC_PARAMCONV_ARR:
+ /* If parent token has REF class (REF token in REFTYPE
+ function parameter), then RPT does not repeat the
+ previous explicit ORG or ARR conversion, but always
+ falls back to VAL conversion. */
+ eClassConv = bWasRefClass ? EXC_CLASSCONV_VAL : ePrevClassConv;
+ break;
+ case EXC_PARAMCONV_RPT:
+ // nested RPT repeats the previous effective conversion
+ eClassConv = ePrevClassConv;
+ break;
+ case EXC_PARAMCONV_RPX:
+ /* If parent token has REF class (REF token in REFTYPE
+ function parameter), then RPX repeats the previous
+ effective conversion (wich will be either ORG or ARR,
+ but never VAL), otherwise falls back to ORG conversion. */
+ eClassConv = bWasRefClass ? ePrevClassConv : EXC_CLASSCONV_ORG;
+ break;
+ case EXC_PARAMCONV_RPO: // does not occur
+ break;
}
- }
+ break;
+ case EXC_PARAMCONV_RPX:
+ /* If current token still has REF class, set previous effective
+ conversion as current conversion. This will not have an effect
+ on the REF token but is needed for RPT parameters of this
+ function that want to repeat this conversion type. If current
+ token is VAL or ARR class, the previous ARR conversion will be
+ repeated on the token, but VAL conversion will not. */
+ eClassConv = ((nTokClass == EXC_TOKCLASS_REF) || (ePrevClassConv == EXC_CLASSCONV_ARR)) ?
+ ePrevClassConv : EXC_CLASSCONV_ORG;
+ break;
+ case EXC_PARAMCONV_RPO: // does not occur (see above)
+ break;
}
+
+ // do the token class conversion
+ switch( eClassConv )
+ {
+ case EXC_CLASSCONV_ORG:
+ /* Cell formulas: leave the current token class. Cell formulas
+ are the only type of formulas where all tokens can keep
+ their original token class.
+ Array and defined name formulas: convert VAL to ARR. */
+ if( (mxData->mrCfg.meClassType != EXC_CLASSTYPE_CELL) && (nTokClass == EXC_TOKCLASS_VAL) )
+ ChangeTokenClass( rnTokenId, nTokClass = EXC_TOKCLASS_ARR );
+ break;
+ case EXC_CLASSCONV_VAL:
+ // convert ARR to VAL
+ if( nTokClass == EXC_TOKCLASS_ARR )
+ ChangeTokenClass( rnTokenId, nTokClass = EXC_TOKCLASS_VAL );
+ break;
+ case EXC_CLASSCONV_ARR:
+ // convert VAL to ARR
+ if( nTokClass == EXC_TOKCLASS_VAL )
+ ChangeTokenClass( rnTokenId, nTokClass = EXC_TOKCLASS_ARR );
+ break;
+ }
+
+ // do conversion for nested operands, if token is an operator or function
+ if( rConvInfo.mnTokPos < mxData->maOpListVec.size() )
+ if( const XclExpOperandList* pOperands = mxData->maOpListVec[ rConvInfo.mnTokPos ].get() )
+ for( XclExpOperandList::const_iterator aIt = pOperands->begin(), aEnd = pOperands->end(); aIt != aEnd; ++aIt )
+ RecalcTokenClass( *aIt, eConv, eClassConv, nTokClass == EXC_TOKCLASS_REF );
}
-void XclExpFmlaCompImpl::FinalizeFormula( ScfUInt8Vec & rExtensionTokens )
+void XclExpFmlaCompImpl::FinalizeFormula()
{
- if( mbOk )
+ if( mxData->mbOk )
{
// Volatile? Add a tAttrVolatile token at the beginning of the token array.
- if( mbVolatile )
+ if( mxData->mbVolatile )
{
// tAttrSpace token can be extended with volatile flag
if( !IsSpaceToken( 0 ) )
{
- Insert( 0, 4 );
- maTokVec[ 0 ] = EXC_TOKID_ATTR;
+ InsertZeros( 0, 4 );
+ mxData->maTokVec[ 0 ] = EXC_TOKID_ATTR;
}
- maTokVec[ 1 ] |= EXC_TOK_ATTR_VOLATILE;
+ mxData->maTokVec[ 1 ] |= EXC_TOK_ATTR_VOLATILE;
}
// Token array too long? -> error
- mbOk = maTokVec.size() <= EXC_TOKARR_MAXLEN;
-
- // Store any inline arrays
- if( mbOk && mxInlineArr.is() )
- AppendInlineArrays( rExtensionTokens );
+ mxData->mbOk = mxData->maTokVec.size() <= EXC_TOKARR_MAXLEN;
}
- if( !mbOk )
+ if( !mxData->mbOk )
{
// Any unrecoverable error? -> Create a =#NA formula.
- maTokVec.clear();
- mbVolatile = false;
+ mxData->maTokVec.clear();
+ mxData->maExtDataVec.clear();
+ mxData->mbVolatile = false;
AppendErrorToken( EXC_ERR_NA );
}
}
-XclTokenArrayRef XclExpFmlaCompImpl::CreateTokenArray( ScfUInt8Vec* pExtensionTokens )
+XclTokenArrayRef XclExpFmlaCompImpl::CreateTokenArray()
{
- // create the Excel token array object before calling LeaveRecursive()
- XclTokenArrayRef xTokArr( new XclTokenArray( maTokVec, mbVolatile, pExtensionTokens ) );
+ // create the Excel token array from working data before resetting mxData
+ DBG_ASSERT( mxData->mrCfg.mbAllowArrays || mxData->maExtDataVec.empty(), "XclExpFmlaCompImpl::CreateTokenArray - unexpected extended data" );
+ if( !mxData->mrCfg.mbAllowArrays )
+ mxData->maExtDataVec.clear();
+ XclTokenArrayRef xTokArr( new XclTokenArray( mxData->maTokVec, mxData->maExtDataVec, mxData->mbVolatile ) );
+ mxData.reset();
// compiler invoked recursively? - restore old working data
- LeaveRecursive();
+ if( !maDataStack.empty() )
+ {
+ mxData = maDataStack.back();
+ maDataStack.pop_back();
+ }
return xTokArr;
}
// compiler -------------------------------------------------------------------
-const formula::FormulaToken* XclExpFmlaCompImpl::GetNextRawToken()
+const FormulaToken* XclExpFmlaCompImpl::GetNextRawToken()
{
- const formula::FormulaToken* pScToken = maTokArrIt.Get();
- ++maTokArrIt;
+ const FormulaToken* pScToken = mxData->maTokArrIt.Get();
+ ++mxData->maTokArrIt;
return pScToken;
}
-const formula::FormulaToken* XclExpFmlaCompImpl::PeekNextRawToken( bool bSkipSpaces ) const
+const FormulaToken* XclExpFmlaCompImpl::PeekNextRawToken( bool bSkipSpaces ) const
{
/* Returns pointer to next raw token in the token array. The token array
iterator already points to the next token (A call to GetNextToken()
@@ -806,11 +835,11 @@ const formula::FormulaToken* XclExpFmlaCompImpl::PeekNextRawToken( bool bSkipSpa
created and set to the passed skip-spaces mode. If spaces have to be
skipped, and the iterator currently points to a space token, the
constructor will move it to the next non-space token. */
- XclTokenArrayIterator aTempIt( maTokArrIt, bSkipSpaces );
+ XclTokenArrayIterator aTempIt( mxData->maTokArrIt, bSkipSpaces );
return aTempIt.Get();
}
-bool XclExpFmlaCompImpl::GetNextToken( XclExpTokenData& rTokData )
+bool XclExpFmlaCompImpl::GetNextToken( XclExpScToken& rTokData )
{
rTokData.mpScToken = GetNextRawToken();
rTokData.mnSpaces = (rTokData.GetOpCode() == ocSpaces) ? rTokData.mpScToken->GetByte() : 0;
@@ -819,9 +848,9 @@ bool XclExpFmlaCompImpl::GetNextToken( XclExpTokenData& rTokData )
return rTokData.Is();
}
-XclExpTokenData XclExpFmlaCompImpl::GetNextToken()
+XclExpScToken XclExpFmlaCompImpl::GetNextToken()
{
- XclExpTokenData aTokData;
+ XclExpScToken aTokData;
GetNextToken( aTokData );
return aTokData;
}
@@ -919,195 +948,187 @@ inline sal_uInt8 lclGetRangeTokenId( OpCode eOpCode )
} // namespace
-XclExpTokenData XclExpFmlaCompImpl::Expression( XclExpTokenData aTokData, sal_uInt8 nExpClass, bool bInParentheses, bool bStopAtSep )
+XclExpScToken XclExpFmlaCompImpl::Expression( XclExpScToken aTokData, bool bInParentheses, bool bStopAtSep )
{
- if( mbOk && aTokData.Is() )
+ if( mxData->mbOk && aTokData.Is() )
{
// remember old stop-at-ocSep mode, restored below
- bool bOldStopAtSep = mbStopAtSep;
- mbStopAtSep = bStopAtSep;
+ bool bOldStopAtSep = mxData->mbStopAtSep;
+ mxData->mbStopAtSep = bStopAtSep;
// start compilation of the subexpression
- aTokData = OrTerm( aTokData, nExpClass, bInParentheses );
+ aTokData = OrTerm( aTokData, bInParentheses );
// restore old stop-at-ocSep mode
- mbStopAtSep = bOldStopAtSep;
+ mxData->mbStopAtSep = bOldStopAtSep;
}
return aTokData;
}
-XclExpTokenData XclExpFmlaCompImpl::SkipExpression( XclExpTokenData aTokData, bool bStopAtSep )
+XclExpScToken XclExpFmlaCompImpl::SkipExpression( XclExpScToken aTokData, bool bStopAtSep )
{
- while( mbOk && aTokData.Is() && (aTokData.GetOpCode() != ocClose) && (!bStopAtSep || (aTokData.GetOpCode() != ocSep)) )
+ while( mxData->mbOk && aTokData.Is() && (aTokData.GetOpCode() != ocClose) && (!bStopAtSep || (aTokData.GetOpCode() != ocSep)) )
{
if( aTokData.GetOpCode() == ocOpen )
{
aTokData = SkipExpression( GetNextToken(), false );
- if( mbOk ) mbOk = aTokData.GetOpCode() == ocClose;
+ if( mxData->mbOk ) mxData->mbOk = aTokData.GetOpCode() == ocClose;
}
aTokData = GetNextToken();
}
return aTokData;
}
-XclExpTokenData XclExpFmlaCompImpl::OrTerm( XclExpTokenData aTokData, sal_uInt8 nExpClass, bool bInParentheses )
+XclExpScToken XclExpFmlaCompImpl::OrTerm( XclExpScToken aTokData, bool bInParentheses )
{
- aTokData = AndTerm( aTokData, nExpClass, bInParentheses );
+ aTokData = AndTerm( aTokData, bInParentheses );
sal_uInt8 nParamCount = 1;
- while( mbOk && (aTokData.GetOpCode() == ocOr) )
+ while( mxData->mbOk && (aTokData.GetOpCode() == ocOr) )
{
- AdjustLastTokenClassForEastereggOp(); // see comment in this function
RemoveTrailingParen();
- aTokData = AndTerm( GetNextToken(), EXC_TOKCLASS_REF, bInParentheses );
+ aTokData = AndTerm( GetNextToken(), bInParentheses );
RemoveTrailingParen();
++nParamCount;
- if( mbOk ) mbOk = nParamCount <= EXC_FUNC_MAXPARAM;
+ if( mxData->mbOk ) mxData->mbOk = nParamCount <= EXC_FUNC_MAXPARAM;
}
- if( mbOk && (nParamCount > 1) )
- AppendVarFuncTokenId( EXC_FUNCID_OR, EXC_TOKCLASS_VAL, nExpClass, nParamCount );
+ if( mxData->mbOk && (nParamCount > 1) )
+ AppendLogicalOperatorToken( EXC_FUNCID_OR, nParamCount );
return aTokData;
}
-XclExpTokenData XclExpFmlaCompImpl::AndTerm( XclExpTokenData aTokData, sal_uInt8 nExpClass, bool bInParentheses )
+XclExpScToken XclExpFmlaCompImpl::AndTerm( XclExpScToken aTokData, bool bInParentheses )
{
- aTokData = CompareTerm( aTokData, nExpClass, bInParentheses );
+ aTokData = CompareTerm( aTokData, bInParentheses );
sal_uInt8 nParamCount = 1;
- while( mbOk && (aTokData.GetOpCode() == ocAnd) )
+ while( mxData->mbOk && (aTokData.GetOpCode() == ocAnd) )
{
- AdjustLastTokenClassForEastereggOp(); // see comment in this function
RemoveTrailingParen();
- aTokData = CompareTerm( GetNextToken(), EXC_TOKCLASS_REF, bInParentheses );
+ aTokData = CompareTerm( GetNextToken(), bInParentheses );
RemoveTrailingParen();
++nParamCount;
- if( mbOk ) mbOk = nParamCount <= EXC_FUNC_MAXPARAM;
+ if( mxData->mbOk ) mxData->mbOk = nParamCount <= EXC_FUNC_MAXPARAM;
}
- if( mbOk && (nParamCount > 1) )
- AppendVarFuncTokenId( EXC_FUNCID_AND, EXC_TOKCLASS_VAL, nExpClass, nParamCount );
+ if( mxData->mbOk && (nParamCount > 1) )
+ AppendLogicalOperatorToken( EXC_FUNCID_AND, nParamCount );
return aTokData;
}
-XclExpTokenData XclExpFmlaCompImpl::CompareTerm( XclExpTokenData aTokData, sal_uInt8 nExpClass, bool bInParentheses )
+XclExpScToken XclExpFmlaCompImpl::CompareTerm( XclExpScToken aTokData, bool bInParentheses )
{
- aTokData = ConcatTerm( aTokData, nExpClass, bInParentheses );
+ aTokData = ConcatTerm( aTokData, bInParentheses );
sal_uInt8 nOpTokenId = EXC_TOKID_NONE;
- while( mbOk && ((nOpTokenId = lclGetCompareTokenId( aTokData.GetOpCode() )) != EXC_TOKID_NONE) )
+ while( mxData->mbOk && ((nOpTokenId = lclGetCompareTokenId( aTokData.GetOpCode() )) != EXC_TOKID_NONE) )
{
- AdjustLastTokenClass( nExpClass | EXC_TOKCLASS_INOP_FLAG );
sal_uInt8 nSpaces = aTokData.mnSpaces;
- aTokData = ConcatTerm( GetNextToken(), nExpClass | EXC_TOKCLASS_INOP_FLAG, bInParentheses );
- AppendOpTokenId( nOpTokenId, nExpClass, nSpaces );
+ aTokData = ConcatTerm( GetNextToken(), bInParentheses );
+ AppendBinaryOperatorToken( nOpTokenId, true, nSpaces );
}
return aTokData;
}
-XclExpTokenData XclExpFmlaCompImpl::ConcatTerm( XclExpTokenData aTokData, sal_uInt8 nExpClass, bool bInParentheses )
+XclExpScToken XclExpFmlaCompImpl::ConcatTerm( XclExpScToken aTokData, bool bInParentheses )
{
- aTokData = AddSubTerm( aTokData, nExpClass, bInParentheses );
+ aTokData = AddSubTerm( aTokData, bInParentheses );
sal_uInt8 nOpTokenId = EXC_TOKID_NONE;
- while( mbOk && ((nOpTokenId = lclGetConcatTokenId( aTokData.GetOpCode() )) != EXC_TOKID_NONE) )
+ while( mxData->mbOk && ((nOpTokenId = lclGetConcatTokenId( aTokData.GetOpCode() )) != EXC_TOKID_NONE) )
{
- AdjustLastTokenClass( nExpClass | EXC_TOKCLASS_INOP_FLAG );
sal_uInt8 nSpaces = aTokData.mnSpaces;
- aTokData = AddSubTerm( GetNextToken(), nExpClass | EXC_TOKCLASS_INOP_FLAG, bInParentheses );
- AppendOpTokenId( nOpTokenId, nExpClass, nSpaces );
+ aTokData = AddSubTerm( GetNextToken(), bInParentheses );
+ AppendBinaryOperatorToken( nOpTokenId, true, nSpaces );
}
return aTokData;
}
-XclExpTokenData XclExpFmlaCompImpl::AddSubTerm( XclExpTokenData aTokData, sal_uInt8 nExpClass, bool bInParentheses )
+XclExpScToken XclExpFmlaCompImpl::AddSubTerm( XclExpScToken aTokData, bool bInParentheses )
{
- aTokData = MulDivTerm( aTokData, nExpClass, bInParentheses );
+ aTokData = MulDivTerm( aTokData, bInParentheses );
sal_uInt8 nOpTokenId = EXC_TOKID_NONE;
- while( mbOk && ((nOpTokenId = lclGetAddSubTokenId( aTokData.GetOpCode() )) != EXC_TOKID_NONE) )
+ while( mxData->mbOk && ((nOpTokenId = lclGetAddSubTokenId( aTokData.GetOpCode() )) != EXC_TOKID_NONE) )
{
- AdjustLastTokenClass( nExpClass | EXC_TOKCLASS_INOP_FLAG );
sal_uInt8 nSpaces = aTokData.mnSpaces;
- aTokData = MulDivTerm( GetNextToken(), nExpClass | EXC_TOKCLASS_INOP_FLAG, bInParentheses );
- AppendOpTokenId( nOpTokenId, nExpClass, nSpaces );
+ aTokData = MulDivTerm( GetNextToken(), bInParentheses );
+ AppendBinaryOperatorToken( nOpTokenId, true, nSpaces );
}
return aTokData;
}
-XclExpTokenData XclExpFmlaCompImpl::MulDivTerm( XclExpTokenData aTokData, sal_uInt8 nExpClass, bool bInParentheses )
+XclExpScToken XclExpFmlaCompImpl::MulDivTerm( XclExpScToken aTokData, bool bInParentheses )
{
- aTokData = PowTerm( aTokData, nExpClass, bInParentheses );
+ aTokData = PowTerm( aTokData, bInParentheses );
sal_uInt8 nOpTokenId = EXC_TOKID_NONE;
- while( mbOk && ((nOpTokenId = lclGetMulDivTokenId( aTokData.GetOpCode() )) != EXC_TOKID_NONE) )
+ while( mxData->mbOk && ((nOpTokenId = lclGetMulDivTokenId( aTokData.GetOpCode() )) != EXC_TOKID_NONE) )
{
- AdjustLastTokenClass( nExpClass | EXC_TOKCLASS_INOP_FLAG );
sal_uInt8 nSpaces = aTokData.mnSpaces;
- aTokData = PowTerm( GetNextToken(), nExpClass | EXC_TOKCLASS_INOP_FLAG, bInParentheses );
- AppendOpTokenId( nOpTokenId, nExpClass, nSpaces );
+ aTokData = PowTerm( GetNextToken(), bInParentheses );
+ AppendBinaryOperatorToken( nOpTokenId, true, nSpaces );
}
return aTokData;
}
-XclExpTokenData XclExpFmlaCompImpl::PowTerm( XclExpTokenData aTokData, sal_uInt8 nExpClass, bool bInParentheses )
+XclExpScToken XclExpFmlaCompImpl::PowTerm( XclExpScToken aTokData, bool bInParentheses )
{
- aTokData = UnaryPostTerm( aTokData, nExpClass, bInParentheses );
+ aTokData = UnaryPostTerm( aTokData, bInParentheses );
sal_uInt8 nOpTokenId = EXC_TOKID_NONE;
- while( mbOk && ((nOpTokenId = lclGetPowTokenId( aTokData.GetOpCode() )) != EXC_TOKID_NONE) )
+ while( mxData->mbOk && ((nOpTokenId = lclGetPowTokenId( aTokData.GetOpCode() )) != EXC_TOKID_NONE) )
{
- AdjustLastTokenClass( nExpClass | EXC_TOKCLASS_INOP_FLAG );
sal_uInt8 nSpaces = aTokData.mnSpaces;
- aTokData = UnaryPostTerm( GetNextToken(), nExpClass | EXC_TOKCLASS_INOP_FLAG, bInParentheses );
- AppendOpTokenId( nOpTokenId, nExpClass, nSpaces );
+ aTokData = UnaryPostTerm( GetNextToken(), bInParentheses );
+ AppendBinaryOperatorToken( nOpTokenId, true, nSpaces );
}
return aTokData;
}
-XclExpTokenData XclExpFmlaCompImpl::UnaryPostTerm( XclExpTokenData aTokData, sal_uInt8 nExpClass, bool bInParentheses )
+XclExpScToken XclExpFmlaCompImpl::UnaryPostTerm( XclExpScToken aTokData, bool bInParentheses )
{
- aTokData = UnaryPreTerm( aTokData, nExpClass, bInParentheses );
+ aTokData = UnaryPreTerm( aTokData, bInParentheses );
sal_uInt8 nOpTokenId = EXC_TOKID_NONE;
- while( mbOk && ((nOpTokenId = lclGetUnaryPostTokenId( aTokData.GetOpCode() )) != EXC_TOKID_NONE) )
+ while( mxData->mbOk && ((nOpTokenId = lclGetUnaryPostTokenId( aTokData.GetOpCode() )) != EXC_TOKID_NONE) )
{
- AdjustLastTokenClass( nExpClass | EXC_TOKCLASS_INOP_FLAG );
- AppendOpTokenId( nOpTokenId, nExpClass, aTokData.mnSpaces );
+ AppendUnaryOperatorToken( nOpTokenId, aTokData.mnSpaces );
GetNextToken( aTokData );
}
return aTokData;
}
-XclExpTokenData XclExpFmlaCompImpl::UnaryPreTerm( XclExpTokenData aTokData, sal_uInt8 nExpClass, bool bInParentheses )
+XclExpScToken XclExpFmlaCompImpl::UnaryPreTerm( XclExpScToken aTokData, bool bInParentheses )
{
- sal_uInt8 nOpTokenId = mbOk ? lclGetUnaryPreTokenId( aTokData.GetOpCode() ) : EXC_TOKID_NONE;
+ sal_uInt8 nOpTokenId = mxData->mbOk ? lclGetUnaryPreTokenId( aTokData.GetOpCode() ) : EXC_TOKID_NONE;
if( nOpTokenId != EXC_TOKID_NONE )
{
sal_uInt8 nSpaces = aTokData.mnSpaces;
- aTokData = UnaryPreTerm( GetNextToken(), nExpClass | EXC_TOKCLASS_INOP_FLAG, bInParentheses );
- AppendOpTokenId( nOpTokenId, nExpClass, nSpaces );
+ aTokData = UnaryPreTerm( GetNextToken(), bInParentheses );
+ AppendUnaryOperatorToken( nOpTokenId, nSpaces );
}
else
- aTokData = ListTerm( aTokData, nExpClass, bInParentheses );
+ {
+ aTokData = ListTerm( aTokData, bInParentheses );
+ }
return aTokData;
}
-XclExpTokenData XclExpFmlaCompImpl::ListTerm( XclExpTokenData aTokData, sal_uInt8 nExpClass, bool bInParentheses )
+XclExpScToken XclExpFmlaCompImpl::ListTerm( XclExpScToken aTokData, bool bInParentheses )
{
sal_uInt16 nSubExprPos = GetSize();
bool bHasAnyRefOp = false;
bool bHasListOp = false;
- aTokData = IntersectTerm( aTokData, nExpClass, bHasAnyRefOp );
+ aTokData = IntersectTerm( aTokData, bHasAnyRefOp );
sal_uInt8 nOpTokenId = EXC_TOKID_NONE;
- while( mbOk && ((nOpTokenId = lclGetListTokenId( aTokData.GetOpCode(), mbStopAtSep )) != EXC_TOKID_NONE) )
+ while( mxData->mbOk && ((nOpTokenId = lclGetListTokenId( aTokData.GetOpCode(), mxData->mbStopAtSep )) != EXC_TOKID_NONE) )
{
- AdjustLastTokenClass( EXC_TOKCLASS_ANY_IN_REFOP );
sal_uInt8 nSpaces = aTokData.mnSpaces;
- aTokData = IntersectTerm( GetNextToken(), EXC_TOKCLASS_ANY_IN_REFOP, bHasAnyRefOp );
- AppendOpTokenId( nOpTokenId, nExpClass, nSpaces );
+ aTokData = IntersectTerm( GetNextToken(), bHasAnyRefOp );
+ AppendBinaryOperatorToken( nOpTokenId, false, nSpaces );
bHasAnyRefOp = bHasListOp = true;
}
if( bHasAnyRefOp )
{
- // adjust last added token back to REF
- AdjustLastTokenClass( EXC_TOKCLASS_ANY_IN_REFOP );
// add a tMemFunc token enclosing the entire reference subexpression
sal_uInt16 nSubExprSize = GetSize() - nSubExprPos;
- Insert( nSubExprPos, 3 );
- maTokVec[ nSubExprPos ] = GetTokenId( EXC_TOKID_MEMFUNC, EXC_TOKCLASS_REF );
+ InsertZeros( nSubExprPos, 3 );
+ mxData->maTokVec[ nSubExprPos ] = GetTokenId( EXC_TOKID_MEMFUNC, EXC_TOKCLASS_REF );
Overwrite( nSubExprPos + 1, nSubExprSize );
- // adjust the tMemFunc token according to passed expected token class
- mnLastTokPos = nSubExprPos;
- AdjustLastTokenClass( nExpClass );
+ // update the operand/operator stack (set the list expression as operand of the tMemFunc)
+ XclExpOperandListRef xOperands( new XclExpOperandList );
+ xOperands->AppendOperand( PopOperandPos(), EXC_PARAMCONV_VAL, false );
+ PushOperatorPos( nSubExprPos, xOperands );
}
// #i86439# enclose list operator into parentheses, e.g. Calc's =AREAS(A1~A2) to Excel's =AREAS((A1;A2))
if( bHasListOp && !bInParentheses )
@@ -1115,77 +1136,66 @@ XclExpTokenData XclExpFmlaCompImpl::ListTerm( XclExpTokenData aTokData, sal_uInt
return aTokData;
}
-XclExpTokenData XclExpFmlaCompImpl::IntersectTerm( XclExpTokenData aTokData, sal_uInt8 nExpClass, bool& rbHasRefOp )
+XclExpScToken XclExpFmlaCompImpl::IntersectTerm( XclExpScToken aTokData, bool& rbHasRefOp )
{
- aTokData = RangeTerm( aTokData, nExpClass, rbHasRefOp );
+ aTokData = RangeTerm( aTokData, rbHasRefOp );
sal_uInt8 nOpTokenId = EXC_TOKID_NONE;
- while( mbOk && ((nOpTokenId = lclGetIntersectTokenId( aTokData.GetOpCode() )) != EXC_TOKID_NONE) )
+ while( mxData->mbOk && ((nOpTokenId = lclGetIntersectTokenId( aTokData.GetOpCode() )) != EXC_TOKID_NONE) )
{
- AdjustLastTokenClass( EXC_TOKCLASS_ANY_IN_REFOP );
sal_uInt8 nSpaces = aTokData.mnSpaces;
- aTokData = RangeTerm( GetNextToken(), EXC_TOKCLASS_ANY_IN_REFOP, rbHasRefOp );
- AppendOpTokenId( nOpTokenId, nExpClass, nSpaces );
+ aTokData = RangeTerm( GetNextToken(), rbHasRefOp );
+ AppendBinaryOperatorToken( nOpTokenId, false, nSpaces );
rbHasRefOp = true;
}
return aTokData;
}
-XclExpTokenData XclExpFmlaCompImpl::RangeTerm( XclExpTokenData aTokData, sal_uInt8 nExpClass, bool& rbHasRefOp )
+XclExpScToken XclExpFmlaCompImpl::RangeTerm( XclExpScToken aTokData, bool& rbHasRefOp )
{
- aTokData = Factor( aTokData, nExpClass );
+ aTokData = Factor( aTokData );
sal_uInt8 nOpTokenId = EXC_TOKID_NONE;
- while( mbOk && ((nOpTokenId = lclGetRangeTokenId( aTokData.GetOpCode() )) != EXC_TOKID_NONE) )
+ while( mxData->mbOk && ((nOpTokenId = lclGetRangeTokenId( aTokData.GetOpCode() )) != EXC_TOKID_NONE) )
{
- AdjustLastTokenClass( EXC_TOKCLASS_ANY_IN_REFOP );
sal_uInt8 nSpaces = aTokData.mnSpaces;
- aTokData = Factor( GetNextToken(), EXC_TOKCLASS_ANY_IN_REFOP );
- AppendOpTokenId( nOpTokenId, nExpClass, nSpaces );
+ aTokData = Factor( GetNextToken() );
+ AppendBinaryOperatorToken( nOpTokenId, false, nSpaces );
rbHasRefOp = true;
}
return aTokData;
}
-XclExpTokenData XclExpFmlaCompImpl::Factor( XclExpTokenData aTokData, sal_uInt8 nExpClass )
+XclExpScToken XclExpFmlaCompImpl::Factor( XclExpScToken aTokData )
{
- if( !mbOk || !aTokData.Is() ) return XclExpTokenData();
+ if( !mxData->mbOk || !aTokData.Is() ) return XclExpScToken();
- formula::StackVar eTokType = aTokData.GetType();
- OpCode eOpCode = aTokData.GetOpCode();
-
- if (eOpCode == ocExternalRef)
+ switch( aTokData.GetType() )
{
- ProcessExternalName( aTokData, nExpClass );
- return GetNextToken();
- }
-
- switch( eTokType )
- {
- case svUnknown: mbOk = false; break;
- case formula::svDouble: ProcessDouble( aTokData ); break;
- case formula::svString: ProcessString( aTokData ); break;
+ case svUnknown: mxData->mbOk = false; break;
+ case svDouble: ProcessDouble( aTokData ); break;
+ case svString: ProcessString( aTokData ); break;
#if 0 // erAck
- case formula::svError: ProcessError( aTokData ); break;
+ case svError: ProcessError( aTokData ); break;
#endif
- case svSingleRef: ProcessCellRef( aTokData, nExpClass ); break;
- case formula::svDoubleRef: ProcessRangeRef( aTokData, nExpClass ); break;
- case svMatrix: ProcessMatrix( aTokData, nExpClass ); break;
- case svExternal: ProcessExternal( aTokData, nExpClass ); break;
-
- default:
+ case svSingleRef: ProcessCellRef( aTokData ); break;
+ case svDoubleRef: ProcessRangeRef( aTokData ); break;
+ case svExternalSingleRef: ProcessExternalCellRef( aTokData ); break;
+ case svExternalDoubleRef: ProcessExternalRangeRef( aTokData ); break;
+ case svExternalName: ProcessExternalName( aTokData ); break;
+ case svMatrix: ProcessMatrix( aTokData ); break;
+ case svExternal: ProcessExternal( aTokData ); break;
+
+ default: switch( aTokData.GetOpCode() )
{
- switch( eOpCode )
- {
- case ocNone: /* do nothing */ break;
- case ocMissing: ProcessMissing( aTokData ); break;
- case ocBad: ProcessBad( aTokData ); break;
- case ocOpen: ProcessParentheses( aTokData, nExpClass ); break;
- case ocName: ProcessDefinedName( aTokData, nExpClass ); break;
- case ocDBArea: ProcessDatabaseArea( aTokData, nExpClass ); break;
- case ocFalse:
- case ocTrue: ProcessBoolean( aTokData ); break;
- case ocDde: ProcessDdeLink( aTokData, nExpClass ); break;
- default: ProcessFunction( aTokData, nExpClass );
- }
+ case ocNone: /* do nothing */ break;
+ case ocMissing: ProcessMissing( aTokData ); break;
+ case ocBad: ProcessBad( aTokData ); break;
+ case ocOpen: ProcessParentheses( aTokData ); break;
+ case ocName: ProcessDefinedName( aTokData ); break;
+ case ocDBArea: ProcessDatabaseArea( aTokData ); break;
+ case ocFalse:
+ case ocTrue: ProcessBoolean( aTokData ); break;
+ case ocDde: ProcessDdeLink( aTokData ); break;
+ default: ProcessFunction( aTokData );
}
}
@@ -1194,7 +1204,7 @@ XclExpTokenData XclExpFmlaCompImpl::Factor( XclExpTokenData aTokData, sal_uInt8
// formula structure ----------------------------------------------------------
-void XclExpFmlaCompImpl::ProcessDouble( const XclExpTokenData& rTokData )
+void XclExpFmlaCompImpl::ProcessDouble( const XclExpScToken& rTokData )
{
double fValue = rTokData.mpScToken->GetDouble();
double fInt;
@@ -1205,13 +1215,13 @@ void XclExpFmlaCompImpl::ProcessDouble( const XclExpTokenData& rTokData )
AppendNumToken( fValue, rTokData.mnSpaces );
}
-void XclExpFmlaCompImpl::ProcessString( const XclExpTokenData& rTokData )
+void XclExpFmlaCompImpl::ProcessString( const XclExpScToken& rTokData )
{
- AppendOpTokenId( EXC_TOKID_STR, EXC_TOKCLASS_NONE, rTokData.mnSpaces );
+ AppendOperandTokenId( EXC_TOKID_STR, rTokData.mnSpaces );
Append( rTokData.mpScToken->GetString() );
}
-void XclExpFmlaCompImpl::ProcessError( const XclExpTokenData& rTokData )
+void XclExpFmlaCompImpl::ProcessError( const XclExpScToken& rTokData )
{
#if 0 // erAck
AppendErrorToken( XclTools::GetXclErrorCode( rTokData.mpScToken->GetError() ), rTokData.mnSpaces );
@@ -1220,36 +1230,36 @@ void XclExpFmlaCompImpl::ProcessError( const XclExpTokenData& rTokData )
#endif
}
-void XclExpFmlaCompImpl::ProcessMissing( const XclExpTokenData& rTokData )
+void XclExpFmlaCompImpl::ProcessMissing( const XclExpScToken& rTokData )
{
AppendMissingToken( rTokData.mnSpaces );
}
-void XclExpFmlaCompImpl::ProcessBad( const XclExpTokenData& rTokData )
+void XclExpFmlaCompImpl::ProcessBad( const XclExpScToken& rTokData )
{
AppendErrorToken( EXC_ERR_NA, rTokData.mnSpaces );
}
-void XclExpFmlaCompImpl::ProcessParentheses( const XclExpTokenData& rTokData, sal_uInt8 nExpClass )
+void XclExpFmlaCompImpl::ProcessParentheses( const XclExpScToken& rTokData )
{
- XclExpTokenData aTokData( Expression( GetNextToken(), nExpClass, true, false ) );
- mbOk = aTokData.GetOpCode() == ocClose;
+ XclExpScToken aTokData = Expression( GetNextToken(), true, false );
+ mxData->mbOk = aTokData.GetOpCode() == ocClose;
AppendParenToken( rTokData.mnSpaces, aTokData.mnSpaces );
}
-void XclExpFmlaCompImpl::ProcessBoolean( const XclExpTokenData& rTokData )
+void XclExpFmlaCompImpl::ProcessBoolean( const XclExpScToken& rTokData )
{
- mbOk = GetNextToken().GetOpCode() == ocOpen;
- if( mbOk ) mbOk = GetNextToken().GetOpCode() == ocClose;
- if( mbOk )
+ mxData->mbOk = GetNextToken().GetOpCode() == ocOpen;
+ if( mxData->mbOk ) mxData->mbOk = GetNextToken().GetOpCode() == ocClose;
+ if( mxData->mbOk )
AppendBoolToken( rTokData.GetOpCode() == ocTrue, rTokData.mnSpaces );
}
namespace {
-inline bool lclGetTokenString( String& rString, const XclExpTokenData& rTokData )
+inline bool lclGetTokenString( String& rString, const XclExpScToken& rTokData )
{
- bool bIsStr = (rTokData.GetType() == formula::svString) && (rTokData.GetOpCode() == ocPush);
+ bool bIsStr = (rTokData.GetType() == svString) && (rTokData.GetOpCode() == ocPush);
if( bIsStr )
rString = rTokData.mpScToken->GetString();
return bIsStr;
@@ -1257,169 +1267,113 @@ inline bool lclGetTokenString( String& rString, const XclExpTokenData& rTokData
} // namespace
-void XclExpFmlaCompImpl::ProcessDdeLink( const XclExpTokenData& rTokData, sal_uInt8 nExpClass )
+void XclExpFmlaCompImpl::ProcessDdeLink( const XclExpScToken& rTokData )
{
String aApplic, aTopic, aItem;
- mbOk = GetNextToken().GetOpCode() == ocOpen;
- if( mbOk ) mbOk = lclGetTokenString( aApplic, GetNextToken() );
- if( mbOk ) mbOk = GetNextToken().GetOpCode() == ocSep;
- if( mbOk ) mbOk = lclGetTokenString( aTopic, GetNextToken() );
- if( mbOk ) mbOk = GetNextToken().GetOpCode() == ocSep;
- if( mbOk ) mbOk = lclGetTokenString( aItem, GetNextToken() );
- if( mbOk ) mbOk = GetNextToken().GetOpCode() == ocClose;
- if( mbOk ) mbOk = aApplic.Len() && aTopic.Len() && aItem.Len();
- if( mbOk )
+ mxData->mbOk = GetNextToken().GetOpCode() == ocOpen;
+ if( mxData->mbOk ) mxData->mbOk = lclGetTokenString( aApplic, GetNextToken() );
+ if( mxData->mbOk ) mxData->mbOk = GetNextToken().GetOpCode() == ocSep;
+ if( mxData->mbOk ) mxData->mbOk = lclGetTokenString( aTopic, GetNextToken() );
+ if( mxData->mbOk ) mxData->mbOk = GetNextToken().GetOpCode() == ocSep;
+ if( mxData->mbOk ) mxData->mbOk = lclGetTokenString( aItem, GetNextToken() );
+ if( mxData->mbOk ) mxData->mbOk = GetNextToken().GetOpCode() == ocClose;
+ if( mxData->mbOk ) mxData->mbOk = aApplic.Len() && aTopic.Len() && aItem.Len();
+ if( mxData->mbOk )
{
sal_uInt16 nExtSheet, nExtName;
- if( mpLinkMgr && mpLinkMgr->InsertDde( nExtSheet, nExtName, aApplic, aTopic, aItem ) )
- AppendNameXToken( nExtSheet, nExtName, nExpClass, rTokData.mnSpaces );
+ if( mxData->mpLinkMgr && mxData->mpLinkMgr->InsertDde( nExtSheet, nExtName, aApplic, aTopic, aItem ) )
+ AppendNameXToken( nExtSheet, nExtName, rTokData.mnSpaces );
else
AppendErrorToken( EXC_ERR_NA, rTokData.mnSpaces );
}
}
-void XclExpFmlaCompImpl::ProcessExternal( const XclExpTokenData& rTokData, sal_uInt8 nExpClass )
+void XclExpFmlaCompImpl::ProcessExternal( const XclExpScToken& rTokData )
{
/* #i47228# Excel import generates svExternal/ocMacro tokens for invalid
names and for external/invalid function calls. This function looks for
the next token in the token array. If it is an opening parenthesis, the
token is processed as external function call, otherwise as undefined name. */
- const formula::FormulaToken* pNextScToken = PeekNextRawToken( true );
+ const FormulaToken* pNextScToken = PeekNextRawToken( true );
if( !pNextScToken || (pNextScToken->GetOpCode() != ocOpen) )
- AppendMissingNameToken( rTokData.mpScToken->GetExternal(), nExpClass, rTokData.mnSpaces );
+ AppendMissingNameToken( rTokData.mpScToken->GetExternal(), rTokData.mnSpaces );
else
- ProcessFunction( rTokData, nExpClass );
+ ProcessFunction( rTokData );
}
-void XclExpFmlaCompImpl::ProcessExternalName( const XclExpTokenData& rTokData, sal_uInt8 nExpClass )
+void XclExpFmlaCompImpl::ProcessMatrix( const XclExpScToken& rTokData )
{
- StackVar eType = rTokData.GetType();
-
- ScExternalRefManager* pRefMgr = GetDoc().GetExternalRefManager();
- USHORT nFileId = rTokData.mpScToken->GetIndex();
- switch (eType)
+ const ScMatrix* pMatrix = static_cast< const ScToken* >( rTokData.mpScToken )->GetMatrix();
+ if( pMatrix && mxData->mrCfg.mbAllowArrays )
{
- case svExternalSingleRef:
- {
- if (!mpScBasePos)
- {
- AppendErrorToken(EXC_ERR_REF, rTokData.mnSpaces);
- break;
- }
- ScSingleRefData aRef(static_cast<const ScToken*>(rTokData.mpScToken)->GetSingleRef());
- aRef.CalcAbsIfRel(*mpScBasePos);
- const String& rTabName = rTokData.mpScToken->GetString();
- ScExternalRefCache::TokenRef p = pRefMgr->getSingleRefToken(nFileId, rTabName, ScAddress(aRef.nCol, aRef.nRow, aRef.nTab), NULL, NULL);
- if (!p.get())
- {
- AppendErrorToken(EXC_ERR_REF, rTokData.mnSpaces);
- break;
- }
+ SCSIZE nScCols, nScRows;
+ pMatrix->GetDimensions( nScCols, nScRows );
+ DBG_ASSERT( (nScCols > 0) && (nScRows > 0), "XclExpFmlaCompImpl::ProcessMatrix - invalid matrix size" );
+ sal_uInt16 nCols = ::limit_cast< sal_uInt16 >( nScCols, 0, 256 );
+ sal_uInt16 nRows = ::limit_cast< sal_uInt16 >( nScRows, 0, 1024 );
- mpLinkMgr->StoreCell(nFileId, rTabName, aRef);
-
- XclAddress aXclPos(ScAddress::UNINITIALIZED);
- ConvertRefData(aRef, aXclPos, false, false, false);
-
- sal_uInt16 nExtSheet, nFirstSBTab, nLastSBTab;
- mpLinkMgr->FindExtSheet(nFileId, rTabName, 1, nExtSheet, nFirstSBTab, nLastSBTab, GetNewRefLogEntry());
- sal_uInt8 nBaseId = lclIsRefDel2D(aRef) ? EXC_TOKID_REFERR3D : EXC_TOKID_REF3D;
- AppendOpTokenId(GetTokenId(nBaseId, EXC_TOKCLASS_REF), nExpClass, rTokData.mnSpaces);
- Append(nExtSheet);
- if (meBiff <= EXC_BIFF5)
- {
- Append(0, 8);
- Append(static_cast<sal_uInt16>(nFirstSBTab));
- Append(static_cast<sal_uInt16>(nFirstSBTab));
- }
- AppendAddress(aXclPos);
- }
- break;
- case svExternalDoubleRef:
- {
- if (!mpScBasePos)
- {
- AppendErrorToken(XclTools::GetXclErrorCode(errNoRef), rTokData.mnSpaces);
- break;
- }
- ScComplexRefData aRef(static_cast<const ScToken*>(rTokData.mpScToken)->GetDoubleRef());
- aRef.CalcAbsIfRel(*mpScBasePos);
- const String& rTabName = rTokData.mpScToken->GetString();
- const ScSingleRefData& r1 = aRef.Ref1;
- const ScSingleRefData& r2 = aRef.Ref2;
- ScRange aRange(r1.nCol, r1.nRow, r1.nTab, r2.nCol, r2.nRow, r2.nTab);
- ScExternalRefCache::TokenArrayRef pArray = pRefMgr->getDoubleRefTokens(nFileId, rTabName, aRange, NULL);
- if (!pArray.get())
- {
- AppendErrorToken(EXC_ERR_REF, rTokData.mnSpaces);
- break;
- }
+ // create the tArray token
+ AppendOperandTokenId( GetTokenId( EXC_TOKID_ARRAY, EXC_TOKCLASS_ARR ), rTokData.mnSpaces );
+ Append( static_cast< sal_uInt8 >( (meBiff == EXC_BIFF8) ? (nCols - 1) : nCols ) );
+ Append( static_cast< sal_uInt16 >( (meBiff == EXC_BIFF8) ? (nRows - 1) : nRows ) );
+ Append( static_cast< sal_uInt32 >( 0 ) );
- mpLinkMgr->StoreCellRange(nFileId, rTabName, aRef);
- XclRange aXclRange(ScAddress::UNINITIALIZED);
- ConvertRefData(aRef, aXclRange, false);
- sal_uInt16 nExtSheet, nFirstSBTab, nLastSBTab;
- sal_uInt16 nTabSpan = r2.nTab - r1.nTab + 1;
- mpLinkMgr->FindExtSheet(nFileId, rTabName, nTabSpan, nExtSheet, nFirstSBTab, nLastSBTab, GetNewRefLogEntry());
-
- sal_uInt8 nBaseId = lclIsRefDel2D(aRef) ? EXC_TOKID_AREAERR3D : EXC_TOKID_AREA3D;
- AppendOpTokenId(GetTokenId( nBaseId, EXC_TOKCLASS_REF ), nExpClass, rTokData.mnSpaces);
- Append(nExtSheet);
- if (meBiff <= EXC_BIFF5)
- {
- Append(0, 8);
- Append(static_cast<sal_uInt16>(nFirstSBTab));
- Append(static_cast<sal_uInt16>(nLastSBTab));
- }
- AppendRange(aXclRange);
- }
- break;
- case svExternalName:
+ // create the extended data containing the array values
+ AppendExt( static_cast< sal_uInt8 >( (meBiff == EXC_BIFF8) ? (nCols - 1) : nCols ) );
+ AppendExt( static_cast< sal_uInt16 >( (meBiff == EXC_BIFF8) ? (nRows - 1) : nRows ) );
+ for( SCSIZE nScRow = 0; nScRow < nScRows; ++nScRow )
{
- const String& aName = rTokData.mpScToken->GetString();
- ScExternalRefCache::TokenArrayRef pArray = pRefMgr->getRangeNameTokens(nFileId, aName);
- if (!pArray.get() || !mpScBasePos)
+ for( SCSIZE nScCol = 0; nScCol < nScCols; ++nScCol )
{
- AppendErrorToken(XclTools::GetXclErrorCode(errNoName), rTokData.mnSpaces);
- break;
- }
-
- // Go through all these tokens to store the external cell/range
- // references for CRN records.
- for (formula::FormulaToken* p = pArray->First(); p; p = pArray->Next())
- {
- if (p->GetOpCode() == ocExternalRef)
+ ScMatValType nType;
+ const ScMatrixValue* pMatVal = pMatrix->Get( nScCol, nScRow, nType );
+ DBG_ASSERT( pMatVal, "XclExpFmlaCompImpl::ProcessMatrix - missing matrix value" );
+ if( ScMatrix::IsValueType( nType ) ) // value, boolean, or error
+ {
+ if( ScMatrix::IsBooleanType( nType ) )
+ {
+ AppendExt( EXC_CACHEDVAL_BOOL );
+ AppendExt( static_cast< sal_uInt8 >( pMatVal->GetBoolean() ? 1 : 0 ) );
+ AppendExt( 0, 7 );
+ }
+ else if( USHORT nErr = pMatVal->GetError() )
+ {
+ AppendExt( EXC_CACHEDVAL_ERROR );
+ AppendExt( XclTools::GetXclErrorCode( nErr ) );
+ AppendExt( 0, 7 );
+ }
+ else
+ {
+ AppendExt( EXC_CACHEDVAL_DOUBLE );
+ AppendExt( pMatVal->fVal );
+ }
+ }
+ else // string or empty
{
- if (p->GetType() == svExternalSingleRef)
+ const String& rStr = pMatVal->GetString();
+ if( rStr.Len() == 0 )
{
- ScSingleRefData aData(static_cast<ScToken*>(p)->GetSingleRef());
- aData.CalcAbsIfRel(*mpScBasePos);
- mpLinkMgr->StoreCell(nFileId, p->GetString(), aData);
+ AppendExt( EXC_CACHEDVAL_EMPTY );
+ AppendExt( 0, 8 );
}
- else if (p->GetType() == svExternalDoubleRef)
+ else
{
- ScComplexRefData aData(static_cast<ScToken*>(p)->GetDoubleRef());
- aData.CalcAbsIfRel(*mpScBasePos);
- mpLinkMgr->StoreCellRange(nFileId, p->GetString(), aData);
+ AppendExt( EXC_CACHEDVAL_STRING );
+ AppendExt( rStr );
}
}
}
-
- const String* pFile = pRefMgr->getExternalFileName(nFileId);
- sal_uInt16 nExtSheet, nExtName;
- if (mpLinkMgr->InsertExtName(nExtSheet, nExtName, *pFile, aName, pArray))
- AppendNameXToken(nExtSheet, nExtName, nExpClass, rTokData.mnSpaces);
- else
- AppendErrorToken(EXC_ERR_REF, rTokData.mnSpaces);
}
- break;
- default:
- ; // nothing
+ }
+ else
+ {
+ // array in places that do not allow it (cond fmts, data validation)
+ AppendErrorToken( EXC_ERR_NA, rTokData.mnSpaces );
}
}
-void XclExpFmlaCompImpl::ProcessFunction( const XclExpTokenData& rTokData, sal_uInt8 nExpClass )
+void XclExpFmlaCompImpl::ProcessFunction( const XclExpScToken& rTokData )
{
OpCode eOpCode = rTokData.GetOpCode();
const XclFunctionInfo* pFuncInfo = maFuncProv.GetFuncInfoFromOpCode( eOpCode );
@@ -1437,15 +1391,15 @@ void XclExpFmlaCompImpl::ProcessFunction( const XclExpTokenData& rTokData, sal_u
}
}
- mbOk = pFuncInfo != 0;
- if( !mbOk ) return;
+ mxData->mbOk = pFuncInfo != 0;
+ if( !mxData->mbOk ) return;
// functions simulated by a macro call in file format
if( pFuncInfo->IsMacroFunc() )
aExtFuncData.Set( pFuncInfo->GetMacroFuncName(), false, true );
- XclExpFuncData aFuncData( rTokData, *pFuncInfo, aExtFuncData, nExpClass );
- XclExpTokenData aTokData;
+ XclExpFuncData aFuncData( rTokData, *pFuncInfo, aExtFuncData );
+ XclExpScToken aTokData;
// preparations for special functions, before function processing starts
PrepareFunction( aFuncData );
@@ -1455,12 +1409,12 @@ void XclExpFmlaCompImpl::ProcessFunction( const XclExpTokenData& rTokData, sal_u
while( eState != STATE_END ) switch( eState )
{
case STATE_START:
- mbOk = GetNextToken( aTokData ) && (aTokData.GetOpCode() == ocOpen);
- eState = mbOk ? STATE_OPEN : STATE_END;
+ mxData->mbOk = GetNextToken( aTokData ) && (aTokData.GetOpCode() == ocOpen);
+ eState = mxData->mbOk ? STATE_OPEN : STATE_END;
break;
case STATE_OPEN:
- mbOk = GetNextToken( aTokData );
- eState = mbOk ? ((aTokData.GetOpCode() == ocClose) ? STATE_CLOSE : STATE_PARAM) : STATE_END;
+ mxData->mbOk = GetNextToken( aTokData );
+ eState = mxData->mbOk ? ((aTokData.GetOpCode() == ocClose) ? STATE_CLOSE : STATE_PARAM) : STATE_END;
break;
case STATE_PARAM:
aTokData = ProcessParam( aTokData, aFuncData );
@@ -1468,13 +1422,13 @@ void XclExpFmlaCompImpl::ProcessFunction( const XclExpTokenData& rTokData, sal_u
{
case ocSep: eState = STATE_SEP; break;
case ocClose: eState = STATE_CLOSE; break;
- default: mbOk = false;
+ default: mxData->mbOk = false;
}
- if( !mbOk ) eState = STATE_END;
+ if( !mxData->mbOk ) eState = STATE_END;
break;
case STATE_SEP:
- mbOk = (aFuncData.GetParamCount() < EXC_FUNC_MAXPARAM) && GetNextToken( aTokData );
- eState = mbOk ? STATE_PARAM : STATE_END;
+ mxData->mbOk = (aFuncData.GetParamCount() < EXC_FUNC_MAXPARAM) && GetNextToken( aTokData );
+ eState = mxData->mbOk ? STATE_PARAM : STATE_END;
break;
case STATE_CLOSE:
FinishFunction( aFuncData, aTokData.mnSpaces );
@@ -1506,11 +1460,8 @@ void XclExpFmlaCompImpl::FinishFunction( XclExpFuncData& rFuncData, sal_uInt8 nC
// check if parameter count fits into the limits of the function
sal_uInt8 nParamCount = rFuncData.GetParamCount();
- sal_uInt8 nMinCount = rFuncData.GetMinParamCount();
- sal_uInt8 nMaxCount = rFuncData.GetMaxParamCount();
- if( (nMinCount <= nParamCount) && (nParamCount <= nMaxCount) )
+ if( (rFuncData.GetMinParamCount() <= nParamCount) && (nParamCount <= rFuncData.GetMaxParamCount()) )
{
- sal_uInt16 nXclFuncIdx = rFuncData.GetXclFuncIdx();
// first put the tAttrSpace tokens, they must not be included in tAttrGoto handling
AppendSpaceToken( EXC_TOK_ATTR_SPACE_SP_CLOSE, nCloseSpaces );
AppendSpaceToken( EXC_TOK_ATTR_SPACE_SP, rFuncData.GetSpaces() );
@@ -1526,31 +1477,10 @@ void XclExpFmlaCompImpl::FinishFunction( XclExpFuncData& rFuncData, sal_uInt8 nC
}
// put the tFunc or tFuncVar token (or another special token, e.g. tAttrSum)
- sal_uInt8 nRetClass = rFuncData.GetReturnClass();
- sal_uInt8 nExpRetClass = rFuncData.GetExpReturnClass();
- if( (nXclFuncIdx == EXC_FUNCID_SUM) && (nParamCount == 1) )
- {
- // SUM with only one parameter
- AppendOpTokenId( EXC_TOKID_ATTR, nExpRetClass );
- Append( EXC_TOK_ATTR_SUM );
- Append( sal_uInt16( 0 ) );
- }
- else if( (nMinCount == nMaxCount) && (nXclFuncIdx != EXC_FUNCID_EXTERNCALL) )
- {
- // fixed number of parameters
- AppendOpTokenId( GetTokenId( EXC_TOKID_FUNC, nRetClass ), nExpRetClass );
- Append( nXclFuncIdx );
- }
- else
- {
- // variable number of parameters
- AppendOpTokenId( GetTokenId( EXC_TOKID_FUNCVAR, nRetClass ), nExpRetClass );
- Append( nParamCount );
- Append( nXclFuncIdx );
- }
+ AppendFuncToken( rFuncData );
// update volatile flag - is set if at least one used function is volatile
- mbVolatile |= rFuncData.IsVolatile();
+ mxData->mbVolatile |= rFuncData.IsVolatile();
// update jump tokens for specific functions, add additional tokens
switch( rFuncData.GetOpCode() )
@@ -1564,11 +1494,11 @@ void XclExpFmlaCompImpl::FinishFunction( XclExpFuncData& rFuncData, sal_uInt8 nC
case ocCot: // simulate COT(x) by (1/TAN(x))
case ocCotHyp: // simulate COTH(x) by (1/TANH(x))
- AppendOpTokenId( EXC_TOKID_DIV, EXC_TOKCLASS_NONE );
+ AppendBinaryOperatorToken( EXC_TOKID_DIV, true );
AppendParenToken();
break;
case ocArcCot: // simulate ACOT(x) by (PI/2-ATAN(x))
- AppendOpTokenId( EXC_TOKID_SUB, EXC_TOKCLASS_NONE );
+ AppendBinaryOperatorToken( EXC_TOKID_SUB, true );
AppendParenToken();
break;
@@ -1576,7 +1506,7 @@ void XclExpFmlaCompImpl::FinishFunction( XclExpFuncData& rFuncData, sal_uInt8 nC
}
}
else
- mbOk = false;
+ mxData->mbOk = false;
}
void XclExpFmlaCompImpl::FinishIfFunction( XclExpFuncData& rFuncData )
@@ -1607,7 +1537,7 @@ void XclExpFmlaCompImpl::FinishChooseFunction( XclExpFuncData& rFuncData )
// size of jump table: number of choices, plus 1 for error position
sal_uInt16 nJumpArrSize = 2 * (nChoices + 1);
// insert the jump table into the tAttrChoose token
- Insert( nJumpArrPos, nJumpArrSize );
+ InsertZeros( nJumpArrPos, nJumpArrSize );
// update positions of tAttrGoto tokens after jump table insertion
sal_uInt16 nIdx;
for( nIdx = 1; nIdx < nParamCount; ++nIdx )
@@ -1621,25 +1551,20 @@ void XclExpFmlaCompImpl::FinishChooseFunction( XclExpFuncData& rFuncData )
Overwrite( nJumpArrPos + 2 * nIdx, static_cast< sal_uInt16 >( rAttrPos[ nIdx ] + 4 - nJumpArrPos ) );
}
-XclExpTokenData XclExpFmlaCompImpl::ProcessParam( XclExpTokenData aTokData, XclExpFuncData& rFuncData )
+XclExpScToken XclExpFmlaCompImpl::ProcessParam( XclExpScToken aTokData, XclExpFuncData& rFuncData )
{
- if( rFuncData.GetExpParamClass() == EXC_FUNC_PAR_CALCONLY )
+ if( rFuncData.IsCalcOnlyParam() )
{
// skip Calc-only parameter, stop at next ocClose or ocSep
aTokData = SkipExpression( aTokData, true );
- rFuncData.IncExpParamClassIdx();
+ rFuncData.IncParamInfoIdx();
}
else
{
// insert Excel-only parameters, modifies param count and class in rFuncData
- while( rFuncData.GetExpParamClass() == EXC_FUNC_PAR_EXCELONLY )
+ while( rFuncData.IsExcelOnlyParam() )
AppendDefaultParam( rFuncData );
- // propagate expected ARR class to subsequent subexpressions
- sal_uInt8 nExpClass = rFuncData.GetExpParamClass();
- bool bOldIsArrExp = mbIsArrExp;
- UpdateArrExpFlag( nExpClass, rFuncData.GetReturnClass() );
-
// process the parameter, stop at next ocClose or ocSep
PrepareParam( rFuncData );
/* #i37355# insert tMissArg token for missing parameters --
@@ -1649,12 +1574,10 @@ XclExpTokenData XclExpFmlaCompImpl::ProcessParam( XclExpTokenData aTokData, XclE
{
case ocSep:
case ocClose: AppendMissingToken(); break; // empty parameter
- default: aTokData = Expression( aTokData, nExpClass, false, true );
+ default: aTokData = Expression( aTokData, false, true );
}
- // restore old expected ARR class mode
- SetArrExpFlag( bOldIsArrExp );
// finalize the parameter and add special tokens, e.g. for IF or CHOOSE parameters
- if( mbOk ) FinishParam( rFuncData );
+ if( mxData->mbOk ) FinishParam( rFuncData );
}
return aTokData;
}
@@ -1698,21 +1621,18 @@ void XclExpFmlaCompImpl::PrepareParam( XclExpFuncData& rFuncData )
void XclExpFmlaCompImpl::FinishParam( XclExpFuncData& rFuncData )
{
- // index of this parameter is equal to number of already finished parameters
- sal_uInt8 nParamIdx = rFuncData.GetParamCount();
-
- // increase parameter count
- rFuncData.IncParamCount();
- // move to next expected parameter class
- rFuncData.IncExpParamClassIdx();
+ // increase parameter count, update operand stack
+ rFuncData.FinishParam( PopOperandPos() );
+ // append more tokens for parameters of some special functions
+ sal_uInt8 nParamIdx = rFuncData.GetParamCount() - 1;
switch( rFuncData.GetOpCode() )
{
case ocArcCotHyp: // simulate ACOTH(x) by ATANH(1/(x))
if( nParamIdx == 0 )
{
AppendParenToken();
- AppendOpTokenId( EXC_TOKID_DIV, EXC_TOKCLASS_NONE );
+ AppendBinaryOperatorToken( EXC_TOKID_DIV, true );
}
break;
default:;
@@ -1727,19 +1647,19 @@ void XclExpFmlaCompImpl::AppendDefaultParam( XclExpFuncData& rFuncData )
switch( rFuncData.GetOpCode() )
{
case ocExternal:
- AppendAddInFuncToken( rFuncData.GetExtFuncData(), EXC_TOKCLASS_REF );
+ AppendAddInCallToken( rFuncData.GetExtFuncData() );
break;
case ocEuroConvert:
- AppendEuroToolFuncToken( rFuncData.GetExtFuncData(), EXC_TOKCLASS_REF );
+ AppendEuroToolCallToken( rFuncData.GetExtFuncData() );
break;
case ocMacro:
- AppendMacroCallToken( rFuncData.GetExtFuncData(), EXC_TOKCLASS_REF );
+ AppendMacroCallToken( rFuncData.GetExtFuncData() );
break;
default:
{
DBG_ASSERT( rFuncData.IsMacroFunc(), "XclExpFmlaCompImpl::AppendDefaultParam - unknown opcode" );
if( rFuncData.IsMacroFunc() )
- AppendMacroCallToken( rFuncData.GetExtFuncData(), EXC_TOKCLASS_REF );
+ AppendMacroCallToken( rFuncData.GetExtFuncData() );
else
AppendMissingToken(); // to keep parameter count valid
}
@@ -1813,25 +1733,77 @@ void XclExpFmlaCompImpl::AppendTrailingParam( XclExpFuncData& rFuncData )
}
break;
+ case ocNormDist:
+ if( nParamCount == 3 )
+ {
+ // NORMDIST function needs 4 parameters in Excel
+ PrepareParam( rFuncData );
+ AppendBoolToken( true );
+ FinishParam( rFuncData );
+ }
+ break;
+
+ case ocLogNormDist:
+ switch( nParamCount )
+ {
+ // LOGNORMDIST function needs 3 parameters in Excel
+ case 1:
+ PrepareParam( rFuncData );
+ AppendIntToken( 0 );
+ FinishParam( rFuncData );
+ // do not break, add next default parameter
+ case 2:
+ PrepareParam( rFuncData );
+ AppendIntToken( 1 );
+ FinishParam( rFuncData );
+ break;
+ default:;
+ }
+
+ break;
+
default:;
}
}
-// ----------------------------------------------------------------------------
+// reference handling ---------------------------------------------------------
+
+namespace {
+
+inline bool lclIsRefRel2D( const ScSingleRefData& rRefData )
+{
+ return rRefData.IsColRel() || rRefData.IsRowRel();
+}
+
+inline bool lclIsRefDel2D( const ScSingleRefData& rRefData )
+{
+ return rRefData.IsColDeleted() || rRefData.IsRowDeleted();
+}
+
+inline bool lclIsRefRel2D( const ScComplexRefData& rRefData )
+{
+ return lclIsRefRel2D( rRefData.Ref1 ) || lclIsRefRel2D( rRefData.Ref2 );
+}
+
+inline bool lclIsRefDel2D( const ScComplexRefData& rRefData )
+{
+ return lclIsRefDel2D( rRefData.Ref1 ) || lclIsRefDel2D( rRefData.Ref2 );
+}
+
+} // namespace
SCTAB XclExpFmlaCompImpl::GetScTab( const ScSingleRefData& rRefData ) const
{
- bool bInvTab = rRefData.IsTabDeleted() || (!mpScBasePos && rRefData.IsTabRel());
+ bool bInvTab = rRefData.IsTabDeleted() || (!mxData->mpScBasePos && IsInGlobals() && rRefData.IsTabRel());
return bInvTab ? SCTAB_INVALID : static_cast< SCTAB >( rRefData.nTab );
}
bool XclExpFmlaCompImpl::IsRef2D( const ScSingleRefData& rRefData ) const
{
- /* rRefData.IsFlag3D() determines if sheet name is always visible, even on the
- own sheet. If 3D references are allowed, the passed reference does not count
- as 2D reference. If only 2D references are allowed (mpLinkMgr is 0), this
- flag is ignored, thus the passed reference will be handled as 2D reference. */
- return (!mpLinkMgr || !rRefData.IsFlag3D()) && !rRefData.IsTabDeleted() &&
+ /* rRefData.IsFlag3D() determines if sheet name is always visible, even on
+ the own sheet. If 3D references are allowed, the passed reference does
+ not count as 2D reference. */
+ return (!mxData->mpLinkMgr || !rRefData.IsFlag3D()) && !rRefData.IsTabDeleted() &&
(rRefData.IsTabRel() ? (rRefData.nRelTab == 0) : (static_cast< SCTAB >( rRefData.nTab ) == GetCurrScTab()));
}
@@ -1844,10 +1816,10 @@ void XclExpFmlaCompImpl::ConvertRefData(
ScSingleRefData& rRefData, XclAddress& rXclPos,
bool bNatLangRef, bool bTruncMaxCol, bool bTruncMaxRow ) const
{
- if( mpScBasePos )
+ if( mxData->mpScBasePos )
{
// *** reference position exists (cell, matrix) - convert to absolute ***
- rRefData.CalcAbsIfRel( *mpScBasePos );
+ rRefData.CalcAbsIfRel( *mxData->mpScBasePos );
// convert column index
SCsCOL& rnScCol = rRefData.nCol;
@@ -1876,6 +1848,10 @@ void XclExpFmlaCompImpl::ConvertRefData(
// convert row index (2-step-cast ScsROW->sal_Int16->sal_uInt16 to get all bits correctly)
sal_Int16 nXclRelRow = static_cast< sal_Int16 >( rRefData.IsRowRel() ? rRefData.nRelRow : rRefData.nRow );
rXclPos.mnRow = static_cast< sal_uInt16 >( nXclRelRow ) & mnMaxRowMask;
+
+ // resolve relative tab index if possible
+ if( rRefData.IsTabRel() && !IsInGlobals() && (GetCurrScTab() < GetDoc().GetTableCount()) )
+ rRefData.nTab = static_cast< SCsTAB >( GetCurrScTab() + rRefData.nRelTab );
}
// flags for relative column and row
@@ -1905,19 +1881,19 @@ void XclExpFmlaCompImpl::ConvertRefData(
XclExpRefLogEntry* XclExpFmlaCompImpl::GetNewRefLogEntry()
{
- if( mpRefLog )
+ if( mxData->mpRefLog )
{
- mpRefLog->resize( mpRefLog->size() + 1 );
- return &mpRefLog->back();
+ mxData->mpRefLog->resize( mxData->mpRefLog->size() + 1 );
+ return &mxData->mpRefLog->back();
}
return 0;
}
-void XclExpFmlaCompImpl::ProcessCellRef( const XclExpTokenData& rTokData, sal_uInt8 nExpClass )
+void XclExpFmlaCompImpl::ProcessCellRef( const XclExpScToken& rTokData )
{
// get the Excel address components, adjust internal data in aRefData
- bool bNatLangRef = (meBiff == EXC_BIFF8) && mpScBasePos && (rTokData.GetOpCode() == ocColRowName);
- ScSingleRefData aRefData( static_cast<const ScToken*>(rTokData.mpScToken)->GetSingleRef() );
+ bool bNatLangRef = (meBiff == EXC_BIFF8) && mxData->mpScBasePos && (rTokData.GetOpCode() == ocColRowName);
+ ScSingleRefData aRefData = static_cast< const ScToken* >( rTokData.mpScToken )->GetSingleRef();
XclAddress aXclPos( ScAddress::UNINITIALIZED );
ConvertRefData( aRefData, aXclPos, bNatLangRef, false, false );
@@ -1927,33 +1903,33 @@ void XclExpFmlaCompImpl::ProcessCellRef( const XclExpTokenData& rTokData, sal_uI
"XclExpFmlaCompImpl::ProcessCellRef - broken natural language reference" );
// create tNlr token for natural language reference
sal_uInt8 nSubId = aRefData.IsColRel() ? EXC_TOK_NLR_COLV : EXC_TOK_NLR_ROWV;
- AppendOpTokenId( EXC_TOKID_NLR, nExpClass, rTokData.mnSpaces );
+ AppendOperandTokenId( EXC_TOKID_NLR, rTokData.mnSpaces );
Append( nSubId );
AppendAddress( aXclPos );
}
else
{
// store external cell contents in CRN records
- if( maCfg.mbFromCell && mpLinkMgr && mpScBasePos )
- mpLinkMgr->StoreCell( aRefData );
+ if( mxData->mrCfg.mbFromCell && mxData->mpLinkMgr && mxData->mpScBasePos )
+ mxData->mpLinkMgr->StoreCell( aRefData );
// create the tRef, tRefErr, tRefN, tRef3d, or tRefErr3d token
- if( !maCfg.mb3DRefOnly && IsRef2D( aRefData ) )
+ if( !mxData->mrCfg.mb3DRefOnly && IsRef2D( aRefData ) )
{
// 2D reference (not in defined names, but allowed in range lists)
- sal_uInt8 nBaseId = (!mpScBasePos && lclIsRefRel2D( aRefData )) ? EXC_TOKID_REFN :
+ sal_uInt8 nBaseId = (!mxData->mpScBasePos && lclIsRefRel2D( aRefData )) ? EXC_TOKID_REFN :
(lclIsRefDel2D( aRefData ) ? EXC_TOKID_REFERR : EXC_TOKID_REF);
- AppendOpTokenId( GetTokenId( nBaseId, EXC_TOKCLASS_REF ), nExpClass, rTokData.mnSpaces );
+ AppendOperandTokenId( GetTokenId( nBaseId, EXC_TOKCLASS_REF ), rTokData.mnSpaces );
AppendAddress( aXclPos );
}
- else if( mpLinkMgr ) // 3D reference
+ else if( mxData->mpLinkMgr ) // 3D reference
{
// 1-based EXTERNSHEET index and 0-based Excel sheet index
sal_uInt16 nExtSheet, nXclTab;
- mpLinkMgr->FindExtSheet( nExtSheet, nXclTab, GetScTab( aRefData ), GetNewRefLogEntry() );
+ mxData->mpLinkMgr->FindExtSheet( nExtSheet, nXclTab, GetScTab( aRefData ), GetNewRefLogEntry() );
// write the token
sal_uInt8 nBaseId = lclIsRefDel2D( aRefData ) ? EXC_TOKID_REFERR3D : EXC_TOKID_REF3D;
- AppendOpTokenId( GetTokenId( nBaseId, EXC_TOKCLASS_REF ), nExpClass, rTokData.mnSpaces );
+ AppendOperandTokenId( GetTokenId( nBaseId, EXC_TOKCLASS_REF ), rTokData.mnSpaces );
Append( nExtSheet );
if( meBiff <= EXC_BIFF5 )
{
@@ -1971,35 +1947,35 @@ void XclExpFmlaCompImpl::ProcessCellRef( const XclExpTokenData& rTokData, sal_uI
}
}
-void XclExpFmlaCompImpl::ProcessRangeRef( const XclExpTokenData& rTokData, sal_uInt8 nExpClass )
+void XclExpFmlaCompImpl::ProcessRangeRef( const XclExpScToken& rTokData )
{
// get the Excel address components, adjust internal data in aRefData
- ScComplexRefData aRefData( static_cast<const ScToken*>(rTokData.mpScToken)->GetDoubleRef() );
+ ScComplexRefData aRefData = static_cast< const ScToken* >( rTokData.mpScToken )->GetDoubleRef();
XclRange aXclRange( ScAddress::UNINITIALIZED );
ConvertRefData( aRefData, aXclRange, false );
// store external cell contents in CRN records
- if( maCfg.mbFromCell && mpLinkMgr && mpScBasePos )
- mpLinkMgr->StoreCellRange( aRefData );
+ if( mxData->mrCfg.mbFromCell && mxData->mpLinkMgr && mxData->mpScBasePos )
+ mxData->mpLinkMgr->StoreCellRange( aRefData );
// create the tArea, tAreaErr, tAreaN, tArea3d, or tAreaErr3d token
- if( !maCfg.mb3DRefOnly && IsRef2D( aRefData ) )
+ if( !mxData->mrCfg.mb3DRefOnly && IsRef2D( aRefData ) )
{
// 2D reference (not in name formulas, but allowed in range lists)
- sal_uInt8 nBaseId = (!mpScBasePos && lclIsRefRel2D( aRefData )) ? EXC_TOKID_AREAN :
+ sal_uInt8 nBaseId = (!mxData->mpScBasePos && lclIsRefRel2D( aRefData )) ? EXC_TOKID_AREAN :
(lclIsRefDel2D( aRefData ) ? EXC_TOKID_AREAERR : EXC_TOKID_AREA);
- AppendOpTokenId( GetTokenId( nBaseId, EXC_TOKCLASS_REF ), nExpClass, rTokData.mnSpaces );
+ AppendOperandTokenId( GetTokenId( nBaseId, EXC_TOKCLASS_REF ), rTokData.mnSpaces );
AppendRange( aXclRange );
}
- else if( mpLinkMgr ) // 3D reference
+ else if( mxData->mpLinkMgr ) // 3D reference
{
// 1-based EXTERNSHEET index and 0-based Excel sheet indexes
sal_uInt16 nExtSheet, nFirstXclTab, nLastXclTab;
- mpLinkMgr->FindExtSheet( nExtSheet, nFirstXclTab, nLastXclTab,
+ mxData->mpLinkMgr->FindExtSheet( nExtSheet, nFirstXclTab, nLastXclTab,
GetScTab( aRefData.Ref1 ), GetScTab( aRefData.Ref2 ), GetNewRefLogEntry() );
// write the token
sal_uInt8 nBaseId = lclIsRefDel2D( aRefData ) ? EXC_TOKID_AREAERR3D : EXC_TOKID_AREA3D;
- AppendOpTokenId( GetTokenId( nBaseId, EXC_TOKCLASS_REF ), nExpClass, rTokData.mnSpaces );
+ AppendOperandTokenId( GetTokenId( nBaseId, EXC_TOKCLASS_REF ), rTokData.mnSpaces );
Append( nExtSheet );
if( meBiff <= EXC_BIFF5 )
{
@@ -2016,7 +1992,80 @@ void XclExpFmlaCompImpl::ProcessRangeRef( const XclExpTokenData& rTokData, sal_u
}
}
-void XclExpFmlaCompImpl::ProcessDefinedName( const XclExpTokenData& rTokData, sal_uInt8 nExpClass )
+void XclExpFmlaCompImpl::ProcessExternalCellRef( const XclExpScToken& rTokData )
+{
+ if( mxData->mpLinkMgr )
+ {
+ // get the Excel address components, adjust internal data in aRefData
+ ScSingleRefData aRefData = static_cast< const ScToken* >( rTokData.mpScToken )->GetSingleRef();
+ XclAddress aXclPos( ScAddress::UNINITIALIZED );
+ ConvertRefData( aRefData, aXclPos, false, false, false );
+
+ // store external cell contents in CRN records
+ USHORT nFileId = rTokData.mpScToken->GetIndex();
+ const String& rTabName = rTokData.mpScToken->GetString();
+ if( mxData->mrCfg.mbFromCell && mxData->mpScBasePos )
+ mxData->mpLinkMgr->StoreCell( nFileId, rTabName, aRefData );
+
+ // 1-based EXTERNSHEET index and 0-based Excel sheet indexes
+ sal_uInt16 nExtSheet, nFirstSBTab, nLastSBTab;
+ mxData->mpLinkMgr->FindExtSheet( nFileId, rTabName, 1, nExtSheet, nFirstSBTab, nLastSBTab, GetNewRefLogEntry() );
+ // write the token
+ sal_uInt8 nBaseId = lclIsRefDel2D( aRefData ) ? EXC_TOKID_REFERR3D : EXC_TOKID_REF3D;
+ AppendOperandTokenId( GetTokenId( nBaseId, EXC_TOKCLASS_REF ), rTokData.mnSpaces );
+ Append( nExtSheet );
+ if( meBiff <= EXC_BIFF5 )
+ {
+ Append( 0, 8 );
+ Append( nFirstSBTab );
+ Append( nLastSBTab );
+ }
+ AppendAddress( aXclPos );
+ }
+ else
+ {
+ AppendErrorToken( EXC_ERR_REF, rTokData.mnSpaces );
+ }
+}
+
+void XclExpFmlaCompImpl::ProcessExternalRangeRef( const XclExpScToken& rTokData )
+{
+ if( mxData->mpLinkMgr )
+ {
+ // get the Excel address components, adjust internal data in aRefData
+ ScComplexRefData aRefData = static_cast< const ScToken* >( rTokData.mpScToken )->GetDoubleRef();
+ XclRange aXclRange( ScAddress::UNINITIALIZED );
+ ConvertRefData( aRefData, aXclRange, false );
+
+ // store external cell contents in CRN records
+ USHORT nFileId = rTokData.mpScToken->GetIndex();
+ const String& rTabName = rTokData.mpScToken->GetString();
+ if( mxData->mrCfg.mbFromCell && mxData->mpScBasePos )
+ mxData->mpLinkMgr->StoreCellRange( nFileId, rTabName, aRefData );
+
+ // 1-based EXTERNSHEET index and 0-based Excel sheet indexes
+ sal_uInt16 nExtSheet, nFirstSBTab, nLastSBTab;
+ sal_uInt16 nTabSpan = static_cast< sal_uInt16 >( aRefData.Ref2.nTab - aRefData.Ref1.nTab + 1 );
+ mxData->mpLinkMgr->FindExtSheet( nFileId, rTabName, nTabSpan, nExtSheet, nFirstSBTab, nLastSBTab, GetNewRefLogEntry() );
+ // write the token
+ sal_uInt8 nBaseId = lclIsRefDel2D( aRefData ) ? EXC_TOKID_AREAERR3D : EXC_TOKID_AREA3D;
+ AppendOperandTokenId( GetTokenId( nBaseId, EXC_TOKCLASS_REF ), rTokData.mnSpaces );
+ Append( nExtSheet );
+ if( meBiff <= EXC_BIFF5 )
+ {
+ Append( 0, 8 );
+ Append( nFirstSBTab );
+ Append( nLastSBTab );
+ }
+ AppendRange( aXclRange );
+ }
+ else
+ {
+ AppendErrorToken( EXC_ERR_REF, rTokData.mnSpaces );
+ }
+}
+
+void XclExpFmlaCompImpl::ProcessDefinedName( const XclExpScToken& rTokData )
{
XclExpNameManager& rNameMgr = GetNameManager();
sal_uInt16 nNameIdx = rNameMgr.InsertName( rTokData.mpScToken->GetIndex() );
@@ -2024,218 +2073,167 @@ void XclExpFmlaCompImpl::ProcessDefinedName( const XclExpTokenData& rTokData, sa
{
// global names always with tName token, local names dependent on config
SCTAB nScTab = rNameMgr.GetScTab( nNameIdx );
- if( (nScTab == SCTAB_GLOBAL) || (!maCfg.mb3DRefOnly && (nScTab == GetCurrScTab())) )
+ if( (nScTab == SCTAB_GLOBAL) || (!mxData->mrCfg.mb3DRefOnly && (nScTab == GetCurrScTab())) )
{
- AppendNameToken( nNameIdx, nExpClass, rTokData.mnSpaces );
+ AppendNameToken( nNameIdx, rTokData.mnSpaces );
}
- else if( mpLinkMgr )
+ else if( mxData->mpLinkMgr )
{
// use the same special EXTERNNAME to refer to any local name
- sal_uInt16 nExtSheet = mpLinkMgr->FindExtSheet( EXC_EXTSH_OWNDOC );
- AppendNameXToken( nExtSheet, nNameIdx, nExpClass, rTokData.mnSpaces );
+ sal_uInt16 nExtSheet = mxData->mpLinkMgr->FindExtSheet( EXC_EXTSH_OWNDOC );
+ AppendNameXToken( nExtSheet, nNameIdx, rTokData.mnSpaces );
}
else
AppendErrorToken( EXC_ERR_NAME, rTokData.mnSpaces );
// volatile names (containing volatile functions)
- mbVolatile |= rNameMgr.IsVolatile( nNameIdx );
+ mxData->mbVolatile |= rNameMgr.IsVolatile( nNameIdx );
}
else
AppendErrorToken( EXC_ERR_NAME, rTokData.mnSpaces );
}
-void XclExpFmlaCompImpl::ProcessDatabaseArea( const XclExpTokenData& rTokData, sal_uInt8 nExpClass )
-{
- sal_uInt16 nNameIdx = GetNameManager().InsertDBRange( rTokData.mpScToken->GetIndex() );
- AppendNameToken( nNameIdx, nExpClass, rTokData.mnSpaces );
-}
-
-// token identifiers ----------------------------------------------------------
-
-void XclExpFmlaCompImpl::SetReplaceTokenClasses()
+void XclExpFmlaCompImpl::ProcessExternalName( const XclExpScToken& rTokData )
{
- /* REF expected: change VAL to ARR in array and name type, or if ARR is expected somewhere before.
- Example: How does the return class of PI() (default VAL) change in SUM() (expects REF)?
- =SUM(PI()) -> PI() still returns VAL in cell formula
- {=SUM(PI())} -> PI() returns ARR in array formula
- =MDET(SUM(PI())) -> expected ARR from MDET(), PI() returns ARR too
- */
- mnRefExpClass = (mbIsArrExp || (maCfg.meClassType != EXC_CLASSTYPE_CELL)) ? EXC_TOKCLASS_ARR : EXC_TOKCLASS_VAL;
+ if( mxData->mpLinkMgr )
+ {
+ ScExternalRefManager& rExtRefMgr = *GetDoc().GetExternalRefManager();
+ USHORT nFileId = rTokData.mpScToken->GetIndex();
+ const String& rName = rTokData.mpScToken->GetString();
+ ScExternalRefCache::TokenArrayRef xArray = rExtRefMgr.getRangeNameTokens( nFileId, rName );
+ if( xArray.get() )
+ {
+ // store external cell contents in CRN records
+ if( mxData->mpScBasePos )
+ {
+ for( FormulaToken* pScToken = xArray->First(); pScToken; pScToken = xArray->Next() )
+ {
+ if( pScToken->GetOpCode() == ocExternalRef )
+ {
+ switch( pScToken->GetType() )
+ {
+ case svExternalSingleRef:
+ {
+ ScSingleRefData aRefData = static_cast< ScToken* >( pScToken )->GetSingleRef();
+ aRefData.CalcAbsIfRel( *mxData->mpScBasePos );
+ mxData->mpLinkMgr->StoreCell( nFileId, pScToken->GetString(), aRefData );
+ }
+ break;
+ case svExternalDoubleRef:
+ {
+ ScComplexRefData aRefData = static_cast< ScToken* >( pScToken )->GetDoubleRef();
+ aRefData.CalcAbsIfRel( *mxData->mpScBasePos );
+ mxData->mpLinkMgr->StoreCellRange( nFileId, pScToken->GetString(), aRefData );
+ }
+ default:
+ ; // nothing, avoid compiler warning
+ }
+ }
+ }
+ }
- /* VAL expected: set to ARR, if ARR is expected somewhere before; otherwise set to VAL.
- Example: How does the class of A1 (default REF) change in ABS() (expects VAL)?
- =ABS(A1) -> A1 is VAL in cell formula
- =MDET(ABS(A1)) -> expected ARR from MDET(), A1 is ARR in cell formula
- */
- mnValExpClass = mbIsArrExp ? EXC_TOKCLASS_ARR : EXC_TOKCLASS_VAL;
+ // insert the new external name and create the tNameX token
+ sal_uInt16 nExtSheet, nExtName;
+ const String* pFile = rExtRefMgr.getExternalFileName( nFileId );
+ if( pFile && mxData->mpLinkMgr->InsertExtName( nExtSheet, nExtName, *pFile, rName, xArray ) )
+ {
+ AppendNameXToken( nExtSheet, nExtName, rTokData.mnSpaces );
+ return;
+ }
+ }
+ }
- /* ARR expected: always set to ARR. */
- mnArrExpClass = EXC_TOKCLASS_ARR;
+ // on any error: create a #NAME? error
+ AppendErrorToken( EXC_ERR_NAME, rTokData.mnSpaces );
}
-void XclExpFmlaCompImpl::SetArrExpFlag( bool bIsArrExp )
+void XclExpFmlaCompImpl::ProcessDatabaseArea( const XclExpScToken& rTokData )
{
- if( mbIsArrExp != bIsArrExp )
- {
- mbIsArrExp = bIsArrExp;
- SetReplaceTokenClasses();
- }
+ sal_uInt16 nNameIdx = GetNameManager().InsertDBRange( rTokData.mpScToken->GetIndex() );
+ AppendNameToken( nNameIdx, rTokData.mnSpaces );
}
-void XclExpFmlaCompImpl::UpdateArrExpFlag( sal_uInt8 nParamExpClass, sal_uInt8 nFuncRetClass )
-{
- bool bNewIsArrExp = false;
- switch( maCfg.meClassType )
- {
- case EXC_CLASSTYPE_CELL:
- bNewIsArrExp = nParamExpClass == EXC_TOKCLASS_ARR;
- break;
- case EXC_CLASSTYPE_ARRAY:
- bNewIsArrExp = nParamExpClass != EXC_TOKCLASS_VAL;
- break;
- case EXC_CLASSTYPE_NAME:
- bNewIsArrExp = ((nParamExpClass != EXC_TOKCLASS_VAL) || (nFuncRetClass != EXC_TOKCLASS_REF));
- break;
+// token vector ---------------------------------------------------------------
- default :
- break;
- }
- SetArrExpFlag( mbIsArrExp || bNewIsArrExp );
+void XclExpFmlaCompImpl::PushOperandPos( sal_uInt16 nTokPos )
+{
+ mxData->maOpPosStack.push_back( nTokPos );
}
-void XclExpFmlaCompImpl::AdjustTokenClass( sal_uInt8& rnTokenId, sal_uInt8 nExpClass )
+void XclExpFmlaCompImpl::PushOperatorPos( sal_uInt16 nTokPos, const XclExpOperandListRef& rxOperands )
{
- sal_uInt8 nIsClass = GetTokenClass( rnTokenId );
- if( nIsClass != EXC_TOKCLASS_NONE )
- {
- if( nExpClass == EXC_TOKCLASS_ANY_IN_REFOP )
- {
- // always set to REF, if used by reference operators
- ChangeTokenClass( rnTokenId, EXC_TOKCLASS_REF );
- }
- else
- {
- /* If a REF token is part of a value operator, it behaves like a VAL token.
- e.g.: =SUM(A1) -> SUM() expects REF, A1 is REF.
- =SUM(A1+A1) -> SUM() expects REF, but both A1 are handled like VAL tokens. */
- if( (nIsClass == EXC_TOKCLASS_REF) && ::get_flag( nExpClass, EXC_TOKCLASS_INOP_FLAG ) )
- {
- ChangeTokenClass( rnTokenId, EXC_TOKCLASS_VAL );
- nIsClass = EXC_TOKCLASS_VAL; // update nIsClass for following switch
- }
-
- // change token class according to expected parameter class
- switch( nExpClass )
- {
- case EXC_TOKCLASS_REF:
- case EXC_TOKCLASS_REF_IN_VALOP:
- if( nIsClass == EXC_TOKCLASS_VAL )
- ChangeTokenClass( rnTokenId, mnRefExpClass );
- break;
- case EXC_TOKCLASS_VAL:
- case EXC_TOKCLASS_VAL_IN_VALOP:
- ChangeTokenClass( rnTokenId, mnValExpClass );
- break;
- case EXC_TOKCLASS_ARR:
- case EXC_TOKCLASS_ARR_IN_VALOP:
- ChangeTokenClass( rnTokenId, mnArrExpClass );
- break;
- }
- }
- }
+ PushOperandPos( nTokPos );
+ DBG_ASSERT( rxOperands.get(), "XclExpFmlaCompImpl::AppendOperatorTokenId - missing operand list" );
+ if( mxData->maOpListVec.size() <= nTokPos )
+ mxData->maOpListVec.resize( nTokPos + 1, XclExpOperandListRef() );
+ mxData->maOpListVec[ nTokPos ] = rxOperands;
}
-void XclExpFmlaCompImpl::AdjustLastTokenClass( sal_uInt8 nExpClass )
+sal_uInt16 XclExpFmlaCompImpl::PopOperandPos()
{
- DBG_ASSERT( mnLastTokPos < GetSize(), "XclExpFmlaCompImpl::AdjustLastTokenClass - invalid position" );
- sal_uInt8& rnTokenId = maTokVec[ mnLastTokPos ];
- mnLastDefClass = GetTokenClass( rnTokenId );
- AdjustTokenClass( rnTokenId, nExpClass );
+ DBG_ASSERT( !mxData->maOpPosStack.empty(), "XclExpFmlaCompImpl::PopOperandPos - token stack broken" );
+ sal_uInt16 nTokPos = mxData->maOpPosStack.back();
+ mxData->maOpPosStack.pop_back();
+ return nTokPos;
}
-void XclExpFmlaCompImpl::AdjustLastTokenClassForEastereggOp()
+namespace {
+
+inline void lclAppend( ScfUInt8Vec& orVector, sal_uInt16 nData )
{
- /* This very special function cares about the leading subexpression of the
- Calc easteregg operators OR and AND.
- Example: The Calc formula =(A1:A2)OR(0) will be compiled to the Excel
- formula =OR(A1:A2,0). The Excel OR function expects REF parameters to
- be able to process all cells in a range reference. Since this compiler
- didn't know this when processing the (A1:A2) subexpression, it may
- create a tAreaV token from the reference (e.g. if in cell context).
- This would cause Excel to only evaluate cell A1, and to ignore cell A2,
- if the formula is located in cell B1.
- So this function changes the last token back to its default class and
- adjusts it with expected REF class, which is what would happen, if a
- regular OR or AND function is processed. */
- DBG_ASSERT( mnLastTokPos < GetSize(), "XclExpFmlaCompImpl::AdjustLastTokenClassForEastereggOp - invalid position" );
- sal_uInt8& rnTokenId = maTokVec[ mnLastTokPos ];
- if( GetTokenClass( rnTokenId ) != EXC_TOKCLASS_NONE )
- {
- ChangeTokenClass( rnTokenId, mnLastDefClass );
- AdjustTokenClass( rnTokenId, EXC_TOKCLASS_REF );
- }
+ orVector.resize( orVector.size() + 2 );
+ ShortToSVBT16( nData, &*(orVector.end() - 2) );
}
-void XclExpFmlaCompImpl::AppendOpTokenId( sal_uInt8 nTokenId, sal_uInt8 nExpClass, sal_uInt8 nSpaces )
+inline void lclAppend( ScfUInt8Vec& orVector, sal_uInt32 nData )
{
- AppendSpaceToken( EXC_TOK_ATTR_SPACE_SP, nSpaces );
- mnLastTokPos = GetSize();
- Append( nTokenId );
- AdjustLastTokenClass( nExpClass );
+ orVector.resize( orVector.size() + 4 );
+ UInt32ToSVBT32( nData, &*(orVector.end() - 4) );
}
-//UNUSED2008-05 void XclExpFmlaCompImpl::AppendFuncTokenId(
-//UNUSED2008-05 sal_uInt16 nXclFuncIdx, sal_uInt8 nRetClass, sal_uInt8 nExpRetClass, sal_uInt8 nSpaces )
-//UNUSED2008-05 {
-//UNUSED2008-05 AppendOpTokenId( GetTokenId( EXC_TOKID_FUNC, nRetClass ), nExpRetClass, nSpaces );
-//UNUSED2008-05 Append( nXclFuncIdx );
-//UNUSED2008-05 }
+inline void lclAppend( ScfUInt8Vec& orVector, double fData )
+{
+ orVector.resize( orVector.size() + 8 );
+ DoubleToSVBT64( fData, &*(orVector.end() - 8) );
+}
-void XclExpFmlaCompImpl::AppendVarFuncTokenId(
- sal_uInt16 nXclFuncIdx, sal_uInt8 nRetClass, sal_uInt8 nExpRetClass,
- sal_uInt8 nParamCount, sal_uInt8 nSpaces )
+inline void lclAppend( ScfUInt8Vec& orVector, const XclExpRoot& rRoot, const String& rString, XclStrFlags nStrFlags )
{
- AppendOpTokenId( GetTokenId( EXC_TOKID_FUNCVAR, nRetClass ), nExpRetClass, nSpaces );
- Append( nParamCount );
- Append( nXclFuncIdx );
+ XclExpStringRef xXclStr = XclExpStringHelper::CreateString( rRoot, rString, nStrFlags, EXC_TOK_STR_MAXLEN );
+ size_t nSize = orVector.size();
+ orVector.resize( nSize + xXclStr->GetSize() );
+ xXclStr->WriteToMem( &orVector[ nSize ] );
}
-// token vector ---------------------------------------------------------------
+} // namespace
void XclExpFmlaCompImpl::Append( sal_uInt8 nData )
{
- maTokVec.push_back( nData );
+ mxData->maTokVec.push_back( nData );
}
void XclExpFmlaCompImpl::Append( sal_uInt8 nData, size_t nCount )
{
- maTokVec.resize( maTokVec.size() + nCount, nData );
+ mxData->maTokVec.resize( mxData->maTokVec.size() + nCount, nData );
}
void XclExpFmlaCompImpl::Append( sal_uInt16 nData )
{
- maTokVec.resize( maTokVec.size() + 2 );
- ShortToSVBT16( nData, &*(maTokVec.end() - 2) );
+ lclAppend( mxData->maTokVec, nData );
}
void XclExpFmlaCompImpl::Append( sal_uInt32 nData )
{
- maTokVec.resize( maTokVec.size() + 4 );
- UInt32ToSVBT32( nData, &*(maTokVec.end() - 4) );
+ lclAppend( mxData->maTokVec, nData );
}
void XclExpFmlaCompImpl::Append( double fData )
{
- maTokVec.resize( maTokVec.size() + 8 );
- DoubleToSVBT64( fData, &*(maTokVec.end() - 8) );
+ lclAppend( mxData->maTokVec, fData );
}
void XclExpFmlaCompImpl::Append( const String& rString )
{
- XclExpStringRef xXclStr = XclExpStringHelper::CreateString(
- GetRoot(), rString, EXC_STR_8BITLENGTH, EXC_TOK_STR_MAXLEN );
- size_t nSize = maTokVec.size();
- maTokVec.resize( nSize + xXclStr->GetSize() );
- xXclStr->WriteToMem( &maTokVec[ nSize ] );
+ lclAppend( mxData->maTokVec, GetRoot(), rString, EXC_STR_8BITLENGTH );
}
void XclExpFmlaCompImpl::AppendAddress( const XclAddress& rXclPos )
@@ -2265,7 +2263,7 @@ void XclExpFmlaCompImpl::AppendRange( const XclRange& rXclRange )
void XclExpFmlaCompImpl::AppendSpaceToken( sal_uInt8 nType, sal_uInt8 nCount )
{
- if( nCount )
+ if( nCount > 0 )
{
Append( EXC_TOKID_ATTR );
Append( EXC_TOK_ATTR_SPACE );
@@ -2274,40 +2272,47 @@ void XclExpFmlaCompImpl::AppendSpaceToken( sal_uInt8 nType, sal_uInt8 nCount )
}
}
+void XclExpFmlaCompImpl::AppendOperandTokenId( sal_uInt8 nTokenId, sal_uInt8 nSpaces )
+{
+ AppendSpaceToken( EXC_TOK_ATTR_SPACE_SP, nSpaces );
+ PushOperandPos( GetSize() );
+ Append( nTokenId );
+}
+
void XclExpFmlaCompImpl::AppendIntToken( sal_uInt16 nValue, sal_uInt8 nSpaces )
{
- AppendOpTokenId( EXC_TOKID_INT, EXC_TOKCLASS_NONE, nSpaces );
+ AppendOperandTokenId( EXC_TOKID_INT, nSpaces );
Append( nValue );
}
void XclExpFmlaCompImpl::AppendNumToken( double fValue, sal_uInt8 nSpaces )
{
- AppendOpTokenId( EXC_TOKID_NUM, EXC_TOKCLASS_NONE, nSpaces );
+ AppendOperandTokenId( EXC_TOKID_NUM, nSpaces );
Append( fValue );
}
void XclExpFmlaCompImpl::AppendBoolToken( bool bValue, sal_uInt8 nSpaces )
{
- AppendOpTokenId( EXC_TOKID_BOOL, EXC_TOKCLASS_NONE, nSpaces );
+ AppendOperandTokenId( EXC_TOKID_BOOL, nSpaces );
Append( bValue ? EXC_TOK_BOOL_TRUE : EXC_TOK_BOOL_FALSE );
}
void XclExpFmlaCompImpl::AppendErrorToken( sal_uInt8 nErrCode, sal_uInt8 nSpaces )
{
- AppendOpTokenId( EXC_TOKID_ERR, EXC_TOKCLASS_NONE, nSpaces );
+ AppendOperandTokenId( EXC_TOKID_ERR, nSpaces );
Append( nErrCode );
}
void XclExpFmlaCompImpl::AppendMissingToken( sal_uInt8 nSpaces )
{
- AppendOpTokenId( EXC_TOKID_MISSARG, EXC_TOKCLASS_NONE, nSpaces );
+ AppendOperandTokenId( EXC_TOKID_MISSARG, nSpaces );
}
-void XclExpFmlaCompImpl::AppendNameToken( sal_uInt16 nNameIdx, sal_uInt8 nExpClass, sal_uInt8 nSpaces )
+void XclExpFmlaCompImpl::AppendNameToken( sal_uInt16 nNameIdx, sal_uInt8 nSpaces )
{
if( nNameIdx > 0 )
{
- AppendOpTokenId( GetTokenId( EXC_TOKID_NAME, EXC_TOKCLASS_REF ), nExpClass, nSpaces );
+ AppendOperandTokenId( GetTokenId( EXC_TOKID_NAME, EXC_TOKCLASS_REF ), nSpaces );
Append( nNameIdx );
Append( 0, (meBiff <= EXC_BIFF5) ? 12 : 2 );
}
@@ -2315,15 +2320,15 @@ void XclExpFmlaCompImpl::AppendNameToken( sal_uInt16 nNameIdx, sal_uInt8 nExpCla
AppendErrorToken( EXC_ERR_NAME );
}
-void XclExpFmlaCompImpl::AppendMissingNameToken( const String& rName, sal_uInt8 nExpClass, sal_uInt8 nSpaces )
+void XclExpFmlaCompImpl::AppendMissingNameToken( const String& rName, sal_uInt8 nSpaces )
{
sal_uInt16 nNameIdx = GetNameManager().InsertRawName( rName );
- AppendNameToken( nNameIdx, nExpClass, nSpaces );
+ AppendNameToken( nNameIdx, nSpaces );
}
-void XclExpFmlaCompImpl::AppendNameXToken( sal_uInt16 nExtSheet, sal_uInt16 nExtName, sal_uInt8 nExpClass, sal_uInt8 nSpaces )
+void XclExpFmlaCompImpl::AppendNameXToken( sal_uInt16 nExtSheet, sal_uInt16 nExtName, sal_uInt8 nSpaces )
{
- AppendOpTokenId( GetTokenId( EXC_TOKID_NAMEX, EXC_TOKCLASS_REF ), nExpClass, nSpaces );
+ AppendOperandTokenId( GetTokenId( EXC_TOKID_NAMEX, EXC_TOKCLASS_REF ), nSpaces );
Append( nExtSheet );
if( meBiff <= EXC_BIFF5 )
Append( 0, 8 );
@@ -2331,34 +2336,94 @@ void XclExpFmlaCompImpl::AppendNameXToken( sal_uInt16 nExtSheet, sal_uInt16 nExt
Append( 0, (meBiff <= EXC_BIFF5) ? 12 : 2 );
}
-void XclExpFmlaCompImpl::AppendMacroCallToken( const XclExpExtFuncData& rExtFuncData, sal_uInt8 nExpClass, sal_uInt8 nSpaces )
+void XclExpFmlaCompImpl::AppendMacroCallToken( const XclExpExtFuncData& rExtFuncData, sal_uInt8 nSpaces )
{
sal_uInt16 nNameIdx = GetNameManager().InsertMacroCall( rExtFuncData.maFuncName, rExtFuncData.mbVBasic, true, rExtFuncData.mbHidden );
- AppendNameToken( nNameIdx, nExpClass, nSpaces );
+ AppendNameToken( nNameIdx, nSpaces );
}
-void XclExpFmlaCompImpl::AppendAddInFuncToken( const XclExpExtFuncData& rExtFuncData, sal_uInt8 nExpClass, sal_uInt8 nSpaces )
+void XclExpFmlaCompImpl::AppendAddInCallToken( const XclExpExtFuncData& rExtFuncData, sal_uInt8 nSpaces )
{
String aXclFuncName;
- if( ScGlobal::GetAddInCollection()->GetExcelName( rExtFuncData.maFuncName, GetUILanguage(), aXclFuncName ) )
+ if( mxData->mpLinkMgr && ScGlobal::GetAddInCollection()->GetExcelName( rExtFuncData.maFuncName, GetUILanguage(), aXclFuncName ) )
{
sal_uInt16 nExtSheet, nExtName;
- if( mpLinkMgr && mpLinkMgr->InsertAddIn( nExtSheet, nExtName, aXclFuncName ) )
+ if( mxData->mpLinkMgr->InsertAddIn( nExtSheet, nExtName, aXclFuncName ) )
{
- AppendNameXToken( nExtSheet, nExtName, nExpClass, nSpaces );
+ AppendNameXToken( nExtSheet, nExtName, nSpaces );
return;
}
}
- AppendMacroCallToken( rExtFuncData, nExpClass, nSpaces );
+ AppendMacroCallToken( rExtFuncData, nSpaces );
}
-void XclExpFmlaCompImpl::AppendEuroToolFuncToken( const XclExpExtFuncData& rExtFuncData, sal_uInt8 nExpClass, sal_uInt8 nSpaces )
+void XclExpFmlaCompImpl::AppendEuroToolCallToken( const XclExpExtFuncData& rExtFuncData, sal_uInt8 nSpaces )
{
sal_uInt16 nExtSheet, nExtName;
- if( mpLinkMgr && mpLinkMgr->InsertEuroTool( nExtSheet, nExtName, rExtFuncData.maFuncName ) )
- AppendNameXToken( nExtSheet, nExtName, nExpClass, nSpaces );
+ if( mxData->mpLinkMgr && mxData->mpLinkMgr->InsertEuroTool( nExtSheet, nExtName, rExtFuncData.maFuncName ) )
+ AppendNameXToken( nExtSheet, nExtName, nSpaces );
+ else
+ AppendMacroCallToken( rExtFuncData, nSpaces );
+}
+
+void XclExpFmlaCompImpl::AppendOperatorTokenId( sal_uInt8 nTokenId, const XclExpOperandListRef& rxOperands, sal_uInt8 nSpaces )
+{
+ AppendSpaceToken( EXC_TOK_ATTR_SPACE_SP, nSpaces );
+ PushOperatorPos( GetSize(), rxOperands );
+ Append( nTokenId );
+}
+
+void XclExpFmlaCompImpl::AppendUnaryOperatorToken( sal_uInt8 nTokenId, sal_uInt8 nSpaces )
+{
+ XclExpOperandListRef xOperands( new XclExpOperandList );
+ xOperands->AppendOperand( PopOperandPos(), EXC_PARAMCONV_RPO, true );
+ AppendOperatorTokenId( nTokenId, xOperands, nSpaces );
+}
+
+void XclExpFmlaCompImpl::AppendBinaryOperatorToken( sal_uInt8 nTokenId, bool bValType, sal_uInt8 nSpaces )
+{
+ XclExpOperandListRef xOperands( new XclExpOperandList );
+ xOperands->AppendOperand( PopOperandPos(), EXC_PARAMCONV_RPO, bValType );
+ xOperands->AppendOperand( PopOperandPos(), EXC_PARAMCONV_RPO, bValType );
+ AppendOperatorTokenId( nTokenId, xOperands, nSpaces );
+}
+
+void XclExpFmlaCompImpl::AppendLogicalOperatorToken( sal_uInt16 nXclFuncIdx, sal_uInt8 nOpCount )
+{
+ XclExpOperandListRef xOperands( new XclExpOperandList );
+ for( sal_uInt8 nOpIdx = 0; nOpIdx < nOpCount; ++nOpIdx )
+ xOperands->AppendOperand( PopOperandPos(), EXC_PARAMCONV_RPX, false );
+ AppendOperatorTokenId( GetTokenId( EXC_TOKID_FUNCVAR, EXC_TOKCLASS_VAL ), xOperands );
+ Append( nOpCount );
+ Append( nXclFuncIdx );
+}
+
+void XclExpFmlaCompImpl::AppendFuncToken( const XclExpFuncData& rFuncData )
+{
+ sal_uInt16 nXclFuncIdx = rFuncData.GetXclFuncIdx();
+ sal_uInt8 nParamCount = rFuncData.GetParamCount();
+ sal_uInt8 nRetClass = rFuncData.GetReturnClass();
+
+ if( (nXclFuncIdx == EXC_FUNCID_SUM) && (nParamCount == 1) )
+ {
+ // SUM with only one parameter
+ AppendOperatorTokenId( EXC_TOKID_ATTR, rFuncData.GetOperandList() );
+ Append( EXC_TOK_ATTR_SUM );
+ Append( sal_uInt16( 0 ) );
+ }
+ else if( rFuncData.IsFixedParamCount() )
+ {
+ // fixed number of parameters
+ AppendOperatorTokenId( GetTokenId( EXC_TOKID_FUNC, nRetClass ), rFuncData.GetOperandList() );
+ Append( nXclFuncIdx );
+ }
else
- AppendMacroCallToken( rExtFuncData, nExpClass, nSpaces );
+ {
+ // variable number of parameters
+ AppendOperatorTokenId( GetTokenId( EXC_TOKID_FUNCVAR, nRetClass ), rFuncData.GetOperandList() );
+ Append( nParamCount );
+ Append( nXclFuncIdx );
+ }
}
void XclExpFmlaCompImpl::AppendParenToken( sal_uInt8 nOpenSpaces, sal_uInt8 nCloseSpaces )
@@ -2378,16 +2443,31 @@ void XclExpFmlaCompImpl::AppendJumpToken( XclExpFuncData& rFuncData, sal_uInt8 n
Append( sal_uInt16( 0 ) ); // placeholder that will be updated later
}
-void XclExpFmlaCompImpl::Insert( sal_uInt16 nInsertPos, sal_uInt16 nInsertSize )
+void XclExpFmlaCompImpl::InsertZeros( sal_uInt16 nInsertPos, sal_uInt16 nInsertSize )
{
- DBG_ASSERT( nInsertPos < maTokVec.size(), "XclExpFmlaCompImpl::Insert - invalid position" );
- maTokVec.insert( maTokVec.begin() + nInsertPos, nInsertSize, 0 );
+ // insert zeros into the token array
+ DBG_ASSERT( nInsertPos < mxData->maTokVec.size(), "XclExpFmlaCompImpl::Insert - invalid position" );
+ mxData->maTokVec.insert( mxData->maTokVec.begin() + nInsertPos, nInsertSize, 0 );
+
+ // update positions of operands waiting for an operator
+ for( ScfUInt16Vec::iterator aIt = mxData->maOpPosStack.begin(), aEnd = mxData->maOpPosStack.end(); aIt != aEnd; ++aIt )
+ if( nInsertPos <= *aIt )
+ *aIt = *aIt + nInsertSize;
+
+ // update operand lists of all operator tokens
+ if( nInsertPos < mxData->maOpListVec.size() )
+ mxData->maOpListVec.insert( mxData->maOpListVec.begin() + nInsertPos, nInsertSize, XclExpOperandListRef() );
+ for( XclExpOperandListVector::iterator aIt = mxData->maOpListVec.begin(), aEnd = mxData->maOpListVec.end(); aIt != aEnd; ++aIt )
+ if( aIt->get() )
+ for( XclExpOperandList::iterator aIt2 = (*aIt)->begin(), aEnd2 = (*aIt)->end(); aIt2 != aEnd2; ++aIt2 )
+ if( nInsertPos <= aIt2->mnTokPos )
+ aIt2->mnTokPos = aIt2->mnTokPos + nInsertSize;
}
void XclExpFmlaCompImpl::Overwrite( sal_uInt16 nWriteToPos, sal_uInt16 nOffset )
{
- DBG_ASSERT( static_cast< size_t >( nWriteToPos + 1 ) < maTokVec.size(), "XclExpFmlaCompImpl::Overwrite - invalid position" );
- ShortToSVBT16( nOffset, &maTokVec[ nWriteToPos ] );
+ DBG_ASSERT( static_cast< size_t >( nWriteToPos + 1 ) < mxData->maTokVec.size(), "XclExpFmlaCompImpl::Overwrite - invalid position" );
+ ShortToSVBT16( nOffset, &mxData->maTokVec[ nWriteToPos ] );
}
void XclExpFmlaCompImpl::UpdateAttrGoto( sal_uInt16 nAttrPos )
@@ -2403,19 +2483,49 @@ void XclExpFmlaCompImpl::UpdateAttrGoto( sal_uInt16 nAttrPos )
bool XclExpFmlaCompImpl::IsSpaceToken( sal_uInt16 nPos ) const
{
return
- (static_cast< size_t >( nPos + 4 ) <= maTokVec.size()) &&
- (maTokVec[ nPos ] == EXC_TOKID_ATTR) &&
- (maTokVec[ nPos + 1 ] == EXC_TOK_ATTR_SPACE);
+ (static_cast< size_t >( nPos + 4 ) <= mxData->maTokVec.size()) &&
+ (mxData->maTokVec[ nPos ] == EXC_TOKID_ATTR) &&
+ (mxData->maTokVec[ nPos + 1 ] == EXC_TOK_ATTR_SPACE);
}
void XclExpFmlaCompImpl::RemoveTrailingParen()
{
// remove trailing tParen token
- if( !maTokVec.empty() && (maTokVec.back() == EXC_TOKID_PAREN) )
- maTokVec.pop_back();
+ if( !mxData->maTokVec.empty() && (mxData->maTokVec.back() == EXC_TOKID_PAREN) )
+ mxData->maTokVec.pop_back();
// remove remaining tAttrSpace tokens
- while( (maTokVec.size() >= 4) && IsSpaceToken( GetSize() - 4 ) )
- maTokVec.erase( maTokVec.end() - 4, maTokVec.end() );
+ while( (mxData->maTokVec.size() >= 4) && IsSpaceToken( GetSize() - 4 ) )
+ mxData->maTokVec.erase( mxData->maTokVec.end() - 4, mxData->maTokVec.end() );
+}
+
+void XclExpFmlaCompImpl::AppendExt( sal_uInt8 nData )
+{
+ mxData->maExtDataVec.push_back( nData );
+}
+
+void XclExpFmlaCompImpl::AppendExt( sal_uInt8 nData, size_t nCount )
+{
+ mxData->maExtDataVec.resize( mxData->maExtDataVec.size() + nCount, nData );
+}
+
+void XclExpFmlaCompImpl::AppendExt( sal_uInt16 nData )
+{
+ lclAppend( mxData->maExtDataVec, nData );
+}
+
+void XclExpFmlaCompImpl::AppendExt( sal_uInt32 nData )
+{
+ lclAppend( mxData->maExtDataVec, nData );
+}
+
+void XclExpFmlaCompImpl::AppendExt( double fData )
+{
+ lclAppend( mxData->maExtDataVec, fData );
+}
+
+void XclExpFmlaCompImpl::AppendExt( const String& rString )
+{
+ lclAppend( mxData->maExtDataVec, GetRoot(), rString, (meBiff == EXC_BIFF8) ? EXC_STR_DEFAULT : EXC_STR_8BITLENGTH );
}
// ============================================================================
@@ -2530,29 +2640,5 @@ XclTokenArrayRef XclExpFormulaCompiler::CreateNameXFormula(
return mxImpl->CreateNameXFormula( nExtSheet, nExtName );
}
-void XclExpFmlaCompImpl::ProcessMatrix( const XclExpTokenData& rTokData, sal_uInt8 nExpClass )
-{
- const ScMatrix* pMatrix = static_cast<const ScToken*>(rTokData.mpScToken)->GetMatrix();
- if( maCfg.mbAllowArrays && pMatrix )
- {
- SCSIZE nCols, nRows;
- pMatrix->GetDimensions( nCols, nRows );
-
- AppendOpTokenId( GetTokenId( EXC_TOKID_ARRAY, EXC_TOKCLASS_ARR ), nExpClass, rTokData.mnSpaces );
- Append( static_cast< sal_uInt8 >( (meBiff == EXC_BIFF8) ? (nCols - 1) : nCols ) );
- Append( static_cast< sal_uInt16 >( (meBiff == EXC_BIFF8) ? (nRows - 1) : nRows ) );
- Append( static_cast< sal_uInt32 >( 0 ) );
-
- if( !mxInlineArr )
- mxInlineArr.reset( new ScMatrixList );
- mxInlineArr->push_front( pMatrix ); // save it for later
- }
- else
- {
- // Array in places that do not allow it (cond fmts, data validation)
- AppendErrorToken( EXC_ERR_NA, rTokData.mnSpaces );
- }
-}
-
// ============================================================================
diff --git a/sc/source/filter/excel/xlformula.cxx b/sc/source/filter/excel/xlformula.cxx
index 2e15a39e68dd..5e6c85b49077 100644
--- a/sc/source/filter/excel/xlformula.cxx
+++ b/sc/source/filter/excel/xlformula.cxx
@@ -30,16 +30,23 @@
// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_sc.hxx"
+
+// XXX xestream.hxx MUST be included before xlformula.hxx because of the
+// redifinition of the CREATE_OUSTRING() macro, which is in oox/helper.hxx
+// (indirectly included via xestream.hxx) and ../inc/ftools.hxx (indirectly
+// included via xlformula.hxx) that does an undef first. Ugly.
#include "xestream.hxx"
#include "xlformula.hxx"
+
#include "compiler.hxx"
#include "rangenam.hxx"
-#include "xlroot.hxx"
-#include "xistream.hxx"
#include "token.hxx"
#include "tokenarray.hxx"
+#include "xistream.hxx"
+#include "xlroot.hxx"
+
+using namespace ::formula;
-using namespace formula;
// Function data ==============================================================
String XclFunctionInfo::GetMacroFuncName() const
@@ -49,278 +56,291 @@ String XclFunctionInfo::GetMacroFuncName() const
return EMPTY_STRING;
}
+// abbreviations for function return token class
const sal_uInt8 R = EXC_TOKCLASS_REF;
const sal_uInt8 V = EXC_TOKCLASS_VAL;
const sal_uInt8 A = EXC_TOKCLASS_ARR;
-const sal_uInt8 C = EXC_FUNC_PAR_CALCONLY;
-const sal_uInt8 E = EXC_FUNC_PAR_EXCELONLY;
-const sal_uInt8 I = EXC_FUNC_PAR_INVALID;
+
+// abbreviations for parameter infos
+#define RO { EXC_PARAM_REGULAR, EXC_PARAMCONV_ORG, false }
+#define RV { EXC_PARAM_REGULAR, EXC_PARAMCONV_VAL, false }
+#define RA { EXC_PARAM_REGULAR, EXC_PARAMCONV_ARR, false }
+#define RR { EXC_PARAM_REGULAR, EXC_PARAMCONV_RPT, false }
+#define RX { EXC_PARAM_REGULAR, EXC_PARAMCONV_RPX, false }
+#define VO { EXC_PARAM_REGULAR, EXC_PARAMCONV_ORG, true }
+#define VV { EXC_PARAM_REGULAR, EXC_PARAMCONV_VAL, true }
+#define VA { EXC_PARAM_REGULAR, EXC_PARAMCONV_ARR, true }
+#define VR { EXC_PARAM_REGULAR, EXC_PARAMCONV_RPT, true }
+#define VX { EXC_PARAM_REGULAR, EXC_PARAMCONV_RPX, true }
+#define RO_E { EXC_PARAM_EXCELONLY, EXC_PARAMCONV_ORG, false }
+#define VR_E { EXC_PARAM_EXCELONLY, EXC_PARAMCONV_RPT, true }
+#define C { EXC_PARAM_CALCONLY, EXC_PARAMCONV_ORG, false }
/** Functions new in BIFF2. */
static const XclFunctionInfo saFuncTable_2[] =
{
- { ocCount, 0, 0, 30, V, { R }, 0, 0 },
- { ocIf, 1, 2, 3, R, { V, R }, 0, 0 },
- { ocIsNA, 2, 1, 1, V, { V }, 0, 0 },
- { ocIsError, 3, 1, 1, V, { V }, 0, 0 },
- { ocSum, 4, 0, 30, V, { R }, 0, 0 },
- { ocAverage, 5, 1, 30, V, { R }, 0, 0 },
- { ocMin, 6, 1, 30, V, { R }, 0, 0 },
- { ocMax, 7, 1, 30, V, { R }, 0, 0 },
- { ocRow, 8, 0, 1, V, { R }, 0, 0 },
- { ocColumn, 9, 0, 1, V, { R }, 0, 0 },
+ { ocCount, 0, 0, 30, V, { RX }, 0, 0 },
+ { ocIf, 1, 2, 3, R, { VO, RO }, 0, 0 },
+ { ocIsNA, 2, 1, 1, V, { VR }, 0, 0 },
+ { ocIsError, 3, 1, 1, V, { VR }, 0, 0 },
+ { ocSum, 4, 0, 30, V, { RX }, 0, 0 },
+ { ocAverage, 5, 1, 30, V, { RX }, 0, 0 },
+ { ocMin, 6, 1, 30, V, { RX }, 0, 0 },
+ { ocMax, 7, 1, 30, V, { RX }, 0, 0 },
+ { ocRow, 8, 0, 1, V, { RO }, 0, 0 },
+ { ocColumn, 9, 0, 1, V, { RO }, 0, 0 },
{ ocNotAvail, 10, 0, 0, V, {}, 0, 0 },
- { ocNPV, 11, 2, 30, V, { V, R }, 0, 0 },
- { ocStDev, 12, 1, 30, V, { R }, 0, 0 },
- { ocCurrency, 13, 1, 2, V, { V }, 0, 0 },
- { ocFixed, 14, 1, 2, V, { V, V, C, I }, 0, 0 },
- { ocSin, 15, 1, 1, V, { V }, 0, 0 },
- { ocCos, 16, 1, 1, V, { V }, 0, 0 },
- { ocTan, 17, 1, 1, V, { V }, 0, 0 },
- { ocCot, 17, 1, 1, V, { V }, EXC_FUNCFLAG_EXPORTONLY, 0 },
- { ocArcTan, 18, 1, 1, V, { V }, 0, 0 },
- { ocArcCot, 18, 1, 1, V, { V }, EXC_FUNCFLAG_EXPORTONLY, 0 },
+ { ocNPV, 11, 2, 30, V, { VR, RX }, 0, 0 },
+ { ocStDev, 12, 1, 30, V, { RX }, 0, 0 },
+ { ocCurrency, 13, 1, 2, V, { VR }, 0, 0 },
+ { ocFixed, 14, 1, 2, V, { VR, VR, C }, 0, 0 },
+ { ocSin, 15, 1, 1, V, { VR }, 0, 0 },
+ { ocCos, 16, 1, 1, V, { VR }, 0, 0 },
+ { ocTan, 17, 1, 1, V, { VR }, 0, 0 },
+ { ocCot, 17, 1, 1, V, { VR }, EXC_FUNCFLAG_EXPORTONLY, 0 },
+ { ocArcTan, 18, 1, 1, V, { VR }, 0, 0 },
+ { ocArcCot, 18, 1, 1, V, { VR }, EXC_FUNCFLAG_EXPORTONLY, 0 },
{ ocPi, 19, 0, 0, V, {}, 0, 0 },
- { ocSqrt, 20, 1, 1, V, { V }, 0, 0 },
- { ocExp, 21, 1, 1, V, { V }, 0, 0 },
- { ocLn, 22, 1, 1, V, { V }, 0, 0 },
- { ocLog10, 23, 1, 1, V, { V }, 0, 0 },
- { ocAbs, 24, 1, 1, V, { V }, 0, 0 },
- { ocInt, 25, 1, 1, V, { V }, 0, 0 },
- { ocPlusMinus, 26, 1, 1, V, { V }, 0, 0 },
- { ocRound, 27, 2, 2, V, { V }, 0, 0 },
- { ocLookup, 28, 2, 3, V, { V, R }, 0, 0 },
- { ocIndex, 29, 2, 4, R, { R, V }, 0, 0 },
- { ocRept, 30, 2, 2, V, { V }, 0, 0 },
- { ocMid, 31, 3, 3, V, { V }, 0, 0 },
- { ocLen, 32, 1, 1, V, { V }, 0, 0 },
- { ocValue, 33, 1, 1, V, { V }, 0, 0 },
+ { ocSqrt, 20, 1, 1, V, { VR }, 0, 0 },
+ { ocExp, 21, 1, 1, V, { VR }, 0, 0 },
+ { ocLn, 22, 1, 1, V, { VR }, 0, 0 },
+ { ocLog10, 23, 1, 1, V, { VR }, 0, 0 },
+ { ocAbs, 24, 1, 1, V, { VR }, 0, 0 },
+ { ocInt, 25, 1, 1, V, { VR }, 0, 0 },
+ { ocPlusMinus, 26, 1, 1, V, { VR }, 0, 0 },
+ { ocRound, 27, 2, 2, V, { VR }, 0, 0 },
+ { ocLookup, 28, 2, 3, V, { VR, RA }, 0, 0 },
+ { ocIndex, 29, 2, 4, R, { RA, VV }, 0, 0 },
+ { ocRept, 30, 2, 2, V, { VR }, 0, 0 },
+ { ocMid, 31, 3, 3, V, { VR }, 0, 0 },
+ { ocLen, 32, 1, 1, V, { VR }, 0, 0 },
+ { ocValue, 33, 1, 1, V, { VR }, 0, 0 },
{ ocTrue, 34, 0, 0, V, {}, 0, 0 },
{ ocFalse, 35, 0, 0, V, {}, 0, 0 },
- { ocAnd, 36, 1, 30, V, { R }, 0, 0 },
- { ocOr, 37, 1, 30, V, { R }, 0, 0 },
- { ocNot, 38, 1, 1, V, { V }, 0, 0 },
- { ocMod, 39, 2, 2, V, { V }, 0, 0 },
- { ocDBCount, 40, 3, 3, V, { R }, 0, 0 },
- { ocDBSum, 41, 3, 3, V, { R }, 0, 0 },
- { ocDBAverage, 42, 3, 3, V, { R }, 0, 0 },
- { ocDBMin, 43, 3, 3, V, { R }, 0, 0 },
- { ocDBMax, 44, 3, 3, V, { R }, 0, 0 },
- { ocDBStdDev, 45, 3, 3, V, { R }, 0, 0 },
- { ocVar, 46, 1, 30, V, { R }, 0, 0 },
- { ocDBVar, 47, 3, 3, V, { R }, 0, 0 },
- { ocText, 48, 2, 2, V, { V }, 0, 0 },
- { ocRGP, 49, 1, 2, A, { R, R, C, C, I }, 0, 0 },
- { ocTrend, 50, 1, 3, A, { R, R, R, C, I }, 0, 0 },
- { ocRKP, 51, 1, 2, A, { R, R, C, C, I }, 0, 0 },
- { ocGrowth, 52, 1, 3, A, { R, R, R, C, I }, 0, 0 },
- { ocBW, 56, 3, 5, V, { V }, 0, 0 },
- { ocZW, 57, 3, 5, V, { V }, 0, 0 },
- { ocZZR, 58, 3, 5, V, { V }, 0, 0 },
- { ocRMZ, 59, 3, 5, V, { V }, 0, 0 },
- { ocZins, 60, 3, 6, V, { V }, 0, 0 },
- { ocMIRR, 61, 3, 3, V, { R, V }, 0, 0 },
- { ocIRR, 62, 1, 2, V, { R, V }, 0, 0 },
+ { ocAnd, 36, 1, 30, V, { RX }, 0, 0 },
+ { ocOr, 37, 1, 30, V, { RX }, 0, 0 },
+ { ocNot, 38, 1, 1, V, { VR }, 0, 0 },
+ { ocMod, 39, 2, 2, V, { VR }, 0, 0 },
+ { ocDBCount, 40, 3, 3, V, { RO, RR }, 0, 0 },
+ { ocDBSum, 41, 3, 3, V, { RO, RR }, 0, 0 },
+ { ocDBAverage, 42, 3, 3, V, { RO, RR }, 0, 0 },
+ { ocDBMin, 43, 3, 3, V, { RO, RR }, 0, 0 },
+ { ocDBMax, 44, 3, 3, V, { RO, RR }, 0, 0 },
+ { ocDBStdDev, 45, 3, 3, V, { RO, RR }, 0, 0 },
+ { ocVar, 46, 1, 30, V, { RX }, 0, 0 },
+ { ocDBVar, 47, 3, 3, V, { RO, RR }, 0, 0 },
+ { ocText, 48, 2, 2, V, { VR }, 0, 0 },
+ { ocRGP, 49, 1, 2, A, { RA, RA, C, C }, 0, 0 },
+ { ocTrend, 50, 1, 3, A, { RA, RA, RA, C }, 0, 0 },
+ { ocRKP, 51, 1, 2, A, { RA, RA, C, C }, 0, 0 },
+ { ocGrowth, 52, 1, 3, A, { RA, RA, RA, C }, 0, 0 },
+ { ocBW, 56, 3, 5, V, { VR }, 0, 0 },
+ { ocZW, 57, 3, 5, V, { VR }, 0, 0 },
+ { ocZZR, 58, 3, 5, V, { VR }, 0, 0 },
+ { ocRMZ, 59, 3, 5, V, { VR }, 0, 0 },
+ { ocZins, 60, 3, 6, V, { VR }, 0, 0 },
+ { ocMIRR, 61, 3, 3, V, { RA, VR }, 0, 0 },
+ { ocIRR, 62, 1, 2, V, { RA, VR }, 0, 0 },
{ ocRandom, 63, 0, 0, V, {}, EXC_FUNCFLAG_VOLATILE, 0 },
- { ocMatch, 64, 2, 3, V, { V, R }, 0, 0 },
- { ocGetDate, 65, 3, 3, V, { V }, 0, 0 },
- { ocGetTime, 66, 3, 3, V, { V }, 0, 0 },
- { ocGetDay, 67, 1, 1, V, { V }, 0, 0 },
- { ocGetMonth, 68, 1, 1, V, { V }, 0, 0 },
- { ocGetYear, 69, 1, 1, V, { V }, 0, 0 },
- { ocGetDayOfWeek, 70, 1, 1, V, { V, C, I }, 0, 0 },
- { ocGetHour, 71, 1, 1, V, { V }, 0, 0 },
- { ocGetMin, 72, 1, 1, V, { V }, 0, 0 },
- { ocGetSec, 73, 1, 1, V, { V }, 0, 0 },
+ { ocMatch, 64, 2, 3, V, { VR, RX, RR }, 0, 0 },
+ { ocGetDate, 65, 3, 3, V, { VR }, 0, 0 },
+ { ocGetTime, 66, 3, 3, V, { VR }, 0, 0 },
+ { ocGetDay, 67, 1, 1, V, { VR }, 0, 0 },
+ { ocGetMonth, 68, 1, 1, V, { VR }, 0, 0 },
+ { ocGetYear, 69, 1, 1, V, { VR }, 0, 0 },
+ { ocGetDayOfWeek, 70, 1, 1, V, { VR, C }, 0, 0 },
+ { ocGetHour, 71, 1, 1, V, { VR }, 0, 0 },
+ { ocGetMin, 72, 1, 1, V, { VR }, 0, 0 },
+ { ocGetSec, 73, 1, 1, V, { VR }, 0, 0 },
{ ocGetActTime, 74, 0, 0, V, {}, EXC_FUNCFLAG_VOLATILE, 0 },
- { ocAreas, 75, 1, 1, V, { R }, 0, 0 },
- { ocRows, 76, 1, 1, V, { R }, 0, 0 },
- { ocColumns, 77, 1, 1, V, { R }, 0, 0 },
- { ocOffset, 78, 3, 5, R, { R, V }, EXC_FUNCFLAG_VOLATILE, 0 },
- { ocSearch, 82, 2, 3, V, { V }, 0, 0 },
- { ocMatTrans, 83, 1, 1, A, { A }, 0, 0 },
- { ocType, 86, 1, 1, V, { V }, 0, 0 },
- { ocArcTan2, 97, 2, 2, V, { V }, 0, 0 },
- { ocArcSin, 98, 1, 1, V, { V }, 0, 0 },
- { ocArcCos, 99, 1, 1, V, { V }, 0, 0 },
- { ocChose, 100, 2, 30, R, { V, R }, 0, 0 },
- { ocHLookup, 101, 3, 3, V, { V, R, R, C, I }, 0, 0 },
- { ocVLookup, 102, 3, 3, V, { V, R, R, C, I }, 0, 0 },
- { ocIsRef, 105, 1, 1, V, { R }, 0, 0 },
- { ocLog, 109, 1, 2, V, { V }, 0, 0 },
- { ocChar, 111, 1, 1, V, { V }, 0, 0 },
- { ocLower, 112, 1, 1, V, { V }, 0, 0 },
- { ocUpper, 113, 1, 1, V, { V }, 0, 0 },
- { ocPropper, 114, 1, 1, V, { V }, 0, 0 },
- { ocLeft, 115, 1, 2, V, { V }, 0, 0 },
- { ocRight, 116, 1, 2, V, { V }, 0, 0 },
- { ocExact, 117, 2, 2, V, { V }, 0, 0 },
- { ocTrim, 118, 1, 1, V, { V }, 0, 0 },
- { ocReplace, 119, 4, 4, V, { V }, 0, 0 },
- { ocSubstitute, 120, 3, 4, V, { V }, 0, 0 },
- { ocCode, 121, 1, 1, V, { V }, 0, 0 },
- { ocFind, 124, 2, 3, V, { V }, 0, 0 },
- { ocCell, 125, 1, 2, V, { V, R }, EXC_FUNCFLAG_VOLATILE, 0 },
- { ocIsErr, 126, 1, 1, V, { V }, 0, 0 },
- { ocIsString, 127, 1, 1, V, { V }, 0, 0 },
- { ocIsValue, 128, 1, 1, V, { V }, 0, 0 },
- { ocIsEmpty, 129, 1, 1, V, { V }, 0, 0 },
- { ocT, 130, 1, 1, V, { R }, 0, 0 },
- { ocN, 131, 1, 1, V, { R }, 0, 0 },
- { ocGetDateValue, 140, 1, 1, V, { V }, 0, 0 },
- { ocGetTimeValue, 141, 1, 1, V, { V }, 0, 0 },
- { ocLIA, 142, 3, 3, V, { V }, 0, 0 },
- { ocDIA, 143, 4, 4, V, { V }, 0, 0 },
- { ocGDA, 144, 4, 5, V, { V }, 0, 0 },
- { ocIndirect, 148, 1, 2, R, { V }, EXC_FUNCFLAG_VOLATILE, 0 },
- { ocClean, 162, 1, 1, V, { V }, 0, 0 },
- { ocMatDet, 163, 1, 1, V, { A }, 0, 0 },
- { ocMatInv, 164, 1, 1, A, { A }, 0, 0 },
- { ocMatMult, 165, 2, 2, A, { A }, 0, 0 },
- { ocZinsZ, 167, 4, 6, V, { V }, 0, 0 },
- { ocKapz, 168, 4, 6, V, { V }, 0, 0 },
- { ocCount2, 169, 0, 30, V, { R }, 0, 0 },
- { ocProduct, 183, 0, 30, V, { R }, 0, 0 },
- { ocFact, 184, 1, 1, V, { V }, 0, 0 },
- { ocDBProduct, 189, 3, 3, V, { R }, 0, 0 },
- { ocIsNonString, 190, 1, 1, V, { V }, 0, 0 },
- { ocStDevP, 193, 1, 30, V, { R }, 0, 0 },
- { ocVarP, 194, 1, 30, V, { R }, 0, 0 },
- { ocDBStdDevP, 195, 3, 3, V, { R }, 0, 0 },
- { ocDBVarP, 196, 3, 3, V, { R }, 0, 0 },
- { ocTrunc, 197, 1, 1, V, { V, C, I }, 0, 0 },
- { ocIsLogical, 198, 1, 1, V, { V }, 0, 0 },
- { ocDBCount2, 199, 3, 3, V, { R }, 0, 0 },
- { ocCurrency, 204, 1, 2, V, { V }, EXC_FUNCFLAG_IMPORTONLY, 0 },
- { ocRoundUp, 212, 2, 2, V, { V }, 0, 0 },
- { ocRoundDown, 213, 2, 2, V, { V }, 0, 0 },
- { ocExternal, 255, 1, 30, R, { E, R }, EXC_FUNCFLAG_IMPORTONLY, 0 }
+ { ocAreas, 75, 1, 1, V, { RO }, 0, 0 },
+ { ocRows, 76, 1, 1, V, { RO }, 0, 0 },
+ { ocColumns, 77, 1, 1, V, { RO }, 0, 0 },
+ { ocOffset, 78, 3, 5, R, { RO, VR }, EXC_FUNCFLAG_VOLATILE, 0 },
+ { ocSearch, 82, 2, 3, V, { VR }, 0, 0 },
+ { ocMatTrans, 83, 1, 1, A, { VO }, 0, 0 },
+ { ocType, 86, 1, 1, V, { VX }, 0, 0 },
+ { ocArcTan2, 97, 2, 2, V, { VR }, 0, 0 },
+ { ocArcSin, 98, 1, 1, V, { VR }, 0, 0 },
+ { ocArcCos, 99, 1, 1, V, { VR }, 0, 0 },
+ { ocChose, 100, 2, 30, R, { VO, RO }, 0, 0 },
+ { ocHLookup, 101, 3, 3, V, { VV, RO, RO, C }, 0, 0 },
+ { ocVLookup, 102, 3, 3, V, { VV, RO, RO, C }, 0, 0 },
+ { ocIsRef, 105, 1, 1, V, { RX }, 0, 0 },
+ { ocLog, 109, 1, 2, V, { VR }, 0, 0 },
+ { ocChar, 111, 1, 1, V, { VR }, 0, 0 },
+ { ocLower, 112, 1, 1, V, { VR }, 0, 0 },
+ { ocUpper, 113, 1, 1, V, { VR }, 0, 0 },
+ { ocPropper, 114, 1, 1, V, { VR }, 0, 0 },
+ { ocLeft, 115, 1, 2, V, { VR }, 0, 0 },
+ { ocRight, 116, 1, 2, V, { VR }, 0, 0 },
+ { ocExact, 117, 2, 2, V, { VR }, 0, 0 },
+ { ocTrim, 118, 1, 1, V, { VR }, 0, 0 },
+ { ocReplace, 119, 4, 4, V, { VR }, 0, 0 },
+ { ocSubstitute, 120, 3, 4, V, { VR }, 0, 0 },
+ { ocCode, 121, 1, 1, V, { VR }, 0, 0 },
+ { ocFind, 124, 2, 3, V, { VR }, 0, 0 },
+ { ocCell, 125, 1, 2, V, { VV, RO }, EXC_FUNCFLAG_VOLATILE, 0 },
+ { ocIsErr, 126, 1, 1, V, { VR }, 0, 0 },
+ { ocIsString, 127, 1, 1, V, { VR }, 0, 0 },
+ { ocIsValue, 128, 1, 1, V, { VR }, 0, 0 },
+ { ocIsEmpty, 129, 1, 1, V, { VR }, 0, 0 },
+ { ocT, 130, 1, 1, V, { RO }, 0, 0 },
+ { ocN, 131, 1, 1, V, { RO }, 0, 0 },
+ { ocGetDateValue, 140, 1, 1, V, { VR }, 0, 0 },
+ { ocGetTimeValue, 141, 1, 1, V, { VR }, 0, 0 },
+ { ocLIA, 142, 3, 3, V, { VR }, 0, 0 },
+ { ocDIA, 143, 4, 4, V, { VR }, 0, 0 },
+ { ocGDA, 144, 4, 5, V, { VR }, 0, 0 },
+ { ocIndirect, 148, 1, 2, R, { VR }, EXC_FUNCFLAG_VOLATILE, 0 },
+ { ocClean, 162, 1, 1, V, { VR }, 0, 0 },
+ { ocMatDet, 163, 1, 1, V, { VA }, 0, 0 },
+ { ocMatInv, 164, 1, 1, A, { VA }, 0, 0 },
+ { ocMatMult, 165, 2, 2, A, { VA }, 0, 0 },
+ { ocZinsZ, 167, 4, 6, V, { VR }, 0, 0 },
+ { ocKapz, 168, 4, 6, V, { VR }, 0, 0 },
+ { ocCount2, 169, 0, 30, V, { RX }, 0, 0 },
+ { ocProduct, 183, 0, 30, V, { RX }, 0, 0 },
+ { ocFact, 184, 1, 1, V, { VR }, 0, 0 },
+ { ocDBProduct, 189, 3, 3, V, { RO, RR }, 0, 0 },
+ { ocIsNonString, 190, 1, 1, V, { VR }, 0, 0 },
+ { ocStDevP, 193, 1, 30, V, { RX }, 0, 0 },
+ { ocVarP, 194, 1, 30, V, { RX }, 0, 0 },
+ { ocDBStdDevP, 195, 3, 3, V, { RO, RR }, 0, 0 },
+ { ocDBVarP, 196, 3, 3, V, { RO, RR }, 0, 0 },
+ { ocTrunc, 197, 1, 1, V, { VR, C }, 0, 0 },
+ { ocIsLogical, 198, 1, 1, V, { VR }, 0, 0 },
+ { ocDBCount2, 199, 3, 3, V, { RO, RR }, 0, 0 },
+ { ocCurrency, 204, 1, 2, V, { VR }, EXC_FUNCFLAG_IMPORTONLY, 0 },
+ { ocRoundUp, 212, 2, 2, V, { VR }, 0, 0 },
+ { ocRoundDown, 213, 2, 2, V, { VR }, 0, 0 },
+ { ocExternal, 255, 1, 30, R, { RO_E, RO }, EXC_FUNCFLAG_IMPORTONLY, 0 }
};
/** Functions new in BIFF3. */
static const XclFunctionInfo saFuncTable_3[] =
{
- { ocRGP, 49, 1, 4, A, { R, R, V, V }, 0, 0 }, // BIFF2: 1-2, BIFF3: 1-4
- { ocTrend, 50, 1, 4, A, { R, R, R, V }, 0, 0 }, // BIFF2: 1-3, BIFF3: 1-4
- { ocRKP, 51, 1, 4, A, { R, R, V, V }, 0, 0 }, // BIFF2: 1-2, BIFF3: 1-4
- { ocGrowth, 52, 1, 4, A, { R, R, R, V }, 0, 0 }, // BIFF2: 1-3, BIFF3: 1-4
- { ocTrunc, 197, 1, 2, V, { V }, 0, 0 }, // BIFF2: 1, BIFF3: 1-2
- { ocAddress, 219, 2, 5, V, { V, V, V, V, V }, 0, 0 },
- { ocGetDiffDate360, 220, 2, 2, V, { V, V, C, I }, 0, 0 },
+ { ocRGP, 49, 1, 4, A, { RA, RA, VV }, 0, 0 }, // BIFF2: 1-2, BIFF3: 1-4
+ { ocTrend, 50, 1, 4, A, { RA, RA, RA, VV }, 0, 0 }, // BIFF2: 1-3, BIFF3: 1-4
+ { ocRKP, 51, 1, 4, A, { RA, RA, VV }, 0, 0 }, // BIFF2: 1-2, BIFF3: 1-4
+ { ocGrowth, 52, 1, 4, A, { RA, RA, RA, VV }, 0, 0 }, // BIFF2: 1-3, BIFF3: 1-4
+ { ocTrunc, 197, 1, 2, V, { VR }, 0, 0 }, // BIFF2: 1, BIFF3: 1-2
+ { ocAddress, 219, 2, 5, V, { VR }, 0, 0 },
+ { ocGetDiffDate360, 220, 2, 2, V, { VR, VR, C }, 0, 0 },
{ ocGetActDate, 221, 0, 0, V, {}, EXC_FUNCFLAG_VOLATILE, 0 },
- { ocVBD, 222, 5, 7, V, { V }, 0, 0 },
- { ocMedian, 227, 1, 30, V, { R }, 0, 0 },
- { ocSumProduct, 228, 1, 30, V, { A }, 0, 0 },
- { ocSinHyp, 229, 1, 1, V, { V }, 0, 0 },
- { ocCosHyp, 230, 1, 1, V, { V }, 0, 0 },
- { ocTanHyp, 231, 1, 1, V, { V }, 0, 0 },
- { ocCotHyp, 231, 1, 1, V, { V }, EXC_FUNCFLAG_EXPORTONLY, 0 },
- { ocArcSinHyp, 232, 1, 1, V, { V }, 0, 0 },
- { ocArcCosHyp, 233, 1, 1, V, { V }, 0, 0 },
- { ocArcTanHyp, 234, 1, 1, V, { V }, 0, 0 },
- { ocArcCotHyp, 234, 1, 1, V, { V }, EXC_FUNCFLAG_EXPORTONLY, 0 },
- { ocDBGet, 235, 3, 3, V, { R }, 0, 0 },
- { ocInfo, 244, 1, 1, V, { V }, EXC_FUNCFLAG_VOLATILE, 0 }
+ { ocVBD, 222, 5, 7, V, { VR }, 0, 0 },
+ { ocMedian, 227, 1, 30, V, { RX }, 0, 0 },
+ { ocSumProduct, 228, 1, 30, V, { VA }, 0, 0 },
+ { ocSinHyp, 229, 1, 1, V, { VR }, 0, 0 },
+ { ocCosHyp, 230, 1, 1, V, { VR }, 0, 0 },
+ { ocTanHyp, 231, 1, 1, V, { VR }, 0, 0 },
+ { ocCotHyp, 231, 1, 1, V, { VR }, EXC_FUNCFLAG_EXPORTONLY, 0 },
+ { ocArcSinHyp, 232, 1, 1, V, { VR }, 0, 0 },
+ { ocArcCosHyp, 233, 1, 1, V, { VR }, 0, 0 },
+ { ocArcTanHyp, 234, 1, 1, V, { VR }, 0, 0 },
+ { ocArcCotHyp, 234, 1, 1, V, { VR }, EXC_FUNCFLAG_EXPORTONLY, 0 },
+ { ocDBGet, 235, 3, 3, V, { RO, RR }, 0, 0 },
+ { ocInfo, 244, 1, 1, V, { VR }, EXC_FUNCFLAG_VOLATILE, 0 }
};
/** Functions new in BIFF4. */
static const XclFunctionInfo saFuncTable_4[] =
{
- { ocFixed, 14, 1, 3, V, { V }, 0, 0 }, // BIFF2-3: 1-2, BIFF4: 1-3
- { ocAsc, 214, 1, 1, V, { V }, 0, 0 },
- { ocJis, 215, 1, 1, V, { V }, 0, 0 },
- { ocRank, 216, 2, 3, V, { V, R, V }, 0, 0 },
- { ocGDA2, 247, 4, 5, V, { V }, 0, 0 },
- { ocFrequency, 252, 2, 2, A, { R }, 0, 0 },
- { ocErrorType, 261, 1, 1, V, { V }, 0, 0 },
- { ocAveDev, 269, 1, 30, V, { R }, 0, 0 },
- { ocBetaDist, 270, 3, 5, V, { V }, 0, 0 },
- { ocGammaLn, 271, 1, 1, V, { V }, 0, 0 },
- { ocBetaInv, 272, 3, 5, V, { V }, 0, 0 },
- { ocBinomDist, 273, 4, 4, V, { V }, 0, 0 },
- { ocChiDist, 274, 2, 2, V, { V }, 0, 0 },
- { ocChiInv, 275, 2, 2, V, { V }, 0, 0 },
- { ocKombin, 276, 2, 2, V, { V }, 0, 0 },
- { ocConfidence, 277, 3, 3, V, { V }, 0, 0 },
- { ocKritBinom, 278, 3, 3, V, { V }, 0, 0 },
- { ocEven, 279, 1, 1, V, { V }, 0, 0 },
- { ocExpDist, 280, 3, 3, V, { V }, 0, 0 },
- { ocFDist, 281, 3, 3, V, { V }, 0, 0 },
- { ocFInv, 282, 3, 3, V, { V }, 0, 0 },
- { ocFisher, 283, 1, 1, V, { V }, 0, 0 },
- { ocFisherInv, 284, 1, 1, V, { V }, 0, 0 },
- { ocFloor, 285, 2, 2, V, { V, V, C, I }, 0, 0 },
- { ocGammaDist, 286, 4, 4, V, { V }, 0, 0 },
- { ocGammaInv, 287, 3, 3, V, { V }, 0, 0 },
- { ocCeil, 288, 2, 2, V, { V, V, C, I }, 0, 0 },
- { ocHypGeomDist, 289, 4, 4, V, { V }, 0, 0 },
- { ocLogNormDist, 290, 3, 3, V, { V }, 0, 0 },
- { ocLogInv, 291, 3, 3, V, { V }, 0, 0 },
- { ocNegBinomVert, 292, 3, 3, V, { V }, 0, 0 },
- { ocNormDist, 293, 4, 4, V, { V }, 0, 0 },
- { ocStdNormDist, 294, 1, 1, V, { V }, 0, 0 },
- { ocNormInv, 295, 3, 3, V, { V }, 0, 0 },
- { ocSNormInv, 296, 1, 1, V, { V }, 0, 0 },
- { ocStandard, 297, 3, 3, V, { V }, 0, 0 },
- { ocOdd, 298, 1, 1, V, { V }, 0, 0 },
- { ocVariationen, 299, 2, 2, V, { V }, 0, 0 },
- { ocPoissonDist, 300, 3, 3, V, { V }, 0, 0 },
- { ocTDist, 301, 3, 3, V, { V }, 0, 0 },
- { ocWeibull, 302, 4, 4, V, { V }, 0, 0 },
- { ocSumXMY2, 303, 2, 2, V, { A }, 0, 0 },
- { ocSumX2MY2, 304, 2, 2, V, { A }, 0, 0 },
- { ocSumX2DY2, 305, 2, 2, V, { A }, 0, 0 },
- { ocChiTest, 306, 2, 2, V, { A }, 0, 0 },
- { ocCorrel, 307, 2, 2, V, { A }, 0, 0 },
- { ocCovar, 308, 2, 2, V, { A }, 0, 0 },
- { ocForecast, 309, 3, 3, V, { V, A }, 0, 0 },
- { ocFTest, 310, 2, 2, V, { A }, 0, 0 },
- { ocIntercept, 311, 2, 2, V, { A }, 0, 0 },
- { ocPearson, 312, 2, 2, V, { A }, 0, 0 },
- { ocRSQ, 313, 2, 2, V, { A }, 0, 0 },
- { ocSTEYX, 314, 2, 2, V, { A }, 0, 0 },
- { ocSlope, 315, 2, 2, V, { A }, 0, 0 },
- { ocTTest, 316, 4, 4, V, { A, A, V }, 0, 0 },
- { ocProb, 317, 3, 4, V, { A, A, V }, 0, 0 },
- { ocDevSq, 318, 1, 30, V, { R }, 0, 0 },
- { ocGeoMean, 319, 1, 30, V, { R }, 0, 0 },
- { ocHarMean, 320, 1, 30, V, { R }, 0, 0 },
- { ocSumSQ, 321, 0, 30, V, { R }, 0, 0 },
- { ocKurt, 322, 1, 30, V, { R }, 0, 0 },
- { ocSchiefe, 323, 1, 30, V, { R }, 0, 0 },
- { ocZTest, 324, 2, 3, V, { R, V }, 0, 0 },
- { ocLarge, 325, 2, 2, V, { R, V }, 0, 0 },
- { ocSmall, 326, 2, 2, V, { R, V }, 0, 0 },
- { ocQuartile, 327, 2, 2, V, { R, V }, 0, 0 },
- { ocPercentile, 328, 2, 2, V, { R, V }, 0, 0 },
- { ocPercentrank, 329, 2, 3, V, { R, V }, 0, 0 },
- { ocModalValue, 330, 1, 30, V, { A }, 0, 0 },
- { ocTrimMean, 331, 2, 2, V, { R, V }, 0, 0 },
- { ocTInv, 332, 2, 2, V, { V }, 0, 0 }
+ { ocFixed, 14, 1, 3, V, { VR }, 0, 0 }, // BIFF2-3: 1-2, BIFF4: 1-3
+ { ocAsc, 214, 1, 1, V, { VR }, 0, 0 },
+ { ocJis, 215, 1, 1, V, { VR }, 0, 0 },
+ { ocRank, 216, 2, 3, V, { VR, RO, VR }, 0, 0 },
+ { ocGDA2, 247, 4, 5, V, { VR }, 0, 0 },
+ { ocFrequency, 252, 2, 2, A, { RA }, 0, 0 },
+ { ocErrorType, 261, 1, 1, V, { VR }, 0, 0 },
+ { ocAveDev, 269, 1, 30, V, { RX }, 0, 0 },
+ { ocBetaDist, 270, 3, 5, V, { VR }, 0, 0 },
+ { ocGammaLn, 271, 1, 1, V, { VR }, 0, 0 },
+ { ocBetaInv, 272, 3, 5, V, { VR }, 0, 0 },
+ { ocBinomDist, 273, 4, 4, V, { VR }, 0, 0 },
+ { ocChiDist, 274, 2, 2, V, { VR }, 0, 0 },
+ { ocChiInv, 275, 2, 2, V, { VR }, 0, 0 },
+ { ocKombin, 276, 2, 2, V, { VR }, 0, 0 },
+ { ocConfidence, 277, 3, 3, V, { VR }, 0, 0 },
+ { ocKritBinom, 278, 3, 3, V, { VR }, 0, 0 },
+ { ocEven, 279, 1, 1, V, { VR }, 0, 0 },
+ { ocExpDist, 280, 3, 3, V, { VR }, 0, 0 },
+ { ocFDist, 281, 3, 3, V, { VR }, 0, 0 },
+ { ocFInv, 282, 3, 3, V, { VR }, 0, 0 },
+ { ocFisher, 283, 1, 1, V, { VR }, 0, 0 },
+ { ocFisherInv, 284, 1, 1, V, { VR }, 0, 0 },
+ { ocFloor, 285, 2, 2, V, { VR, VR, C }, 0, 0 },
+ { ocGammaDist, 286, 4, 4, V, { VR }, 0, 0 },
+ { ocGammaInv, 287, 3, 3, V, { VR }, 0, 0 },
+ { ocCeil, 288, 2, 2, V, { VR, VR, C }, 0, 0 },
+ { ocHypGeomDist, 289, 4, 4, V, { VR }, 0, 0 },
+ { ocLogNormDist, 290, 3, 3, V, { VR }, 0, 0 },
+ { ocLogInv, 291, 3, 3, V, { VR }, 0, 0 },
+ { ocNegBinomVert, 292, 3, 3, V, { VR }, 0, 0 },
+ { ocNormDist, 293, 4, 4, V, { VR }, 0, 0 },
+ { ocStdNormDist, 294, 1, 1, V, { VR }, 0, 0 },
+ { ocNormInv, 295, 3, 3, V, { VR }, 0, 0 },
+ { ocSNormInv, 296, 1, 1, V, { VR }, 0, 0 },
+ { ocStandard, 297, 3, 3, V, { VR }, 0, 0 },
+ { ocOdd, 298, 1, 1, V, { VR }, 0, 0 },
+ { ocVariationen, 299, 2, 2, V, { VR }, 0, 0 },
+ { ocPoissonDist, 300, 3, 3, V, { VR }, 0, 0 },
+ { ocTDist, 301, 3, 3, V, { VR }, 0, 0 },
+ { ocWeibull, 302, 4, 4, V, { VR }, 0, 0 },
+ { ocSumXMY2, 303, 2, 2, V, { VA }, 0, 0 },
+ { ocSumX2MY2, 304, 2, 2, V, { VA }, 0, 0 },
+ { ocSumX2DY2, 305, 2, 2, V, { VA }, 0, 0 },
+ { ocChiTest, 306, 2, 2, V, { VA }, 0, 0 },
+ { ocCorrel, 307, 2, 2, V, { VA }, 0, 0 },
+ { ocCovar, 308, 2, 2, V, { VA }, 0, 0 },
+ { ocForecast, 309, 3, 3, V, { VR, VA }, 0, 0 },
+ { ocFTest, 310, 2, 2, V, { VA }, 0, 0 },
+ { ocIntercept, 311, 2, 2, V, { VA }, 0, 0 },
+ { ocPearson, 312, 2, 2, V, { VA }, 0, 0 },
+ { ocRSQ, 313, 2, 2, V, { VA }, 0, 0 },
+ { ocSTEYX, 314, 2, 2, V, { VA }, 0, 0 },
+ { ocSlope, 315, 2, 2, V, { VA }, 0, 0 },
+ { ocTTest, 316, 4, 4, V, { VA, VA, VR }, 0, 0 },
+ { ocProb, 317, 3, 4, V, { VA, VA, VR }, 0, 0 },
+ { ocDevSq, 318, 1, 30, V, { RX }, 0, 0 },
+ { ocGeoMean, 319, 1, 30, V, { RX }, 0, 0 },
+ { ocHarMean, 320, 1, 30, V, { RX }, 0, 0 },
+ { ocSumSQ, 321, 0, 30, V, { RX }, 0, 0 },
+ { ocKurt, 322, 1, 30, V, { RX }, 0, 0 },
+ { ocSchiefe, 323, 1, 30, V, { RX }, 0, 0 },
+ { ocZTest, 324, 2, 3, V, { RX, VR }, 0, 0 },
+ { ocLarge, 325, 2, 2, V, { RX, VR }, 0, 0 },
+ { ocSmall, 326, 2, 2, V, { RX, VR }, 0, 0 },
+ { ocQuartile, 327, 2, 2, V, { RX, VR }, 0, 0 },
+ { ocPercentile, 328, 2, 2, V, { RX, VR }, 0, 0 },
+ { ocPercentrank, 329, 2, 3, V, { RX, VR, VR_E }, 0, 0 },
+ { ocModalValue, 330, 1, 30, V, { VA }, 0, 0 },
+ { ocTrimMean, 331, 2, 2, V, { RX, VR }, 0, 0 },
+ { ocTInv, 332, 2, 2, V, { VR }, 0, 0 }
};
/** Functions new in BIFF5/BIFF7. Unsupported functions: DATEDIF, DATESTRING, NUMBERSTRING. */
static const XclFunctionInfo saFuncTable_5[] =
{
- { ocGetDayOfWeek, 70, 1, 2, V, { V }, 0, 0 }, // BIFF2-4: 1, BIFF5: 1-2
- { ocHLookup, 101, 3, 4, V, { V, R, R, V }, 0, 0 }, // BIFF2-4: 3, BIFF5: 3-4
- { ocVLookup, 102, 3, 4, V, { V, R, R, V }, 0, 0 }, // BIFF2-4: 3, BIFF5: 3-4
- { ocGetDiffDate360, 220, 2, 3, V, { V }, 0, 0 }, // BIFF3-4: 2, BIFF5: 2-3
- { ocMacro, 255, 1, 30, R, { E, R }, EXC_FUNCFLAG_EXPORTONLY, 0 },
- { ocExternal, 255, 1, 30, R, { E, R }, EXC_FUNCFLAG_EXPORTONLY, 0 },
- { ocConcat, 336, 0, 30, V, { V }, 0, 0 },
- { ocPower, 337, 2, 2, V, { V }, 0, 0 },
- { ocRad, 342, 1, 1, V, { V }, 0, 0 },
- { ocDeg, 343, 1, 1, V, { V }, 0, 0 },
- { ocSubTotal, 344, 2, 30, V, { V, R }, 0, 0 },
- { ocSumIf, 345, 2, 3, V, { R, V, R }, 0, 0 },
- { ocCountIf, 346, 2, 2, V, { R, V }, 0, 0 },
- { ocCountEmptyCells, 347, 1, 1, V, { R }, 0, 0 },
- { ocISPMT, 350, 4, 4, V, { V }, 0, 0 },
- { ocNoName, 351, 3, 3, V, { V }, EXC_FUNCFLAG_IMPORTONLY, 0 }, // DATEDIF
- { ocNoName, 352, 1, 1, V, { V }, EXC_FUNCFLAG_IMPORTONLY, 0 }, // DATESTRING
- { ocNoName, 353, 2, 2, V, { V }, EXC_FUNCFLAG_IMPORTONLY, 0 }, // NUMBERSTRING
- { ocRoman, 354, 1, 2, V, { V }, 0, 0 }
+ { ocGetDayOfWeek, 70, 1, 2, V, { VR }, 0, 0 }, // BIFF2-4: 1, BIFF5: 1-2
+ { ocHLookup, 101, 3, 4, V, { VV, RO, RO, VV }, 0, 0 }, // BIFF2-4: 3, BIFF5: 3-4
+ { ocVLookup, 102, 3, 4, V, { VV, RO, RO, VV }, 0, 0 }, // BIFF2-4: 3, BIFF5: 3-4
+ { ocGetDiffDate360, 220, 2, 3, V, { VR }, 0, 0 }, // BIFF3-4: 2, BIFF5: 2-3
+ { ocMacro, 255, 1, 30, R, { RO_E, RO }, EXC_FUNCFLAG_EXPORTONLY, 0 },
+ { ocExternal, 255, 1, 30, R, { RO_E, RO }, EXC_FUNCFLAG_EXPORTONLY, 0 },
+ { ocConcat, 336, 0, 30, V, { VR }, 0, 0 },
+ { ocPower, 337, 2, 2, V, { VR }, 0, 0 },
+ { ocRad, 342, 1, 1, V, { VR }, 0, 0 },
+ { ocDeg, 343, 1, 1, V, { VR }, 0, 0 },
+ { ocSubTotal, 344, 2, 30, V, { VR, RO }, 0, 0 },
+ { ocSumIf, 345, 2, 3, V, { RO, VR, RO }, 0, 0 },
+ { ocCountIf, 346, 2, 2, V, { RO, VR }, 0, 0 },
+ { ocCountEmptyCells, 347, 1, 1, V, { RO }, 0, 0 },
+ { ocISPMT, 350, 4, 4, V, { VR }, 0, 0 },
+ { ocNoName, 351, 3, 3, V, { VR }, EXC_FUNCFLAG_IMPORTONLY, 0 }, // DATEDIF
+ { ocNoName, 352, 1, 1, V, { VR }, EXC_FUNCFLAG_IMPORTONLY, 0 }, // DATESTRING
+ { ocNoName, 353, 2, 2, V, { VR }, EXC_FUNCFLAG_IMPORTONLY, 0 }, // NUMBERSTRING
+ { ocRoman, 354, 1, 2, V, { VR }, 0, 0 }
};
#define EXC_FUNCNAME_PREFIX "_xlfn."
@@ -330,19 +350,19 @@ const sal_Char* const EXC_FUNCNAME_BAHTTEXT = EXC_FUNCNAME_PREFIX "BAHTTEXT";
/** Functions new in BIFF8. Unsupported functions: PHONETIC. */
static const XclFunctionInfo saFuncTable_8[] =
{
- { ocGetPivotData, 358, 2, 30, V, { V, R, V }, 0, 0 },
- { ocHyperLink, 359, 1, 2, V, { V }, 0, 0 },
- { ocNoName, 360, 1, 1, V, { R }, EXC_FUNCFLAG_IMPORTONLY, 0 }, // PHONETIC
- { ocAverageA, 361, 1, 30, V, { R }, 0, 0 },
- { ocMaxA, 362, 1, 30, V, { R }, 0, 0 },
- { ocMinA, 363, 1, 30, V, { R }, 0, 0 },
- { ocStDevPA, 364, 1, 30, V, { R }, 0, 0 },
- { ocVarPA, 365, 1, 30, V, { R }, 0, 0 },
- { ocStDevA, 366, 1, 30, V, { R }, 0, 0 },
- { ocVarA, 367, 1, 30, V, { R }, 0, 0 },
- { ocBahtText, 368, 1, 1, V, { V }, EXC_FUNCFLAG_IMPORTONLY, EXC_FUNCNAME_BAHTTEXT },
- { ocBahtText, 255, 2, 2, V, { E, V }, EXC_FUNCFLAG_EXPORTONLY, EXC_FUNCNAME_BAHTTEXT },
- { ocEuroConvert, 255, 4, 6, V, { E, V }, EXC_FUNCFLAG_EXPORTONLY, "EUROCONVERT" }
+ { ocGetPivotData, 358, 2, 30, V, { RR, RR, VR }, 0, 0 },
+ { ocHyperLink, 359, 1, 2, V, { VV, VO }, 0, 0 },
+ { ocNoName, 360, 1, 1, V, { RO }, EXC_FUNCFLAG_IMPORTONLY, 0 }, // PHONETIC
+ { ocAverageA, 361, 1, 30, V, { RX }, 0, 0 },
+ { ocMaxA, 362, 1, 30, V, { RX }, 0, 0 },
+ { ocMinA, 363, 1, 30, V, { RX }, 0, 0 },
+ { ocStDevPA, 364, 1, 30, V, { RX }, 0, 0 },
+ { ocVarPA, 365, 1, 30, V, { RX }, 0, 0 },
+ { ocStDevA, 366, 1, 30, V, { RX }, 0, 0 },
+ { ocVarA, 367, 1, 30, V, { RX }, 0, 0 },
+ { ocBahtText, 368, 1, 1, V, { VR }, EXC_FUNCFLAG_IMPORTONLY, EXC_FUNCNAME_BAHTTEXT },
+ { ocBahtText, 255, 2, 2, V, { RO_E, RO }, EXC_FUNCFLAG_EXPORTONLY, EXC_FUNCNAME_BAHTTEXT },
+ { ocEuroConvert, 255, 4, 6, V, { RO_E, RO }, EXC_FUNCFLAG_EXPORTONLY, "EUROCONVERT" }
};
// ----------------------------------------------------------------------------
@@ -436,16 +456,17 @@ XclTokenArray::XclTokenArray( bool bVolatile ) :
{
}
-XclTokenArray::XclTokenArray( ScfUInt8Vec& rTokVec, bool bVolatile,
- ScfUInt8Vec* pExtensionTokens) :
+XclTokenArray::XclTokenArray( ScfUInt8Vec& rTokVec, bool bVolatile ) :
mbVolatile( bVolatile )
{
maTokVec.swap( rTokVec );
- if( NULL != pExtensionTokens)
- {
- DBG_ASSERT( maTokVec.size() <= 0xFFFF, "XclTokenArray::XclTokenArray - extension array too long" );
- maExtensions.swap( *pExtensionTokens );
- }
+}
+
+XclTokenArray::XclTokenArray( ScfUInt8Vec& rTokVec, ScfUInt8Vec& rExtDataVec, bool bVolatile ) :
+ mbVolatile( bVolatile )
+{
+ maTokVec.swap( rTokVec );
+ maExtDataVec.swap( rExtDataVec );
}
sal_uInt16 XclTokenArray::GetSize() const
@@ -482,8 +503,8 @@ void XclTokenArray::WriteArray( XclExpStream& rStrm ) const
{
if( !maTokVec.empty() )
rStrm.Write( &maTokVec.front(), GetSize() );
- if( !maExtensions.empty() )
- rStrm.Write( &maExtensions.front(), limit_cast< sal_uInt16 >(maExtensions.size() ) );
+ if( !maExtDataVec.empty() )
+ rStrm.Write( &maExtDataVec.front(), maExtDataVec.size() );
}
void XclTokenArray::Write( XclExpStream& rStrm ) const
@@ -494,7 +515,7 @@ void XclTokenArray::Write( XclExpStream& rStrm ) const
bool XclTokenArray::operator==( const XclTokenArray& rTokArr ) const
{
- return (mbVolatile == rTokArr.mbVolatile) && (maTokVec == rTokArr.maTokVec);
+ return (mbVolatile == rTokArr.mbVolatile) && (maTokVec == rTokArr.maTokVec) && (maExtDataVec == rTokArr.maExtDataVec);
}
XclImpStream& operator>>( XclImpStream& rStrm, XclTokenArray& rTokArr )
@@ -558,7 +579,7 @@ void XclTokenArrayIterator::Init()
void XclTokenArrayIterator::Init( const ScTokenArray& rScTokArr, bool bSkipSpaces )
{
USHORT nTokArrLen = rScTokArr.GetLen();
- mppScTokenBeg = static_cast< const formula::FormulaToken*const* >( nTokArrLen ? rScTokArr.GetArray() : 0 );
+ mppScTokenBeg = static_cast< const FormulaToken* const* >( nTokArrLen ? rScTokArr.GetArray() : 0 );
mppScTokenEnd = mppScTokenBeg ? (mppScTokenBeg + nTokArrLen) : 0;
mppScToken = (mppScTokenBeg != mppScTokenEnd) ? mppScTokenBeg : 0;
mbSkipSpaces = bSkipSpaces;
@@ -588,9 +609,9 @@ void XclTokenArrayIterator::SkipSpaces()
// strings and string lists ---------------------------------------------------
-bool XclTokenArrayHelper::GetTokenString( String& rString, const formula::FormulaToken& rScToken )
+bool XclTokenArrayHelper::GetTokenString( String& rString, const FormulaToken& rScToken )
{
- bool bIsStr = (rScToken.GetType() == formula::svString) && (rScToken.GetOpCode() == ocPush);
+ bool bIsStr = (rScToken.GetType() == svString) && (rScToken.GetOpCode() == ocPush);
if( bIsStr ) rString = rScToken.GetString();
return bIsStr;
}
@@ -653,7 +674,7 @@ void XclTokenArrayHelper::ConvertStringToList( ScTokenArray& rScTokArr, sal_Unic
const ScTokenArray* XclTokenArrayHelper::GetSharedFormula( const XclRoot& rRoot, const ScTokenArray& rScTokArr )
{
if( rScTokArr.GetLen() == 1 )
- if( const formula::FormulaToken* pScToken = rScTokArr.GetArray()[ 0 ] )
+ if( const FormulaToken* pScToken = rScTokArr.GetArray()[ 0 ] )
if( pScToken->GetOpCode() == ocName )
if( ScRangeData* pData = rRoot.GetNamedRanges().FindIndex( pScToken->GetIndex() ) )
if( pData->HasType( RT_SHARED ) )
@@ -665,7 +686,7 @@ const ScTokenArray* XclTokenArrayHelper::GetSharedFormula( const XclRoot& rRoot,
namespace {
-inline bool lclGetAddress( ScAddress& rAddress, const formula::FormulaToken& rToken )
+inline bool lclGetAddress( ScAddress& rAddress, const FormulaToken& rToken )
{
OpCode eOpCode = rToken.GetOpCode();
bool bIsSingleRef = (eOpCode == ocPush) && (rToken.GetType() == svSingleRef);
diff --git a/sc/source/filter/inc/xlformula.hxx b/sc/source/filter/inc/xlformula.hxx
index ef9274bc0338..aed77452b311 100644
--- a/sc/source/filter/inc/xlformula.hxx
+++ b/sc/source/filter/inc/xlformula.hxx
@@ -32,8 +32,8 @@
#define SC_XLFORMULA_HXX
#include <map>
+#include <formula/opcode.hxx>
#include "address.hxx"
-#include "formula/opcode.hxx"
#include "ftools.hxx"
// Constants ==================================================================
@@ -43,18 +43,11 @@ const size_t EXC_TOKARR_MAXLEN = 4096; /// Maximum size of a to
// Token class flags ----------------------------------------------------------
const sal_uInt8 EXC_TOKCLASS_MASK = 0x60;
-const sal_uInt8 EXC_TOKCLASS_INOP_FLAG = 0x80; /// Used in operators (internal flag).
-
const sal_uInt8 EXC_TOKCLASS_NONE = 0x00; /// 00-1F: Base tokens.
const sal_uInt8 EXC_TOKCLASS_REF = 0x20; /// 20-3F: Reference class tokens.
const sal_uInt8 EXC_TOKCLASS_VAL = 0x40; /// 40-5F: Value class tokens.
const sal_uInt8 EXC_TOKCLASS_ARR = 0x60; /// 60-7F: Array class tokens.
-const sal_uInt8 EXC_TOKCLASS_ANY_IN_REFOP = EXC_TOKCLASS_INOP_FLAG | EXC_TOKCLASS_NONE;
-const sal_uInt8 EXC_TOKCLASS_REF_IN_VALOP = EXC_TOKCLASS_INOP_FLAG | EXC_TOKCLASS_REF;
-const sal_uInt8 EXC_TOKCLASS_VAL_IN_VALOP = EXC_TOKCLASS_INOP_FLAG | EXC_TOKCLASS_VAL;
-const sal_uInt8 EXC_TOKCLASS_ARR_IN_VALOP = EXC_TOKCLASS_INOP_FLAG | EXC_TOKCLASS_ARR;
-
// Base tokens ----------------------------------------------------------------
const sal_uInt8 EXC_TOKID_MASK = 0x1F;
@@ -183,15 +176,120 @@ enum XclFormulaType
EXC_FMLATYPE_LISTVAL /// List (cell range) validation.
};
+// Function parameter info ====================================================
+
+/** Enumerates validity modes for a function parameter. */
+enum XclFuncParamValidity
+{
+ EXC_PARAM_NONE = 0, /// Default for an unspecified entry in a C-array.
+ EXC_PARAM_REGULAR, /// Parameter supported by Calc and Excel.
+ EXC_PARAM_CALCONLY, /// Parameter supported by Calc only.
+ EXC_PARAM_EXCELONLY /// Parameter supported by Excel only.
+};
+
+/** Enumerates different types of token class conversion in function parameters. */
+enum XclFuncParamConv
+{
+ EXC_PARAMCONV_ORG, /// Use original class of current token.
+ EXC_PARAMCONV_VAL, /// Convert tokens to VAL class.
+ EXC_PARAMCONV_ARR, /// Convert tokens to ARR class.
+ EXC_PARAMCONV_RPT, /// Repeat parent conversion in VALTYPE parameters.
+ EXC_PARAMCONV_RPX, /// Repeat parent conversion in REFTYPE parameters.
+ EXC_PARAMCONV_RPO /// Repeat parent conversion in operands of operators.
+};
+
+/** Structure that contains all needed information for a parameter in a
+ function.
+
+ The member meValid specifies which application supports the parameter. If
+ set to CALCONLY, import filters have to insert a default value for this
+ parameter, and export filters have to skip the parameter. If set to
+ EXCELONLY, import filters have to skip the parameter, and export filters
+ have to insert a default value for this parameter.
+
+ The member mbValType specifies whether the parameter requires tokens to be
+ of value type (VAL or ARR class).
+
+ If set to false, the parameter is called to be REFTYPE. Tokens with REF
+ default class can be inserted for the parameter (e.g. tAreaR tokens).
+
+ If set to true, the parameter is called to be VALTYPE. Tokens with REF
+ class need to be converted to VAL tokens first (e.g. tAreaR will be
+ converted to tAreaV), and further conversion is done according to this
+ new token class.
+
+ The member meConv specifies how to convert the current token class of the
+ token inserted for the parameter. If the token class is still REF this
+ means that the token has default REF class and the parameter is REFTYPE
+ (see member mbValType), the token will not be converted at all and remains
+ in REF class. Otherwise, token class conversion is depending on the actual
+ token class of the return value of the function containing this parameter.
+ The function may return REF class (tFuncR, tFuncVarR, tFuncCER), or it may
+ return VAL or ARR class (tFuncV, tFuncA, tFuncVarV, tFuncVarA, tFuncCEV,
+ tFuncCEA). Even if the function is able to return REF class, it may return
+ VAL or ARR class instead due to the VALTYPE data type of the parent
+ function parameter that calls the own function. Example: The INDIRECT
+ function returns REF class by default. But if called from a VALTYPE
+ function parameter, e.g. in the formula =ABS(INDIRECT("A1")), it returns
+ VAL or ARR class instead. Additionally, the repeating conversion types RPT
+ and RPX rely on the conversion executed for the function token class.
+
+ 1) ORG:
+ Use the original class of the token (VAL or ARR), regardless of any
+ conversion done for the function return class.
+
+ 2) VAL:
+ Convert ARR tokens to VAL class, regardless of any conversion done for
+ the function return class.
+
+ 3) ARR:
+ Convert VAL tokens to ARR class, regardless of any conversion done for
+ the function return class.
+
+ 4) RPT:
+ If the own function returns REF class (thus it is called from a REFTYPE
+ parameter, see above), and the parent conversion type (for the function
+ return class) was ORG, VAL, or ARR, ignore that conversion and always
+ use VAL conversion for the own token instead. If the parent conversion
+ type was RPT or RPX, repeat the conversion that would have been used if
+ the function would return value type.
+ If the own function returns value type (VAL or ARR class, see above),
+ and the parent conversion type (for the function return class) was ORG,
+ VAL, ARR, or RPT, repeat this conversion for the own token. If the
+ parent conversion type was RPX, always use ORG conversion type for the
+ own token instead.
+
+ 5) RPX:
+ This type of conversion only occurs in functions returning VAL class by
+ default. If the own token is value type, and the VAL return class of
+ the own function has been changed to ARR class (due to direct ARR
+ conversion, or due to ARR conversion repeated by RPT or RPX), set the
+ own token to ARR type. Otherwise use the original token type (VAL
+ conversion from parent parameter will not be repeated at all). If
+ nested functions have RPT or value-type RPX parameters, they will not
+ repeat this conversion type, but will use ORG conversion instead (see
+ description of RPT above).
+
+ 6) RPO:
+ This type of conversion is only used for the operands of all operators
+ (unary and binary arithmetic operators, comparison operators, and range
+ operators). It is not used for function parameters. On conversion, it
+ will be replaced by the last conversion type that was not the RPO
+ conversion. This leads to a slightly different behaviour than the RPT
+ conversion for operands in conjunction with a parent RPX conversion.
+ */
+struct XclFuncParamInfo
+{
+ XclFuncParamValidity meValid; /// Parameter validity.
+ XclFuncParamConv meConv; /// Token class conversion type.
+ bool mbValType; /// Data type (false = REFTYPE, true = VALTYPE).
+};
+
// Function data ==============================================================
const sal_uInt8 EXC_FUNC_MAXPARAM = 30; /// Maximum parameter count.
-const sal_uInt8 EXC_FUNC_PAR_CALCONLY = 0xFD; /// Placeholder for a parameter existing in Calc, but not in Excel.
-const sal_uInt8 EXC_FUNC_PAR_EXCELONLY = 0xFE; /// Placeholder for a parameter existing in Excel, but not in Calc.
-const sal_uInt8 EXC_FUNC_PAR_INVALID = 0xFF; /// Placeholder for an invalid token class.
-
-const sal_uInt8 EXC_FUNCINFO_CLASSCOUNT = 5; /// Number of token class entries.
+const size_t EXC_FUNCINFO_PARAMINFO_COUNT = 5; /// Number of parameter info entries.
const sal_uInt8 EXC_FUNCFLAG_VOLATILE = 0x01; /// Result is volatile (e.g. NOW() function).
const sal_uInt8 EXC_FUNCFLAG_IMPORTONLY = 0x02; /// Only used in import filter.
@@ -207,14 +305,11 @@ const sal_uInt16 EXC_FUNCID_EXTERNCALL = 255;
/** Represents information for a spreadsheet function for import and export.
- The member mpnParamClass contains an array of token classes for each
- parameter of the function. The last existing (non-null) value in this array
- is used for all following parameters used in a function. Additionally to
- the three actual token classes, this array may contain the special values
- EXC_FUNC_PAR_CALCONLY, EXC_FUNC_PAR_EXCELONLY, and EXC_FUNC_PAR_INVALID.
- The former two specify parameters only existing in one of the applications.
- EXC_FUNC_PAR_INVALID is simply a terminator for the array to prevent that
- the last token class or special value is repeated for additional parameters.
+ The member mpParamInfos points to an array of type information structures
+ for all parameters of the function. The last initialized structure
+ describing a regular parameter (member meValid == EXC_PARAMVALID_ALWAYS) in
+ this array is used repeatedly for all following parameters supported by a
+ function.
*/
struct XclFunctionInfo
{
@@ -223,12 +318,14 @@ struct XclFunctionInfo
sal_uInt8 mnMinParamCount; /// Minimum number of parameters.
sal_uInt8 mnMaxParamCount; /// Maximum number of parameters.
sal_uInt8 mnRetClass; /// Token class of the return value.
- sal_uInt8 mpnParamClass[ EXC_FUNCINFO_CLASSCOUNT ]; /// Expected token classes of parameters.
- sal_uInt8 mnFlags; /// Additional flags.
+ XclFuncParamInfo mpParamInfos[ EXC_FUNCINFO_PARAMINFO_COUNT ]; /// Information for all parameters.
+ sal_uInt8 mnFlags; /// Additional flags (EXC_FUNCFLAG_* constants).
const sal_Char* mpcMacroName; /// Function name, if simulated by a macro call (UTF-8).
/** Returns true, if the function is volatile. */
inline bool IsVolatile() const { return ::get_flag( mnFlags, EXC_FUNCFLAG_VOLATILE ); }
+ /** Returns true, if the function parameter count is fixed. */
+ inline bool IsFixedParamCount() const { return (mnXclFunc != EXC_FUNCID_EXTERNCALL) && (mnMinParamCount == mnMaxParamCount); }
/** Returns true, if the function is simulated by a macro call. */
inline bool IsMacroFunc() const { return mpcMacroName != 0; }
/** Returns the name of the external function as string. */
@@ -278,8 +375,9 @@ public:
/** Creates an empty token array. */
explicit XclTokenArray( bool bVolatile = false );
/** Creates a token array, swaps passed token vector into own data. */
- explicit XclTokenArray( ScfUInt8Vec& rTokVec, bool bVolatile = false,
- ScfUInt8Vec* pExtensionTokens = NULL);
+ explicit XclTokenArray( ScfUInt8Vec& rTokVec, bool bVolatile = false );
+ /** Creates a token array, swaps passed token vectors into own data. */
+ explicit XclTokenArray( ScfUInt8Vec& rTokVec, ScfUInt8Vec& rExtDataVec, bool bVolatile = false );
/** Returns true, if the token array is empty. */
inline bool Empty() const { return maTokVec.empty(); }
@@ -309,7 +407,7 @@ public:
private:
ScfUInt8Vec maTokVec; /// Byte vector containing token data.
- ScfUInt8Vec maExtensions; /// Byte vector of extensions (eg inline arrays)
+ ScfUInt8Vec maExtDataVec; /// Byte vector containing extended data (arrays, stacked NLRs).
bool mbVolatile; /// True = Formula contains volatile function.
};
@@ -326,10 +424,7 @@ XclExpStream& operator<<( XclExpStream& rStrm, const XclTokenArrayRef& rxTokArr
// ----------------------------------------------------------------------------
-namespace formula
-{
- class FormulaToken;
-}
+namespace formula { class FormulaToken; }
class ScTokenArray;
/** Special token array iterator for the Excel filters.
@@ -347,7 +442,7 @@ class XclTokenArrayIterator
public:
explicit XclTokenArrayIterator();
explicit XclTokenArrayIterator( const ScTokenArray& rScTokArr, bool bSkipSpaces );
- /** Copy constructor that allowa to change the skip-spaces mode. */
+ /** Copy constructor that allows to change the skip-spaces mode. */
explicit XclTokenArrayIterator( const XclTokenArrayIterator& rTokArrIt, bool bSkipSpaces );
void Init();
@@ -355,9 +450,9 @@ public:
inline bool Is() const { return mppScToken != 0; }
inline bool operator!() const { return !Is(); }
- inline const formula::FormulaToken* Get() const { return mppScToken ? *mppScToken : 0; }
- inline const formula::FormulaToken* operator->() const { return Get(); }
- inline const formula::FormulaToken& operator*() const { return *Get(); }
+ inline const ::formula::FormulaToken* Get() const { return mppScToken ? *mppScToken : 0; }
+ inline const ::formula::FormulaToken* operator->() const { return Get(); }
+ inline const ::formula::FormulaToken& operator*() const { return *Get(); }
XclTokenArrayIterator& operator++();
@@ -366,9 +461,9 @@ private:
void SkipSpaces();
private:
- const formula::FormulaToken*const* mppScTokenBeg; /// Pointer to first token pointer of token array.
- const formula::FormulaToken*const* mppScTokenEnd; /// Pointer behind last token pointer of token array.
- const formula::FormulaToken*const* mppScToken; /// Pointer to current token pointer of token array.
+ const ::formula::FormulaToken*const* mppScTokenBeg; /// Pointer to first token pointer of token array.
+ const ::formula::FormulaToken*const* mppScTokenEnd; /// Pointer behind last token pointer of token array.
+ const ::formula::FormulaToken*const* mppScToken; /// Pointer to current token pointer of token array.
bool mbSkipSpaces; /// true = Skip whitespace tokens.
};
@@ -407,14 +502,14 @@ public:
/** Returns the token class of the passed token ID. */
inline static sal_uInt8 GetTokenClass( sal_uInt8 nTokenId ) { return nTokenId & EXC_TOKCLASS_MASK; }
/** Changes the token class in the passed classified token ID. */
- inline static void ChangeTokenClass( sal_uInt8& rnTokenId, sal_uInt8 nTokenClass );
+ inline static void ChangeTokenClass( sal_uInt8& rnTokenId, sal_uInt8 nTokenClass );
// strings and string lists -----------------------------------------------
/** Tries to extract a string from the passed token.
@param rString (out-parameter) The string contained in the token.
@return true = Passed token is a string token, rString parameter is valid. */
- static bool GetTokenString( String& rString, const formula::FormulaToken& rScToken );
+ static bool GetTokenString( String& rString, const ::formula::FormulaToken& rScToken );
/** Parses the passed formula and tries to find a single string token, i.e. "abc".
@param rString (out-parameter) The string contained in the formula.
diff --git a/sc/source/ui/inc/tabvwsh.hxx b/sc/source/ui/inc/tabvwsh.hxx
index 10224536bf0b..eede290aa8db 100644
--- a/sc/source/ui/inc/tabvwsh.hxx
+++ b/sc/source/ui/inc/tabvwsh.hxx
@@ -418,7 +418,7 @@ public:
void ExecuteCellFormatDlg ( SfxRequest& rReq, USHORT nTabPage = 0xffff );
- BOOL GetFunction( String& rFuncStr );
+ BOOL GetFunction( String& rFuncStr, sal_uInt16 nErrCode = 0 );
void StartSimpleRefDialog( const String& rTitle, const String& rInitVal,
BOOL bCloseOnButtonUp, BOOL bSingleCell, BOOL bMultiSelection );
diff --git a/sc/source/ui/src/scfuncs.src b/sc/source/ui/src/scfuncs.src
index ed6273e26ae4..f05793872d4c 100644
--- a/sc/source/ui/src/scfuncs.src
+++ b/sc/source/ui/src/scfuncs.src
@@ -2691,7 +2691,7 @@ Resource RID_SC_FUNCTION_DESCRIPTIONS1
{
String 1 // Description
{
- Text [ en-US ] = "Raises a number to the power of another." ;
+ Text [ en-US ] = "Returns a^b, base a raised to the power of exponent b." ;
};
ExtraData =
{
@@ -2707,15 +2707,15 @@ Resource RID_SC_FUNCTION_DESCRIPTIONS1
};
String 3 // Description of Parameter 1
{
- Text [ en-US ] = "The number that is to be raised to the power of another." ;
+ Text [ en-US ] = "The base a of the power a^b." ;
};
String 4 // Name of Parameter 2
{
- Text [ en-US ] = "Power" ;
+ Text [ en-US ] = "Exponent" ;
};
String 5 // Description of Parameter 2
{
- Text [ en-US ] = "The power by which the number is to be raised." ;
+ Text [ en-US ] = "The exponent b of the power a^b." ;
};
};
// -=*# Resource for function ANZAHLLEEREZELLEN #*=-
@@ -5718,7 +5718,7 @@ Resource RID_SC_FUNCTION_DESCRIPTIONS2
0;
ID_FUNCTION_GRP_STATISTIC;
U2S( HID_FUNC_NORMVERT );
- 4; 0; 0; 0; 0;
+ 4; 0; 0; 0; 1;
0;
};
String 2 // Name of Parameter 1
@@ -5731,7 +5731,7 @@ Resource RID_SC_FUNCTION_DESCRIPTIONS2
};
String 4 // Name of Parameter 2
{
- Text [ en-US ] = "mean" ;
+ Text [ en-US ] = "Mean" ;
};
String 5 // Description of Parameter 2
{
@@ -5751,7 +5751,7 @@ Resource RID_SC_FUNCTION_DESCRIPTIONS2
};
String 9 // Description of Parameter 4
{
- Text [ en-US ] = "Cumulated. C=0 calculates the density function, C=1 the distribution." ;
+ Text [ en-US ] = "0 or FALSE calculates the probability density function. Any other value or TRUE or omitted calculates the cumulative distribution function." ;
};
};
// -=*# Resource for function NORMINV #*=-
@@ -5854,7 +5854,7 @@ Resource RID_SC_FUNCTION_DESCRIPTIONS2
0;
ID_FUNCTION_GRP_STATISTIC;
U2S( HID_FUNC_LOGNORMVERT );
- 3; 0; 0; 0;
+ 4; 0; 1; 1; 1;
0;
};
String 2 // Name of Parameter 1
@@ -5871,7 +5871,7 @@ Resource RID_SC_FUNCTION_DESCRIPTIONS2
};
String 5 // Description of Parameter 2
{
- Text [ en-US ] = "Mean value. The mean value of the log normal distribution." ;
+ Text [ en-US ] = "The mean value of the log normal distribution. It is set to 0 if omitted." ;
};
String 6 // Name of Parameter 3
{
@@ -5879,7 +5879,15 @@ Resource RID_SC_FUNCTION_DESCRIPTIONS2
};
String 7 // Description of Parameter 3
{
- Text [ en-US ] = "Standard deviation. The standard deviation of the log normal distribution." ;
+ Text [ en-US ] = "The standard deviation of the log normal distribution. It is set to 1 if omitted." ;
+ };
+ String 8 // Name of Parameter 4
+ {
+ Text [ en-US] = "Cumulative";
+ };
+ String 9 // Description of Parameter 4
+ {
+ Text [ en-US] = "0 or FALSE calculates the probability density function. Any other value or TRUE or omitted calculates the cumulative distribution function." ;
};
};
// -=*# Resource for function LOGINV #*=-
@@ -6758,7 +6766,7 @@ Resource RID_SC_FUNCTION_DESCRIPTIONS2
{
String 1 // Description
{
- Text [ en-US ] = "Returns the two-tailed P value of a z test." ;
+ Text [ en-US ] = "Calculates the probability of observing a z-statistic greater than the one computed based on a sample." ;
};
ExtraData =
{
@@ -6774,15 +6782,15 @@ Resource RID_SC_FUNCTION_DESCRIPTIONS2
};
String 3 // Description of Parameter 1
{
- Text [ en-US ] = "The data array." ;
+ Text [ en-US ] = "The given sample, drawn from a normally distributed population." ;
};
String 4 // Name of Parameter 2
{
- Text [ en-US ] = "Number" ;
+ Text [ en-US ] = "mu" ;
};
String 5 // Description of Parameter 2
{
- Text [ en-US ] = "The value to be tested." ;
+ Text [ en-US ] = "The known mean of the population." ;
};
String 6 // Name of Parameter 3
{
@@ -6790,7 +6798,7 @@ Resource RID_SC_FUNCTION_DESCRIPTIONS2
};
String 7 // Description of Parameter 3
{
- Text [ en-US ] = "The standard deviation of the population." ;
+ Text [ en-US ] = "The known standard deviation of the population. If omitted, the standard deviation of the given sample is used." ;
};
};
// -=*# Resource for function CHITEST #*=-
@@ -8906,7 +8914,7 @@ Resource RID_SC_FUNCTION_DESCRIPTIONS2
};
ExtraData =
{
- 1; // TODO: implementation and unsuppress
+ 0;
ID_FUNCTION_GRP_TEXT;
U2S( HID_FUNC_UNICODE );
1; 0;
@@ -8929,7 +8937,7 @@ Resource RID_SC_FUNCTION_DESCRIPTIONS2
};
ExtraData =
{
- 1; // TODO: implementation and unsuppress
+ 0;
ID_FUNCTION_GRP_TEXT;
U2S( HID_FUNC_UNICHAR );
1; 0;
diff --git a/sc/source/ui/view/cellsh.cxx b/sc/source/ui/view/cellsh.cxx
index 722885363346..0090ec42a0e9 100644
--- a/sc/source/ui/view/cellsh.cxx
+++ b/sc/source/ui/view/cellsh.cxx
@@ -669,15 +669,9 @@ void ScCellShell::GetState(SfxItemSet &rSet)
nErrCode = pFCell->GetErrCode();
}
- if ( nErrCode > 0 )
- rSet.Put( SfxStringItem( nWhich,
- ScGlobal::GetLongErrorString( nErrCode ) ) );
- else
- {
- String aFuncStr;
- if ( pTabViewShell->GetFunction( aFuncStr ) )
- rSet.Put( SfxStringItem( nWhich, aFuncStr ) );
- }
+ String aFuncStr;
+ if ( pTabViewShell->GetFunction( aFuncStr, nErrCode ) )
+ rSet.Put( SfxStringItem( nWhich, aFuncStr ) );
}
}
break;
diff --git a/sc/source/ui/view/tabvwsha.cxx b/sc/source/ui/view/tabvwsha.cxx
index 72fb7bfdf06f..9e844f970909 100644
--- a/sc/source/ui/view/tabvwsha.cxx
+++ b/sc/source/ui/view/tabvwsha.cxx
@@ -72,11 +72,23 @@
#include "compiler.hxx"
-BOOL ScTabViewShell::GetFunction( String& rFuncStr )
+BOOL ScTabViewShell::GetFunction( String& rFuncStr, sal_uInt16 nErrCode )
{
String aStr;
ScSubTotalFunc eFunc = (ScSubTotalFunc) SC_MOD()->GetAppOptions().GetStatusFunc();
+ ScViewData* pViewData = GetViewData();
+ ScMarkData& rMark = pViewData->GetMarkData();
+ bool bIgnoreError = (rMark.IsMarked() || rMark.IsMultiMarked());
+
+ if (bIgnoreError && (eFunc == SUBTOTAL_FUNC_CNT || eFunc == SUBTOTAL_FUNC_CNT2))
+ nErrCode = 0;
+
+ if (nErrCode)
+ {
+ rFuncStr = ScGlobal::GetLongErrorString(nErrCode);
+ return true;
+ }
USHORT nGlobStrId = 0;
switch (eFunc)
@@ -94,9 +106,7 @@ BOOL ScTabViewShell::GetFunction( String& rFuncStr )
}
if (nGlobStrId)
{
- ScViewData* pViewData = GetViewData();
ScDocument* pDoc = pViewData->GetDocument();
- ScMarkData& rMark = pViewData->GetMarkData();
SCCOL nPosX = pViewData->GetCurX();
SCROW nPosY = pViewData->GetCurY();
SCTAB nTab = pViewData->GetTabNo();