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