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