fix baseline build (old cairo) - 'cairo_rectangle_int_t' does not name a type
[LibreOffice.git] / sc / source / core / inc / interpre.hxx
blob1a2481ee72e2447911a572ed2bed5acd8af5a412
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #ifndef INCLUDED_SC_SOURCE_CORE_INC_INTERPRE_HXX
21 #define INCLUDED_SC_SOURCE_CORE_INC_INTERPRE_HXX
23 #include <math.h>
24 #include <rtl/math.hxx>
25 #include <rtl/ustring.hxx>
26 #include <formula/errorcodes.hxx>
27 #include <formula/tokenarray.hxx>
28 #include "scdll.hxx"
29 #include "scdllapi.h"
30 #include "types.hxx"
31 #include "externalrefmgr.hxx"
32 #include "calcconfig.hxx"
33 #include "token.hxx"
34 #include "math.hxx"
35 #include "parclass.hxx"
37 #include <map>
38 #include <vector>
40 class ScDocument;
41 class SbxVariable;
42 class ScFormulaCell;
43 class SvNumberFormatter;
44 class ScDBRangeBase;
45 struct ScQueryParam;
46 struct ScDBQueryParamBase;
47 struct ScQueryEntry;
49 struct ScSingleRefData;
50 struct ScComplexRefData;
52 namespace formula { class FormulaToken; }
53 class ScJumpMatrix;
54 struct ScRefCellValue;
56 namespace sc {
58 struct RangeMatrix;
59 struct Compare;
60 struct CompareOptions;
64 namespace svl {
66 class SharedStringPool;
70 #define MAXSTACK (4096 / sizeof(formula::FormulaToken*))
72 class ScTokenStack
74 public:
75 DECL_FIXEDMEMPOOL_NEWDEL( ScTokenStack )
76 formula::FormulaToken* pPointer[ MAXSTACK ];
79 enum ScIterFunc {
80 ifSUM, // Add up
81 ifSUMSQ, // Sums of squares
82 ifPRODUCT, // Product
83 ifAVERAGE, // Average
84 ifCOUNT, // Count Values
85 ifCOUNT2, // Count Values (not empty)
86 ifMIN, // Minimum
87 ifMAX // Maximum
90 enum ScIterFuncIf
92 ifSUMIF, // Conditional sum
93 ifAVERAGEIF // Conditional average
96 enum ScIterFuncIfs
98 ifSUMIFS, // Multi-Conditional sum
99 ifAVERAGEIFS, // Multi-Conditional average
100 ifCOUNTIFS // Multi-Conditional count
103 struct FormulaTokenRef_less
105 bool operator () ( const formula::FormulaConstTokenRef& r1, const formula::FormulaConstTokenRef& r2 ) const
106 { return r1.get() < r2.get(); }
108 typedef ::std::map< const formula::FormulaConstTokenRef, formula::FormulaTokenRef, FormulaTokenRef_less> ScTokenMatrixMap;
110 class ScInterpreter
112 // distibution function objects need the GetxxxDist methods
113 friend class ScGammaDistFunction;
114 friend class ScBetaDistFunction;
115 friend class ScTDistFunction;
116 friend class ScFDistFunction;
117 friend class ScChiDistFunction;
118 friend class ScChiSqDistFunction;
120 public:
121 DECL_FIXEDMEMPOOL_NEWDEL( ScInterpreter )
123 static SC_DLLPUBLIC void SetGlobalConfig(const ScCalcConfig& rConfig);
124 static SC_DLLPUBLIC const ScCalcConfig& GetGlobalConfig();
126 static void GlobalExit(); // called by ScGlobal::Clear()
128 /// Could string be a regular expression?
129 /// If pDoc!=NULL the document options are taken into account and if
130 /// RegularExpressions are disabled the function returns false regardless
131 /// of the string content.
132 static bool MayBeRegExp( const OUString& rStr, const ScDocument* pDoc );
134 /// Fail safe division, returning an errDivisionByZero coded into a double
135 /// if denominator is 0.0
136 static inline double div( const double& fNumerator, const double& fDenominator );
138 ScMatrixRef GetNewMat(SCSIZE nC, SCSIZE nR, bool bEmpty = false);
140 enum VolatileType {
141 VOLATILE,
142 VOLATILE_MACRO,
143 NOT_VOLATILE
146 VolatileType GetVolatileType() const { return meVolatileType;}
148 private:
149 static ScCalcConfig maGlobalConfig;
151 static ScTokenStack* pGlobalStack;
152 static bool bGlobalStackInUse;
154 ScCalcConfig maCalcConfig;
155 formula::FormulaTokenIterator aCode;
156 ScAddress aPos;
157 ScTokenArray& rArr;
158 ScDocument* pDok;
159 svl::SharedStringPool& mrStrPool;
160 formula::FormulaTokenRef xResult;
161 ScJumpMatrix* pJumpMatrix; // currently active array condition, if any
162 ScTokenMatrixMap* pTokenMatrixMap; // map FormulaToken* to formula::FormulaTokenRef if in array condition
163 ScFormulaCell* pMyFormulaCell; // the cell of this formula expression
164 SvNumberFormatter* pFormatter;
166 const formula::FormulaToken*
167 pCur; // current token
168 ScTokenStack* pStackObj; // contains the stacks
169 formula::FormulaToken** pStack; // the current stack
170 sal_uInt16 nGlobalError; // global (local to this formula expression) error
171 sal_uInt16 sp; // stack pointer
172 sal_uInt16 maxsp; // the maximal used stack pointer
173 sal_uLong nFuncFmtIndex; // NumberFormatIndex of a function
174 sal_uLong nCurFmtIndex; // current NumberFormatIndex
175 sal_uLong nRetFmtIndex; // NumberFormatIndex of an expression, if any
176 short nFuncFmtType; // NumberFormatType of a function
177 short nCurFmtType; // current NumberFormatType
178 short nRetFmtType; // NumberFormatType of an expression
179 sal_uInt16 mnStringNoValueError; // the error set in ConvertStringToValue() if no value
180 sal_uInt16 mnSubTotalFlags; // flags for subtotal and aggregate functions
181 sal_uInt8 cPar; // current count of parameters
182 bool bCalcAsShown; // precision as shown
183 bool bMatrixFormula; // formula cell is a matrix formula
185 VolatileType meVolatileType;
187 /// Merge global and document specific settings.
188 void MergeCalcConfig();
190 // nMust <= nAct <= nMax ? ok : PushError
191 inline bool MustHaveParamCount( short nAct, short nMust );
192 inline bool MustHaveParamCount( short nAct, short nMust, short nMax );
193 inline bool MustHaveParamCountMin( short nAct, short nMin );
194 void PushParameterExpected();
195 void PushIllegalParameter();
196 void PushIllegalArgument();
197 void PushNoValue();
198 void PushNA();
200 // Functions for accessing a document
202 void ReplaceCell( ScAddress& ); // for TableOp
203 void ReplaceCell( SCCOL& rCol, SCROW& rRow, SCTAB& rTab ); // for TableOp
204 bool IsTableOpInRange( const ScRange& );
205 sal_uLong GetCellNumberFormat( const ScAddress& rPos, ScRefCellValue& rCell );
206 double ConvertStringToValue( const OUString& );
207 public:
208 /** For matrix back calls into the current interpreter.
209 Uses rError instead of nGlobalError and rCurFmtType instead of nCurFmtType. */
210 double ConvertStringToValue( const OUString&, sal_uInt16& rError, short& rCurFmtType );
211 private:
212 double GetCellValue( const ScAddress&, ScRefCellValue& rCell );
213 double GetCellValueOrZero( const ScAddress&, ScRefCellValue& rCell );
214 double GetValueCellValue( const ScAddress&, double fOrig );
215 void GetCellString( svl::SharedString& rStr, ScRefCellValue& rCell );
216 static sal_uInt16 GetCellErrCode( const ScRefCellValue& rCell );
218 bool CreateDoubleArr(SCCOL nCol1, SCROW nRow1, SCTAB nTab1,
219 SCCOL nCol2, SCROW nRow2, SCTAB nTab2, sal_uInt8* pCellArr);
220 bool CreateStringArr(SCCOL nCol1, SCROW nRow1, SCTAB nTab1,
221 SCCOL nCol2, SCROW nRow2, SCTAB nTab2, sal_uInt8* pCellArr);
222 bool CreateCellArr(SCCOL nCol1, SCROW nRow1, SCTAB nTab1,
223 SCCOL nCol2, SCROW nRow2, SCTAB nTab2, sal_uInt8* pCellArr);
225 // Stack operations
227 /** Does substitute with formula::FormulaErrorToken in case nGlobalError is set and the token
228 passed is not formula::FormulaErrorToken.
229 Increments RefCount of the original token if not substituted. */
230 void Push( formula::FormulaToken& r );
232 /** Does not substitute with formula::FormulaErrorToken in case nGlobalError is set.
233 Used to push RPN tokens or from within Push() or tokens that are already
234 explicit formula::FormulaErrorToken. Increments RefCount. */
235 void PushWithoutError( formula::FormulaToken& r );
237 /** Clones the token to be pushed or substitutes with formula::FormulaErrorToken if
238 nGlobalError is set and the token passed is not formula::FormulaErrorToken. */
239 void PushTempToken( const formula::FormulaToken& );
241 /** Does substitute with formula::FormulaErrorToken in case nGlobalError is set and the token
242 passed is not formula::FormulaErrorToken.
243 Increments RefCount of the original token if not substituted.
244 ATTENTION! The token had to be allocated with `new' and must not be used
245 after this call if no RefCount was set because possibly it gets immediately
246 deleted in case of an errStackOverflow or if substituted with formula::FormulaErrorToken! */
247 void PushTempToken( formula::FormulaToken* );
249 /** Does not substitute with formula::FormulaErrorToken in case nGlobalError is set.
250 Used to push tokens from within PushTempToken() or tokens that are already
251 explicit formula::FormulaErrorToken. Increments RefCount.
252 ATTENTION! The token had to be allocated with `new' and must not be used
253 after this call if no RefCount was set because possibly it gets immediately
254 decremented again and thus deleted in case of an errStackOverflow! */
255 void PushTempTokenWithoutError( formula::FormulaToken* );
257 /** If nGlobalError is set push formula::FormulaErrorToken.
258 If nGlobalError is not set do nothing.
259 Used in PushTempToken() and alike to simplify handling.
260 @return: <TRUE/> if nGlobalError. */
261 inline bool IfErrorPushError()
263 if (nGlobalError)
265 PushTempTokenWithoutError( new formula::FormulaErrorToken( nGlobalError));
266 return true;
268 return false;
271 /** Obtain cell result / content from address and push as temp token.
272 bDisplayEmptyAsString is passed to ScEmptyCell in case of an empty cell
273 result. Also obtain number format and type if _both_, type and index
274 pointer, are not NULL. */
275 void PushCellResultToken( bool bDisplayEmptyAsString, const ScAddress & rAddress,
276 short * pRetTypeExpr, sal_uLong * pRetIndexExpr );
278 formula::FormulaTokenRef PopToken();
279 void Pop();
280 void PopError();
281 double PopDouble();
282 svl::SharedString PopString();
283 void ValidateRef( const ScSingleRefData & rRef );
284 void ValidateRef( const ScComplexRefData & rRef );
285 void ValidateRef( const ScRefList & rRefList );
286 void SingleRefToVars( const ScSingleRefData & rRef, SCCOL & rCol, SCROW & rRow, SCTAB & rTab );
287 void PopSingleRef( ScAddress& );
288 void PopSingleRef(SCCOL& rCol, SCROW &rRow, SCTAB& rTab);
289 void DoubleRefToRange( const ScComplexRefData&, ScRange&, bool bDontCheckForTableOp = false );
290 /** If formula::StackVar formula::svDoubleRef pop ScDoubleRefToken and return values of
291 ScComplexRefData.
292 Else if StackVar svRefList return values of the ScComplexRefData where
293 rRefInList is pointing to. rRefInList is incremented. If rRefInList was the
294 last element in list pop ScRefListToken and set rRefInList to 0, else
295 rParam is incremented (!) to allow usage as in
296 while(nParamCount--) PopDoubleRef(aRange,nParamCount,nRefInList);
298 void PopDoubleRef( ScRange & rRange, short & rParam, size_t & rRefInList );
299 void PopDoubleRef( ScRange&, bool bDontCheckForTableOp = false );
300 void DoubleRefToVars( const formula::FormulaToken* p,
301 SCCOL& rCol1, SCROW &rRow1, SCTAB& rTab1,
302 SCCOL& rCol2, SCROW &rRow2, SCTAB& rTab2,
303 bool bDontCheckForTableOp = false );
304 ScDBRangeBase* PopDBDoubleRef();
305 void PopDoubleRef(SCCOL& rCol1, SCROW &rRow1, SCTAB& rTab1,
306 SCCOL& rCol2, SCROW &rRow2, SCTAB& rTab2,
307 bool bDontCheckForTableOp = false );
308 void PopExternalSingleRef(sal_uInt16& rFileId, OUString& rTabName, ScSingleRefData& rRef);
309 void PopExternalSingleRef(ScExternalRefCache::TokenRef& rToken, ScExternalRefCache::CellFormat* pFmt = NULL);
310 void PopExternalSingleRef(sal_uInt16& rFileId, OUString& rTabName, ScSingleRefData& rRef,
311 ScExternalRefCache::TokenRef& rToken, ScExternalRefCache::CellFormat* pFmt = NULL);
312 void PopExternalDoubleRef(sal_uInt16& rFileId, OUString& rTabName, ScComplexRefData& rRef);
313 void PopExternalDoubleRef(ScExternalRefCache::TokenArrayRef& rArray);
314 void PopExternalDoubleRef(ScMatrixRef& rMat);
315 void GetExternalDoubleRef(sal_uInt16 nFileId, const OUString& rTabName, const ScComplexRefData& aData, ScExternalRefCache::TokenArrayRef& rArray);
316 bool PopDoubleRefOrSingleRef( ScAddress& rAdr );
317 void PopDoubleRefPushMatrix();
318 // If MatrixFormula: convert formula::svDoubleRef to svMatrix, create JumpMatrix.
319 // Else convert area reference parameters marked as ForceArray to array.
320 // Returns true if JumpMatrix created.
321 bool ConvertMatrixParameters();
322 inline void MatrixDoubleRefToMatrix(); // if MatrixFormula: PopDoubleRefPushMatrix
323 // If MatrixFormula or ForceArray: ConvertMatrixParameters()
324 inline bool MatrixParameterConversion();
325 ScMatrixRef PopMatrix();
326 sc::RangeMatrix PopRangeMatrix();
327 void QueryMatrixType(ScMatrixRef& xMat, short& rRetTypeExpr, sal_uLong& rRetIndexExpr);
329 void PushDouble(double nVal);
330 void PushInt( int nVal );
331 void PushStringBuffer( const sal_Unicode* pString );
332 void PushString( const OUString& rStr );
333 void PushString( const svl::SharedString& rString );
334 void PushSingleRef(SCCOL nCol, SCROW nRow, SCTAB nTab);
335 void PushDoubleRef(SCCOL nCol1, SCROW nRow1, SCTAB nTab1,
336 SCCOL nCol2, SCROW nRow2, SCTAB nTab2);
337 void PushExternalSingleRef(sal_uInt16 nFileId, const OUString& rTabName,
338 SCCOL nCol, SCROW nRow, SCTAB nTab);
339 void PushExternalDoubleRef(sal_uInt16 nFileId, const OUString& rTabName,
340 SCCOL nCol1, SCROW nRow1, SCTAB nTab1,
341 SCCOL nCol2, SCROW nRow2, SCTAB nTab2);
342 void PushSingleRef( const ScRefAddress& rRef );
343 void PushDoubleRef( const ScRefAddress& rRef1, const ScRefAddress& rRef2 );
344 void PushMatrix( const sc::RangeMatrix& rMat );
345 void PushMatrix(const ScMatrixRef& pMat);
346 void PushError( sal_uInt16 nError );
347 /// Raw stack type without default replacements.
348 formula::StackVar GetRawStackType();
349 /// Stack type with replacement of defaults, e.g. svMissing and formula::svEmptyCell will result in formula::svDouble.
350 formula::StackVar GetStackType();
351 // peek StackType of Parameter, Parameter 1 == TOS, 2 == TOS-1, ...
352 formula::StackVar GetStackType( sal_uInt8 nParam );
353 sal_uInt8 GetByte() { return cPar; }
354 // generates a position-dependent SingleRef out of a DoubleRef
355 bool DoubleRefToPosSingleRef( const ScRange& rRange, ScAddress& rAdr );
356 double GetDoubleFromMatrix(const ScMatrixRef& pMat);
357 double GetDouble();
358 double GetDoubleWithDefault(double nDefault);
359 bool IsMissing();
360 bool GetBool() { return GetDouble() != 0.0; }
361 svl::SharedString GetString();
362 svl::SharedString GetStringFromMatrix(const ScMatrixRef& pMat);
363 // pop matrix and obtain one element, upper left or according to jump matrix
364 ScMatValType GetDoubleOrStringFromMatrix( double& rDouble, svl::SharedString& rString );
365 ScMatrixRef CreateMatrixFromDoubleRef( const formula::FormulaToken* pToken,
366 SCCOL nCol1, SCROW nRow1, SCTAB nTab1,
367 SCCOL nCol2, SCROW nRow2, SCTAB nTab2 );
368 inline ScTokenMatrixMap& GetTokenMatrixMap();
369 static ScTokenMatrixMap* CreateTokenMatrixMap();
370 ScMatrixRef GetMatrix();
371 sc::RangeMatrix GetRangeMatrix();
373 void ScTableOp(); // repeated operations
375 // common helper functions
377 void SetMaxIterationCount(sal_uInt16 n);
378 inline void CurFmtToFuncFmt()
379 { nFuncFmtType = nCurFmtType; nFuncFmtIndex = nCurFmtIndex; }
381 /** Check if a double is suitable as string position or length argument.
383 If fVal is Inf or NaN it is changed to -1, if it is less than 0 it is
384 sanitized to 0, if it is greater than some implementation defined max
385 string length it is sanitized to that max.
387 @return TRUE if double value fVal is suitable as string argument and was
388 not sanitized.
389 FALSE if not and fVal was adapted.
391 static inline bool CheckStringPositionArgument( double & fVal );
393 /** Obtain a double suitable as string position or length argument.
394 Returns -1 if the number is Inf or NaN or less than 0 or greater than some
395 implementation defined max string length. */
396 inline double GetStringPositionArgument();
398 // Check for String overflow of rResult+rAdd and set error and erase rResult
399 // if so. Return true if ok, false if overflow
400 inline bool CheckStringResultLen( OUString& rResult, const OUString& rAdd );
401 // Set error according to rVal, and set rVal to 0.0 if there was an error.
402 inline void TreatDoubleError( double& rVal );
403 // Lookup using ScLookupCache, @returns true if found and result address
404 bool LookupQueryWithCache( ScAddress & o_rResultPos,
405 const ScQueryParam & rParam ) const;
407 void ScIfJump();
408 void ScIfError( bool bNAonly );
409 void ScChooseJump();
411 // Be sure to only call this if pStack[sp-nStackLevel] really contains a
412 // ScJumpMatrixToken, no further checks are applied!
413 // Returns true if last jump was executed and result matrix pushed.
414 bool JumpMatrix( short nStackLevel );
416 double Compare( ScQueryOp eOp );
417 /** @param pOptions
418 NULL means case sensitivity document option is to be used!
420 sc::RangeMatrix CompareMat( ScQueryOp eOp, sc::CompareOptions* pOptions = NULL );
421 ScMatrixRef QueryMat( const ScMatrixRef& pMat, sc::CompareOptions& rOptions );
422 void ScEqual();
423 void ScNotEqual();
424 void ScLess();
425 void ScGreater();
426 void ScLessEqual();
427 void ScGreaterEqual();
428 void ScAnd();
429 void ScOr();
430 void ScXor();
431 void ScNot();
432 void ScNeg();
433 void ScPercentSign();
434 void ScIntersect();
435 void ScRangeFunc();
436 void ScUnionFunc();
437 void ScPi();
438 void ScRandom();
439 void ScTrue();
440 void ScFalse();
441 void ScDeg();
442 void ScRad();
443 void ScSin();
444 void ScCos();
445 void ScTan();
446 void ScCot();
447 void ScArcSin();
448 void ScArcCos();
449 void ScArcTan();
450 void ScArcCot();
451 void ScSinHyp();
452 void ScCosHyp();
453 void ScTanHyp();
454 void ScCotHyp();
455 void ScArcSinHyp();
456 void ScArcCosHyp();
457 void ScArcTanHyp();
458 void ScArcCotHyp();
459 void ScCosecant();
460 void ScSecant();
461 void ScCosecantHyp();
462 void ScSecantHyp();
463 void ScExp();
464 void ScLn();
465 void ScLog10();
466 void ScSqrt();
467 void ScIsEmpty();
468 bool IsString();
469 void ScIsString();
470 void ScIsNonString();
471 void ScIsLogical();
472 void ScType();
473 void ScCell();
474 void ScCellExternal();
475 void ScIsRef();
476 void ScIsValue();
477 void ScIsFormula();
478 void ScFormula();
479 void ScRoman();
480 void ScArabic();
481 void ScIsNV();
482 void ScIsErr();
483 void ScIsError();
484 bool IsEven();
485 void ScIsEven();
486 void ScIsOdd();
487 void ScN();
488 void ScCode();
489 void ScTrim();
490 void ScUpper();
491 void ScProper();
492 void ScLower();
493 void ScLen();
494 void ScT();
495 void ScValue();
496 void ScNumberValue();
497 void ScClean();
498 void ScChar();
499 void ScJis();
500 void ScAsc();
501 void ScUnicode();
502 void ScUnichar();
503 void ScMin( bool bTextAsZero = false );
504 void ScMax( bool bTextAsZero = false );
505 double IterateParameters( ScIterFunc, bool bTextAsZero = false );
506 void ScSumSQ();
507 void ScSum();
508 void ScProduct();
509 void ScAverage( bool bTextAsZero = false );
510 void ScCount();
511 void ScCount2();
512 void GetStVarParams( double& rVal, double& rValCount, bool bTextAsZero = false );
513 void ScVar( bool bTextAsZero = false );
514 void ScVarP( bool bTextAsZero = false );
515 void ScStDev( bool bTextAsZero = false );
516 void ScStDevP( bool bTextAsZero = false );
517 void ScColumns();
518 void ScRows();
519 void ScSheets();
520 void ScColumn();
521 void ScRow();
522 void ScSheet();
523 void ScMatch();
524 double IterateParametersIf( ScIterFuncIf );
525 void ScCountIf();
526 void ScSumIf();
527 void ScAverageIf();
528 double IterateParametersIfs( ScIterFuncIfs );
529 void ScSumIfs();
530 void ScAverageIfs();
531 void ScCountIfs();
532 void ScCountEmptyCells();
533 void ScLookup();
534 void ScHLookup();
535 void ScVLookup();
536 void ScSubTotal();
538 // If upon call rMissingField==true then the database field parameter may be
539 // missing (Xcl DCOUNT() syntax), or may be faked as missing by having the
540 // value 0.0 or being exactly the entire database range reference (old SO
541 // compatibility). If this was the case then rMissingField is set to true upon
542 // return. If rMissingField==false upon call all "missing cases" are considered
543 // to be an error.
544 ScDBQueryParamBase* GetDBParams( bool& rMissingField );
546 void DBIterator( ScIterFunc );
547 void ScDBSum();
548 void ScDBCount();
549 void ScDBCount2();
550 void ScDBAverage();
551 void ScDBGet();
552 void ScDBMax();
553 void ScDBMin();
554 void ScDBProduct();
555 void GetDBStVarParams( double& rVal, double& rValCount );
556 void ScDBStdDev();
557 void ScDBStdDevP();
558 void ScDBVar();
559 void ScDBVarP();
560 void ScIndirect();
561 void ScAddressFunc();
562 void ScOffset();
563 void ScIndex();
564 void ScMultiArea();
565 void ScAreas();
566 void ScCurrency();
567 void ScReplace();
568 void ScFixed();
569 void ScFind();
570 void ScExact();
571 void ScLeft();
572 void ScRight();
573 void ScSearch();
574 void ScMid();
575 void ScText();
576 void ScSubstitute();
577 void ScRept();
578 void ScConcat();
579 void ScExternal();
580 void ScMissing();
581 void ScMacro();
582 bool SetSbxVariable( SbxVariable* pVar, const ScAddress& );
583 bool SetSbxVariable( SbxVariable* pVar, SCCOL nCol, SCROW nRow, SCTAB nTab );
584 sal_uInt16 GetErrorType();
585 void ScErrorType();
586 void ScErrorType_ODF();
587 void ScDBArea();
588 void ScColRowNameAuto();
589 void ScGetPivotData();
590 void ScHyperLink();
591 void ScBahtText();
592 void ScBitAnd();
593 void ScBitOr();
594 void ScBitXor();
595 void ScBitRshift();
596 void ScBitLshift();
597 void ScTTT();
598 void ScDebugVar();
600 /** Obtain the date serial number for a given date.
601 @param bStrict
602 If false, nYear < 100 takes the two-digit year setting into account,
603 and rollover of invalid calendar dates takes place, e.g. 1999-02-31 =>
604 1999-03-03.
605 If true, the date passed must be a valid Gregorian calendar date. No
606 two-digit expanding or rollover is done.
608 @param bCheckGregorian
609 If true, date must be Gregorian, i.e. >= 1582-10-15.
610 If false, don't care, any valid date >= 0-1-1 will do.
612 double GetDateSerial( sal_Int16 nYear, sal_Int16 nMonth, sal_Int16 nDay, bool bStrict, bool bCheckGregorian );
614 void ScGetActDate();
615 void ScGetActTime();
616 void ScGetYear();
617 void ScGetMonth();
618 void ScGetDay();
619 void ScGetDayOfWeek();
620 void ScGetWeekOfYear();
621 void ScEasterSunday();
622 sal_uInt16 GetWeekendAndHolidayMasks( const sal_uInt8 nParamCount, const sal_uInt32 nNullDate,
623 ::std::vector<double>& rSortArray, bool bWeekendMask[ 7 ] );
624 sal_uInt16 GetWeekendAndHolidayMasks_MS( const sal_uInt8 nParamCount, const sal_uInt32 nNullDate,
625 ::std::vector<double>& rSortArray, bool bWeekendMask[ 7 ] );
626 static inline sal_Int16 GetDayOfWeek( sal_Int32 n );
627 void ScNetWorkdays( bool bOOXML_Version );
628 void ScWorkday_MS();
629 void ScGetHour();
630 void ScGetMin();
631 void ScGetSec();
632 void ScPlusMinus();
633 void ScAbs();
634 void ScInt();
635 void ScEven();
636 void ScOdd();
637 void ScCeil( bool bODFF );
638 void ScCeil_MS();
639 void ScCeil_Precise();
640 void ScFloor( bool bODFF );
641 void ScFloor_MS();
642 void ScFloor_Precise();
643 void RoundNumber( rtl_math_RoundingMode eMode );
644 void ScRound();
645 void ScRoundUp();
646 void ScRoundDown();
647 void ScGetDateValue();
648 void ScGetTimeValue();
649 void ScArcTan2();
650 void ScLog();
651 void ScGetDate();
652 void ScGetTime();
653 void ScGetDiffDate();
654 void ScGetDiffDate360();
655 void ScGetDateDif();
656 void ScPower();
657 void ScAmpersand();
658 void ScAdd();
659 void ScSub();
660 void ScMul();
661 void ScDiv();
662 void ScPow();
663 void ScCurrent();
664 void ScStyle();
665 void ScDde();
666 void ScBase();
667 void ScDecimal();
668 void ScConvert();
669 void ScEuroConvert();
671 // financial functions
672 void ScNPV();
673 void ScIRR();
674 void ScMIRR();
675 void ScISPMT();
677 static double ScGetBw(double fZins, double fZzr, double fRmz,
678 double fZw, double fF);
679 void ScPV();
680 void ScSYD();
681 static double ScGetGDA(double fWert, double fRest, double fDauer,
682 double fPeriode, double fFactor);
683 void ScDDB();
684 void ScDB();
685 static double ScInterVDB(double fWert,double fRest,double fDauer,double fDauer1,
686 double fPeriode,double fFactor);
687 void ScVDB();
688 void ScDuration();
689 void ScSLN();
690 static double ScGetRmz(double fZins, double fZzr, double fBw,
691 double fZw, double fF);
692 void ScPMT();
693 void ScRRI();
694 static double ScGetZw(double fZins, double fZzr, double fRmz,
695 double fBw, double fF);
696 void ScFV();
697 void ScNper();
698 static bool RateIteration(double fNper, double fPayment, double fPv,
699 double fFv, double fPayType, double& fGuess);
700 void ScRate();
701 double ScGetCompoundInterest(double fZins, double fZr, double fZzr, double fBw,
702 double fZw, double fF, double& fRmz);
703 void ScIpmt();
704 void ScPpmt();
705 void ScCumIpmt();
706 void ScCumPrinc();
707 void ScEffective();
708 void ScNominal();
709 void ScMod();
710 void ScIntercept();
711 static double ScGetGCD(double fx, double fy);
712 void ScGCD();
713 void ScLCM();
715 // matrix functions
716 void ScMatValue();
717 static void MEMat(const ScMatrixRef& mM, SCSIZE n);
718 void ScMatDet();
719 void ScMatInv();
720 void ScMatMult();
721 void ScMatTrans();
722 void ScEMat();
723 void ScMatRef();
724 ScMatrixRef MatConcat(const ScMatrixRef& pMat1, const ScMatrixRef& pMat2);
725 void ScSumProduct();
726 void ScSumX2MY2();
727 void ScSumX2DY2();
728 void ScSumXMY2();
729 void ScGrowth();
730 bool CalculateSkew(double& fSum,double& fCount,double& vSum,std::vector<double>& values);
731 void CalculateSkewOrSkewp( bool bSkewp );
732 void CalculateSlopeIntercept(bool bSlope);
733 void CalculateSmallLarge(bool bSmall);
734 void CalculatePearsonCovar( bool _bPearson, bool _bStexy, bool _bSample ); //fdo#70000 argument _bSample is ignored if _bPearson == true
735 bool CalculateTest( bool _bTemplin
736 ,const SCSIZE nC1, const SCSIZE nC2,const SCSIZE nR1,const SCSIZE nR2
737 ,const ScMatrixRef& pMat1,const ScMatrixRef& pMat2
738 ,double& fT,double& fF);
739 void CalculateLookup(bool bHLookup);
740 bool FillEntry(ScQueryEntry& rEntry);
741 void CalculateAddSub(bool _bSub);
742 void CalculateTrendGrowth(bool _bGrowth);
743 void CalculateRGPRKP(bool _bRKP);
744 void CalculateSumX2MY2SumX2DY2(bool _bSumX2DY2);
745 void CalculateMatrixValue(const ScMatrix* pMat,SCSIZE nC,SCSIZE nR);
746 bool CheckMatrix(bool _bLOG,sal_uInt8& nCase,SCSIZE& nCX,SCSIZE& nCY,SCSIZE& nRX,SCSIZE& nRY,SCSIZE& M,SCSIZE& N,ScMatrixRef& pMatX,ScMatrixRef& pMatY);
747 void ScLinest();
748 void ScLogest();
749 void ScForecast();
750 void ScNoName();
751 void ScBadName();
752 // Statistics:
753 static double taylor(const double* pPolynom, sal_uInt16 nMax, double x);
754 static double gauss(double x);
756 public:
757 static SC_DLLPUBLIC double phi(double x);
758 static SC_DLLPUBLIC double integralPhi(double x);
759 static SC_DLLPUBLIC double gaussinv(double x);
761 private:
762 double GetBetaDist(double x, double alpha, double beta); //cumulative distribution function
763 double GetBetaDistPDF(double fX, double fA, double fB); //probability density function)
764 double GetChiDist(double fChi, double fDF); // for LEGACY.CHIDIST, returns right tail
765 double GetChiSqDistCDF(double fX, double fDF); // for CHISQDIST, returns left tail
766 static double GetChiSqDistPDF(double fX, double fDF); // probability density function
767 double GetFDist(double x, double fF1, double fF2);
768 double GetTDist( double T, double fDF, int nType );
769 double Fakultaet(double x);
770 static double BinomKoeff(double n, double k);
771 double GetGamma(double x);
772 static double GetLogGamma(double x);
773 double GetBeta(double fAlpha, double fBeta);
774 static double GetLogBeta(double fAlpha, double fBeta);
775 double GetBinomDistPMF(double x, double n, double p); //probability mass function
776 double GetHypGeomDist( double x, double n, double M, double N );
777 void ScLogGamma();
778 void ScGamma();
779 void ScPhi();
780 void ScGauss();
781 void ScStdNormDist();
782 void ScStdNormDist_MS();
783 void ScFisher();
784 void ScFisherInv();
785 void ScFact();
786 void ScNormDist( int nMinParamCount );
787 void ScGammaDist( int nMinParamCount );
788 void ScGammaInv();
789 void ScExpDist();
790 void ScBinomDist();
791 void ScPoissonDist();
792 void ScCombin();
793 void ScCombinA();
794 void ScPermut();
795 void ScPermutationA();
796 void ScB();
797 void ScHypGeomDist();
798 void ScHypGeomDist_MS();
799 void ScLogNormDist( int nMinParamCount );
800 void ScLogNormInv();
801 void ScTDist();
802 void ScTDist_MS();
803 void ScTDist_T( int nTails );
804 void ScFDist();
805 void ScFDist_LT();
806 void ScChiDist(); // for LEGACY.CHIDIST, returns right tail
807 void ScChiSqDist(); // returns left tail or density
808 void ScChiSqDist_MS();
809 void ScChiSqInv(); //invers to CHISQDIST
810 void ScWeibull();
811 void ScBetaDist();
812 void ScBetaDist_MS();
813 void ScFInv();
814 void ScFInv_LT();
815 void ScTInv( int nType );
816 void ScChiInv();
817 void ScBetaInv();
818 void ScCritBinom();
819 void ScNegBinomDist();
820 void ScNegBinomDist_MS();
821 void ScKurt();
822 void ScHarMean();
823 void ScGeoMean();
824 void ScStandard();
825 void ScSkew();
826 void ScSkewp();
827 void ScMedian();
828 double GetMedian( ::std::vector<double> & rArray );
829 double GetPercentile( ::std::vector<double> & rArray, double fPercentile );
830 double GetPercentileExclusive( ::std::vector<double> & rArray, double fPercentile );
831 void GetNumberSequenceArray( sal_uInt8 nParamCount, ::std::vector<double>& rArray, bool bConvertTextInArray );
832 void GetSortArray( sal_uInt8 nParamCount, ::std::vector<double>& rSortArray, ::std::vector<long>* pIndexOrder, bool bConvertTextInArray, bool bAllowEmptyArray );
833 static void QuickSort(::std::vector<double>& rSortArray, ::std::vector<long>* pIndexOrder = NULL);
834 void ScModalValue();
835 void ScModalValue_Multi();
836 void ScAveDev();
837 void ScAggregate();
838 void ScDevSq();
839 void ScZTest();
840 void ScTTest();
841 void ScFTest();
842 void ScChiTest();
843 void ScRank( bool bAverage );
844 void ScPercentile( bool bInclusive );
845 void ScPercentrank( bool bInclusive );
846 static double GetPercentrank( ::std::vector<double> & rArray, double fVal, bool bInclusive );
847 void ScLarge();
848 void ScSmall();
849 void ScFrequency();
850 void ScQuartile( bool bInclusive );
851 void ScNormInv();
852 void ScSNormInv();
853 void ScConfidence();
854 void ScConfidenceT();
855 void ScTrimMean();
856 void ScProbability();
857 void ScCorrel();
858 void ScCovarianceP();
859 void ScCovarianceS();
860 void ScPearson();
861 void ScRSQ();
862 void ScSTEYX();
863 void ScSlope();
864 void ScTrend();
865 void ScInfo();
866 void ScLenB();
867 void ScRightB();
868 void ScLeftB();
869 void ScMidB();
871 void ScFilterXML();
872 void ScWebservice();
873 void ScEncodeURL();
874 void ScColor();
875 void ScErf();
876 void ScErfc();
878 static const double fMaxGammaArgument;
880 double GetGammaContFraction(double fA,double fX);
881 double GetGammaSeries(double fA,double fX);
882 double GetLowRegIGamma(double fA,double fX); // lower regularized incomplete gamma function, GAMMAQ
883 double GetUpRegIGamma(double fA,double fX); // upper regularized incomplete gamma function, GAMMAP
884 // probability density function; fLambda is "scale" parameter
885 double GetGammaDistPDF(double fX, double fAlpha, double fLambda);
886 // cumulative distribution function; fLambda is "scale" parameter
887 double GetGammaDist(double fX, double fAlpha, double fLambda);
888 double GetTInv( double fAlpha, double fSize, int nType );
890 public:
891 ScInterpreter( ScFormulaCell* pCell, ScDocument* pDoc,
892 const ScAddress&, ScTokenArray& );
893 ~ScInterpreter();
895 formula::StackVar Interpret();
897 void SetError(sal_uInt16 nError)
898 { if (nError && !nGlobalError) nGlobalError = nError; }
900 sal_uInt16 GetError() const { return nGlobalError; }
901 formula::StackVar GetResultType() const { return xResult->GetType(); }
902 svl::SharedString GetStringResult() const;
903 double GetNumResult() const { return xResult->GetDouble(); }
904 formula::FormulaTokenRef GetResultToken() const { return xResult; }
905 short GetRetFormatType() const { return nRetFmtType; }
906 sal_uLong GetRetFormatIndex() const { return nRetFmtIndex; }
909 inline void ScInterpreter::MatrixDoubleRefToMatrix()
911 if ( (bMatrixFormula || pCur->HasForceArray()) && GetStackType() == formula::svDoubleRef )
913 GetTokenMatrixMap(); // make sure it exists, create if not.
914 PopDoubleRefPushMatrix();
918 inline bool ScInterpreter::MatrixParameterConversion()
920 if ( (bMatrixFormula || pCur->HasForceArray() || ScParameterClassification::HasForceArray( pCur->GetOpCode())) &&
921 !pJumpMatrix && sp > 0 )
922 return ConvertMatrixParameters();
923 return false;
926 inline ScTokenMatrixMap& ScInterpreter::GetTokenMatrixMap()
928 if (!pTokenMatrixMap)
929 pTokenMatrixMap = CreateTokenMatrixMap();
930 return *pTokenMatrixMap;
933 inline bool ScInterpreter::MustHaveParamCount( short nAct, short nMust )
935 if ( nAct == nMust )
936 return true;
937 if ( nAct < nMust )
938 PushParameterExpected();
939 else
940 PushIllegalParameter();
941 return false;
944 inline bool ScInterpreter::MustHaveParamCount( short nAct, short nMust, short nMax )
946 if ( nMust <= nAct && nAct <= nMax )
947 return true;
948 if ( nAct < nMust )
949 PushParameterExpected();
950 else
951 PushIllegalParameter();
952 return false;
955 inline bool ScInterpreter::MustHaveParamCountMin( short nAct, short nMin )
957 if ( nAct >= nMin )
958 return true;
959 PushParameterExpected();
960 return false;
963 inline bool ScInterpreter::CheckStringPositionArgument( double & fVal )
965 if (!rtl::math::isFinite( fVal))
967 fVal = -1.0;
968 return false;
970 else if (fVal < 0.0)
972 fVal = 0.0;
973 return false;
975 else if (fVal > SAL_MAX_UINT16)
977 fVal = static_cast<double>(SAL_MAX_UINT16);
978 return false;
980 return true;
983 inline double ScInterpreter::GetStringPositionArgument()
985 double fVal = rtl::math::approxFloor( GetDouble());
986 if (!CheckStringPositionArgument( fVal))
988 fVal = -1.0;
990 return fVal;
993 inline bool ScInterpreter::CheckStringResultLen( OUString& rResult, const OUString& rAdd )
995 if ( rResult.getLength() + rAdd.getLength() > SAL_MAX_UINT16 )
997 SetError( errStringOverflow );
998 rResult.clear();
999 return false;
1001 return true;
1004 inline void ScInterpreter::TreatDoubleError( double& rVal )
1006 if ( !::rtl::math::isFinite( rVal ) )
1008 sal_uInt16 nErr = GetDoubleErrorValue( rVal );
1009 if ( nErr )
1010 SetError( nErr );
1011 else
1012 SetError( errNoValue );
1013 rVal = 0.0;
1017 inline double ScInterpreter::div( const double& fNumerator, const double& fDenominator )
1019 return sc::div(fNumerator, fDenominator);
1022 inline sal_Int16 ScInterpreter::GetDayOfWeek( sal_Int32 n )
1023 { // monday = 0, ..., sunday = 6
1024 return static_cast< sal_Int16 >( ( n - 1 ) % 7 );
1027 #endif
1029 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */