xref: /aoo41x/main/sc/source/core/inc/interpre.hxx (revision cdf0e10c)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 #ifndef SC_INTERPRE_HXX
29 #define SC_INTERPRE_HXX
30 
31 #include <math.h>
32 #include <rtl/math.hxx>
33 #include "formula/errorcodes.hxx"
34 #include "cell.hxx"
35 #include "scdll.hxx"
36 #include "document.hxx"
37 #include "scmatrix.hxx"
38 
39 #include <math.h>
40 #include <map>
41 
42 class ScDocument;
43 class SbxVariable;
44 class ScBaseCell;
45 class ScFormulaCell;
46 class SvNumberFormatter;
47 class ScDBRangeBase;
48 struct MatrixDoubleOp;
49 struct ScQueryParam;
50 struct ScDBQueryParamBase;
51 
52 struct ScCompare
53 {
54     double  nVal[2];
55     String* pVal[2];
56     sal_Bool    bVal[2];
57     sal_Bool    bEmpty[2];
58         ScCompare( String* p1, String* p2 )
59         {
60             pVal[ 0 ] = p1;
61             pVal[ 1 ] = p2;
62             bEmpty[0] = sal_False;
63             bEmpty[1] = sal_False;
64         }
65 };
66 
67 struct ScCompareOptions
68 {
69     ScQueryEntry        aQueryEntry;
70     bool                bRegEx;
71     bool                bMatchWholeCell;
72     bool                bIgnoreCase;
73 
74                         ScCompareOptions( ScDocument* pDoc, const ScQueryEntry& rEntry, bool bReg );
75 private:
76                         // Not implemented, prevent usage.
77                         ScCompareOptions();
78                         ScCompareOptions( const ScCompareOptions & );
79      ScCompareOptions&  operator=( const ScCompareOptions & );
80 };
81 
82 class ScToken;
83 
84 #define MAXSTACK      (4096 / sizeof(formula::FormulaToken*))
85 
86 class ScTokenStack
87 {
88 public:
89     DECL_FIXEDMEMPOOL_NEWDEL( ScTokenStack )
90     formula::FormulaToken* pPointer[ MAXSTACK ];
91 };
92 
93 enum ScIterFunc {
94     ifSUM,                              // Aufsummieren
95     ifSUMSQ,                            // Quadratsummen
96     ifPRODUCT,                          // Multiplizieren
97     ifAVERAGE,                          // Durchschnitt
98     ifCOUNT,                            // Anzahl Werte
99     ifCOUNT2,                           // Anzahl Werte (nichtleer)
100     ifMIN,                              // Minimum
101     ifMAX                               // Maximum
102 };
103 
104 struct FormulaTokenRef_less
105 {
106     bool operator () ( const formula::FormulaConstTokenRef& r1, const formula::FormulaConstTokenRef& r2 ) const
107         { return &r1 < &r2; }
108 };
109 typedef ::std::map< const formula::FormulaConstTokenRef, formula::FormulaTokenRef, FormulaTokenRef_less> ScTokenMatrixMap;
110 
111 class ScInterpreter
112 {
113     // distibution function objects need the GetxxxDist methods
114     friend class ScGammaDistFunction;
115     friend class ScBetaDistFunction;
116     friend class ScTDistFunction;
117     friend class ScFDistFunction;
118     friend class ScChiDistFunction;
119     friend class ScChiSqDistFunction;
120 
121 public:
122     DECL_FIXEDMEMPOOL_NEWDEL( ScInterpreter )
123 
124     static void GlobalExit();           // aus ScGlobal::Clear() gerufen
125 
126     /// Could string be a regular expression?
127     /// If pDoc!=NULL the document options are taken into account and if
128     /// RegularExpressions are disabled the function returns sal_False regardless
129     /// of the string content.
130     static sal_Bool MayBeRegExp( const String& rStr, const ScDocument* pDoc );
131 
132     /// Fail safe division, returning an errDivisionByZero coded into a double
133     /// if denominator is 0.0
134     static inline double div( const double& fNumerator, const double& fDenominator );
135 
136     ScMatrixRef GetNewMat(SCSIZE nC, SCSIZE nR);
137 private:
138     static ScTokenStack*    pGlobalStack;
139     static sal_Bool             bGlobalStackInUse;
140 
141     formula::FormulaTokenIterator aCode;
142     ScAddress   aPos;
143     ScTokenArray& rArr;
144     ScDocument* pDok;
145     formula::FormulaTokenRef  xResult;
146     ScJumpMatrix*   pJumpMatrix;        // currently active array condition, if any
147     ScTokenMatrixMap* pTokenMatrixMap;  // map ScToken* to formula::FormulaTokenRef if in array condition
148     ScFormulaCell* pMyFormulaCell;      // the cell of this formula expression
149     SvNumberFormatter* pFormatter;
150 
151     const formula::FormulaToken*
152                 pCur;                // current token
153     String      aTempStr;               // for GetString()
154     ScTokenStack* pStackObj;            // contains the stacks
155     formula::FormulaToken**   pStack;                 // the current stack
156     sal_uInt16      nGlobalError;           // global (local to this formula expression) error
157     sal_uInt16      sp;                     // stack pointer
158     sal_uInt16      maxsp;                  // the maximal used stack pointer
159     sal_uLong       nFuncFmtIndex;          // NumberFormatIndex of a function
160     sal_uLong       nCurFmtIndex;           // current NumberFormatIndex
161     sal_uLong       nRetFmtIndex;           // NumberFormatIndex of an expression, if any
162     short       nFuncFmtType;           // NumberFormatType of a function
163     short       nCurFmtType;            // current NumberFormatType
164     short       nRetFmtType;            // NumberFormatType of an expression
165     sal_uInt16      mnStringNoValueError;   // the error set in ConvertStringToValue() if no value
166     sal_Bool        glSubTotal;             // flag for subtotal functions
167     sal_uInt8        cPar;                   // current count of parameters
168     sal_Bool        bCalcAsShown;           // precision as shown
169     sal_Bool        bMatrixFormula;         // formula cell is a matrix formula
170 
171 //---------------------------------Funktionen in interpre.cxx---------
172 // nMust <= nAct <= nMax ? ok : PushError
173 inline sal_Bool MustHaveParamCount( short nAct, short nMust );
174 inline sal_Bool MustHaveParamCount( short nAct, short nMust, short nMax );
175 inline sal_Bool MustHaveParamCountMin( short nAct, short nMin );
176 void PushParameterExpected();
177 void PushIllegalParameter();
178 void PushIllegalArgument();
179 void PushNoValue();
180 void PushNA();
181 //-------------------------------------------------------------------------
182 // Funktionen fuer den Zugriff auf das Document
183 //-------------------------------------------------------------------------
184 void ReplaceCell( ScAddress& );     // for TableOp
185 void ReplaceCell( SCCOL& rCol, SCROW& rRow, SCTAB& rTab );  // for TableOp
186 sal_Bool IsTableOpInRange( const ScRange& );
187 sal_uLong GetCellNumberFormat( const ScAddress&, const ScBaseCell* );
188 double ConvertStringToValue( const String& );
189 double GetCellValue( const ScAddress&, const ScBaseCell* );
190 double GetCellValueOrZero( const ScAddress&, const ScBaseCell* );
191 double GetValueCellValue( const ScAddress&, const ScValueCell* );
192 ScBaseCell* GetCell( const ScAddress& rPos )
193     { return pDok->GetCell( rPos ); }
194 void GetCellString( String& rStr, const ScBaseCell* pCell );
195 inline sal_uInt16 GetCellErrCode( const ScBaseCell* pCell )
196     { return pCell ? pCell->GetErrorCode() : 0; }
197 inline CellType GetCellType( const ScBaseCell* pCell )
198     { return pCell ? pCell->GetCellType() : CELLTYPE_NONE; }
199 /// Really empty or inherited emptiness.
200 inline sal_Bool HasCellEmptyData( const ScBaseCell* pCell )
201     { return pCell ? pCell->HasEmptyData() : sal_True; }
202 /// This includes inherited emptiness, which usually is regarded as value!
203 inline sal_Bool HasCellValueData( const ScBaseCell* pCell )
204     { return pCell ? pCell->HasValueData() : sal_False; }
205 /// Not empty and not value.
206 inline sal_Bool HasCellStringData( const ScBaseCell* pCell )
207     { return pCell ? pCell->HasStringData() : sal_False; }
208 
209 sal_Bool CreateDoubleArr(SCCOL nCol1, SCROW nRow1, SCTAB nTab1,
210                      SCCOL nCol2, SCROW nRow2, SCTAB nTab2, sal_uInt8* pCellArr);
211 sal_Bool CreateStringArr(SCCOL nCol1, SCROW nRow1, SCTAB nTab1,
212                      SCCOL nCol2, SCROW nRow2, SCTAB nTab2, sal_uInt8* pCellArr);
213 sal_Bool CreateCellArr(SCCOL nCol1, SCROW nRow1, SCTAB nTab1,
214                    SCCOL nCol2, SCROW nRow2, SCTAB nTab2, sal_uInt8* pCellArr);
215 
216 //-----------------------------------------------------------------------------
217 // Stack operations
218 //-----------------------------------------------------------------------------
219 
220 /** Does substitute with formula::FormulaErrorToken in case nGlobalError is set and the token
221     passed is not formula::FormulaErrorToken.
222     Increments RefCount of the original token if not substituted. */
223 void Push( formula::FormulaToken& r );
224 
225 /** Does not substitute with formula::FormulaErrorToken in case nGlobalError is set.
226     Used to push RPN tokens or from within Push() or tokens that are already
227     explicit formula::FormulaErrorToken. Increments RefCount. */
228 void PushWithoutError( formula::FormulaToken& r );
229 
230 /** Clones the token to be pushed or substitutes with formula::FormulaErrorToken if
231     nGlobalError is set and the token passed is not formula::FormulaErrorToken. */
232 void PushTempToken( const formula::FormulaToken& );
233 
234 /** Does substitute with formula::FormulaErrorToken in case nGlobalError is set and the token
235     passed is not formula::FormulaErrorToken.
236     Increments RefCount of the original token if not substituted.
237     ATTENTION! The token had to be allocated with `new' and must not be used
238     after this call if no RefCount was set because possibly it gets immediately
239     deleted in case of an errStackOverflow or if substituted with formula::FormulaErrorToken! */
240 void PushTempToken( formula::FormulaToken* );
241 
242 /** Does not substitute with formula::FormulaErrorToken in case nGlobalError is set.
243     Used to push tokens from within PushTempToken() or tokens that are already
244     explicit formula::FormulaErrorToken. Increments RefCount.
245     ATTENTION! The token had to be allocated with `new' and must not be used
246     after this call if no RefCount was set because possibly it gets immediately
247     decremented again and thus deleted in case of an errStackOverflow! */
248 void PushTempTokenWithoutError( formula::FormulaToken* );
249 
250 /** If nGlobalError is set push formula::FormulaErrorToken.
251     If nGlobalError is not set do nothing.
252     Used in PushTempToken() and alike to simplify handling.
253     @return: <TRUE/> if nGlobalError. */
254 inline bool IfErrorPushError()
255 {
256     if (nGlobalError)
257     {
258         PushTempTokenWithoutError( new formula::FormulaErrorToken( nGlobalError));
259         return true;
260     }
261     return false;
262 }
263 
264 /** Obtain cell result / content from address and push as temp token.
265     bDisplayEmptyAsString is passed to ScEmptyCell in case of an empty cell
266     result. Also obtain number format and type if _both_, type and index
267     pointer, are not NULL. */
268 void PushCellResultToken( bool bDisplayEmptyAsString, const ScAddress & rAddress,
269         short * pRetTypeExpr, sal_uLong * pRetIndexExpr );
270 
271 formula::FormulaTokenRef PopToken();
272 void Pop();
273 void PopError();
274 double PopDouble();
275 const String& PopString();
276 void ValidateRef( const ScSingleRefData & rRef );
277 void ValidateRef( const ScComplexRefData & rRef );
278 void ValidateRef( const ScRefList & rRefList );
279 void SingleRefToVars( const ScSingleRefData & rRef, SCCOL & rCol, SCROW & rRow, SCTAB & rTab );
280 void PopSingleRef( ScAddress& );
281 void PopSingleRef(SCCOL& rCol, SCROW &rRow, SCTAB& rTab);
282 void DoubleRefToRange( const ScComplexRefData&, ScRange&, sal_Bool bDontCheckForTableOp = sal_False );
283 /** If formula::StackVar formula::svDoubleRef pop ScDoubleRefToken and return values of
284     ScComplexRefData.
285     Else if StackVar svRefList return values of the ScComplexRefData where
286     rRefInList is pointing to. rRefInList is incremented. If rRefInList was the
287     last element in list pop ScRefListToken and set rRefInList to 0, else
288     rParam is incremented (!) to allow usage as in
289     while(nParamCount--) PopDoubleRef(aRange,nParamCount,nRefInList);
290   */
291 void PopDoubleRef( ScRange & rRange, short & rParam, size_t & rRefInList );
292 void PopDoubleRef( ScRange&, sal_Bool bDontCheckForTableOp = sal_False );
293 void DoubleRefToVars( const ScToken* p,
294         SCCOL& rCol1, SCROW &rRow1, SCTAB& rTab1,
295         SCCOL& rCol2, SCROW &rRow2, SCTAB& rTab2,
296         sal_Bool bDontCheckForTableOp = sal_False );
297 ScDBRangeBase* PopDoubleRef();
298 void PopDoubleRef(SCCOL& rCol1, SCROW &rRow1, SCTAB& rTab1,
299                           SCCOL& rCol2, SCROW &rRow2, SCTAB& rTab2,
300                           sal_Bool bDontCheckForTableOp = sal_False );
301 sal_Bool PopDoubleRefOrSingleRef( ScAddress& rAdr );
302 void PopDoubleRefPushMatrix();
303 // If MatrixFormula: convert formula::svDoubleRef to svMatrix, create JumpMatrix.
304 // Else convert area reference parameters marked as ForceArray to array.
305 // Returns sal_True if JumpMatrix created.
306 bool ConvertMatrixParameters();
307 inline void MatrixDoubleRefToMatrix();      // if MatrixFormula: PopDoubleRefPushMatrix
308 // If MatrixFormula or ForceArray: ConvertMatrixParameters()
309 inline bool MatrixParameterConversion();
310 ScMatrixRef PopMatrix();
311 //void PushByte(sal_uInt8 nVal);
312 void PushDouble(double nVal);
313 void PushInt( int nVal );
314 void PushStringBuffer( const sal_Unicode* pString );
315 void PushString( const String& rString );
316 void PushSingleRef(SCCOL nCol, SCROW nRow, SCTAB nTab);
317 void PushDoubleRef(SCCOL nCol1, SCROW nRow1, SCTAB nTab1,
318                                  SCCOL nCol2, SCROW nRow2, SCTAB nTab2);
319 void PushMatrix(ScMatrix* pMat);
320 void PushError( sal_uInt16 nError );
321 /// Raw stack type without default replacements.
322 formula::StackVar GetRawStackType();
323 /// Stack type with replacement of defaults, e.g. svMissing and formula::svEmptyCell will result in formula::svDouble.
324 formula::StackVar GetStackType();
325 // peek StackType of Parameter, Parameter 1 == TOS, 2 == TOS-1, ...
326 formula::StackVar GetStackType( sal_uInt8 nParam );
327 sal_uInt8 GetByte() { return cPar; }
328 // generiert aus DoubleRef positionsabhaengige SingleRef
329 sal_Bool DoubleRefToPosSingleRef( const ScRange& rRange, ScAddress& rAdr );
330 double GetDouble();
331 double GetDoubleWithDefault(double nDefault);
332 sal_Bool IsMissing();
333 sal_Bool GetBool() { return GetDouble() != 0.0; }
334 const String& GetString();
335 // pop matrix and obtain one element, upper left or according to jump matrix
336 ScMatValType GetDoubleOrStringFromMatrix( double& rDouble, String& rString );
337 ScMatrixRef CreateMatrixFromDoubleRef( const formula::FormulaToken* pToken,
338         SCCOL nCol1, SCROW nRow1, SCTAB nTab1,
339         SCCOL nCol2, SCROW nRow2, SCTAB nTab2 );
340 inline ScTokenMatrixMap& GetTokenMatrixMap();
341 ScTokenMatrixMap* CreateTokenMatrixMap();
342 ScMatrixRef GetMatrix();
343 void ScTableOp();                                       // Mehrfachoperationen
344 void ScErrCell();                                       // Sonderbehandlung
345                                                         // Fehlerzelle
346 //-----------------------------allgemeine Hilfsfunktionen
347 void SetMaxIterationCount(sal_uInt16 n);
348 inline void CurFmtToFuncFmt()
349     { nFuncFmtType = nCurFmtType; nFuncFmtIndex = nCurFmtIndex; }
350 // Check for String overflow of rResult+rAdd and set error and erase rResult
351 // if so. Return sal_True if ok, sal_False if overflow
352 inline sal_Bool CheckStringResultLen( String& rResult, const String& rAdd );
353 // Set error according to rVal, and set rVal to 0.0 if there was an error.
354 inline void TreatDoubleError( double& rVal );
355 // Lookup using ScLookupCache, @returns sal_True if found and result address
356 bool LookupQueryWithCache( ScAddress & o_rResultPos,
357         const ScQueryParam & rParam ) const;
358 
359 //---------------------------------Funktionen in interpr1.cxx---------
360 void ScIfJump();
361 void ScChoseJump();
362 
363 // Be sure to only call this if pStack[sp-nStackLevel] really contains a
364 // ScJumpMatrixToken, no further checks are applied!
365 // Returns true if last jump was executed and result matrix pushed.
366 bool JumpMatrix( short nStackLevel );
367 
368 /** @param pOptions
369         NULL means case sensitivity document option is to be used!
370  */
371 double CompareFunc( const ScCompare& rComp, ScCompareOptions* pOptions = NULL );
372 double Compare();
373 /** @param pOptions
374         NULL means case sensitivity document option is to be used!
375  */
376 ScMatrixRef CompareMat( ScCompareOptions* pOptions = NULL );
377 ScMatrixRef QueryMat( ScMatrix* pMat, ScCompareOptions& rOptions );
378 void ScEqual();
379 void ScNotEqual();
380 void ScLess();
381 void ScGreater();
382 void ScLessEqual();
383 void ScGreaterEqual();
384 void ScAnd();
385 void ScOr();
386 void ScNot();
387 void ScNeg();
388 void ScPercentSign();
389 void ScIntersect();
390 void ScRangeFunc();
391 void ScUnionFunc();
392 void ScPi();
393 void ScRandom();
394 void ScTrue();
395 void ScFalse();
396 void ScDeg();
397 void ScRad();
398 void ScSin();
399 void ScCos();
400 void ScTan();
401 void ScCot();
402 void ScArcSin();
403 void ScArcCos();
404 void ScArcTan();
405 void ScArcCot();
406 void ScSinHyp();
407 void ScCosHyp();
408 void ScTanHyp();
409 void ScCotHyp();
410 void ScArcSinHyp();
411 void ScArcCosHyp();
412 void ScArcTanHyp();
413 void ScArcCotHyp();
414 void ScCosecant();
415 void ScSecant();
416 void ScCosecantHyp();
417 void ScSecantHyp();
418 void ScExp();
419 void ScLn();
420 void ScLog10();
421 void ScSqrt();
422 void ScIsEmpty();
423 short IsString();
424 void ScIsString();
425 void ScIsNonString();
426 void ScIsLogical();
427 void ScType();
428 void ScCell();
429 void ScIsRef();
430 void ScIsValue();
431 void ScIsFormula();
432 void ScFormula();
433 void ScRoman();
434 void ScArabic();
435 void ScIsNV();
436 void ScIsErr();
437 void ScIsError();
438 short IsEven();
439 void ScIsEven();
440 void ScIsOdd();
441 void ScN();
442 void ScCode();
443 void ScTrim();
444 void ScUpper();
445 void ScPropper();
446 void ScLower();
447 void ScLen();
448 void ScT();
449 void ScValue();
450 void ScClean();
451 void ScChar();
452 void ScJis();
453 void ScAsc();
454 void ScUnicode();
455 void ScUnichar();
456 void ScMin( sal_Bool bTextAsZero = sal_False );
457 void ScMax( sal_Bool bTextAsZero = sal_False );
458 double IterateParameters( ScIterFunc, sal_Bool bTextAsZero = sal_False );
459 void ScSumSQ();
460 void ScSum();
461 void ScProduct();
462 void ScAverage( sal_Bool bTextAsZero = sal_False );
463 void ScCount();
464 void ScCount2();
465 void GetStVarParams( double& rVal, double& rValCount, sal_Bool bTextAsZero = sal_False );
466 void ScVar( sal_Bool bTextAsZero = sal_False );
467 void ScVarP( sal_Bool bTextAsZero = sal_False );
468 void ScStDev( sal_Bool bTextAsZero = sal_False );
469 void ScStDevP( sal_Bool bTextAsZero = sal_False );
470 void ScColumns();
471 void ScRows();
472 void ScTables();
473 void ScColumn();
474 void ScRow();
475 void ScTable();
476 void ScMatch();
477 void ScCountIf();
478 void ScSumIf();
479 void ScCountEmptyCells();
480 void ScLookup();
481 void ScHLookup();
482 void ScVLookup();
483 void ScSubTotal();
484 
485 // If upon call rMissingField==sal_True then the database field parameter may be
486 // missing (Xcl DCOUNT() syntax), or may be faked as missing by having the
487 // value 0.0 or being exactly the entire database range reference (old SO
488 // compatibility). If this was the case then rMissingField is set to sal_True upon
489 // return. If rMissingField==sal_False upon call all "missing cases" are considered
490 // to be an error.
491 ScDBQueryParamBase* GetDBParams( sal_Bool& rMissingField );
492 
493 void DBIterator( ScIterFunc );
494 void ScDBSum();
495 void ScDBCount();
496 void ScDBCount2();
497 void ScDBAverage();
498 void ScDBGet();
499 void ScDBMax();
500 void ScDBMin();
501 void ScDBProduct();
502 void GetDBStVarParams( double& rVal, double& rValCount );
503 void ScDBStdDev();
504 void ScDBStdDevP();
505 void ScDBVar();
506 void ScDBVarP();
507 void ScIndirect();
508 void ScAddressFunc();
509 void ScOffset();
510 void ScIndex();
511 void ScMultiArea();
512 void ScAreas();
513 void ScCurrency();
514 void ScReplace();
515 void ScFixed();
516 void ScFind();
517 void ScExact();
518 void ScLeft();
519 void ScRight();
520 void ScSearch();
521 void ScMid();
522 void ScText();
523 void ScSubstitute();
524 void ScRept();
525 void ScConcat();
526 void ScExternal();
527 void ScMissing();
528 void ScMacro();
529 sal_Bool SetSbxVariable( SbxVariable* pVar, const ScAddress& );
530 sal_Bool SetSbxVariable( SbxVariable* pVar, SCCOL nCol, SCROW nRow, SCTAB nTab );
531 void ScErrorType();
532 void ScDBArea();
533 void ScColRowNameAuto();
534 void ScExternalRef();
535 void ScGetPivotData();
536 void ScHyperLink();
537 void ScBahtText();
538 void ScTTT();
539 
540 //----------------Funktionen in interpr2.cxx---------------
541 
542 /** Obtain the date serial number for a given date.
543     @param bStrict
544         If sal_False, nYear < 100 takes the two-digit year setting into account,
545         and rollover of invalid calendar dates takes place, e.g. 1999-02-31 =>
546         1999-03-03.
547         If sal_True, the date passed must be a valid Gregorian calendar date. No
548         two-digit expanding or rollover is done.
549  */
550 double GetDateSerial( sal_Int16 nYear, sal_Int16 nMonth, sal_Int16 nDay, bool bStrict );
551 
552 void ScGetActDate();
553 void ScGetActTime();
554 void ScGetYear();
555 void ScGetMonth();
556 void ScGetDay();
557 void ScGetDayOfWeek();
558 void ScGetWeekOfYear();
559 void ScEasterSunday();
560 void ScGetHour();
561 void ScGetMin();
562 void ScGetSec();
563 void ScPlusMinus();
564 void ScAbs();
565 void ScInt();
566 void ScEven();
567 void ScOdd();
568 void ScCeil();
569 void ScFloor();
570 void RoundNumber( rtl_math_RoundingMode eMode );
571 void ScRound();
572 void ScRoundUp();
573 void ScRoundDown();
574 void ScGetDateValue();
575 void ScGetTimeValue();
576 void ScArcTan2();
577 void ScLog();
578 void ScGetDate();
579 void ScGetTime();
580 void ScGetDiffDate();
581 void ScGetDiffDate360();
582 void ScPower();
583 void ScAmpersand();
584 void ScAdd();
585 void ScSub();
586 void ScMul();
587 void ScDiv();
588 void ScPow();
589 void ScCurrent();
590 void ScStyle();
591 void ScDde();
592 void ScBase();
593 void ScDecimal();
594 void ScConvert();
595 void ScEuroConvert();
596 
597 //----------------------- Finanzfunktionen ------------------------------------
598 void ScNPV();
599 void ScIRR();
600 void ScMIRR();
601 void ScISPMT();
602 
603 double ScGetBw(double fZins, double fZzr, double fRmz,
604                       double fZw, double fF);
605 void ScBW();
606 void ScDIA();
607 double ScGetGDA(double fWert, double fRest, double fDauer,
608                        double fPeriode, double fFaktor);
609 void ScGDA();
610 void ScGDA2();
611 double ScInterVDB(double fWert,double fRest,double fDauer,double fDauer1,
612                 double fPeriode,double fFaktor);
613 void ScVDB();
614 void ScLaufz();
615 void ScLIA();
616 double ScGetRmz(double fZins, double fZzr, double fBw,
617                        double fZw, double fF);
618 void ScRMZ();
619 void ScZGZ();
620 double ScGetZw(double fZins, double fZzr, double fRmz,
621                       double fBw, double fF);
622 void ScZW();
623 void ScZZR();
624 bool RateIteration(double fNper, double fPayment, double fPv,
625                                 double fFv, double fPayType, double& fGuess);
626 void ScZins();
627 double ScGetZinsZ(double fZins, double fZr, double fZzr, double fBw,
628                          double fZw, double fF, double& fRmz);
629 void ScZinsZ();
630 void ScKapz();
631 void ScKumZinsZ();
632 void ScKumKapZ();
633 void ScEffektiv();
634 void ScNominal();
635 void ScMod();
636 void ScBackSolver();
637 void ScIntercept();
638 //-------------------------Funktionen in interpr5.cxx--------------------------
639 double ScGetGCD(double fx, double fy);
640 void ScGCD();
641 void ScLCM();
642 //-------------------------- Matrixfunktionen ---------------------------------
643 
644 void ScMatValue();
645 void MEMat(ScMatrix* mM, SCSIZE n);
646 void ScMatDet();
647 void ScMatInv();
648 void ScMatMult();
649 void ScMatTrans();
650 void ScEMat();
651 void ScMatRef();
652 ScMatrixRef MatConcat(ScMatrix* pMat1, ScMatrix* pMat2);
653 void ScSumProduct();
654 void ScSumX2MY2();
655 void ScSumX2DY2();
656 void ScSumXMY2();
657 void ScGrowth();
658 bool CalculateSkew(double& fSum,double& fCount,double& vSum,std::vector<double>& values);
659 void CalculateSlopeIntercept(sal_Bool bSlope);
660 void CalculateSmallLarge(sal_Bool bSmall);
661 void CalculatePearsonCovar(sal_Bool _bPearson,sal_Bool _bStexy);
662 bool CalculateTest( sal_Bool _bTemplin
663                    ,const SCSIZE nC1, const SCSIZE nC2,const SCSIZE nR1,const SCSIZE nR2
664                    ,const ScMatrixRef& pMat1,const ScMatrixRef& pMat2
665                    ,double& fT,double& fF);
666 void CalculateLookup(sal_Bool HLookup);
667 bool FillEntry(ScQueryEntry& rEntry);
668 void CalculateAddSub(sal_Bool _bSub);
669 void CalculateTrendGrowth(bool _bGrowth);
670 void CalulateRGPRKP(bool _bRKP);
671 void CalculateSumX2MY2SumX2DY2(sal_Bool _bSumX2DY2);
672 void CalculateMatrixValue(const ScMatrix* pMat,SCSIZE nC,SCSIZE nR);
673 bool CheckMatrix(bool _bLOG,sal_uInt8& nCase,SCSIZE& nCX,SCSIZE& nCY,SCSIZE& nRX,SCSIZE& nRY,SCSIZE& M,SCSIZE& N,ScMatrixRef& pMatX,ScMatrixRef& pMatY);
674 void ScRGP();
675 void ScRKP();
676 void ScForecast();
677 //------------------------- Functions in interpr3.cxx -------------------------
678 void ScNoName();
679 void ScBadName();
680 // Statistik:
681 double phi(double x);
682 double integralPhi(double x);
683 double taylor(double* pPolynom, sal_uInt16 nMax, double x);
684 double gauss(double x);
685 double gaussinv(double x);
686 double GetBetaDist(double x, double alpha, double beta);  //cumulative distribution function
687 double GetBetaDistPDF(double fX, double fA, double fB); //probability density function)
688 double GetChiDist(double fChi, double fDF);     // for LEGACY.CHIDIST, returns right tail
689 double GetChiSqDistCDF(double fX, double fDF);  // for CHISQDIST, returns left tail
690 double GetChiSqDistPDF(double fX, double fDF);  // probability density function
691 double GetFDist(double x, double fF1, double fF2);
692 double GetTDist(double T, double fDF);
693 double Fakultaet(double x);
694 double BinomKoeff(double n, double k);
695 double GetGamma(double x);
696 double GetLogGamma(double x);
697 double GetBeta(double fAlpha, double fBeta);
698 double GetLogBeta(double fAlpha, double fBeta);
699 double GetBinomDistPMF(double x, double n, double p); //probability mass function
700 void ScLogGamma();
701 void ScGamma();
702 void ScPhi();
703 void ScGauss();
704 void ScStdNormDist();
705 void ScFisher();
706 void ScFisherInv();
707 void ScFact();
708 void ScNormDist();
709 void ScGammaDist();
710 void ScGammaInv();
711 void ScExpDist();
712 void ScBinomDist();
713 void ScPoissonDist();
714 void ScKombin();
715 void ScKombin2();
716 void ScVariationen();
717 void ScVariationen2();
718 void ScB();
719 void ScHypGeomDist();
720 void ScLogNormDist();
721 void ScLogNormInv();
722 void ScTDist();
723 void ScFDist();
724 void ScChiDist();   // for LEGACY.CHIDIST, returns right tail
725 void ScChiSqDist(); // returns left tail or density
726 void ScChiSqInv(); //invers to CHISQDIST
727 void ScWeibull();
728 void ScBetaDist();
729 void ScFInv();
730 void ScTInv();
731 void ScChiInv();
732 void ScBetaInv();
733 void ScCritBinom();
734 void ScNegBinomDist();
735 void ScKurt();
736 void ScHarMean();
737 void ScGeoMean();
738 void ScStandard();
739 void ScSkew();
740 void ScMedian();
741 double GetMedian( ::std::vector<double> & rArray );
742 double GetPercentile( ::std::vector<double> & rArray, double fPercentile );
743 void GetNumberSequenceArray( sal_uInt8 nParamCount, ::std::vector<double>& rArray );
744 void GetSortArray(sal_uInt8 nParamCount, ::std::vector<double>& rSortArray, ::std::vector<long>* pIndexOrder = NULL);
745 void QuickSort(::std::vector<double>& rSortArray, ::std::vector<long>* pIndexOrder = NULL);
746 void ScModalValue();
747 void ScAveDev();
748 void ScDevSq();
749 void ScZTest();
750 void ScTTest();
751 void ScFTest();
752 void ScChiTest();
753 void ScRank();
754 void ScPercentile();
755 void ScPercentrank();
756 void ScLarge();
757 void ScSmall();
758 void ScFrequency();
759 void ScQuartile();
760 void ScNormInv();
761 void ScSNormInv();
762 void ScConfidence();
763 void ScTrimMean();
764 void ScProbability();
765 void ScCorrel();
766 void ScCovar();
767 void ScPearson();
768 void ScRSQ();
769 void ScSTEXY();
770 void ScSlope();
771 void ScTrend();
772 void ScInfo();
773 
774 //------------------------ Functions in interpr6.cxx -------------------------
775 
776 static const double fMaxGammaArgument;  // defined in interpr3.cxx
777 
778 double GetGammaContFraction(double fA,double fX);
779 double GetGammaSeries(double fA,double fX);
780 double GetLowRegIGamma(double fA,double fX);    // lower regularized incomplete gamma function, GAMMAQ
781 double GetUpRegIGamma(double fA,double fX);     // upper regularized incomplete gamma function, GAMMAP
782 // probability density function; fLambda is "scale" parameter
783 double GetGammaDistPDF(double fX, double fAlpha, double fLambda);
784 // cumulative distribution function; fLambda is "scale" parameter
785 double GetGammaDist(double fX, double fAlpha, double fLambda);
786 
787 //----------------------------------------------------------------------------
788 public:
789     ScInterpreter( ScFormulaCell* pCell, ScDocument* pDoc,
790                     const ScAddress&, ScTokenArray& );
791     ~ScInterpreter();
792 
793     formula::StackVar Interpret();
794 
795     void SetError(sal_uInt16 nError)
796             { if (nError && !nGlobalError) nGlobalError = nError; }
797 
798     sal_uInt16 GetError()                               const   { return nGlobalError; }
799     formula::StackVar  GetResultType()              const   { return xResult->GetType(); }
800     const String&   GetStringResult()               const   { return xResult->GetString(); }
801     double          GetNumResult()                  const   { return xResult->GetDouble(); }
802     formula::FormulaTokenRef
803                     GetResultToken()                const   { return xResult; }
804     short           GetRetFormatType()              const   { return nRetFmtType; }
805     sal_uLong           GetRetFormatIndex()             const   { return nRetFmtIndex; }
806 };
807 
808 
809 inline void ScInterpreter::MatrixDoubleRefToMatrix()
810 {
811     if ( bMatrixFormula && GetStackType() == formula::svDoubleRef )
812     {
813         GetTokenMatrixMap();    // make sure it exists, create if not.
814         PopDoubleRefPushMatrix();
815     }
816 }
817 
818 
819 inline bool ScInterpreter::MatrixParameterConversion()
820 {
821     if ( (bMatrixFormula || pCur->HasForceArray()) && !pJumpMatrix && sp > 0 )
822         return ConvertMatrixParameters();
823     return false;
824 }
825 
826 
827 inline ScTokenMatrixMap& ScInterpreter::GetTokenMatrixMap()
828 {
829     if (!pTokenMatrixMap)
830         pTokenMatrixMap = CreateTokenMatrixMap();
831     return *pTokenMatrixMap;
832 }
833 
834 
835 inline sal_Bool ScInterpreter::MustHaveParamCount( short nAct, short nMust )
836 {
837     if ( nAct == nMust )
838         return sal_True;
839     if ( nAct < nMust )
840         PushParameterExpected();
841     else
842         PushIllegalParameter();
843     return sal_False;
844 }
845 
846 
847 inline sal_Bool ScInterpreter::MustHaveParamCount( short nAct, short nMust, short nMax )
848 {
849     if ( nMust <= nAct && nAct <= nMax )
850         return sal_True;
851     if ( nAct < nMust )
852         PushParameterExpected();
853     else
854         PushIllegalParameter();
855     return sal_False;
856 }
857 
858 
859 inline sal_Bool ScInterpreter::MustHaveParamCountMin( short nAct, short nMin )
860 {
861     if ( nAct >= nMin )
862         return sal_True;
863     PushParameterExpected();
864     return sal_False;
865 }
866 
867 
868 inline sal_Bool ScInterpreter::CheckStringResultLen( String& rResult, const String& rAdd )
869 {
870     if ( (sal_uLong) rResult.Len() + rAdd.Len() > STRING_MAXLEN )
871     {
872         SetError( errStringOverflow );
873         rResult.Erase();
874         return sal_False;
875     }
876     return sal_True;
877 }
878 
879 
880 inline void ScInterpreter::TreatDoubleError( double& rVal )
881 {
882     if ( !::rtl::math::isFinite( rVal ) )
883     {
884         sal_uInt16 nErr = GetDoubleErrorValue( rVal );
885         if ( nErr )
886             SetError( nErr );
887         else
888             SetError( errNoValue );
889         rVal = 0.0;
890     }
891 }
892 
893 
894 // static
895 inline double ScInterpreter::div( const double& fNumerator, const double& fDenominator )
896 {
897     return (fDenominator != 0.0) ? (fNumerator / fDenominator) :
898         CreateDoubleError( errDivisionByZero);
899 }
900 
901 #endif
902