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