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