Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
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/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
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 .
18 : */
19 :
20 : #ifndef SC_INTERPRE_HXX
21 : #define SC_INTERPRE_HXX
22 :
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 "types.hxx"
30 : #include "externalrefmgr.hxx"
31 : #include "calcconfig.hxx"
32 : #include "token.hxx"
33 :
34 : #include <map>
35 : #include <vector>
36 :
37 : class ScDocument;
38 : class SbxVariable;
39 : class ScFormulaCell;
40 : class SvNumberFormatter;
41 : class ScDBRangeBase;
42 : struct ScQueryParam;
43 : struct ScDBQueryParamBase;
44 : struct ScQueryEntry;
45 :
46 : struct ScSingleRefData;
47 : struct ScComplexRefData;
48 :
49 : class ScToken;
50 : class ScJumpMatrix;
51 : struct ScRefCellValue;
52 :
53 : namespace sc {
54 :
55 : struct RangeMatrix;
56 : struct Compare;
57 : struct CompareOptions;
58 :
59 : }
60 :
61 : namespace svl {
62 :
63 : class SharedStringPool;
64 :
65 : }
66 :
67 : #define MAXSTACK (4096 / sizeof(formula::FormulaToken*))
68 :
69 : class ScTokenStack
70 : {
71 : public:
72 0 : DECL_FIXEDMEMPOOL_NEWDEL( ScTokenStack )
73 : formula::FormulaToken* pPointer[ MAXSTACK ];
74 : };
75 :
76 : enum ScIterFunc {
77 : ifSUM, // Add up
78 : ifSUMSQ, // Sums of squares
79 : ifPRODUCT, // Product
80 : ifAVERAGE, // Average
81 : ifCOUNT, // Count Values
82 : ifCOUNT2, // Count Values (not empty)
83 : ifMIN, // Minimum
84 : ifMAX // Maximum
85 : };
86 :
87 : enum ScIterFuncIf
88 : {
89 : ifSUMIF, // Conditional sum
90 : ifAVERAGEIF // Conditional average
91 : };
92 :
93 : enum ScIterFuncIfs
94 : {
95 : ifSUMIFS, // Multi-Conditional sum
96 : ifAVERAGEIFS, // Multi-Conditional average
97 : ifCOUNTIFS // Multi-Conditional count
98 : };
99 :
100 : struct FormulaTokenRef_less
101 : {
102 0 : bool operator () ( const formula::FormulaConstTokenRef& r1, const formula::FormulaConstTokenRef& r2 ) const
103 0 : { return r1.get() < r2.get(); }
104 : };
105 : typedef ::std::map< const formula::FormulaConstTokenRef, formula::FormulaTokenRef, FormulaTokenRef_less> ScTokenMatrixMap;
106 :
107 : class ScInterpreter
108 : {
109 : // distibution function objects need the GetxxxDist methods
110 : friend class ScGammaDistFunction;
111 : friend class ScBetaDistFunction;
112 : friend class ScTDistFunction;
113 : friend class ScFDistFunction;
114 : friend class ScChiDistFunction;
115 : friend class ScChiSqDistFunction;
116 :
117 : public:
118 0 : DECL_FIXEDMEMPOOL_NEWDEL( ScInterpreter )
119 :
120 : static void SetGlobalConfig(const ScCalcConfig& rConfig);
121 : static const ScCalcConfig& GetGlobalConfig();
122 :
123 : static void GlobalExit(); // called by ScGlobal::Clear()
124 :
125 : /// Could string be a regular expression?
126 : /// If pDoc!=NULL the document options are taken into account and if
127 : /// RegularExpressions are disabled the function returns false regardless
128 : /// of the string content.
129 : static bool MayBeRegExp( const OUString& rStr, const ScDocument* pDoc );
130 :
131 : /// Fail safe division, returning an errDivisionByZero coded into a double
132 : /// if denominator is 0.0
133 : static inline double div( const double& fNumerator, const double& fDenominator );
134 :
135 : ScMatrixRef GetNewMat(SCSIZE nC, SCSIZE nR, bool bEmpty = false);
136 :
137 : enum VolatileType {
138 : VOLATILE,
139 : VOLATILE_MACRO,
140 : NOT_VOLATILE
141 : };
142 :
143 : VolatileType GetVolatileType() const;
144 :
145 : private:
146 : static ScCalcConfig maGlobalConfig;
147 :
148 : static ScTokenStack* pGlobalStack;
149 : static bool bGlobalStackInUse;
150 :
151 : ScCalcConfig maCalcConfig;
152 : formula::FormulaTokenIterator aCode;
153 : ScAddress aPos;
154 : ScTokenArray& rArr;
155 : ScDocument* pDok;
156 : svl::SharedStringPool& mrStrPool;
157 : formula::FormulaTokenRef xResult;
158 : ScJumpMatrix* pJumpMatrix; // currently active array condition, if any
159 : ScTokenMatrixMap* pTokenMatrixMap; // map ScToken* to formula::FormulaTokenRef if in array condition
160 : ScFormulaCell* pMyFormulaCell; // the cell of this formula expression
161 : SvNumberFormatter* pFormatter;
162 :
163 : const formula::FormulaToken*
164 : pCur; // current token
165 : ScTokenStack* pStackObj; // contains the stacks
166 : formula::FormulaToken** pStack; // the current stack
167 : sal_uInt16 nGlobalError; // global (local to this formula expression) error
168 : sal_uInt16 sp; // stack pointer
169 : sal_uInt16 maxsp; // the maximal used stack pointer
170 : sal_uLong nFuncFmtIndex; // NumberFormatIndex of a function
171 : sal_uLong nCurFmtIndex; // current NumberFormatIndex
172 : sal_uLong nRetFmtIndex; // NumberFormatIndex of an expression, if any
173 : short nFuncFmtType; // NumberFormatType of a function
174 : short nCurFmtType; // current NumberFormatType
175 : short nRetFmtType; // NumberFormatType of an expression
176 : sal_uInt16 mnStringNoValueError; // the error set in ConvertStringToValue() if no value
177 : bool glSubTotal; // flag for subtotal functions
178 : sal_uInt8 cPar; // current count of parameters
179 : bool bCalcAsShown; // precision as shown
180 : bool bMatrixFormula; // formula cell is a matrix formula
181 :
182 : VolatileType meVolatileType;
183 :
184 :
185 : /// Merge global and document specific settings.
186 : void MergeCalcConfig();
187 :
188 : // nMust <= nAct <= nMax ? ok : PushError
189 : inline bool MustHaveParamCount( short nAct, short nMust );
190 : inline bool MustHaveParamCount( short nAct, short nMust, short nMax );
191 : inline bool MustHaveParamCountMin( short nAct, short nMin );
192 : void PushParameterExpected();
193 : void PushIllegalParameter();
194 : void PushIllegalArgument();
195 : void PushNoValue();
196 : void PushNA();
197 :
198 : // Functions for accessing a document
199 :
200 : void ReplaceCell( ScAddress& ); // for TableOp
201 : void ReplaceCell( SCCOL& rCol, SCROW& rRow, SCTAB& rTab ); // for TableOp
202 : bool IsTableOpInRange( const ScRange& );
203 : sal_uLong GetCellNumberFormat( const ScAddress& rPos, ScRefCellValue& rCell );
204 : double ConvertStringToValue( const OUString& );
205 : double GetCellValue( const ScAddress&, ScRefCellValue& rCell );
206 : double GetCellValueOrZero( const ScAddress&, ScRefCellValue& rCell );
207 : double GetValueCellValue( const ScAddress&, double fOrig );
208 : void GetCellString( svl::SharedString& rStr, ScRefCellValue& rCell );
209 : sal_uInt16 GetCellErrCode( const ScRefCellValue& rCell );
210 :
211 : bool CreateDoubleArr(SCCOL nCol1, SCROW nRow1, SCTAB nTab1,
212 : SCCOL nCol2, SCROW nRow2, SCTAB nTab2, sal_uInt8* pCellArr);
213 : bool CreateStringArr(SCCOL nCol1, SCROW nRow1, SCTAB nTab1,
214 : SCCOL nCol2, SCROW nRow2, SCTAB nTab2, sal_uInt8* pCellArr);
215 : bool CreateCellArr(SCCOL nCol1, SCROW nRow1, SCTAB nTab1,
216 : SCCOL nCol2, SCROW nRow2, SCTAB nTab2, sal_uInt8* pCellArr);
217 :
218 : // Stack operations
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 0 : inline bool IfErrorPushError()
255 : {
256 0 : if (nGlobalError)
257 : {
258 0 : PushTempTokenWithoutError( new formula::FormulaErrorToken( nGlobalError));
259 0 : return true;
260 : }
261 0 : 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 : svl::SharedString 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&, bool bDontCheckForTableOp = 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&, bool bDontCheckForTableOp = false );
293 : void DoubleRefToVars( const ScToken* p,
294 : SCCOL& rCol1, SCROW &rRow1, SCTAB& rTab1,
295 : SCCOL& rCol2, SCROW &rRow2, SCTAB& rTab2,
296 : bool bDontCheckForTableOp = false );
297 : ScDBRangeBase* PopDBDoubleRef();
298 : void PopDoubleRef(SCCOL& rCol1, SCROW &rRow1, SCTAB& rTab1,
299 : SCCOL& rCol2, SCROW &rRow2, SCTAB& rTab2,
300 : bool bDontCheckForTableOp = false );
301 : void PopExternalSingleRef(sal_uInt16& rFileId, OUString& rTabName, ScSingleRefData& rRef);
302 : void PopExternalSingleRef(ScExternalRefCache::TokenRef& rToken, ScExternalRefCache::CellFormat* pFmt = NULL);
303 : void PopExternalSingleRef(sal_uInt16& rFileId, OUString& rTabName, ScSingleRefData& rRef,
304 : ScExternalRefCache::TokenRef& rToken, ScExternalRefCache::CellFormat* pFmt = NULL);
305 : void PopExternalDoubleRef(sal_uInt16& rFileId, OUString& rTabName, ScComplexRefData& rRef);
306 : void PopExternalDoubleRef(ScExternalRefCache::TokenArrayRef& rArray);
307 : void PopExternalDoubleRef(ScMatrixRef& rMat);
308 : void GetExternalDoubleRef(sal_uInt16 nFileId, const OUString& rTabName, const ScComplexRefData& aData, ScExternalRefCache::TokenArrayRef& rArray);
309 : bool PopDoubleRefOrSingleRef( ScAddress& rAdr );
310 : void PopDoubleRefPushMatrix();
311 : // If MatrixFormula: convert formula::svDoubleRef to svMatrix, create JumpMatrix.
312 : // Else convert area reference parameters marked as ForceArray to array.
313 : // Returns true if JumpMatrix created.
314 : bool ConvertMatrixParameters();
315 : inline void MatrixDoubleRefToMatrix(); // if MatrixFormula: PopDoubleRefPushMatrix
316 : // If MatrixFormula or ForceArray: ConvertMatrixParameters()
317 : inline bool MatrixParameterConversion();
318 : ScMatrixRef PopMatrix();
319 : sc::RangeMatrix PopRangeMatrix();
320 : void QueryMatrixType(ScMatrixRef& xMat, short& rRetTypeExpr, sal_uLong& rRetIndexExpr);
321 :
322 : void PushDouble(double nVal);
323 : void PushInt( int nVal );
324 : void PushStringBuffer( const sal_Unicode* pString );
325 : void PushString( const OUString& rStr );
326 : void PushString( const svl::SharedString& rString );
327 : void PushSingleRef(SCCOL nCol, SCROW nRow, SCTAB nTab);
328 : void PushDoubleRef(SCCOL nCol1, SCROW nRow1, SCTAB nTab1,
329 : SCCOL nCol2, SCROW nRow2, SCTAB nTab2);
330 : void PushExternalSingleRef(sal_uInt16 nFileId, const OUString& rTabName,
331 : SCCOL nCol, SCROW nRow, SCTAB nTab);
332 : void PushExternalDoubleRef(sal_uInt16 nFileId, const OUString& rTabName,
333 : SCCOL nCol1, SCROW nRow1, SCTAB nTab1,
334 : SCCOL nCol2, SCROW nRow2, SCTAB nTab2);
335 : void PushMatrix( const sc::RangeMatrix& rMat );
336 : void PushMatrix(const ScMatrixRef& pMat);
337 : void PushError( sal_uInt16 nError );
338 : /// Raw stack type without default replacements.
339 : formula::StackVar GetRawStackType();
340 : /// Stack type with replacement of defaults, e.g. svMissing and formula::svEmptyCell will result in formula::svDouble.
341 : formula::StackVar GetStackType();
342 : // peek StackType of Parameter, Parameter 1 == TOS, 2 == TOS-1, ...
343 : formula::StackVar GetStackType( sal_uInt8 nParam );
344 0 : sal_uInt8 GetByte() { return cPar; }
345 : // generates a position-dependent SingleRef out of a DoubleRef
346 : bool DoubleRefToPosSingleRef( const ScRange& rRange, ScAddress& rAdr );
347 : double GetDoubleFromMatrix(const ScMatrixRef& pMat);
348 : double GetDouble();
349 : double GetDoubleWithDefault(double nDefault);
350 : bool IsMissing();
351 0 : bool GetBool() { return GetDouble() != 0.0; }
352 : svl::SharedString GetString();
353 : svl::SharedString GetStringFromMatrix(const ScMatrixRef& pMat);
354 : // pop matrix and obtain one element, upper left or according to jump matrix
355 : ScMatValType GetDoubleOrStringFromMatrix( double& rDouble, svl::SharedString& rString );
356 : ScMatrixRef CreateMatrixFromDoubleRef( const formula::FormulaToken* pToken,
357 : SCCOL nCol1, SCROW nRow1, SCTAB nTab1,
358 : SCCOL nCol2, SCROW nRow2, SCTAB nTab2 );
359 : inline ScTokenMatrixMap& GetTokenMatrixMap();
360 : ScTokenMatrixMap* CreateTokenMatrixMap();
361 : ScMatrixRef GetMatrix();
362 : sc::RangeMatrix GetRangeMatrix();
363 :
364 : void ScTableOp(); // repeated operations
365 :
366 : // common helper functions
367 :
368 : void SetMaxIterationCount(sal_uInt16 n);
369 0 : inline void CurFmtToFuncFmt()
370 0 : { nFuncFmtType = nCurFmtType; nFuncFmtIndex = nCurFmtIndex; }
371 : // Check for String overflow of rResult+rAdd and set error and erase rResult
372 : // if so. Return true if ok, false if overflow
373 : inline bool CheckStringResultLen( OUString& rResult, const OUString& rAdd );
374 : // Set error according to rVal, and set rVal to 0.0 if there was an error.
375 : inline void TreatDoubleError( double& rVal );
376 : // Lookup using ScLookupCache, @returns true if found and result address
377 : bool LookupQueryWithCache( ScAddress & o_rResultPos,
378 : const ScQueryParam & rParam ) const;
379 :
380 : void ScIfJump();
381 : void ScIfError( bool bNAonly );
382 : void ScChoseJump();
383 :
384 : // Be sure to only call this if pStack[sp-nStackLevel] really contains a
385 : // ScJumpMatrixToken, no further checks are applied!
386 : // Returns true if last jump was executed and result matrix pushed.
387 : bool JumpMatrix( short nStackLevel );
388 :
389 : double Compare();
390 : /** @param pOptions
391 : NULL means case sensitivity document option is to be used!
392 : */
393 : sc::RangeMatrix CompareMat( ScQueryOp eOp, sc::CompareOptions* pOptions = NULL );
394 : ScMatrixRef QueryMat( const ScMatrixRef& pMat, sc::CompareOptions& rOptions );
395 : void ScEqual();
396 : void ScNotEqual();
397 : void ScLess();
398 : void ScGreater();
399 : void ScLessEqual();
400 : void ScGreaterEqual();
401 : void ScAnd();
402 : void ScOr();
403 : void ScXor();
404 : void ScNot();
405 : void ScNeg();
406 : void ScPercentSign();
407 : void ScIntersect();
408 : void ScRangeFunc();
409 : void ScUnionFunc();
410 : void ScPi();
411 : void ScRandom();
412 : void ScTrue();
413 : void ScFalse();
414 : void ScDeg();
415 : void ScRad();
416 : void ScSin();
417 : void ScCos();
418 : void ScTan();
419 : void ScCot();
420 : void ScArcSin();
421 : void ScArcCos();
422 : void ScArcTan();
423 : void ScArcCot();
424 : void ScSinHyp();
425 : void ScCosHyp();
426 : void ScTanHyp();
427 : void ScCotHyp();
428 : void ScArcSinHyp();
429 : void ScArcCosHyp();
430 : void ScArcTanHyp();
431 : void ScArcCotHyp();
432 : void ScCosecant();
433 : void ScSecant();
434 : void ScCosecantHyp();
435 : void ScSecantHyp();
436 : void ScExp();
437 : void ScLn();
438 : void ScLog10();
439 : void ScSqrt();
440 : void ScIsEmpty();
441 : bool IsString();
442 : void ScIsString();
443 : void ScIsNonString();
444 : void ScIsLogical();
445 : void ScType();
446 : void ScCell();
447 : void ScCellExternal();
448 : void ScIsRef();
449 : void ScIsValue();
450 : void ScIsFormula();
451 : void ScFormula();
452 : void ScRoman();
453 : void ScArabic();
454 : void ScIsNV();
455 : void ScIsErr();
456 : void ScIsError();
457 : bool IsEven();
458 : void ScIsEven();
459 : void ScIsOdd();
460 : void ScN();
461 : void ScCode();
462 : void ScTrim();
463 : void ScUpper();
464 : void ScPropper();
465 : void ScLower();
466 : void ScLen();
467 : void ScT();
468 : void ScValue();
469 : void ScNumberValue();
470 : void ScClean();
471 : void ScChar();
472 : void ScJis();
473 : void ScAsc();
474 : void ScUnicode();
475 : void ScUnichar();
476 : void ScMin( bool bTextAsZero = false );
477 : void ScMax( bool bTextAsZero = false );
478 : double IterateParameters( ScIterFunc, bool bTextAsZero = false );
479 : void ScSumSQ();
480 : void ScSum();
481 : void ScProduct();
482 : void ScAverage( bool bTextAsZero = false );
483 : void ScCount();
484 : void ScCount2();
485 : void GetStVarParams( double& rVal, double& rValCount, bool bTextAsZero = false );
486 : void ScVar( bool bTextAsZero = false );
487 : void ScVarP( bool bTextAsZero = false );
488 : void ScStDev( bool bTextAsZero = false );
489 : void ScStDevP( bool bTextAsZero = false );
490 : void ScColumns();
491 : void ScRows();
492 : void ScTables();
493 : void ScColumn();
494 : void ScRow();
495 : void ScTable();
496 : void ScMatch();
497 : double IterateParametersIf( ScIterFuncIf );
498 : void ScCountIf();
499 : void ScSumIf();
500 : void ScAverageIf();
501 : double IterateParametersIfs( ScIterFuncIfs );
502 : void ScSumIfs();
503 : void ScAverageIfs();
504 : void ScCountIfs();
505 : void ScCountEmptyCells();
506 : void ScLookup();
507 : void ScHLookup();
508 : void ScVLookup();
509 : void ScSubTotal();
510 :
511 : // If upon call rMissingField==true then the database field parameter may be
512 : // missing (Xcl DCOUNT() syntax), or may be faked as missing by having the
513 : // value 0.0 or being exactly the entire database range reference (old SO
514 : // compatibility). If this was the case then rMissingField is set to true upon
515 : // return. If rMissingField==false upon call all "missing cases" are considered
516 : // to be an error.
517 : ScDBQueryParamBase* GetDBParams( bool& rMissingField );
518 :
519 : void DBIterator( ScIterFunc );
520 : void ScDBSum();
521 : void ScDBCount();
522 : void ScDBCount2();
523 : void ScDBAverage();
524 : void ScDBGet();
525 : void ScDBMax();
526 : void ScDBMin();
527 : void ScDBProduct();
528 : void GetDBStVarParams( double& rVal, double& rValCount );
529 : void ScDBStdDev();
530 : void ScDBStdDevP();
531 : void ScDBVar();
532 : void ScDBVarP();
533 : void ScIndirect();
534 : void ScAddressFunc();
535 : void ScOffset();
536 : void ScIndex();
537 : void ScMultiArea();
538 : void ScAreas();
539 : void ScCurrency();
540 : void ScReplace();
541 : void ScFixed();
542 : void ScFind();
543 : void ScExact();
544 : void ScLeft();
545 : void ScRight();
546 : void ScSearch();
547 : void ScMid();
548 : void ScText();
549 : void ScSubstitute();
550 : void ScRept();
551 : void ScConcat();
552 : void ScExternal();
553 : void ScMissing();
554 : void ScMacro();
555 : bool SetSbxVariable( SbxVariable* pVar, const ScAddress& );
556 : bool SetSbxVariable( SbxVariable* pVar, SCCOL nCol, SCROW nRow, SCTAB nTab );
557 : void ScErrorType();
558 : void ScDBArea();
559 : void ScColRowNameAuto();
560 : void ScGetPivotData();
561 : void ScHyperLink();
562 : void ScBahtText();
563 : void ScBitAnd();
564 : void ScBitOr();
565 : void ScBitXor();
566 : void ScBitRshift();
567 : void ScBitLshift();
568 : void ScTTT();
569 : void ScDebugVar();
570 :
571 : /** Obtain the date serial number for a given date.
572 : @param bStrict
573 : If false, nYear < 100 takes the two-digit year setting into account,
574 : and rollover of invalid calendar dates takes place, e.g. 1999-02-31 =>
575 : 1999-03-03.
576 : If true, the date passed must be a valid Gregorian calendar date. No
577 : two-digit expanding or rollover is done.
578 :
579 : @param bCheckGregorian
580 : If true, date must be Gregorian, i.e. >= 1582-10-15.
581 : If false, don't care, any valid date >= 0-1-1 will do.
582 : */
583 : double GetDateSerial( sal_Int16 nYear, sal_Int16 nMonth, sal_Int16 nDay, bool bStrict, bool bCheckGregorian );
584 :
585 : void ScGetActDate();
586 : void ScGetActTime();
587 : void ScGetYear();
588 : void ScGetMonth();
589 : void ScGetDay();
590 : void ScGetDayOfWeek();
591 : void ScGetWeekOfYear();
592 : void ScEasterSunday();
593 : sal_uInt16 GetWeekendAndHolidayMasks( const sal_uInt8 nParamCount, const sal_uInt32 nNullDate,
594 : ::std::vector<double>& rSortArray, OUString& rWeekendDays, bool bWeekendMask[ 7 ] );
595 : inline sal_Int16 GetDayOfWeek( sal_Int32 n );
596 : void ScNetWorkdays_MS();
597 : void ScWorkday_MS();
598 : void ScGetHour();
599 : void ScGetMin();
600 : void ScGetSec();
601 : void ScPlusMinus();
602 : void ScAbs();
603 : void ScInt();
604 : void ScEven();
605 : void ScOdd();
606 : void ScCeil();
607 : void ScCeil_MS();
608 : void ScFloor();
609 : void ScFloor_MS();
610 : void RoundNumber( rtl_math_RoundingMode eMode );
611 : void ScRound();
612 : void ScRoundUp();
613 : void ScRoundDown();
614 : void ScGetDateValue();
615 : void ScGetTimeValue();
616 : void ScArcTan2();
617 : void ScLog();
618 : void ScGetDate();
619 : void ScGetTime();
620 : void ScGetDiffDate();
621 : void ScGetDiffDate360();
622 : void ScGetDateDif();
623 : void ScPower();
624 : void ScAmpersand();
625 : void ScAdd();
626 : void ScSub();
627 : void ScMul();
628 : void ScDiv();
629 : void ScPow();
630 : void ScCurrent();
631 : void ScStyle();
632 : void ScDde();
633 : void ScBase();
634 : void ScDecimal();
635 : void ScConvert();
636 : void ScEuroConvert();
637 :
638 : // financial functions
639 : void ScNPV();
640 : void ScIRR();
641 : void ScMIRR();
642 : void ScISPMT();
643 :
644 : double ScGetBw(double fZins, double fZzr, double fRmz,
645 : double fZw, double fF);
646 : void ScBW();
647 : void ScDIA();
648 : double ScGetGDA(double fWert, double fRest, double fDauer,
649 : double fPeriode, double fFactor);
650 : void ScGDA();
651 : void ScGDA2();
652 : double ScInterVDB(double fWert,double fRest,double fDauer,double fDauer1,
653 : double fPeriode,double fFactor);
654 : void ScVDB();
655 : void ScLaufz();
656 : void ScLIA();
657 : double ScGetRmz(double fZins, double fZzr, double fBw,
658 : double fZw, double fF);
659 : void ScRMZ();
660 : void ScZGZ();
661 : double ScGetZw(double fZins, double fZzr, double fRmz,
662 : double fBw, double fF);
663 : void ScZW();
664 : void ScZZR();
665 : bool RateIteration(double fNper, double fPayment, double fPv,
666 : double fFv, double fPayType, double& fGuess);
667 : void ScZins();
668 : double ScGetZinsZ(double fZins, double fZr, double fZzr, double fBw,
669 : double fZw, double fF, double& fRmz);
670 : void ScZinsZ();
671 : void ScKapz();
672 : void ScKumZinsZ();
673 : void ScKumKapZ();
674 : void ScEffektiv();
675 : void ScNominal();
676 : void ScMod();
677 : void ScIntercept();
678 : double ScGetGCD(double fx, double fy);
679 : void ScGCD();
680 : void ScLCM();
681 :
682 : // matrix functions
683 : void ScMatValue();
684 : void MEMat(const ScMatrixRef& mM, SCSIZE n);
685 : void ScMatDet();
686 : void ScMatInv();
687 : void ScMatMult();
688 : void ScMatTrans();
689 : void ScEMat();
690 : void ScMatRef();
691 : ScMatrixRef MatConcat(const ScMatrixRef& pMat1, const ScMatrixRef& pMat2);
692 : void ScSumProduct();
693 : void ScSumX2MY2();
694 : void ScSumX2DY2();
695 : void ScSumXMY2();
696 : void ScGrowth();
697 : bool CalculateSkew(double& fSum,double& fCount,double& vSum,std::vector<double>& values);
698 : void CalculateSkewOrSkewp( bool bSkewp );
699 : void CalculateSlopeIntercept(bool bSlope);
700 : void CalculateSmallLarge(bool bSmall);
701 : void CalculatePearsonCovar( bool _bPearson, bool _bStexy, bool _bSample ); //fdo#70000 argument _bSample is ignored if _bPearson == true
702 : bool CalculateTest( bool _bTemplin
703 : ,const SCSIZE nC1, const SCSIZE nC2,const SCSIZE nR1,const SCSIZE nR2
704 : ,const ScMatrixRef& pMat1,const ScMatrixRef& pMat2
705 : ,double& fT,double& fF);
706 : void CalculateLookup(bool bHLookup);
707 : bool FillEntry(ScQueryEntry& rEntry);
708 : void CalculateAddSub(bool _bSub);
709 : void CalculateTrendGrowth(bool _bGrowth);
710 : void CalulateRGPRKP(bool _bRKP);
711 : void CalculateSumX2MY2SumX2DY2(bool _bSumX2DY2);
712 : void CalculateMatrixValue(const ScMatrix* pMat,SCSIZE nC,SCSIZE nR);
713 : bool CheckMatrix(bool _bLOG,sal_uInt8& nCase,SCSIZE& nCX,SCSIZE& nCY,SCSIZE& nRX,SCSIZE& nRY,SCSIZE& M,SCSIZE& N,ScMatrixRef& pMatX,ScMatrixRef& pMatY);
714 : void ScRGP();
715 : void ScRKP();
716 : void ScForecast();
717 : void ScNoName();
718 : void ScBadName();
719 : // Statistics:
720 : double phi(double x);
721 : double integralPhi(double x);
722 : double taylor(const double* pPolynom, sal_uInt16 nMax, double x);
723 : double gauss(double x);
724 : double gaussinv(double x);
725 : double GetBetaDist(double x, double alpha, double beta); //cumulative distribution function
726 : double GetBetaDistPDF(double fX, double fA, double fB); //probability density function)
727 : double GetChiDist(double fChi, double fDF); // for LEGACY.CHIDIST, returns right tail
728 : double GetChiSqDistCDF(double fX, double fDF); // for CHISQDIST, returns left tail
729 : double GetChiSqDistPDF(double fX, double fDF); // probability density function
730 : double GetFDist(double x, double fF1, double fF2);
731 : double GetTDist( double T, double fDF, int nType );
732 : double Fakultaet(double x);
733 : double BinomKoeff(double n, double k);
734 : double GetGamma(double x);
735 : double GetLogGamma(double x);
736 : double GetBeta(double fAlpha, double fBeta);
737 : double GetLogBeta(double fAlpha, double fBeta);
738 : double GetBinomDistPMF(double x, double n, double p); //probability mass function
739 : double GetHypGeomDist( double x, double n, double M, double N );
740 : void ScLogGamma();
741 : void ScGamma();
742 : void ScPhi();
743 : void ScGauss();
744 : void ScStdNormDist();
745 : void ScStdNormDist_MS();
746 : void ScFisher();
747 : void ScFisherInv();
748 : void ScFact();
749 : void ScNormDist( int nMinParamCount );
750 : void ScGammaDist( int nMinParamCount );
751 : void ScGammaInv();
752 : void ScExpDist();
753 : void ScBinomDist();
754 : void ScPoissonDist();
755 : void ScKombin();
756 : void ScKombin2();
757 : void ScVariationen();
758 : void ScVariationen2();
759 : void ScB();
760 : void ScHypGeomDist();
761 : void ScHypGeomDist_MS();
762 : void ScLogNormDist( int nMinParamCount );
763 : void ScLogNormInv();
764 : void ScTDist();
765 : void ScTDist_MS();
766 : void ScTDist_T( int nTails );
767 : void ScFDist();
768 : void ScFDist_LT();
769 : void ScChiDist(); // for LEGACY.CHIDIST, returns right tail
770 : void ScChiSqDist(); // returns left tail or density
771 : void ScChiSqDist_MS();
772 : void ScChiSqInv(); //invers to CHISQDIST
773 : void ScWeibull();
774 : void ScBetaDist();
775 : void ScBetaDist_MS();
776 : void ScFInv();
777 : void ScFInv_LT();
778 : void ScTInv( int nType );
779 : void ScChiInv();
780 : void ScBetaInv();
781 : void ScCritBinom();
782 : void ScNegBinomDist();
783 : void ScNegBinomDist_MS();
784 : void ScKurt();
785 : void ScHarMean();
786 : void ScGeoMean();
787 : void ScStandard();
788 : void ScSkew();
789 : void ScSkewp();
790 : void ScMedian();
791 : double GetMedian( ::std::vector<double> & rArray );
792 : double GetPercentile( ::std::vector<double> & rArray, double fPercentile );
793 : double GetPercentileExclusive( ::std::vector<double> & rArray, double fPercentile );
794 : void GetNumberSequenceArray( sal_uInt8 nParamCount, ::std::vector<double>& rArray );
795 : void GetSortArray(sal_uInt8 nParamCount, ::std::vector<double>& rSortArray, ::std::vector<long>* pIndexOrder = NULL);
796 : void QuickSort(::std::vector<double>& rSortArray, ::std::vector<long>* pIndexOrder = NULL);
797 : void ScModalValue();
798 : void ScModalValue_Multi();
799 : void ScAveDev();
800 : void ScDevSq();
801 : void ScZTest();
802 : void ScTTest();
803 : void ScFTest();
804 : void ScChiTest();
805 : void ScRank( bool bAverage );
806 : void ScPercentile( bool bInclusive );
807 : void ScPercentrank( bool bInclusive );
808 : double GetPercentrank( ::std::vector<double> & rArray, double fVal, bool bInclusive );
809 : void ScLarge();
810 : void ScSmall();
811 : void ScFrequency();
812 : void ScQuartile( bool bInclusive );
813 : void ScNormInv();
814 : void ScSNormInv();
815 : void ScConfidence();
816 : void ScConfidenceT();
817 : void ScTrimMean();
818 : void ScProbability();
819 : void ScCorrel();
820 : void ScCovarianceP();
821 : void ScCovarianceS();
822 : void ScPearson();
823 : void ScRSQ();
824 : void ScSTEXY();
825 : void ScSlope();
826 : void ScTrend();
827 : void ScInfo();
828 : void ScLenB();
829 : void ScRightB();
830 : void ScLeftB();
831 : void ScMidB();
832 :
833 : void ScFilterXML();
834 : void ScWebservice();
835 : void ScErf();
836 : void ScErfc();
837 :
838 : static const double fMaxGammaArgument;
839 :
840 : double GetGammaContFraction(double fA,double fX);
841 : double GetGammaSeries(double fA,double fX);
842 : double GetLowRegIGamma(double fA,double fX); // lower regularized incomplete gamma function, GAMMAQ
843 : double GetUpRegIGamma(double fA,double fX); // upper regularized incomplete gamma function, GAMMAP
844 : // probability density function; fLambda is "scale" parameter
845 : double GetGammaDistPDF(double fX, double fAlpha, double fLambda);
846 : // cumulative distribution function; fLambda is "scale" parameter
847 : double GetGammaDist(double fX, double fAlpha, double fLambda);
848 : double GetTInv( double fAlpha, double fSize, int nType );
849 :
850 : public:
851 : ScInterpreter( ScFormulaCell* pCell, ScDocument* pDoc,
852 : const ScAddress&, ScTokenArray& );
853 : ~ScInterpreter();
854 :
855 : formula::StackVar Interpret();
856 :
857 0 : void SetError(sal_uInt16 nError)
858 0 : { if (nError && !nGlobalError) nGlobalError = nError; }
859 :
860 0 : sal_uInt16 GetError() const { return nGlobalError; }
861 0 : formula::StackVar GetResultType() const { return xResult->GetType(); }
862 : svl::SharedString GetStringResult() const;
863 0 : double GetNumResult() const { return xResult->GetDouble(); }
864 0 : formula::FormulaTokenRef GetResultToken() const { return xResult; }
865 0 : short GetRetFormatType() const { return nRetFmtType; }
866 0 : sal_uLong GetRetFormatIndex() const { return nRetFmtIndex; }
867 : };
868 :
869 0 : inline void ScInterpreter::MatrixDoubleRefToMatrix()
870 : {
871 0 : if ( bMatrixFormula && GetStackType() == formula::svDoubleRef )
872 : {
873 0 : GetTokenMatrixMap(); // make sure it exists, create if not.
874 0 : PopDoubleRefPushMatrix();
875 : }
876 0 : }
877 :
878 0 : inline bool ScInterpreter::MatrixParameterConversion()
879 : {
880 0 : if ( (bMatrixFormula || pCur->HasForceArray()) && !pJumpMatrix && sp > 0 )
881 0 : return ConvertMatrixParameters();
882 0 : return false;
883 : }
884 :
885 0 : inline ScTokenMatrixMap& ScInterpreter::GetTokenMatrixMap()
886 : {
887 0 : if (!pTokenMatrixMap)
888 0 : pTokenMatrixMap = CreateTokenMatrixMap();
889 0 : return *pTokenMatrixMap;
890 : }
891 :
892 0 : inline bool ScInterpreter::MustHaveParamCount( short nAct, short nMust )
893 : {
894 0 : if ( nAct == nMust )
895 0 : return true;
896 0 : if ( nAct < nMust )
897 0 : PushParameterExpected();
898 : else
899 0 : PushIllegalParameter();
900 0 : return false;
901 : }
902 :
903 0 : inline bool ScInterpreter::MustHaveParamCount( short nAct, short nMust, short nMax )
904 : {
905 0 : if ( nMust <= nAct && nAct <= nMax )
906 0 : return true;
907 0 : if ( nAct < nMust )
908 0 : PushParameterExpected();
909 : else
910 0 : PushIllegalParameter();
911 0 : return false;
912 : }
913 :
914 0 : inline bool ScInterpreter::MustHaveParamCountMin( short nAct, short nMin )
915 : {
916 0 : if ( nAct >= nMin )
917 0 : return true;
918 0 : PushParameterExpected();
919 0 : return false;
920 : }
921 :
922 0 : inline bool ScInterpreter::CheckStringResultLen( OUString& rResult, const OUString& rAdd )
923 : {
924 0 : if ( rResult.getLength() + rAdd.getLength() > SAL_MAX_UINT16 )
925 : {
926 0 : SetError( errStringOverflow );
927 0 : rResult = "";
928 0 : return false;
929 : }
930 0 : return true;
931 : }
932 :
933 0 : inline void ScInterpreter::TreatDoubleError( double& rVal )
934 : {
935 0 : if ( !::rtl::math::isFinite( rVal ) )
936 : {
937 0 : sal_uInt16 nErr = GetDoubleErrorValue( rVal );
938 0 : if ( nErr )
939 0 : SetError( nErr );
940 : else
941 0 : SetError( errNoValue );
942 0 : rVal = 0.0;
943 : }
944 0 : }
945 :
946 0 : inline double ScInterpreter::div( const double& fNumerator, const double& fDenominator )
947 : {
948 0 : return (fDenominator != 0.0) ? (fNumerator / fDenominator) :
949 0 : CreateDoubleError( errDivisionByZero);
950 : }
951 :
952 0 : inline sal_Int16 ScInterpreter::GetDayOfWeek( sal_Int32 n )
953 : { // monday = 0, ..., sunday = 6
954 0 : return static_cast< sal_Int16 >( ( n - 1 ) % 7 );
955 : }
956 :
957 : #endif
958 :
959 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|