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