LibreOffice Module sc (master) 1
interpr4.cxx
Go to the documentation of this file.
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#include <config_features.h>
21
22#include <interpre.hxx>
23
24#include <sal/log.hxx>
25#include <o3tl/safeint.hxx>
26#include <rtl/math.hxx>
27#include <sfx2/app.hxx>
28#include <sfx2/objsh.hxx>
29#include <basic/sbmeth.hxx>
30#include <basic/sbmod.hxx>
31#include <basic/sbstar.hxx>
32#include <basic/sbx.hxx>
33#include <basic/sbxobj.hxx>
34#include <basic/sbuno.hxx>
35#include <osl/thread.h>
36#include <svl/numformat.hxx>
37#include <svl/zforlist.hxx>
40#include <stdlib.h>
41#include <string.h>
42
43#include <com/sun/star/table/XCellRange.hpp>
44#include <com/sun/star/script/XInvocation.hpp>
45#include <com/sun/star/sheet/XSheetCellRange.hpp>
46
47#include <global.hxx>
48#include <dbdata.hxx>
49#include <formulacell.hxx>
50#include <callform.hxx>
51#include <addincol.hxx>
52#include <document.hxx>
53#include <dociter.hxx>
54#include <docoptio.hxx>
55#include <scmatrix.hxx>
56#include <adiasync.hxx>
57#include <cellsuno.hxx>
58#include <optuno.hxx>
59#include <rangeseq.hxx>
60#include <addinlis.hxx>
61#include <jumpmatrix.hxx>
62#include <parclass.hxx>
63#include <externalrefmgr.hxx>
65#include <macromgr.hxx>
66#include <doubleref.hxx>
67#include <queryparam.hxx>
68#include <tokenarray.hxx>
69#include <compiler.hxx>
70
71#include <map>
72#include <algorithm>
73#include <basic/basmgr.hxx>
75#include <memory>
76
77using namespace com::sun::star;
78using namespace formula;
79using ::std::unique_ptr;
80
81#define ADDIN_MAXSTRLEN 256
82
83thread_local std::unique_ptr<ScTokenStack> ScInterpreter::pGlobalStack;
84thread_local bool ScInterpreter::bGlobalStackInUse = false;
85
86// document access functions
87
89{
90 size_t ListSize = mrDoc.m_TableOpList.size();
91 for ( size_t i = 0; i < ListSize; ++i )
92 {
94 if ( rPos == pTOp->aOld1 )
95 {
96 rPos = pTOp->aNew1;
97 return ;
98 }
99 else if ( rPos == pTOp->aOld2 )
100 {
101 rPos = pTOp->aNew2;
102 return ;
103 }
104 }
105}
106
108{
109 if ( rRange.aStart == rRange.aEnd )
110 return false; // not considered to be a range in TableOp sense
111
112 // we can't replace a single cell in a range
113 size_t ListSize = mrDoc.m_TableOpList.size();
114 for ( size_t i = 0; i < ListSize; ++i )
115 {
117 if ( rRange.Contains( pTOp->aOld1 ) )
118 return true;
119 if ( rRange.Contains( pTOp->aOld2 ) )
120 return true;
121 }
122 return false;
123}
124
126{
127 sal_uInt32 nFormat;
128 FormulaError nErr;
129 if (rCell.isEmpty())
130 {
131 nFormat = mrDoc.GetNumberFormat( mrContext, rPos );
132 nErr = FormulaError::NONE;
133 }
134 else
135 {
136 if (rCell.getType() == CELLTYPE_FORMULA)
137 nErr = rCell.getFormula()->GetErrCode();
138 else
139 nErr = FormulaError::NONE;
140 nFormat = mrDoc.GetNumberFormat( mrContext, rPos );
141 }
142
143 SetError(nErr);
144 return nFormat;
145}
146
148double ScInterpreter::GetValueCellValue( const ScAddress& rPos, double fOrig )
149{
150 if ( bCalcAsShown && fOrig != 0.0 )
151 {
152 sal_uInt32 nFormat = mrDoc.GetNumberFormat( mrContext, rPos );
153 fOrig = mrDoc.RoundValueAsShown( fOrig, nFormat, &mrContext );
154 }
155 return fOrig;
156}
157
159{
160 return rCell.getType() == CELLTYPE_FORMULA ? rCell.getFormula()->GetErrCode() : FormulaError::NONE;
161}
162
163double ScInterpreter::ConvertStringToValue( const OUString& rStr )
164{
165 FormulaError nError = FormulaError::NONE;
168 if (nError != FormulaError::NONE)
169 SetError(nError);
170 return fValue;
171}
172
173double ScInterpreter::ConvertStringToValue( const OUString& rStr, FormulaError& rError, SvNumFormatType& rCurFmtType )
174{
176}
177
179{
181 nGlobalError = FormulaError::NONE;
182 double nVal = GetCellValueOrZero(rPos, rCell);
183 if ( nGlobalError == FormulaError::NONE || nGlobalError == FormulaError::CellNoValue )
184 nGlobalError = nErr;
185 return nVal;
186}
187
189{
190 double fValue = 0.0;
191
192 CellType eType = rCell.getType();
193 switch (eType)
194 {
195 case CELLTYPE_FORMULA:
196 {
197 ScFormulaCell* pFCell = rCell.getFormula();
198 FormulaError nErr = pFCell->GetErrCode();
199 if( nErr == FormulaError::NONE )
200 {
201 if (pFCell->IsValue())
202 {
203 fValue = pFCell->GetValue();
205 rPos );
206 }
207 else
208 {
209 fValue = ConvertStringToValue(pFCell->GetString().getString());
210 }
211 }
212 else
213 {
214 fValue = 0.0;
215 SetError(nErr);
216 }
217 }
218 break;
219 case CELLTYPE_VALUE:
220 {
221 fValue = rCell.getDouble();
224 if ( bCalcAsShown && fValue != 0.0 )
225 fValue = mrDoc.RoundValueAsShown( fValue, nCurFmtIndex, &mrContext );
226 }
227 break;
228 case CELLTYPE_STRING:
229 case CELLTYPE_EDIT:
230 {
231 // SUM(A1:A2) differs from A1+A2. No good. But people insist on
232 // it ... #i5658#
233 OUString aStr = rCell.getString(&mrDoc);
234 fValue = ConvertStringToValue( aStr );
235 }
236 break;
237 case CELLTYPE_NONE:
238 fValue = 0.0; // empty or broadcaster cell
239 break;
240 }
241
242 return fValue;
243}
244
246{
247 FormulaError nErr = FormulaError::NONE;
248
249 switch (rCell.getType())
250 {
251 case CELLTYPE_STRING:
252 case CELLTYPE_EDIT:
253 rStr = mrStrPool.intern(rCell.getString(&mrDoc));
254 break;
255 case CELLTYPE_FORMULA:
256 {
257 ScFormulaCell* pFCell = rCell.getFormula();
258 nErr = pFCell->GetErrCode();
259 if (pFCell->IsValue())
260 {
261 rStr = GetStringFromDouble( pFCell->GetValue() );
262 }
263 else
264 rStr = pFCell->GetString();
265 }
266 break;
267 case CELLTYPE_VALUE:
268 {
269 rStr = GetStringFromDouble( rCell.getDouble() );
270 }
271 break;
272 default:
274 break;
275 }
276
277 SetError(nErr);
278}
279
281 SCCOL nCol2, SCROW nRow2, SCTAB nTab2, sal_uInt8* pCellArr)
282{
283
284 // Old Add-Ins are hard limited to sal_uInt16 values.
286 "Add check for columns > SAL_MAX_UINT16!");
287 if (nRow1 > SAL_MAX_UINT16 || nRow2 > SAL_MAX_UINT16)
288 return false;
289
290 sal_uInt16 nCount = 0;
291 sal_uInt16* p = reinterpret_cast<sal_uInt16*>(pCellArr);
292 *p++ = static_cast<sal_uInt16>(nCol1);
293 *p++ = static_cast<sal_uInt16>(nRow1);
294 *p++ = static_cast<sal_uInt16>(nTab1);
295 *p++ = static_cast<sal_uInt16>(nCol2);
296 *p++ = static_cast<sal_uInt16>(nRow2);
297 *p++ = static_cast<sal_uInt16>(nTab2);
298 sal_uInt16* pCount = p;
299 *p++ = 0;
300 sal_uInt16 nPos = 14;
301 SCTAB nTab = nTab1;
302 ScAddress aAdr;
303 while (nTab <= nTab2)
304 {
305 aAdr.SetTab( nTab );
306 SCROW nRow = nRow1;
307 while (nRow <= nRow2)
308 {
309 aAdr.SetRow( nRow );
310 SCCOL nCol = nCol1;
311 while (nCol <= nCol2)
312 {
313 aAdr.SetCol( nCol );
314
315 ScRefCellValue aCell(mrDoc, aAdr);
316 if (!aCell.isEmpty())
317 {
318 FormulaError nErr = FormulaError::NONE;
319 double nVal = 0.0;
320 bool bOk = true;
321 switch (aCell.getType())
322 {
323 case CELLTYPE_VALUE :
324 nVal = GetValueCellValue(aAdr, aCell.getDouble());
325 break;
326 case CELLTYPE_FORMULA :
327 if (aCell.getFormula()->IsValue())
328 {
329 nErr = aCell.getFormula()->GetErrCode();
330 nVal = aCell.getFormula()->GetValue();
331 }
332 else
333 bOk = false;
334 break;
335 default :
336 bOk = false;
337 break;
338 }
339 if (bOk)
340 {
341 if ((nPos + (4 * sizeof(sal_uInt16)) + sizeof(double)) > MAXARRSIZE)
342 return false;
343 *p++ = static_cast<sal_uInt16>(nCol);
344 *p++ = static_cast<sal_uInt16>(nRow);
345 *p++ = static_cast<sal_uInt16>(nTab);
346 *p++ = static_cast<sal_uInt16>(nErr);
347 memcpy( p, &nVal, sizeof(double));
348 nPos += 8 + sizeof(double);
349 p = reinterpret_cast<sal_uInt16*>( pCellArr + nPos );
350 nCount++;
351 }
352 }
353 nCol++;
354 }
355 nRow++;
356 }
357 nTab++;
358 }
359 *pCount = nCount;
360 return true;
361}
362
364 SCCOL nCol2, SCROW nRow2, SCTAB nTab2,
365 sal_uInt8* pCellArr)
366{
367
368 // Old Add-Ins are hard limited to sal_uInt16 values.
370 "Add check for columns > SAL_MAX_UINT16!");
371 if (nRow1 > SAL_MAX_UINT16 || nRow2 > SAL_MAX_UINT16)
372 return false;
373
374 sal_uInt16 nCount = 0;
375 sal_uInt16* p = reinterpret_cast<sal_uInt16*>(pCellArr);
376 *p++ = static_cast<sal_uInt16>(nCol1);
377 *p++ = static_cast<sal_uInt16>(nRow1);
378 *p++ = static_cast<sal_uInt16>(nTab1);
379 *p++ = static_cast<sal_uInt16>(nCol2);
380 *p++ = static_cast<sal_uInt16>(nRow2);
381 *p++ = static_cast<sal_uInt16>(nTab2);
382 sal_uInt16* pCount = p;
383 *p++ = 0;
384 sal_uInt16 nPos = 14;
385 SCTAB nTab = nTab1;
386 while (nTab <= nTab2)
387 {
388 SCROW nRow = nRow1;
389 while (nRow <= nRow2)
390 {
391 SCCOL nCol = nCol1;
392 while (nCol <= nCol2)
393 {
394 ScRefCellValue aCell(mrDoc, ScAddress(nCol, nRow, nTab));
395 if (!aCell.isEmpty())
396 {
397 OUString aStr;
398 FormulaError nErr = FormulaError::NONE;
399 bool bOk = true;
400 switch (aCell.getType())
401 {
402 case CELLTYPE_STRING:
403 case CELLTYPE_EDIT:
404 aStr = aCell.getString(&mrDoc);
405 break;
406 case CELLTYPE_FORMULA:
407 if (!aCell.getFormula()->IsValue())
408 {
409 nErr = aCell.getFormula()->GetErrCode();
410 aStr = aCell.getFormula()->GetString().getString();
411 }
412 else
413 bOk = false;
414 break;
415 default :
416 bOk = false;
417 break;
418 }
419 if (bOk)
420 {
421 OString aTmp(OUStringToOString(aStr,
422 osl_getThreadTextEncoding()));
423 // Old Add-Ins are limited to sal_uInt16 string
424 // lengths, and room for pad byte check.
425 if ( aTmp.getLength() > SAL_MAX_UINT16 - 2 )
426 return false;
427 // Append a 0-pad-byte if string length is odd
428 // MUST be sal_uInt16
429 sal_uInt16 nStrLen = static_cast<sal_uInt16>(aTmp.getLength());
430 sal_uInt16 nLen = ( nStrLen + 2 ) & ~1;
431
432 if ((static_cast<sal_uLong>(nPos) + (5 * sizeof(sal_uInt16)) + nLen) > MAXARRSIZE)
433 return false;
434 *p++ = static_cast<sal_uInt16>(nCol);
435 *p++ = static_cast<sal_uInt16>(nRow);
436 *p++ = static_cast<sal_uInt16>(nTab);
437 *p++ = static_cast<sal_uInt16>(nErr);
438 *p++ = nLen;
439 memcpy( p, aTmp.getStr(), nStrLen + 1);
440 nPos += 10 + nStrLen + 1;
441 sal_uInt8* q = pCellArr + nPos;
442 if( (nStrLen & 1) == 0 )
443 {
444 *q++ = 0;
445 nPos++;
446 }
447 p = reinterpret_cast<sal_uInt16*>( pCellArr + nPos );
448 nCount++;
449 }
450 }
451 nCol++;
452 }
453 nRow++;
454 }
455 nTab++;
456 }
457 *pCount = nCount;
458 return true;
459}
460
462 SCCOL nCol2, SCROW nRow2, SCTAB nTab2,
463 sal_uInt8* pCellArr)
464{
465
466 // Old Add-Ins are hard limited to sal_uInt16 values.
468 "Add check for columns > SAL_MAX_UINT16!");
469 if (nRow1 > SAL_MAX_UINT16 || nRow2 > SAL_MAX_UINT16)
470 return false;
471
472 sal_uInt16 nCount = 0;
473 sal_uInt16* p = reinterpret_cast<sal_uInt16*>(pCellArr);
474 *p++ = static_cast<sal_uInt16>(nCol1);
475 *p++ = static_cast<sal_uInt16>(nRow1);
476 *p++ = static_cast<sal_uInt16>(nTab1);
477 *p++ = static_cast<sal_uInt16>(nCol2);
478 *p++ = static_cast<sal_uInt16>(nRow2);
479 *p++ = static_cast<sal_uInt16>(nTab2);
480 sal_uInt16* pCount = p;
481 *p++ = 0;
482 sal_uInt16 nPos = 14;
483 SCTAB nTab = nTab1;
484 ScAddress aAdr;
485 while (nTab <= nTab2)
486 {
487 aAdr.SetTab( nTab );
488 SCROW nRow = nRow1;
489 while (nRow <= nRow2)
490 {
491 aAdr.SetRow( nRow );
492 SCCOL nCol = nCol1;
493 while (nCol <= nCol2)
494 {
495 aAdr.SetCol( nCol );
496 ScRefCellValue aCell(mrDoc, aAdr);
497 if (!aCell.isEmpty())
498 {
499 FormulaError nErr = FormulaError::NONE;
500 sal_uInt16 nType = 0; // 0 = number; 1 = string
501 double nVal = 0.0;
502 OUString aStr;
503 bool bOk = true;
504 switch (aCell.getType())
505 {
506 case CELLTYPE_STRING :
507 case CELLTYPE_EDIT :
508 aStr = aCell.getString(&mrDoc);
509 nType = 1;
510 break;
511 case CELLTYPE_VALUE :
512 nVal = GetValueCellValue(aAdr, aCell.getDouble());
513 break;
514 case CELLTYPE_FORMULA :
515 nErr = aCell.getFormula()->GetErrCode();
516 if (aCell.getFormula()->IsValue())
517 nVal = aCell.getFormula()->GetValue();
518 else
519 aStr = aCell.getFormula()->GetString().getString();
520 break;
521 default :
522 bOk = false;
523 break;
524 }
525 if (bOk)
526 {
527 if ((nPos + (5 * sizeof(sal_uInt16))) > MAXARRSIZE)
528 return false;
529 *p++ = static_cast<sal_uInt16>(nCol);
530 *p++ = static_cast<sal_uInt16>(nRow);
531 *p++ = static_cast<sal_uInt16>(nTab);
532 *p++ = static_cast<sal_uInt16>(nErr);
533 *p++ = nType;
534 nPos += 10;
535 if (nType == 0)
536 {
537 if ((nPos + sizeof(double)) > MAXARRSIZE)
538 return false;
539 memcpy( p, &nVal, sizeof(double));
540 nPos += sizeof(double);
541 }
542 else
543 {
544 OString aTmp(OUStringToOString(aStr,
545 osl_getThreadTextEncoding()));
546 // Old Add-Ins are limited to sal_uInt16 string
547 // lengths, and room for pad byte check.
548 if ( aTmp.getLength() > SAL_MAX_UINT16 - 2 )
549 return false;
550 // Append a 0-pad-byte if string length is odd
551 // MUST be sal_uInt16
552 sal_uInt16 nStrLen = static_cast<sal_uInt16>(aTmp.getLength());
553 sal_uInt16 nLen = ( nStrLen + 2 ) & ~1;
554 if ( (static_cast<sal_uLong>(nPos) + 2 + nLen) > MAXARRSIZE)
555 return false;
556 *p++ = nLen;
557 memcpy( p, aTmp.getStr(), nStrLen + 1);
558 nPos += 2 + nStrLen + 1;
559 sal_uInt8* q = pCellArr + nPos;
560 if( (nStrLen & 1) == 0 )
561 {
562 *q++ = 0;
563 nPos++;
564 }
565 }
566 nCount++;
567 p = reinterpret_cast<sal_uInt16*>( pCellArr + nPos );
568 }
569 }
570 nCol++;
571 }
572 nRow++;
573 }
574 nTab++;
575 }
576 *pCount = nCount;
577 return true;
578}
579
580// Stack operations
581
582// Also releases a TempToken if appropriate.
583
585{
586 if ( sp >= MAXSTACK )
587 SetError( FormulaError::StackOverflow );
588 else
589 {
590 r.IncRef();
591 if( sp >= maxsp )
592 maxsp = sp + 1;
593 else
594 pStack[ sp ]->DecRef();
595 pStack[ sp ] = &r;
596 ++sp;
597 }
598}
599
601{
602 if ( sp >= MAXSTACK )
603 SetError( FormulaError::StackOverflow );
604 else
605 {
606 if (nGlobalError != FormulaError::NONE)
607 {
608 if (r.GetType() == svError)
610 else
612 }
613 else
615 }
616}
617
619{
620 if ( sp >= MAXSTACK )
621 {
622 SetError( FormulaError::StackOverflow );
623 // p may be a dangling pointer hereafter!
624 p->DeleteIfZeroRef();
625 }
626 else
627 {
628 if (nGlobalError != FormulaError::NONE)
629 {
630 if (p->GetType() == svError)
631 {
632 p->SetError( nGlobalError);
634 }
635 else
636 {
637 // p may be a dangling pointer hereafter!
638 p->DeleteIfZeroRef();
640 }
641 }
642 else
644 }
645}
646
648{
649 p->IncRef();
650 if ( sp >= MAXSTACK )
651 {
652 SetError( FormulaError::StackOverflow );
653 // p may be a dangling pointer hereafter!
654 p->DecRef();
655 }
656 else
657 {
658 if( sp >= maxsp )
659 maxsp = sp + 1;
660 else
661 pStack[ sp ]->DecRef();
662 pStack[ sp ] = p;
663 ++sp;
664 }
665}
666
668{
669 if ( sp >= MAXSTACK )
670 {
671 SetError( FormulaError::StackOverflow );
672 }
673 else
674 {
675 if (nGlobalError != FormulaError::NONE)
676 {
677 if (x->GetType() == svError && x->GetError() == nGlobalError)
679 else
681 }
682 else
684 }
685}
686
687void ScInterpreter::PushCellResultToken( bool bDisplayEmptyAsString,
688 const ScAddress & rAddress, SvNumFormatType * pRetTypeExpr, sal_uInt32 * pRetIndexExpr, bool bFinalResult )
689{
690 ScRefCellValue aCell(mrDoc, rAddress);
691 if (aCell.hasEmptyValue())
692 {
693 bool bInherited = (aCell.getType() == CELLTYPE_FORMULA);
694 if (pRetTypeExpr && pRetIndexExpr)
695 mrDoc.GetNumberFormatInfo(mrContext, *pRetTypeExpr, *pRetIndexExpr, rAddress);
696 PushTempToken( new ScEmptyCellToken( bInherited, bDisplayEmptyAsString));
697 return;
698 }
699
700 FormulaError nErr = FormulaError::NONE;
701 if (aCell.getType() == CELLTYPE_FORMULA)
702 nErr = aCell.getFormula()->GetErrCode();
703
704 if (nErr != FormulaError::NONE)
705 {
706 PushError( nErr);
707 if (pRetTypeExpr)
708 *pRetTypeExpr = SvNumFormatType::UNDEFINED;
709 if (pRetIndexExpr)
710 *pRetIndexExpr = 0;
711 }
712 else if (aCell.hasString())
713 {
715 GetCellString( aRes, aCell);
716 PushString( aRes);
717 if (pRetTypeExpr)
718 *pRetTypeExpr = SvNumFormatType::TEXT;
719 if (pRetIndexExpr)
720 *pRetIndexExpr = 0;
721 }
722 else
723 {
724 double fVal = GetCellValue(rAddress, aCell);
725 if (bFinalResult)
726 {
727 TreatDoubleError( fVal);
728 if (!IfErrorPushError())
730 }
731 else
732 {
733 PushDouble( fVal);
734 }
735 if (pRetTypeExpr)
736 *pRetTypeExpr = nCurFmtType;
737 if (pRetIndexExpr)
738 *pRetIndexExpr = nCurFmtIndex;
739 }
740}
741
742// Simply throw away TOS.
743
745{
746 if( sp )
747 sp--;
748 else
749 SetError(FormulaError::UnknownStackVariable);
750}
751
752// Simply throw away TOS and set error code, used with ocIsError et al.
753
755{
756 if( sp )
757 {
758 sp--;
759 if (pStack[sp]->GetType() == svError)
761 }
762 else
763 SetError(FormulaError::UnknownStackVariable);
764}
765
767{
768 if (sp)
769 {
770 sp--;
771 const FormulaToken* p = pStack[ sp ];
772 if (p->GetType() == svError)
773 nGlobalError = p->GetError();
774 return p;
775 }
776 else
777 SetError(FormulaError::UnknownStackVariable);
778 return nullptr;
779}
780
782{
783 nCurFmtType = SvNumFormatType::NUMBER;
784 nCurFmtIndex = 0;
785 if( sp )
786 {
787 --sp;
788 const FormulaToken* p = pStack[ sp ];
789 switch (p->GetType())
790 {
791 case svError:
792 nGlobalError = p->GetError();
793 break;
794 case svDouble:
795 {
796 SvNumFormatType nType = static_cast<SvNumFormatType>(p->GetDoubleType());
797 if (nType != SvNumFormatType::ALL && nType != SvNumFormatType::UNDEFINED)
799 return p->GetDouble();
800 }
801 case svEmptyCell:
802 case svMissing:
803 return 0.0;
804 default:
805 SetError( FormulaError::IllegalArgument);
806 }
807 }
808 else
809 SetError( FormulaError::UnknownStackVariable);
810 return 0.0;
811}
812
814{
815 nCurFmtType = SvNumFormatType::TEXT;
816 nCurFmtIndex = 0;
817 if( sp )
818 {
819 --sp;
820 const FormulaToken* p = pStack[ sp ];
821 switch (p->GetType())
822 {
823 case svError:
824 nGlobalError = p->GetError();
825 break;
826 case svString:
827 return p->GetString();
828 case svEmptyCell:
829 case svMissing:
831 default:
832 SetError( FormulaError::IllegalArgument);
833 }
834 }
835 else
836 SetError( FormulaError::UnknownStackVariable);
837
839}
840
842{
843 SCCOL nCol;
844 SCROW nRow;
845 SCTAB nTab;
846 SingleRefToVars( rRef, nCol, nRow, nTab);
847}
848
850{
851 ValidateRef( rRef.Ref1);
852 ValidateRef( rRef.Ref2);
853}
854
855void ScInterpreter::ValidateRef( const ScRefList & rRefList )
856{
857 for (const auto& rRef : rRefList)
858 {
859 ValidateRef( rRef);
860 }
861}
862
864 SCCOL & rCol, SCROW & rRow, SCTAB & rTab )
865{
866 if ( rRef.IsColRel() )
867 rCol = aPos.Col() + rRef.Col();
868 else
869 rCol = rRef.Col();
870
871 if ( rRef.IsRowRel() )
872 rRow = aPos.Row() + rRef.Row();
873 else
874 rRow = rRef.Row();
875
876 if ( rRef.IsTabRel() )
877 rTab = aPos.Tab() + rRef.Tab();
878 else
879 rTab = rRef.Tab();
880
881 if( !mrDoc.ValidCol( rCol) || rRef.IsColDeleted() )
882 {
883 SetError( FormulaError::NoRef );
884 rCol = 0;
885 }
886 if( !mrDoc.ValidRow( rRow) || rRef.IsRowDeleted() )
887 {
888 SetError( FormulaError::NoRef );
889 rRow = 0;
890 }
891 if( !ValidTab( rTab, mrDoc.GetTableCount() - 1) || rRef.IsTabDeleted() )
892 {
893 SetError( FormulaError::NoRef );
894 rTab = 0;
895 }
896}
897
899{
900 ScAddress aAddr(rCol, rRow, rTab);
901 PopSingleRef(aAddr);
902 rCol = aAddr.Col();
903 rRow = aAddr.Row();
904 rTab = aAddr.Tab();
905}
906
908{
909 if( sp )
910 {
911 --sp;
912 const FormulaToken* p = pStack[ sp ];
913 switch (p->GetType())
914 {
915 case svError:
916 nGlobalError = p->GetError();
917 break;
918 case svSingleRef:
919 {
920 const ScSingleRefData* pRefData = p->GetSingleRef();
921 if (pRefData->IsDeleted())
922 {
923 SetError( FormulaError::NoRef);
924 break;
925 }
926
927 SCCOL nCol;
928 SCROW nRow;
929 SCTAB nTab;
930 SingleRefToVars( *pRefData, nCol, nRow, nTab);
931 rAdr.Set( nCol, nRow, nTab );
932 if (!mrDoc.m_TableOpList.empty())
933 ReplaceCell( rAdr );
934 }
935 break;
936 default:
937 SetError( FormulaError::IllegalParameter);
938 }
939 }
940 else
941 SetError( FormulaError::UnknownStackVariable);
942}
943
945 SCCOL& rCol1, SCROW &rRow1, SCTAB& rTab1,
946 SCCOL& rCol2, SCROW &rRow2, SCTAB& rTab2 )
947{
948 const ScComplexRefData& rCRef = *p->GetDoubleRef();
949 SingleRefToVars( rCRef.Ref1, rCol1, rRow1, rTab1);
950 SingleRefToVars( rCRef.Ref2, rCol2, rRow2, rTab2);
951 PutInOrder(rCol1, rCol2);
952 PutInOrder(rRow1, rRow2);
953 PutInOrder(rTab1, rTab2);
954 if (!mrDoc.m_TableOpList.empty())
955 {
956 ScRange aRange( rCol1, rRow1, rTab1, rCol2, rRow2, rTab2 );
957 if ( IsTableOpInRange( aRange ) )
958 SetError( FormulaError::IllegalParameter );
959 }
960}
961
963{
965 switch (eType)
966 {
967 case svUnknown:
968 SetError(FormulaError::UnknownStackVariable);
969 break;
970 case svError:
971 PopError();
972 break;
973 case svDoubleRef:
974 {
975 SCCOL nCol1, nCol2;
976 SCROW nRow1, nRow2;
977 SCTAB nTab1, nTab2;
978 PopDoubleRef(nCol1, nRow1, nTab1, nCol2, nRow2, nTab2);
979 if (nGlobalError != FormulaError::NONE)
980 break;
981 return new ScDBInternalRange(&mrDoc,
982 ScRange(nCol1, nRow1, nTab1, nCol2, nRow2, nTab2));
983 }
984 case svMatrix:
986 {
987 ScMatrixRef pMat;
988 if (eType == svMatrix)
989 pMat = PopMatrix();
990 else
992 if (nGlobalError != FormulaError::NONE)
993 break;
994 return new ScDBExternalRange(&mrDoc, std::move(pMat));
995 }
996 default:
997 SetError( FormulaError::IllegalParameter);
998 }
999
1000 return nullptr;
1001}
1002
1003void ScInterpreter::PopDoubleRef(SCCOL& rCol1, SCROW &rRow1, SCTAB& rTab1,
1004 SCCOL& rCol2, SCROW &rRow2, SCTAB& rTab2)
1005{
1006 if( sp )
1007 {
1008 --sp;
1009 const FormulaToken* p = pStack[ sp ];
1010 switch (p->GetType())
1011 {
1012 case svError:
1013 nGlobalError = p->GetError();
1014 break;
1015 case svDoubleRef:
1016 DoubleRefToVars( p, rCol1, rRow1, rTab1, rCol2, rRow2, rTab2);
1017 break;
1018 default:
1019 SetError( FormulaError::IllegalParameter);
1020 }
1021 }
1022 else
1023 SetError( FormulaError::UnknownStackVariable);
1024}
1025
1027 ScRange & rRange, bool bDontCheckForTableOp )
1028{
1029 SCCOL nCol;
1030 SCROW nRow;
1031 SCTAB nTab;
1032 SingleRefToVars( rCRef.Ref1, nCol, nRow, nTab);
1033 rRange.aStart.Set( nCol, nRow, nTab );
1034 SingleRefToVars( rCRef.Ref2, nCol, nRow, nTab);
1035 rRange.aEnd.Set( nCol, nRow, nTab );
1036 rRange.PutInOrder();
1037 if (!mrDoc.m_TableOpList.empty() && !bDontCheckForTableOp)
1038 {
1039 if ( IsTableOpInRange( rRange ) )
1040 SetError( FormulaError::IllegalParameter );
1041 }
1042}
1043
1044void ScInterpreter::PopDoubleRef( ScRange & rRange, short & rParam, size_t & rRefInList )
1045{
1046 if (sp)
1047 {
1048 const formula::FormulaToken* pToken = pStack[ sp-1 ];
1049 switch (pToken->GetType())
1050 {
1051 case svError:
1052 nGlobalError = pToken->GetError();
1053 break;
1054 case svDoubleRef:
1055 {
1056 --sp;
1057 const ScComplexRefData* pRefData = pToken->GetDoubleRef();
1058 if (pRefData->IsDeleted())
1059 {
1060 SetError( FormulaError::NoRef);
1061 break;
1062 }
1063 DoubleRefToRange( *pRefData, rRange);
1064 break;
1065 }
1066 case svRefList:
1067 {
1068 const ScRefList* pList = pToken->GetRefList();
1069 if (rRefInList < pList->size())
1070 {
1071 DoubleRefToRange( (*pList)[rRefInList], rRange);
1072 if (++rRefInList < pList->size())
1073 ++rParam;
1074 else
1075 {
1076 --sp;
1077 rRefInList = 0;
1078 }
1079 }
1080 else
1081 {
1082 --sp;
1083 rRefInList = 0;
1084 SetError( FormulaError::IllegalParameter);
1085 }
1086 }
1087 break;
1088 default:
1089 SetError( FormulaError::IllegalParameter);
1090 }
1091 }
1092 else
1093 SetError( FormulaError::UnknownStackVariable);
1094}
1095
1096void ScInterpreter::PopDoubleRef( ScRange& rRange, bool bDontCheckForTableOp )
1097{
1098 if( sp )
1099 {
1100 --sp;
1101 const FormulaToken* p = pStack[ sp ];
1102 switch (p->GetType())
1103 {
1104 case svError:
1105 nGlobalError = p->GetError();
1106 break;
1107 case svDoubleRef:
1108 DoubleRefToRange( *p->GetDoubleRef(), rRange, bDontCheckForTableOp);
1109 break;
1110 default:
1111 SetError( FormulaError::IllegalParameter);
1112 }
1113 }
1114 else
1115 SetError( FormulaError::UnknownStackVariable);
1116}
1117
1119{
1120 if( sp )
1121 {
1122 const FormulaToken* p = pStack[ sp - 1 ];
1123 switch (p->GetType())
1124 {
1125 case svDoubleRef:
1126 return p->GetDoubleRef();
1127 case svRefList:
1128 {
1129 const ScRefList* pList = p->GetRefList();
1130 if (rRefInList < pList->size())
1131 return &(*pList)[rRefInList];
1132 break;
1133 }
1134 default:
1135 break;
1136 }
1137 }
1138 return nullptr;
1139}
1140
1141void ScInterpreter::PopExternalSingleRef(sal_uInt16& rFileId, OUString& rTabName, ScSingleRefData& rRef)
1142{
1143 if (!sp)
1144 {
1145 SetError(FormulaError::UnknownStackVariable);
1146 return;
1147 }
1148
1149 --sp;
1150 const FormulaToken* p = pStack[sp];
1151 StackVar eType = p->GetType();
1152
1153 if (eType == svError)
1154 {
1155 nGlobalError = p->GetError();
1156 return;
1157 }
1158
1160 {
1161 SetError( FormulaError::IllegalParameter);
1162 return;
1163 }
1164
1165 rFileId = p->GetIndex();
1166 rTabName = p->GetString().getString();
1167 rRef = *p->GetSingleRef();
1168}
1169
1171{
1172 sal_uInt16 nFileId;
1173 OUString aTabName;
1175 PopExternalSingleRef(nFileId, aTabName, aData, rToken, pFmt);
1176}
1177
1179 sal_uInt16& rFileId, OUString& rTabName, ScSingleRefData& rRef,
1181{
1182 PopExternalSingleRef(rFileId, rTabName, rRef);
1183 if (nGlobalError != FormulaError::NONE)
1184 return;
1185
1187 const OUString* pFile = pRefMgr->getExternalFileName(rFileId);
1188 if (!pFile)
1189 {
1190 SetError(FormulaError::NoName);
1191 return;
1192 }
1193
1194 if (rRef.IsTabRel())
1195 {
1196 OSL_FAIL("ScCompiler::GetToken: external single reference must have an absolute table reference!");
1197 SetError(FormulaError::NoRef);
1198 return;
1199 }
1200
1201 ScAddress aAddr = rRef.toAbs(mrDoc, aPos);
1204 rFileId, rTabName, aAddr, &aPos, nullptr, &aFmt);
1205
1206 if (!xNew)
1207 {
1208 SetError(FormulaError::NoRef);
1209 return;
1210 }
1211
1212 if (xNew->GetType() == svError)
1213 SetError( xNew->GetError());
1214
1215 rToken = xNew;
1216 if (pFmt)
1217 *pFmt = aFmt;
1218}
1219
1220void ScInterpreter::PopExternalDoubleRef(sal_uInt16& rFileId, OUString& rTabName, ScComplexRefData& rRef)
1221{
1222 if (!sp)
1223 {
1224 SetError(FormulaError::UnknownStackVariable);
1225 return;
1226 }
1227
1228 --sp;
1229 const FormulaToken* p = pStack[sp];
1230 StackVar eType = p->GetType();
1231
1232 if (eType == svError)
1233 {
1234 nGlobalError = p->GetError();
1235 return;
1236 }
1237
1239 {
1240 SetError( FormulaError::IllegalParameter);
1241 return;
1242 }
1243
1244 rFileId = p->GetIndex();
1245 rTabName = p->GetString().getString();
1246 rRef = *p->GetDoubleRef();
1247}
1248
1250{
1251 sal_uInt16 nFileId;
1252 OUString aTabName;
1254 PopExternalDoubleRef(nFileId, aTabName, aData);
1255 if (nGlobalError != FormulaError::NONE)
1256 return;
1257
1258 GetExternalDoubleRef(nFileId, aTabName, aData, rArray);
1259 if (nGlobalError != FormulaError::NONE)
1260 return;
1261}
1262
1264{
1266 PopExternalDoubleRef(pArray);
1267 if (nGlobalError != FormulaError::NONE)
1268 return;
1269
1270 // For now, we only support single range data for external
1271 // references, which means the array should only contain a
1272 // single matrix token.
1273 formula::FormulaToken* p = pArray->FirstToken();
1274 if (!p || p->GetType() != svMatrix)
1275 SetError( FormulaError::IllegalParameter);
1276 else
1277 {
1278 rMat = p->GetMatrix();
1279 if (!rMat)
1280 SetError( FormulaError::UnknownVariable);
1281 }
1282}
1283
1285 sal_uInt16 nFileId, const OUString& rTabName, const ScComplexRefData& rData, ScExternalRefCache::TokenArrayRef& rArray)
1286{
1288 const OUString* pFile = pRefMgr->getExternalFileName(nFileId);
1289 if (!pFile)
1290 {
1291 SetError(FormulaError::NoName);
1292 return;
1293 }
1294 if (rData.Ref1.IsTabRel() || rData.Ref2.IsTabRel())
1295 {
1296 OSL_FAIL("ScCompiler::GetToken: external double reference must have an absolute table reference!");
1297 SetError(FormulaError::NoRef);
1298 return;
1299 }
1300
1301 ScComplexRefData aData(rData);
1302 ScRange aRange = aData.toAbs(mrDoc, aPos);
1303 if (!mrDoc.ValidColRow(aRange.aStart.Col(), aRange.aStart.Row()) || !mrDoc.ValidColRow(aRange.aEnd.Col(), aRange.aEnd.Row()))
1304 {
1305 SetError(FormulaError::NoRef);
1306 return;
1307 }
1308
1310 nFileId, rTabName, aRange, &aPos);
1311
1312 if (!pArray)
1313 {
1314 SetError(FormulaError::IllegalArgument);
1315 return;
1316 }
1317
1319 formula::FormulaToken* pToken = aIter.First();
1320 assert(pToken);
1321 if (pToken->GetType() == svError)
1322 {
1323 SetError( pToken->GetError());
1324 return;
1325 }
1326 if (pToken->GetType() != svMatrix)
1327 {
1328 SetError(FormulaError::IllegalArgument);
1329 return;
1330 }
1331
1332 if (aIter.Next())
1333 {
1334 // Can't handle more than one matrix per parameter.
1335 SetError( FormulaError::IllegalArgument);
1336 return;
1337 }
1338
1339 rArray = pArray;
1340}
1341
1343{
1344 switch ( GetStackType() )
1345 {
1346 case svDoubleRef :
1347 {
1348 ScRange aRange;
1349 PopDoubleRef( aRange, true );
1350 return DoubleRefToPosSingleRef( aRange, rAdr );
1351 }
1352 case svSingleRef :
1353 {
1354 PopSingleRef( rAdr );
1355 return true;
1356 }
1357 default:
1358 PopError();
1359 SetError( FormulaError::NoRef );
1360 }
1361 return false;
1362}
1363
1365{
1366 if ( GetStackType() == svDoubleRef )
1367 {
1368 ScMatrixRef pMat = GetMatrix();
1369 if ( pMat )
1370 PushMatrix( pMat );
1371 else
1373 }
1374 else
1375 SetError( FormulaError::NoRef );
1376}
1377
1379{
1380 if ( GetStackType() == svRefList )
1381 {
1382 FormulaConstTokenRef xTok = pStack[sp-1];
1383 const std::vector<ScComplexRefData>* pv = xTok->GetRefList();
1384 if (pv)
1385 {
1386 const size_t nEntries = pv->size();
1387 if (nEntries == 1)
1388 {
1389 --sp;
1391 }
1392 else if (bMatrixFormula)
1393 {
1394 // Only single cells can be stuffed into a column vector.
1395 // XXX NOTE: Excel doesn't do this but returns #VALUE! instead.
1396 // Though there's no compelling reason not to...
1397 for (const auto & rRef : *pv)
1398 {
1399 if (rRef.Ref1 != rRef.Ref2)
1400 return;
1401 }
1402 ScMatrixRef xMat = GetNewMat( 1, nEntries, true); // init empty
1403 if (!xMat)
1404 return;
1405 for (size_t i=0; i < nEntries; ++i)
1406 {
1407 SCCOL nCol; SCROW nRow; SCTAB nTab;
1408 SingleRefToVars( (*pv)[i].Ref1, nCol, nRow, nTab);
1409 if (nGlobalError == FormulaError::NONE)
1410 {
1411 ScAddress aAdr( nCol, nRow, nTab);
1412 ScRefCellValue aCell(mrDoc, aAdr);
1413 if (aCell.hasError())
1414 xMat->PutError( aCell.getFormula()->GetErrCode(), 0, i);
1415 else if (aCell.hasEmptyValue())
1416 xMat->PutEmpty( 0, i);
1417 else if (aCell.hasString())
1418 xMat->PutString( mrStrPool.intern( aCell.getString(&mrDoc)), 0, i);
1419 else
1420 xMat->PutDouble( aCell.getValue(), 0, i);
1421 }
1422 else
1423 {
1424 xMat->PutError( nGlobalError, 0, i);
1425 nGlobalError = FormulaError::NONE;
1426 }
1427 }
1428 --sp;
1429 PushMatrix( xMat);
1430 }
1431 }
1432 // else: keep token on stack, something will handle the error
1433 }
1434 else
1435 SetError( FormulaError::NoRef );
1436}
1437
1439{
1440 StackVar eStackType = GetStackType();
1441 if (eStackType == svUnknown)
1442 return; // can't do anything, some caller will catch that
1443 if (eStackType == svMatrix)
1444 return; // already matrix, nothing to do
1445
1446 if (eStackType != svDoubleRef && GetStackType(2) != svJumpMatrix)
1447 return; // always convert svDoubleRef, others only in JumpMatrix context
1448
1449 GetTokenMatrixMap(); // make sure it exists, create if not.
1450 ScMatrixRef pMat = GetMatrix();
1451 if ( pMat )
1452 PushMatrix( pMat );
1453 else
1455}
1456
1458{
1459 sal_uInt16 nParams = pCur->GetParamCount();
1460 SAL_WARN_IF( nParams > sp, "sc.core", "ConvertMatrixParameters: stack/param count mismatch: eOp: "
1461 << static_cast<int>(pCur->GetOpCode()) << " sp: " << sp << " nParams: " << nParams);
1462 assert(nParams <= sp);
1463 SCSIZE nJumpCols = 0, nJumpRows = 0;
1464 for ( sal_uInt16 i=1; i <= nParams && i <= sp; ++i )
1465 {
1466 const FormulaToken* p = pStack[ sp - i ];
1467 if ( p->GetOpCode() != ocPush && p->GetOpCode() != ocMissing)
1468 {
1469 assert(!"ConvertMatrixParameters: not a push");
1470 }
1471 else
1472 {
1473 switch ( p->GetType() )
1474 {
1475 case svDouble:
1476 case svString:
1477 case svSingleRef:
1479 case svMissing:
1480 case svError:
1481 case svEmptyCell:
1482 // nothing to do
1483 break;
1484 case svMatrix:
1485 {
1487 == formula::ParamClass::Value )
1488 { // only if single value expected
1489 ScConstMatrixRef pMat = p->GetMatrix();
1490 if ( !pMat )
1491 SetError( FormulaError::UnknownVariable);
1492 else
1493 {
1494 SCSIZE nCols, nRows;
1495 pMat->GetDimensions( nCols, nRows);
1496 if ( nJumpCols < nCols )
1497 nJumpCols = nCols;
1498 if ( nJumpRows < nRows )
1499 nJumpRows = nRows;
1500 }
1501 }
1502 }
1503 break;
1504 case svDoubleRef:
1505 {
1507 if ( eType != formula::ParamClass::Reference &&
1508 eType != formula::ParamClass::ReferenceOrRefArray &&
1509 eType != formula::ParamClass::ReferenceOrForceArray &&
1510 // For scalar Value: convert to Array/JumpMatrix
1511 // only if in array formula context, else (function
1512 // has ForceArray or ReferenceOrForceArray
1513 // parameter *somewhere else*) pick a normal
1514 // position dependent implicit intersection later.
1515 (eType != formula::ParamClass::Value || IsInArrayContext()))
1516 {
1517 SCCOL nCol1, nCol2;
1518 SCROW nRow1, nRow2;
1519 SCTAB nTab1, nTab2;
1520 DoubleRefToVars( p, nCol1, nRow1, nTab1, nCol2, nRow2, nTab2);
1521 // Make sure the map exists, created if not.
1524 nCol1, nRow1, nTab1, nCol2, nRow2, nTab2);
1525 if (pMat)
1526 {
1527 if ( eType == formula::ParamClass::Value )
1528 { // only if single value expected
1529 if ( nJumpCols < o3tl::make_unsigned(nCol2 - nCol1 + 1) )
1530 nJumpCols = static_cast<SCSIZE>(nCol2 - nCol1 + 1);
1531 if ( nJumpRows < o3tl::make_unsigned(nRow2 - nRow1 + 1) )
1532 nJumpRows = static_cast<SCSIZE>(nRow2 - nRow1 + 1);
1533 }
1534 formula::FormulaToken* pNew = new ScMatrixToken( std::move(pMat) );
1535 pNew->IncRef();
1536 pStack[ sp - i ] = pNew;
1537 p->DecRef(); // p may be dead now!
1538 }
1539 }
1540 }
1541 break;
1543 {
1545 if (eType == formula::ParamClass::Value || eType == formula::ParamClass::Array)
1546 {
1547 sal_uInt16 nFileId = p->GetIndex();
1548 OUString aTabName = p->GetString().getString();
1549 const ScComplexRefData& rRef = *p->GetDoubleRef();
1551 GetExternalDoubleRef(nFileId, aTabName, rRef, pArray);
1552 if (nGlobalError != FormulaError::NONE || !pArray)
1553 break;
1554 formula::FormulaToken* pTemp = pArray->FirstToken();
1555 if (!pTemp)
1556 break;
1557
1558 ScMatrixRef pMat = pTemp->GetMatrix();
1559 if (pMat)
1560 {
1561 if (eType == formula::ParamClass::Value)
1562 { // only if single value expected
1563 SCSIZE nC, nR;
1564 pMat->GetDimensions( nC, nR);
1565 if (nJumpCols < nC)
1566 nJumpCols = nC;
1567 if (nJumpRows < nR)
1568 nJumpRows = nR;
1569 }
1570 formula::FormulaToken* pNew = new ScMatrixToken( std::move(pMat) );
1571 pNew->IncRef();
1572 pStack[ sp - i ] = pNew;
1573 p->DecRef(); // p may be dead now!
1574 }
1575 }
1576 }
1577 break;
1578 case svRefList:
1579 {
1581 if ( eType != formula::ParamClass::Reference &&
1582 eType != formula::ParamClass::ReferenceOrRefArray &&
1583 eType != formula::ParamClass::ReferenceOrForceArray &&
1584 eType != formula::ParamClass::ForceArray)
1585 {
1586 // can't convert to matrix
1587 SetError( FormulaError::NoRef);
1588 }
1589 // else: the consuming function has to decide if and how to
1590 // handle a reference list argument in array context.
1591 }
1592 break;
1593 default:
1594 assert(!"ConvertMatrixParameters: unknown parameter type");
1595 }
1596 }
1597 }
1598 if( nJumpCols && nJumpRows )
1599 {
1600 short nPC = aCode.GetPC();
1601 short nStart = nPC - 1; // restart on current code (-1)
1602 short nNext = nPC; // next instruction after subroutine
1603 short nStop = nPC + 1; // stop subroutine before reaching that
1605 ScTokenMatrixMap::const_iterator aMapIter;
1606 if ((aMapIter = maTokenMatrixMap.find( pCur)) != maTokenMatrixMap.end())
1607 xNew = (*aMapIter).second;
1608 else
1609 {
1610 std::shared_ptr<ScJumpMatrix> pJumpMat;
1611 try
1612 {
1613 pJumpMat = std::make_shared<ScJumpMatrix>( pCur->GetOpCode(), nJumpCols, nJumpRows);
1614 }
1615 catch (const std::bad_alloc&)
1616 {
1617 SAL_WARN("sc.core", "std::bad_alloc in ScJumpMatrix ctor with " << nJumpCols << " columns and " << nJumpRows << " rows");
1618 return false;
1619 }
1620 pJumpMat->SetAllJumps( 1.0, nStart, nNext, nStop);
1621 // pop parameters and store in ScJumpMatrix, push in JumpMatrix()
1622 ScTokenVec aParams(nParams);
1623 for ( sal_uInt16 i=1; i <= nParams && sp > 0; ++i )
1624 {
1625 const FormulaToken* p = pStack[ --sp ];
1626 p->IncRef();
1627 // store in reverse order such that a push may simply iterate
1628 aParams[ nParams - i ] = p;
1629 }
1630 pJumpMat->SetJumpParameters( std::move(aParams) );
1631 xNew = new ScJumpMatrixToken( std::move(pJumpMat) );
1632 GetTokenMatrixMap().emplace(pCur, xNew);
1633 }
1634 PushTempTokenWithoutError( xNew.get());
1635 // set continuation point of path for main code line
1636 aCode.Jump( nNext, nNext);
1637 return true;
1638 }
1639 return false;
1640}
1641
1643{
1644 if( sp )
1645 {
1646 --sp;
1647 const FormulaToken* p = pStack[ sp ];
1648 switch (p->GetType())
1649 {
1650 case svError:
1651 nGlobalError = p->GetError();
1652 break;
1653 case svMatrix:
1654 {
1655 // ScMatrix itself maintains an im/mutable flag that should
1656 // be obeyed where necessary... so we can return ScMatrixRef
1657 // here instead of ScConstMatrixRef.
1658 ScMatrix* pMat = const_cast<FormulaToken*>(p)->GetMatrix();
1659 if ( pMat )
1660 pMat->SetErrorInterpreter( this);
1661 else
1662 SetError( FormulaError::UnknownVariable);
1663 return pMat;
1664 }
1665 default:
1666 SetError( FormulaError::IllegalParameter);
1667 }
1668 }
1669 else
1670 SetError( FormulaError::UnknownStackVariable);
1671 return nullptr;
1672}
1673
1675{
1676 sc::RangeMatrix aRet;
1677 if (sp)
1678 {
1679 switch (pStack[sp-1]->GetType())
1680 {
1681 case svMatrix:
1682 {
1683 --sp;
1684 const FormulaToken* p = pStack[sp];
1685 aRet.mpMat = const_cast<FormulaToken*>(p)->GetMatrix();
1686 if (aRet.mpMat)
1687 {
1688 aRet.mpMat->SetErrorInterpreter(this);
1689 if (p->GetByte() == MATRIX_TOKEN_HAS_RANGE)
1690 {
1691 const ScComplexRefData& rRef = *p->GetDoubleRef();
1692 if (!rRef.Ref1.IsColRel() && !rRef.Ref1.IsRowRel() && !rRef.Ref2.IsColRel() && !rRef.Ref2.IsRowRel())
1693 {
1694 aRet.mnCol1 = rRef.Ref1.Col();
1695 aRet.mnRow1 = rRef.Ref1.Row();
1696 aRet.mnTab1 = rRef.Ref1.Tab();
1697 aRet.mnCol2 = rRef.Ref2.Col();
1698 aRet.mnRow2 = rRef.Ref2.Row();
1699 aRet.mnTab2 = rRef.Ref2.Tab();
1700 }
1701 }
1702 }
1703 else
1704 SetError( FormulaError::UnknownVariable);
1705 }
1706 break;
1707 default:
1708 aRet.mpMat = PopMatrix();
1709 }
1710 }
1711 return aRet;
1712}
1713
1714void ScInterpreter::QueryMatrixType(const ScMatrixRef& xMat, SvNumFormatType& rRetTypeExpr, sal_uInt32& rRetIndexExpr)
1715{
1716 if (xMat)
1717 {
1718 SCSIZE nCols, nRows;
1719 xMat->GetDimensions(nCols, nRows);
1720 ScMatrixValue nMatVal = xMat->Get(0, 0);
1721 ScMatValType nMatValType = nMatVal.nType;
1722 if (ScMatrix::IsNonValueType( nMatValType))
1723 {
1724 if ( xMat->IsEmptyPath( 0, 0))
1725 { // result of empty FALSE jump path
1727 PushTempToken( new ScMatrixFormulaCellToken(nCols, nRows, xMat, xRes.get()));
1728 rRetTypeExpr = SvNumFormatType::LOGICAL;
1729 }
1730 else if ( xMat->IsEmptyResult( 0, 0))
1731 { // empty formula result
1732 FormulaTokenRef xRes = new ScEmptyCellToken( true, true); // inherited, display empty
1733 PushTempToken( new ScMatrixFormulaCellToken(nCols, nRows, xMat, xRes.get()));
1734 }
1735 else if ( xMat->IsEmpty( 0, 0))
1736 { // empty or empty cell
1737 FormulaTokenRef xRes = new ScEmptyCellToken( false, true); // not inherited, display empty
1738 PushTempToken( new ScMatrixFormulaCellToken(nCols, nRows, xMat, xRes.get()));
1739 }
1740 else
1741 {
1742 FormulaTokenRef xRes = new FormulaStringToken( nMatVal.GetString() );
1743 PushTempToken( new ScMatrixFormulaCellToken(nCols, nRows, xMat, xRes.get()));
1744 rRetTypeExpr = SvNumFormatType::TEXT;
1745 }
1746 }
1747 else
1748 {
1749 FormulaError nErr = GetDoubleErrorValue( nMatVal.fVal);
1750 FormulaTokenRef xRes;
1751 if (nErr != FormulaError::NONE)
1752 xRes = new FormulaErrorToken( nErr);
1753 else
1754 xRes = CreateFormulaDoubleToken( nMatVal.fVal);
1755 PushTempToken( new ScMatrixFormulaCellToken(nCols, nRows, xMat, xRes.get()));
1756 if ( rRetTypeExpr != SvNumFormatType::LOGICAL )
1757 rRetTypeExpr = SvNumFormatType::NUMBER;
1758 }
1759 rRetIndexExpr = 0;
1760 xMat->SetErrorInterpreter( nullptr);
1761 }
1762 else
1763 SetError( FormulaError::UnknownStackVariable);
1764}
1765
1767{
1768 assert( mrContext.maTokens.size() == TOKEN_CACHE_SIZE );
1769
1770 // Find a spare token
1771 for ( auto p : mrContext.maTokens )
1772 {
1773 if (p && p->GetRef() == 1)
1774 {
1775 p->GetDoubleAsReference() = fVal;
1776 p->SetDoubleType( static_cast<sal_Int16>(nFmt) );
1777 return p;
1778 }
1779 }
1780
1781 // Allocate a new token
1782 auto p = new FormulaTypedDoubleToken( fVal, static_cast<sal_Int16>(nFmt) );
1786 p->IncRef();
1788 return p;
1789}
1790
1792{
1793 // NumberFormat::NUMBER is the default untyped double.
1794 if (nFuncFmtType != SvNumFormatType::ALL && nFuncFmtType != SvNumFormatType::NUMBER &&
1795 nFuncFmtType != SvNumFormatType::UNDEFINED)
1797 else
1798 return CreateFormulaDoubleToken( fVal);
1799}
1800
1802{
1803 TreatDoubleError( nVal );
1804 if (!IfErrorPushError())
1806}
1807
1809{
1810 if (!IfErrorPushError())
1812}
1813
1815{
1816 if ( pString )
1817 {
1818 svl::SharedString aSS = mrDoc.GetSharedStringPool().intern(OUString(pString));
1819 PushString(aSS);
1820 }
1821 else
1823}
1824
1825void ScInterpreter::PushString( const OUString& rStr )
1826{
1828}
1829
1831{
1832 if (!IfErrorPushError())
1834}
1835
1837{
1838 if (!IfErrorPushError())
1839 {
1840 ScSingleRefData aRef;
1841 aRef.InitAddress(ScAddress(nCol,nRow,nTab));
1843 }
1844}
1845
1847 SCCOL nCol2, SCROW nRow2, SCTAB nTab2)
1848{
1849 if (!IfErrorPushError())
1850 {
1851 ScComplexRefData aRef;
1852 aRef.InitRange(ScRange(nCol1,nRow1,nTab1,nCol2,nRow2,nTab2));
1854 }
1855}
1856
1858 sal_uInt16 nFileId, const OUString& rTabName, SCCOL nCol, SCROW nRow, SCTAB nTab)
1859{
1860 if (!IfErrorPushError())
1861 {
1862 ScSingleRefData aRef;
1863 aRef.InitAddress(ScAddress(nCol,nRow,nTab));
1865 mrDoc.GetSharedStringPool().intern( rTabName), aRef)) ;
1866 }
1867}
1868
1870 sal_uInt16 nFileId, const OUString& rTabName,
1871 SCCOL nCol1, SCROW nRow1, SCTAB nTab1, SCCOL nCol2, SCROW nRow2, SCTAB nTab2)
1872{
1873 if (!IfErrorPushError())
1874 {
1875 ScComplexRefData aRef;
1876 aRef.InitRange(ScRange(nCol1,nRow1,nTab1,nCol2,nRow2,nTab2));
1878 mrDoc.GetSharedStringPool().intern( rTabName), aRef) );
1879 }
1880}
1881
1883{
1884 if (!IfErrorPushError())
1885 {
1886 ScSingleRefData aRef;
1887 aRef.InitFromRefAddress( mrDoc, rRef, aPos);
1889 }
1890}
1891
1893{
1894 if (!IfErrorPushError())
1895 {
1896 ScComplexRefData aRef;
1897 aRef.InitFromRefAddresses( mrDoc, rRef1, rRef2, aPos);
1899 }
1900}
1901
1903{
1904 if (!rMat.isRangeValid())
1905 {
1906 // Just push the matrix part only.
1907 PushMatrix(rMat.mpMat);
1908 return;
1909 }
1910
1911 rMat.mpMat->SetErrorInterpreter(nullptr);
1912 nGlobalError = FormulaError::NONE;
1914}
1915
1917{
1918 pMat->SetErrorInterpreter( nullptr);
1919 // No if (!IfErrorPushError()) because ScMatrix stores errors itself,
1920 // but with notifying ScInterpreter via nGlobalError, substituting it would
1921 // mean to inherit the error on all array elements in all following
1922 // operations.
1923 nGlobalError = FormulaError::NONE;
1925}
1926
1928{
1929 SetError( nError ); // only sets error if not already set
1931}
1932
1934{
1935 PushError( FormulaError::ParameterExpected);
1936}
1937
1939{
1940 PushError( FormulaError::IllegalParameter);
1941}
1942
1944{
1945 PushError( FormulaError::IllegalArgument);
1946}
1947
1949{
1950 PushError( FormulaError::NotAvailable);
1951}
1952
1954{
1955 PushError( FormulaError::NoValue);
1956}
1957
1959{
1960 return sp && pStack[sp - 1]->GetType() == svMissing;
1961}
1962
1964{
1965 StackVar eRes;
1966 if( sp )
1967 {
1968 eRes = pStack[sp - 1]->GetType();
1969 }
1970 else
1971 {
1972 SetError(FormulaError::UnknownStackVariable);
1973 eRes = svUnknown;
1974 }
1975 return eRes;
1976}
1977
1979{
1980 StackVar eRes;
1981 if( sp )
1982 {
1983 eRes = pStack[sp - 1]->GetType();
1984 if( eRes == svMissing || eRes == svEmptyCell )
1985 eRes = svDouble; // default!
1986 }
1987 else
1988 {
1989 SetError(FormulaError::UnknownStackVariable);
1990 eRes = svUnknown;
1991 }
1992 return eRes;
1993}
1994
1996{
1997 StackVar eRes;
1998 if( sp > nParam-1 )
1999 {
2000 eRes = pStack[sp - nParam]->GetType();
2001 if( eRes == svMissing || eRes == svEmptyCell )
2002 eRes = svDouble; // default!
2003 }
2004 else
2005 eRes = svUnknown;
2006 return eRes;
2007}
2008
2010{
2011 //reverse order of parameter stack
2012 assert( sp >= nParamCount && " less stack elements than parameters");
2013 sal_uInt16 nStackParams = std::min<sal_uInt16>( sp, nParamCount);
2014 std::reverse( pStack+(sp-nStackParams), pStack+sp );
2015}
2016
2018{
2019 // Check for a singleton first - no implicit intersection for them.
2020 if( rRange.aStart == rRange.aEnd )
2021 {
2022 rAdr = rRange.aStart;
2023 return true;
2024 }
2025
2026 bool bOk = false;
2027
2028 if ( pJumpMatrix )
2029 {
2030 bOk = rRange.aStart.Tab() == rRange.aEnd.Tab();
2031 if ( !bOk )
2032 SetError( FormulaError::IllegalArgument);
2033 else
2034 {
2035 SCSIZE nC, nR;
2036 pJumpMatrix->GetPos( nC, nR);
2037 rAdr.SetCol( sal::static_int_cast<SCCOL>( rRange.aStart.Col() + nC ) );
2038 rAdr.SetRow( sal::static_int_cast<SCROW>( rRange.aStart.Row() + nR ) );
2039 rAdr.SetTab( rRange.aStart.Tab());
2040 bOk = rRange.aStart.Col() <= rAdr.Col() && rAdr.Col() <=
2041 rRange.aEnd.Col() && rRange.aStart.Row() <= rAdr.Row() &&
2042 rAdr.Row() <= rRange.aEnd.Row();
2043 if ( !bOk )
2044 SetError( FormulaError::NoValue);
2045 }
2046 return bOk;
2047 }
2048
2050
2051 if ( !bOk )
2052 SetError( FormulaError::NoValue );
2053 return bOk;
2054}
2055
2057{
2058 if (!pMat)
2059 return 0.0;
2060
2061 if ( !pJumpMatrix )
2062 {
2063 double fVal = pMat->GetDoubleWithStringConversion( 0, 0);
2064 FormulaError nErr = GetDoubleErrorValue( fVal);
2065 if (nErr != FormulaError::NONE)
2066 {
2067 // Do not propagate the coded double error, but set nGlobalError in
2068 // case the matrix did not have an error interpreter set.
2069 SetError( nErr);
2070 fVal = 0.0;
2071 }
2072 return fVal;
2073 }
2074
2075 SCSIZE nCols, nRows, nC, nR;
2076 pMat->GetDimensions( nCols, nRows);
2077 pJumpMatrix->GetPos( nC, nR);
2078 // Use vector replication for single row/column arrays.
2079 if ( (nC < nCols || nCols == 1) && (nR < nRows || nRows == 1) )
2080 {
2081 double fVal = pMat->GetDoubleWithStringConversion( nC, nR);
2082 FormulaError nErr = GetDoubleErrorValue( fVal);
2083 if (nErr != FormulaError::NONE)
2084 {
2085 // Do not propagate the coded double error, but set nGlobalError in
2086 // case the matrix did not have an error interpreter set.
2087 SetError( nErr);
2088 fVal = 0.0;
2089 }
2090 return fVal;
2091 }
2092
2093 SetError( FormulaError::NoValue);
2094 return 0.0;
2095}
2096
2098{
2099 double nVal(0.0);
2100 switch( GetRawStackType() )
2101 {
2102 case svDouble:
2103 nVal = PopDouble();
2104 break;
2105 case svString:
2107 break;
2108 case svSingleRef:
2109 {
2110 ScAddress aAdr;
2111 PopSingleRef( aAdr );
2112 ScRefCellValue aCell(mrDoc, aAdr);
2113 nVal = GetCellValue(aAdr, aCell);
2114 }
2115 break;
2116 case svDoubleRef:
2117 { // generate position dependent SingleRef
2118 ScRange aRange;
2119 PopDoubleRef( aRange );
2120 ScAddress aAdr;
2121 if ( nGlobalError == FormulaError::NONE && DoubleRefToPosSingleRef( aRange, aAdr ) )
2122 {
2123 ScRefCellValue aCell(mrDoc, aAdr);
2124 nVal = GetCellValue(aAdr, aCell);
2125 }
2126 else
2127 nVal = 0.0;
2128 }
2129 break;
2131 {
2133 PopExternalSingleRef(pToken);
2134 if (nGlobalError == FormulaError::NONE)
2135 {
2136 if (pToken->GetType() == svDouble || pToken->GetType() == svEmptyCell)
2137 nVal = pToken->GetDouble();
2138 else
2139 nVal = ConvertStringToValue( pToken->GetString().getString());
2140 }
2141 }
2142 break;
2144 {
2145 ScMatrixRef pMat;
2147 if (nGlobalError != FormulaError::NONE)
2148 break;
2149
2150 nVal = GetDoubleFromMatrix(pMat);
2151 }
2152 break;
2153 case svMatrix:
2154 {
2155 ScMatrixRef pMat = PopMatrix();
2156 nVal = GetDoubleFromMatrix(pMat);
2157 }
2158 break;
2159 case svError:
2160 PopError();
2161 nVal = 0.0;
2162 break;
2163 case svEmptyCell:
2164 case svMissing:
2165 Pop();
2166 nVal = 0.0;
2167 break;
2168 default:
2169 PopError();
2170 SetError( FormulaError::IllegalParameter);
2171 nVal = 0.0;
2172 }
2173 if ( nFuncFmtType == nCurFmtType )
2175 return nVal;
2176}
2177
2179{
2180 bool bMissing = IsMissing();
2181 double nResultVal = GetDouble();
2182 if ( bMissing )
2183 nResultVal = nDefault;
2184 return nResultVal;
2185}
2186
2188{
2189 if (!std::isfinite(fVal))
2190 {
2192 return SAL_MAX_INT32;
2193 }
2194 if (fVal > 0.0)
2195 {
2196 fVal = rtl::math::approxFloor( fVal);
2197 if (fVal > SAL_MAX_INT32)
2198 {
2199 SetError( FormulaError::IllegalArgument);
2200 return SAL_MAX_INT32;
2201 }
2202 }
2203 else if (fVal < 0.0)
2204 {
2205 fVal = rtl::math::approxCeil( fVal);
2206 if (fVal < SAL_MIN_INT32)
2207 {
2208 SetError( FormulaError::IllegalArgument);
2209 return SAL_MAX_INT32;
2210 }
2211 }
2212 return static_cast<sal_Int32>(fVal);
2213}
2214
2216{
2217 return double_to_int32(GetDouble());
2218}
2219
2220sal_Int32 ScInterpreter::GetInt32WithDefault( sal_Int32 nDefault )
2221{
2222 bool bMissing = IsMissing();
2223 double fVal = GetDouble();
2224 if ( bMissing )
2225 return nDefault;
2226 return double_to_int32(fVal);
2227}
2228
2230{
2231 double fVal = GetDouble();
2232 if (!std::isfinite(fVal))
2233 {
2235 return SAL_MAX_INT16;
2236 }
2237 if (fVal > 0.0)
2238 {
2239 fVal = rtl::math::approxFloor( fVal);
2240 if (fVal > SAL_MAX_INT16)
2241 {
2242 SetError( FormulaError::IllegalArgument);
2243 return SAL_MAX_INT16;
2244 }
2245 }
2246 else if (fVal < 0.0)
2247 {
2248 fVal = rtl::math::approxCeil( fVal);
2249 if (fVal < SAL_MIN_INT16)
2250 {
2251 SetError( FormulaError::IllegalArgument);
2252 return SAL_MAX_INT16;
2253 }
2254 }
2255 return static_cast<sal_Int16>(fVal);
2256}
2257
2259{
2260 double fVal = rtl::math::approxFloor( GetDouble());
2261 if (!std::isfinite(fVal))
2262 {
2264 return SAL_MAX_UINT32;
2265 }
2266 if (fVal < 0.0 || fVal > SAL_MAX_UINT32)
2267 {
2268 SetError( FormulaError::IllegalArgument);
2269 return SAL_MAX_UINT32;
2270 }
2271 return static_cast<sal_uInt32>(fVal);
2272}
2273
2275{
2276 bool bDouble = true;
2277 switch( GetRawStackType() )
2278 {
2279 case svDouble:
2280 rDouble = PopDouble();
2281 break;
2282 case svString:
2283 rString = PopString();
2284 bDouble = false;
2285 break;
2286 case svDoubleRef :
2287 case svSingleRef :
2288 {
2289 ScAddress aAdr;
2290 if (!PopDoubleRefOrSingleRef( aAdr))
2291 {
2292 rDouble = 0.0;
2293 return true; // caller needs to check nGlobalError
2294 }
2295 ScRefCellValue aCell( mrDoc, aAdr);
2296 if (aCell.hasNumeric())
2297 {
2298 rDouble = GetCellValue( aAdr, aCell);
2299 }
2300 else
2301 {
2302 GetCellString( rString, aCell);
2303 bDouble = false;
2304 }
2305 }
2306 break;
2309 case svMatrix:
2310 {
2311 ScMatValType nType = GetDoubleOrStringFromMatrix( rDouble, rString);
2312 bDouble = ScMatrix::IsValueType( nType);
2313 }
2314 break;
2315 case svError:
2316 PopError();
2317 rDouble = 0.0;
2318 break;
2319 case svEmptyCell:
2320 case svMissing:
2321 Pop();
2322 rDouble = 0.0;
2323 break;
2324 default:
2325 PopError();
2326 SetError( FormulaError::IllegalParameter);
2327 rDouble = 0.0;
2328 }
2329 if ( nFuncFmtType == nCurFmtType )
2331 return bDouble;
2332}
2333
2335{
2336 switch (GetRawStackType())
2337 {
2338 case svError:
2339 PopError();
2341 case svMissing:
2342 case svEmptyCell:
2343 Pop();
2345 case svDouble:
2346 {
2347 return GetStringFromDouble( PopDouble() );
2348 }
2349 case svString:
2350 return PopString();
2351 case svSingleRef:
2352 {
2353 ScAddress aAdr;
2354 PopSingleRef( aAdr );
2355 if (nGlobalError == FormulaError::NONE)
2356 {
2357 ScRefCellValue aCell(mrDoc, aAdr);
2359 GetCellString(aSS, aCell);
2360 return aSS;
2361 }
2362 else
2364 }
2365 case svDoubleRef:
2366 { // generate position dependent SingleRef
2367 ScRange aRange;
2368 PopDoubleRef( aRange );
2369 ScAddress aAdr;
2370 if ( nGlobalError == FormulaError::NONE && DoubleRefToPosSingleRef( aRange, aAdr ) )
2371 {
2372 ScRefCellValue aCell(mrDoc, aAdr);
2374 GetCellString(aSS, aCell);
2375 return aSS;
2376 }
2377 else
2379 }
2381 {
2383 PopExternalSingleRef(pToken);
2384 if (nGlobalError != FormulaError::NONE)
2386
2387 if (pToken->GetType() == svDouble)
2388 {
2389 return GetStringFromDouble( pToken->GetDouble() );
2390 }
2391 else // svString or svEmpty
2392 return pToken->GetString();
2393 }
2395 {
2396 ScMatrixRef pMat;
2398 return GetStringFromMatrix(pMat);
2399 }
2400 case svMatrix:
2401 {
2402 ScMatrixRef pMat = PopMatrix();
2403 return GetStringFromMatrix(pMat);
2404 }
2405 break;
2406 default:
2407 PopError();
2408 SetError( FormulaError::IllegalArgument);
2409 }
2411}
2412
2414{
2415 if ( !pMat )
2416 ; // nothing
2417 else if ( !pJumpMatrix )
2418 {
2419 return pMat->GetString( *pFormatter, 0, 0);
2420 }
2421 else
2422 {
2423 SCSIZE nCols, nRows, nC, nR;
2424 pMat->GetDimensions( nCols, nRows);
2425 pJumpMatrix->GetPos( nC, nR);
2426 // Use vector replication for single row/column arrays.
2427 if ( (nC < nCols || nCols == 1) && (nR < nRows || nRows == 1) )
2428 return pMat->GetString( *pFormatter, nC, nR);
2429
2430 SetError( FormulaError::NoValue);
2431 }
2433}
2434
2436 double& rDouble, svl::SharedString& rString )
2437{
2438
2439 rDouble = 0.0;
2441 ScMatValType nMatValType = ScMatValType::Empty;
2442
2443 ScMatrixRef pMat;
2446 {
2447 pMat = GetMatrix();
2448 }
2449 else
2450 {
2451 PopError();
2452 SetError( FormulaError::IllegalParameter);
2453 return nMatValType;
2454 }
2455
2456 ScMatrixValue nMatVal;
2457 if (!pMat)
2458 {
2459 // nothing
2460 }
2461 else if (!pJumpMatrix)
2462 {
2463 nMatVal = pMat->Get(0, 0);
2464 nMatValType = nMatVal.nType;
2465 }
2466 else
2467 {
2468 SCSIZE nCols, nRows, nC, nR;
2469 pMat->GetDimensions( nCols, nRows);
2470 pJumpMatrix->GetPos( nC, nR);
2471 // Use vector replication for single row/column arrays.
2472 if ( (nC < nCols || nCols == 1) && (nR < nRows || nRows == 1) )
2473 {
2474 nMatVal = pMat->Get( nC, nR);
2475 nMatValType = nMatVal.nType;
2476 }
2477 else
2478 SetError( FormulaError::NoValue);
2479 }
2480
2481 if (ScMatrix::IsValueType( nMatValType))
2482 {
2483 rDouble = nMatVal.fVal;
2484 FormulaError nError = nMatVal.GetError();
2485 if (nError != FormulaError::NONE)
2486 SetError( nError);
2487 }
2488 else
2489 {
2490 rString = nMatVal.GetString();
2491 }
2492
2493 return nMatValType;
2494}
2495
2497{
2499 SvNumFormatType::NUMBER,
2501 OUString aStr;
2503 return mrStrPool.intern(aStr);
2504}
2505
2507{
2508 bool bMissingField = false;
2509 unique_ptr<ScDBQueryParamBase> pQueryParam( GetDBParams(bMissingField) );
2510 if (!pQueryParam)
2511 {
2512 // Failed to create query param.
2514 return;
2515 }
2516
2517 pQueryParam->mbSkipString = false;
2518 ScDBQueryDataIterator aValIter(mrDoc, mrContext, std::move(pQueryParam));
2520 if (!aValIter.GetFirst(aValue) || aValue.mnError != FormulaError::NONE)
2521 {
2522 // No match found.
2523 PushNoValue();
2524 return;
2525 }
2526
2528 if (aValIter.GetNext(aValNext) && aValNext.mnError == FormulaError::NONE)
2529 {
2530 // There should be only one unique match.
2532 return;
2533 }
2534
2535 if (aValue.mbIsNumber)
2536 PushDouble(aValue.mfValue);
2537 else
2538 PushString(aValue.maString);
2539}
2540
2542{
2543 sal_uInt8 nParamCount = GetByte();
2544 OUString aUnoName;
2545 OUString aFuncName( pCur->GetExternal().toAsciiUpperCase()); // programmatic name
2546 LegacyFuncData* pLegacyFuncData = ScGlobal::GetLegacyFuncCollection()->findByName(aFuncName);
2547 if (pLegacyFuncData)
2548 {
2549 // Old binary non-UNO add-in function.
2550 // NOTE: parameter count is 1-based with the 0th "parameter" being the
2551 // return value, included in pLegacyFuncDatat->GetParamCount()
2552 if (nParamCount < MAXFUNCPARAM && nParamCount == pLegacyFuncData->GetParamCount() - 1)
2553 {
2554 ParamType eParamType[MAXFUNCPARAM];
2555 void* ppParam[MAXFUNCPARAM];
2556 double nVal[MAXFUNCPARAM];
2557 char* pStr[MAXFUNCPARAM];
2558 sal_uInt8* pCellArr[MAXFUNCPARAM];
2559 short i;
2560
2561 for (i = 0; i < MAXFUNCPARAM; i++)
2562 {
2563 eParamType[i] = pLegacyFuncData->GetParamType(i);
2564 ppParam[i] = nullptr;
2565 nVal[i] = 0.0;
2566 pStr[i] = nullptr;
2567 pCellArr[i] = nullptr;
2568 }
2569
2570 for (i = nParamCount; (i > 0) && (nGlobalError == FormulaError::NONE); i--)
2571 {
2572 if (IsMissing())
2573 {
2574 // Old binary Add-In can't distinguish between missing
2575 // omitted argument and 0 (or any other value). Force
2576 // error.
2577 SetError( FormulaError::ParameterExpected);
2578 break; // for
2579 }
2580 switch (eParamType[i])
2581 {
2583 {
2584 nVal[i-1] = GetDouble();
2585 ppParam[i] = &nVal[i-1];
2586 }
2587 break;
2589 {
2591 osl_getThreadTextEncoding()));
2592 if ( aStr.getLength() >= ADDIN_MAXSTRLEN )
2593 SetError( FormulaError::StringOverflow );
2594 else
2595 {
2596 pStr[i-1] = new char[ADDIN_MAXSTRLEN];
2597 strncpy( pStr[i-1], aStr.getStr(), ADDIN_MAXSTRLEN );
2598 pStr[i-1][ADDIN_MAXSTRLEN-1] = 0;
2599 ppParam[i] = pStr[i-1];
2600 }
2601 }
2602 break;
2604 {
2605 SCCOL nCol1;
2606 SCROW nRow1;
2607 SCTAB nTab1;
2608 SCCOL nCol2;
2609 SCROW nRow2;
2610 SCTAB nTab2;
2611 PopDoubleRef(nCol1, nRow1, nTab1, nCol2, nRow2, nTab2);
2612 pCellArr[i-1] = new sal_uInt8[MAXARRSIZE];
2613 if (!CreateDoubleArr(nCol1, nRow1, nTab1, nCol2, nRow2, nTab2, pCellArr[i-1]))
2614 SetError(FormulaError::CodeOverflow);
2615 else
2616 ppParam[i] = pCellArr[i-1];
2617 }
2618 break;
2620 {
2621 SCCOL nCol1;
2622 SCROW nRow1;
2623 SCTAB nTab1;
2624 SCCOL nCol2;
2625 SCROW nRow2;
2626 SCTAB nTab2;
2627 PopDoubleRef(nCol1, nRow1, nTab1, nCol2, nRow2, nTab2);
2628 pCellArr[i-1] = new sal_uInt8[MAXARRSIZE];
2629 if (!CreateStringArr(nCol1, nRow1, nTab1, nCol2, nRow2, nTab2, pCellArr[i-1]))
2630 SetError(FormulaError::CodeOverflow);
2631 else
2632 ppParam[i] = pCellArr[i-1];
2633 }
2634 break;
2636 {
2637 SCCOL nCol1;
2638 SCROW nRow1;
2639 SCTAB nTab1;
2640 SCCOL nCol2;
2641 SCROW nRow2;
2642 SCTAB nTab2;
2643 PopDoubleRef(nCol1, nRow1, nTab1, nCol2, nRow2, nTab2);
2644 pCellArr[i-1] = new sal_uInt8[MAXARRSIZE];
2645 if (!CreateCellArr(nCol1, nRow1, nTab1, nCol2, nRow2, nTab2, pCellArr[i-1]))
2646 SetError(FormulaError::CodeOverflow);
2647 else
2648 ppParam[i] = pCellArr[i-1];
2649 }
2650 break;
2651 default :
2652 SetError(FormulaError::IllegalParameter);
2653 break;
2654 }
2655 }
2656 while ( i-- )
2657 Pop(); // In case of error (otherwise i==0) pop all parameters
2658
2659 if (nGlobalError == FormulaError::NONE)
2660 {
2661 if ( pLegacyFuncData->GetAsyncType() == ParamType::NONE )
2662 {
2663 switch ( eParamType[0] )
2664 {
2666 {
2667 double nErg = 0.0;
2668 ppParam[0] = &nErg;
2669 pLegacyFuncData->Call(ppParam);
2670 PushDouble(nErg);
2671 }
2672 break;
2674 {
2675 std::unique_ptr<char[]> pcErg(new char[ADDIN_MAXSTRLEN]);
2676 ppParam[0] = pcErg.get();
2677 pLegacyFuncData->Call(ppParam);
2678 OUString aUni( pcErg.get(), strlen(pcErg.get()), osl_getThreadTextEncoding() );
2679 PushString( aUni );
2680 }
2681 break;
2682 default:
2683 PushError( FormulaError::UnknownState );
2684 }
2685 }
2686 else
2687 {
2688 // enable asyncs after loading
2689 pArr->AddRecalcMode( ScRecalcMode::ONLOAD_LENIENT );
2690 // assure identical handler with identical call?
2691 double nErg = 0.0;
2692 ppParam[0] = &nErg;
2693 pLegacyFuncData->Call(ppParam);
2694 sal_uLong nHandle = sal_uLong( nErg );
2695 if ( nHandle >= 65536 )
2696 {
2698 if ( !pAs )
2699 {
2700 pAs = new ScAddInAsync(nHandle, pLegacyFuncData, &mrDoc);
2702 }
2703 else
2704 {
2706 if ( !pAs->HasDocument( &mrDoc ) )
2707 pAs->AddDocument( &mrDoc );
2708 }
2709 if ( pAs->IsValid() )
2710 {
2711 switch ( pAs->GetType() )
2712 {
2714 PushDouble( pAs->GetValue() );
2715 break;
2717 PushString( pAs->GetString() );
2718 break;
2719 default:
2720 PushError( FormulaError::UnknownState );
2721 }
2722 }
2723 else
2724 PushNA();
2725 }
2726 else
2727 PushNoValue();
2728 }
2729 }
2730
2731 for (i = 0; i < MAXFUNCPARAM; i++)
2732 {
2733 delete[] pStr[i];
2734 delete[] pCellArr[i];
2735 }
2736 }
2737 else
2738 {
2739 while( nParamCount-- > 0)
2740 PopError();
2742 }
2743 }
2744 else if ( !( aUnoName = ScGlobal::GetAddInCollection()->FindFunction(aFuncName, false) ).isEmpty() )
2745 {
2746 // bLocalFirst=false in FindFunction, cFunc should be the stored
2747 // internal name
2748
2749 ScUnoAddInCall aCall( mrDoc, *ScGlobal::GetAddInCollection(), aUnoName, nParamCount );
2750
2751 if ( !aCall.ValidParamCount() )
2752 SetError( FormulaError::IllegalParameter );
2753
2754 if ( aCall.NeedsCaller() && GetError() == FormulaError::NONE )
2755 {
2757 if (pShell)
2758 aCall.SetCallerFromObjectShell( pShell );
2759 else
2760 {
2761 // use temporary model object (without document) to supply options
2762 aCall.SetCaller( static_cast<beans::XPropertySet*>(
2763 new ScDocOptionsObj( mrDoc.GetDocOptions() ) ) );
2764 }
2765 }
2766
2767 short nPar = nParamCount;
2768 while ( nPar > 0 && GetError() == FormulaError::NONE )
2769 {
2770 --nPar; // 0 .. (nParamCount-1)
2771
2772 uno::Any aParam;
2773 if (IsMissing())
2774 {
2775 // Add-In has to explicitly handle an omitted empty missing
2776 // argument, do not default to anything like GetDouble() would
2777 // do (e.g. 0).
2778 Pop();
2779 aCall.SetParam( nPar, aParam );
2780 continue; // while
2781 }
2782
2783 StackVar nStackType = GetStackType();
2784 ScAddInArgumentType eType = aCall.GetArgType( nPar );
2785 switch (eType)
2786 {
2788 {
2789 sal_Int32 nVal = GetInt32();
2790 if (nGlobalError == FormulaError::NONE)
2791 aParam <<= nVal;
2792 }
2793 break;
2794
2795 case SC_ADDINARG_DOUBLE:
2796 aParam <<= GetDouble();
2797 break;
2798
2799 case SC_ADDINARG_STRING:
2800 aParam <<= GetString().getString();
2801 break;
2802
2804 switch( nStackType )
2805 {
2806 case svDouble:
2807 case svString:
2808 case svSingleRef:
2809 {
2810 sal_Int32 nVal = GetInt32();
2811 if (nGlobalError == FormulaError::NONE)
2812 {
2813 uno::Sequence<sal_Int32> aInner( &nVal, 1 );
2814 uno::Sequence< uno::Sequence<sal_Int32> > aOuter( &aInner, 1 );
2815 aParam <<= aOuter;
2816 }
2817 }
2818 break;
2819 case svDoubleRef:
2820 {
2821 ScRange aRange;
2822 PopDoubleRef( aRange );
2823 if (!ScRangeToSequence::FillLongArray( aParam, mrDoc, aRange ))
2824 SetError(FormulaError::IllegalParameter);
2825 }
2826 break;
2827 case svMatrix:
2829 SetError(FormulaError::IllegalParameter);
2830 break;
2831 default:
2832 PopError();
2833 SetError(FormulaError::IllegalParameter);
2834 }
2835 break;
2836
2838 switch( nStackType )
2839 {
2840 case svDouble:
2841 case svString:
2842 case svSingleRef:
2843 {
2844 double fVal = GetDouble();
2845 uno::Sequence<double> aInner( &fVal, 1 );
2846 uno::Sequence< uno::Sequence<double> > aOuter( &aInner, 1 );
2847 aParam <<= aOuter;
2848 }
2849 break;
2850 case svDoubleRef:
2851 {
2852 ScRange aRange;
2853 PopDoubleRef( aRange );
2854 if (!ScRangeToSequence::FillDoubleArray( aParam, mrDoc, aRange ))
2855 SetError(FormulaError::IllegalParameter);
2856 }
2857 break;
2858 case svMatrix:
2860 SetError(FormulaError::IllegalParameter);
2861 break;
2862 default:
2863 PopError();
2864 SetError(FormulaError::IllegalParameter);
2865 }
2866 break;
2867
2869 switch( nStackType )
2870 {
2871 case svDouble:
2872 case svString:
2873 case svSingleRef:
2874 {
2875 OUString aString = GetString().getString();
2876 uno::Sequence<OUString> aInner( &aString, 1 );
2877 uno::Sequence< uno::Sequence<OUString> > aOuter( &aInner, 1 );
2878 aParam <<= aOuter;
2879 }
2880 break;
2881 case svDoubleRef:
2882 {
2883 ScRange aRange;
2884 PopDoubleRef( aRange );
2885 if (!ScRangeToSequence::FillStringArray( aParam, mrDoc, aRange ))
2886 SetError(FormulaError::IllegalParameter);
2887 }
2888 break;
2889 case svMatrix:
2891 SetError(FormulaError::IllegalParameter);
2892 break;
2893 default:
2894 PopError();
2895 SetError(FormulaError::IllegalParameter);
2896 }
2897 break;
2898
2900 switch( nStackType )
2901 {
2902 case svDouble:
2903 case svString:
2904 case svSingleRef:
2905 {
2906 uno::Any aElem;
2907 if ( nStackType == svDouble )
2908 aElem <<= GetDouble();
2909 else if ( nStackType == svString )
2910 aElem <<= GetString().getString();
2911 else
2912 {
2913 ScAddress aAdr;
2914 if ( PopDoubleRefOrSingleRef( aAdr ) )
2915 {
2916 ScRefCellValue aCell(mrDoc, aAdr);
2917 if (aCell.hasString())
2918 {
2920 GetCellString(aStr, aCell);
2921 aElem <<= aStr.getString();
2922 }
2923 else
2924 aElem <<= GetCellValue(aAdr, aCell);
2925 }
2926 }
2927 uno::Sequence<uno::Any> aInner( &aElem, 1 );
2928 uno::Sequence< uno::Sequence<uno::Any> > aOuter( &aInner, 1 );
2929 aParam <<= aOuter;
2930 }
2931 break;
2932 case svDoubleRef:
2933 {
2934 ScRange aRange;
2935 PopDoubleRef( aRange );
2936 if (!ScRangeToSequence::FillMixedArray( aParam, mrDoc, aRange ))
2937 SetError(FormulaError::IllegalParameter);
2938 }
2939 break;
2940 case svMatrix:
2942 SetError(FormulaError::IllegalParameter);
2943 break;
2944 default:
2945 PopError();
2946 SetError(FormulaError::IllegalParameter);
2947 }
2948 break;
2949
2951 switch( nStackType )
2952 {
2953 case svDouble:
2954 aParam <<= GetDouble();
2955 break;
2956 case svString:
2957 aParam <<= GetString().getString();
2958 break;
2959 case svSingleRef:
2960 {
2961 ScAddress aAdr;
2962 if ( PopDoubleRefOrSingleRef( aAdr ) )
2963 {
2964 ScRefCellValue aCell(mrDoc, aAdr);
2965 if (aCell.hasString())
2966 {
2968 GetCellString(aStr, aCell);
2969 aParam <<= aStr.getString();
2970 }
2971 else
2972 aParam <<= GetCellValue(aAdr, aCell);
2973 }
2974 }
2975 break;
2976 case svDoubleRef:
2977 {
2978 ScRange aRange;
2979 PopDoubleRef( aRange );
2980 if (!ScRangeToSequence::FillMixedArray( aParam, mrDoc, aRange ))
2981 SetError(FormulaError::IllegalParameter);
2982 }
2983 break;
2984 case svMatrix:
2986 SetError(FormulaError::IllegalParameter);
2987 break;
2988 default:
2989 PopError();
2990 SetError(FormulaError::IllegalParameter);
2991 }
2992 break;
2993
2995 switch( nStackType )
2996 {
2997 case svSingleRef:
2998 {
2999 ScAddress aAdr;
3000 PopSingleRef( aAdr );
3001 ScRange aRange( aAdr );
3002 uno::Reference<table::XCellRange> xObj =
3004 if (xObj.is())
3005 aParam <<= xObj;
3006 else
3007 SetError(FormulaError::IllegalParameter);
3008 }
3009 break;
3010 case svDoubleRef:
3011 {
3012 ScRange aRange;
3013 PopDoubleRef( aRange );
3014 uno::Reference<table::XCellRange> xObj =
3016 if (xObj.is())
3017 {
3018 aParam <<= xObj;
3019 }
3020 else
3021 {
3022 SetError(FormulaError::IllegalParameter);
3023 }
3024 }
3025 break;
3026 default:
3027 PopError();
3028 SetError(FormulaError::IllegalParameter);
3029 }
3030 break;
3031
3032 default:
3033 PopError();
3034 SetError(FormulaError::IllegalParameter);
3035 }
3036 aCall.SetParam( nPar, aParam );
3037 }
3038
3039 while (nPar-- > 0)
3040 {
3041 Pop(); // in case of error, remove remaining args
3042 }
3043 if ( GetError() == FormulaError::NONE )
3044 {
3045 aCall.ExecuteCall();
3046
3047 if ( aCall.HasVarRes() ) // handle async functions
3048 {
3049 pArr->AddRecalcMode( ScRecalcMode::ONLOAD_LENIENT );
3050 uno::Reference<sheet::XVolatileResult> xRes = aCall.GetVarRes();
3051 ScAddInListener* pLis = ScAddInListener::Get( xRes );
3052 // In case there is no pMyFormulaCell, i.e. while interpreting
3053 // temporarily from within the Function Wizard, try to obtain a
3054 // valid result from an existing listener for that volatile, or
3055 // create a new and hope for an immediate result. If none
3056 // available that should lead to a void result and thus #N/A.
3057 bool bTemporaryListener = false;
3058 if ( !pLis )
3059 {
3060 pLis = ScAddInListener::CreateListener( xRes, &mrDoc );
3061 if (pMyFormulaCell)
3063 else
3064 bTemporaryListener = true;
3065 }
3066 else if (pMyFormulaCell)
3067 {
3069 if ( !pLis->HasDocument( &mrDoc ) )
3070 {
3071 pLis->AddDocument( &mrDoc );
3072 }
3073 }
3074
3075 aCall.SetResult( pLis->GetResult() ); // use result from async
3076
3077 if (bTemporaryListener)
3078 {
3079 try
3080 {
3081 // EventObject can be any, not evaluated by
3082 // ScAddInListener::disposing()
3083 css::lang::EventObject aEvent;
3084 pLis->disposing(aEvent); // pLis is dead hereafter
3085 }
3086 catch (const uno::Exception&)
3087 {
3088 }
3089 }
3090 }
3091
3092 if ( aCall.GetErrCode() != FormulaError::NONE )
3093 {
3094 PushError( aCall.GetErrCode() );
3095 }
3096 else if ( aCall.HasMatrix() )
3097 {
3098 PushMatrix( aCall.GetMatrix() );
3099 }
3100 else if ( aCall.HasString() )
3101 {
3102 PushString( aCall.GetString() );
3103 }
3104 else
3105 {
3106 PushDouble( aCall.GetValue() );
3107 }
3108 }
3109 else // error...
3110 PushError( GetError());
3111 }
3112 else
3113 {
3114 while( nParamCount-- > 0)
3115 {
3116 PopError();
3117 }
3118 PushError( FormulaError::NoAddin );
3119 }
3120}
3121
3123{
3124 if ( aCode.IsEndOfPath() )
3125 PushTempToken( new ScEmptyCellToken( false, false ) );
3126 else
3128}
3129
3130#if HAVE_FEATURE_SCRIPTING
3131
3132static uno::Any lcl_getSheetModule( const uno::Reference<table::XCellRange>& xCellRange, const ScDocument* pDok )
3133{
3134 uno::Reference< sheet::XSheetCellRange > xSheetRange( xCellRange, uno::UNO_QUERY_THROW );
3135 uno::Reference< beans::XPropertySet > xProps( xSheetRange->getSpreadsheet(), uno::UNO_QUERY_THROW );
3136 OUString sCodeName;
3137 xProps->getPropertyValue("CodeName") >>= sCodeName;
3138 // #TODO #FIXME ideally we should 'throw' here if we don't get a valid parent, but... it is possible
3139 // to create a module ( and use 'Option VBASupport 1' ) for a calc document, in this scenario there
3140 // are *NO* special document module objects ( of course being able to switch between vba/non vba mode at
3141 // the document in the future could fix this, especially IF the switching of the vba mode takes care to
3142 // create the special document module objects if they don't exist.
3143 BasicManager* pBasMgr = pDok->GetDocumentShell()->GetBasicManager();
3144
3145 uno::Reference< uno::XInterface > xIf;
3146 if ( pBasMgr && !pBasMgr->GetName().isEmpty() )
3147 {
3148 OUString sProj( "Standard" );
3149 if ( !pDok->GetDocumentShell()->GetBasicManager()->GetName().isEmpty() )
3150 {
3151 sProj = pDok->GetDocumentShell()->GetBasicManager()->GetName();
3152 }
3153 StarBASIC* pBasic = pDok->GetDocumentShell()->GetBasicManager()->GetLib( sProj );
3154 if ( pBasic )
3155 {
3156 SbModule* pMod = pBasic->FindModule( sCodeName );
3157 if ( pMod )
3158 {
3159 xIf = pMod->GetUnoModule();
3160 }
3161 }
3162 }
3163 return uno::Any( xIf );
3164}
3165
3166static bool lcl_setVBARange( const ScRange& aRange, const ScDocument& rDok, SbxVariable* pPar )
3167{
3168 bool bOk = false;
3169 try
3170 {
3171 uno::Reference< uno::XInterface > xVBARange;
3172 uno::Reference<table::XCellRange> xCellRange = ScCellRangeObj::CreateRangeFromDoc( rDok, aRange );
3173 uno::Sequence< uno::Any > aArgs{ lcl_getSheetModule( xCellRange, &rDok ),
3174 uno::Any(xCellRange) };
3175 xVBARange = ooo::vba::createVBAUnoAPIServiceWithArgs( rDok.GetDocumentShell(), "ooo.vba.excel.Range", aArgs );
3176 if ( xVBARange.is() )
3177 {
3178 SbxObjectRef aObj = GetSbUnoObject( "A-Range", uno::Any( xVBARange ) );
3180 bOk = pPar->PutObject( aObj.get() );
3181 }
3182 }
3183 catch( uno::Exception& )
3184 {
3185 }
3186 return bOk;
3187}
3188
3189static bool lcl_isNumericResult( double& fVal, const SbxVariable* pVar )
3190{
3191 switch (pVar->GetType())
3192 {
3193 case SbxINTEGER:
3194 case SbxLONG:
3195 case SbxSINGLE:
3196 case SbxDOUBLE:
3197 case SbxCURRENCY:
3198 case SbxDATE:
3199 case SbxUSHORT:
3200 case SbxULONG:
3201 case SbxINT:
3202 case SbxUINT:
3203 case SbxSALINT64:
3204 case SbxSALUINT64:
3205 case SbxDECIMAL:
3206 fVal = pVar->GetDouble();
3207 return true;
3208 case SbxBOOL:
3209 fVal = (pVar->GetBool() ? 1.0 : 0.0);
3210 return true;
3211 default:
3212 ; // nothing
3213 }
3214 return false;
3215}
3216
3217#endif
3218
3220{
3221
3222#if !HAVE_FEATURE_SCRIPTING
3223 PushNoValue(); // without DocShell no CallBasic
3224 return;
3225#else
3227
3228 sal_uInt8 nParamCount = GetByte();
3229 OUString aMacro( pCur->GetExternal() );
3230
3232 if ( !pDocSh )
3233 {
3234 PushNoValue(); // without DocShell no CallBasic
3235 return;
3236 }
3237
3238 // no security queue beforehand (just CheckMacroWarn), moved to CallBasic
3239
3240 // If the Dok was loaded during a Basic-Calls,
3241 // is the Sbx-object created(?)
3242// pDocSh->GetSbxObject();
3243
3244 // search function with the name,
3245 // then assemble SfxObjectShell::CallBasic from aBasicStr, aMacroStr
3246
3247 StarBASIC* pRoot;
3248
3249 try
3250 {
3251 pRoot = pDocSh->GetBasic();
3252 }
3253 catch (...)
3254 {
3255 pRoot = nullptr;
3256 }
3257
3258 SbxVariable* pVar = pRoot ? pRoot->Find(aMacro, SbxClassType::Method) : nullptr;
3259 if( !pVar || pVar->GetType() == SbxVOID )
3260 {
3261 PushError( FormulaError::NoMacro );
3262 return;
3263 }
3264 SbMethod* pMethod = dynamic_cast<SbMethod*>(pVar);
3265 if( !pMethod )
3266 {
3267 PushError( FormulaError::NoMacro );
3268 return;
3269 }
3270
3271 bool bVolatileMacro = false;
3272
3273 SbModule* pModule = pMethod->GetModule();
3274 bool bUseVBAObjects = pModule->IsVBASupport();
3275 SbxObject* pObject = pModule->GetParent();
3276 OSL_ENSURE(dynamic_cast<const StarBASIC *>(pObject) != nullptr, "No Basic found!");
3277 OUString aMacroStr = pObject->GetName() + "." + pModule->GetName() + "." + pMethod->GetName();
3278 OUString aBasicStr;
3279 if (pRoot && bUseVBAObjects)
3280 {
3281 // just here to make sure the VBA objects when we run the macro during ODF import
3282 pRoot->getVBAGlobals();
3283 }
3284 if (pObject->GetParent())
3285 {
3286 aBasicStr = pObject->GetParent()->GetName(); // document BASIC
3287 }
3288 else
3289 {
3290 aBasicStr = SfxGetpApp()->GetName(); // application BASIC
3291 }
3292 // assemble a parameter array
3293
3294 SbxArrayRef refPar = new SbxArray;
3295 bool bOk = true;
3296 for( sal_uInt32 i = nParamCount; i && bOk ; i-- )
3297 {
3298 SbxVariable* pPar = refPar->Get(i);
3299 switch( GetStackType() )
3300 {
3301 case svDouble:
3302 pPar->PutDouble( GetDouble() );
3303 break;
3304 case svString:
3305 pPar->PutString( GetString().getString() );
3306 break;
3308 {
3310 PopExternalSingleRef(pToken);
3311 if (nGlobalError != FormulaError::NONE)
3312 bOk = false;
3313 else
3314 {
3315 if ( pToken->GetType() == svString )
3316 pPar->PutString( pToken->GetString().getString() );
3317 else if ( pToken->GetType() == svDouble )
3318 pPar->PutDouble( pToken->GetDouble() );
3319 else
3320 {
3321 SetError( FormulaError::IllegalArgument );
3322 bOk = false;
3323 }
3324 }
3325 }
3326 break;
3327 case svSingleRef:
3328 {
3329 ScAddress aAdr;
3330 PopSingleRef( aAdr );
3331 if ( bUseVBAObjects )
3332 {
3333 ScRange aRange( aAdr );
3334 bOk = lcl_setVBARange( aRange, mrDoc, pPar );
3335 }
3336 else
3337 {
3338 bOk = SetSbxVariable( pPar, aAdr );
3339 }
3340 }
3341 break;
3342 case svDoubleRef:
3343 {
3344 SCCOL nCol1;
3345 SCROW nRow1;
3346 SCTAB nTab1;
3347 SCCOL nCol2;
3348 SCROW nRow2;
3349 SCTAB nTab2;
3350 PopDoubleRef( nCol1, nRow1, nTab1, nCol2, nRow2, nTab2 );
3351 if( nTab1 != nTab2 )
3352 {
3353 SetError( FormulaError::IllegalParameter );
3354 bOk = false;
3355 }
3356 else
3357 {
3358 if ( bUseVBAObjects )
3359 {
3360 ScRange aRange( nCol1, nRow1, nTab1, nCol2, nRow2, nTab2 );
3361 bOk = lcl_setVBARange( aRange, mrDoc, pPar );
3362 }
3363 else
3364 {
3365 SbxDimArrayRef refArray = new SbxDimArray;
3366 refArray->AddDim(1, nRow2 - nRow1 + 1);
3367 refArray->AddDim(1, nCol2 - nCol1 + 1);
3368 ScAddress aAdr( nCol1, nRow1, nTab1 );
3369 for( SCROW nRow = nRow1; bOk && nRow <= nRow2; nRow++ )
3370 {
3371 aAdr.SetRow( nRow );
3372 sal_Int32 nIdx[ 2 ];
3373 nIdx[ 0 ] = nRow-nRow1+1;
3374 for( SCCOL nCol = nCol1; bOk && nCol <= nCol2; nCol++ )
3375 {
3376 aAdr.SetCol( nCol );
3377 nIdx[ 1 ] = nCol-nCol1+1;
3378 SbxVariable* p = refArray->Get(nIdx);
3379 bOk = SetSbxVariable( p, aAdr );
3380 }
3381 }
3382 pPar->PutObject( refArray.get() );
3383 }
3384 }
3385 }
3386 break;
3388 case svMatrix:
3389 {
3390 ScMatrixRef pMat = GetMatrix();
3391 SCSIZE nC, nR;
3392 if (pMat && nGlobalError == FormulaError::NONE)
3393 {
3394 pMat->GetDimensions(nC, nR);
3395 SbxDimArrayRef refArray = new SbxDimArray;
3396 refArray->AddDim(1, static_cast<sal_Int32>(nR));
3397 refArray->AddDim(1, static_cast<sal_Int32>(nC));
3398 for( SCSIZE nMatRow = 0; nMatRow < nR; nMatRow++ )
3399 {
3400 sal_Int32 nIdx[ 2 ];
3401 nIdx[ 0 ] = static_cast<sal_Int32>(nMatRow+1);
3402 for( SCSIZE nMatCol = 0; nMatCol < nC; nMatCol++ )
3403 {
3404 nIdx[ 1 ] = static_cast<sal_Int32>(nMatCol+1);
3405 SbxVariable* p = refArray->Get(nIdx);
3406 if (pMat->IsStringOrEmpty(nMatCol, nMatRow))
3407 {
3408 p->PutString( pMat->GetString(nMatCol, nMatRow).getString() );
3409 }
3410 else
3411 {
3412 p->PutDouble( pMat->GetDouble(nMatCol, nMatRow));
3413 }
3414 }
3415 }
3416 pPar->PutObject( refArray.get() );
3417 }
3418 else
3419 {
3420 SetError( FormulaError::IllegalParameter );
3421 }
3422 }
3423 break;
3424 default:
3425 SetError( FormulaError::IllegalParameter );
3426 bOk = false;
3427 }
3428 }
3429 if( bOk )
3430 {
3431 mrDoc.LockTable( aPos.Tab() );
3432 SbxVariableRef refRes = new SbxVariable;
3434 ErrCode eRet = pDocSh->CallBasic( aMacroStr, aBasicStr, refPar.get(), refRes.get() );
3437
3438 ScMacroManager* pMacroMgr = mrDoc.GetMacroManager();
3439 if (pMacroMgr)
3440 {
3441 bVolatileMacro = pMacroMgr->GetUserFuncVolatile( pMethod->GetName() );
3442 pMacroMgr->AddDependentCell(pModule->GetName(), pMyFormulaCell);
3443 }
3444
3445 double fVal;
3446 SbxDataType eResType = refRes->GetType();
3447 if( SbxBase::GetError() )
3448 {
3449 SetError( FormulaError::NoValue);
3450 }
3451 if ( eRet != ERRCODE_NONE )
3452 {
3453 PushNoValue();
3454 }
3455 else if (lcl_isNumericResult( fVal, refRes.get()))
3456 {
3457 switch (eResType)
3458 {
3459 case SbxDATE:
3460 nFuncFmtType = SvNumFormatType::DATE;
3461 break;
3462 case SbxBOOL:
3463 nFuncFmtType = SvNumFormatType::LOGICAL;
3464 break;
3465 // Do not add SbxCURRENCY, we don't know which currency.
3466 default:
3467 ; // nothing
3468 }
3469 PushDouble( fVal );
3470 }
3471 else if ( eResType & SbxARRAY )
3472 {
3473 SbxBase* pElemObj = refRes->GetObject();
3474 SbxDimArray* pDimArray = dynamic_cast<SbxDimArray*>(pElemObj);
3475 sal_Int32 nDim = pDimArray ? pDimArray->GetDims() : 0;
3476 if ( 1 <= nDim && nDim <= 2 )
3477 {
3478 sal_Int32 nCs, nCe, nRs;
3479 SCSIZE nC, nR;
3480 SCCOL nColIdx;
3481 SCROW nRowIdx;
3482 if ( nDim == 1 )
3483 { // array( cols ) one line, several columns
3484 pDimArray->GetDim(1, nCs, nCe);
3485 nC = static_cast<SCSIZE>(nCe - nCs + 1);
3486 nRs = 0;
3487 nR = 1;
3488 nColIdx = 0;
3489 nRowIdx = 1;
3490 }
3491 else
3492 { // array( rows, cols )
3493 sal_Int32 nRe;
3494 pDimArray->GetDim(1, nRs, nRe);
3495 nR = static_cast<SCSIZE>(nRe - nRs + 1);
3496 pDimArray->GetDim(2, nCs, nCe);
3497 nC = static_cast<SCSIZE>(nCe - nCs + 1);
3498 nColIdx = 1;
3499 nRowIdx = 0;
3500 }
3501 ScMatrixRef pMat = GetNewMat( nC, nR, /*bEmpty*/true);
3502 if ( pMat )
3503 {
3504 SbxVariable* pV;
3505 for ( SCSIZE j=0; j < nR; j++ )
3506 {
3507 sal_Int32 nIdx[ 2 ];
3508 // in one-dimensional array( cols ) nIdx[1]
3509 // from SbxDimArray::Get is ignored
3510 nIdx[ nRowIdx ] = nRs + static_cast<sal_Int32>(j);
3511 for ( SCSIZE i=0; i < nC; i++ )
3512 {
3513 nIdx[ nColIdx ] = nCs + static_cast<sal_Int32>(i);
3514 pV = pDimArray->Get(nIdx);
3515 if ( lcl_isNumericResult( fVal, pV) )
3516 {
3517 pMat->PutDouble( fVal, i, j );
3518 }
3519 else
3520 {
3521 pMat->PutString(mrStrPool.intern(pV->GetOUString()), i, j);
3522 }
3523 }
3524 }
3525 PushMatrix( pMat );
3526 }
3527 else
3528 {
3530 }
3531 }
3532 else
3533 {
3534 PushNoValue();
3535 }
3536 }
3537 else
3538 {
3539 PushString( refRes->GetOUString() );
3540 }
3541 }
3542
3543 if (bVolatileMacro && meVolatileType == NOT_VOLATILE)
3545#endif
3546}
3547
3548#if HAVE_FEATURE_SCRIPTING
3549
3550bool ScInterpreter::SetSbxVariable( SbxVariable* pVar, const ScAddress& rPos )
3551{
3552 bool bOk = true;
3553 ScRefCellValue aCell(mrDoc, rPos);
3554 if (!aCell.isEmpty())
3555 {
3556 FormulaError nErr;
3557 double nVal;
3558 switch (aCell.getType())
3559 {
3560 case CELLTYPE_VALUE :
3561 nVal = GetValueCellValue(rPos, aCell.getDouble());
3562 pVar->PutDouble( nVal );
3563 break;
3564 case CELLTYPE_STRING :
3565 case CELLTYPE_EDIT :
3566 pVar->PutString(aCell.getString(&mrDoc));
3567 break;
3568 case CELLTYPE_FORMULA :
3569 nErr = aCell.getFormula()->GetErrCode();
3570 if( nErr == FormulaError::NONE )
3571 {
3572 if (aCell.getFormula()->IsValue())
3573 {
3574 nVal = aCell.getFormula()->GetValue();
3575 pVar->PutDouble( nVal );
3576 }
3577 else
3578 pVar->PutString(aCell.getFormula()->GetString().getString());
3579 }
3580 else
3581 {
3582 SetError( nErr );
3583 bOk = false;
3584 }
3585 break;
3586 default :
3587 pVar->PutEmpty();
3588 }
3589 }
3590 else
3591 pVar->PutEmpty();
3592
3593 return bOk;
3594}
3595
3596#endif
3597
3599{
3600 sal_uInt8 nParamCount = GetByte();
3601 if (nParamCount != 3 && nParamCount != 5)
3602 {
3604 return;
3605 }
3607 if (nParamCount == 5)
3608 {
3609 PopSingleRef( aTableOp.aNew2 );
3610 PopSingleRef( aTableOp.aOld2 );
3611 }
3612 PopSingleRef( aTableOp.aNew1 );
3613 PopSingleRef( aTableOp.aOld1 );
3614 PopSingleRef( aTableOp.aFormulaPos );
3615
3616 aTableOp.bValid = true;
3617 mrDoc.m_TableOpList.push_back(&aTableOp);
3619
3620 bool bReuseLastParams = (mrDoc.aLastTableOpParams == aTableOp);
3621 if ( bReuseLastParams )
3622 {
3624 aTableOp.bRefresh = true;
3625 for ( const auto& rPos : aTableOp.aNotifiedFormulaPos )
3626 { // emulate broadcast and indirectly collect cell pointers
3627 ScRefCellValue aCell(mrDoc, rPos);
3628 if (aCell.getType() == CELLTYPE_FORMULA)
3629 aCell.getFormula()->SetTableOpDirty();
3630 }
3631 }
3632 else
3633 { // broadcast and indirectly collect cell pointers and positions
3634 mrDoc.SetTableOpDirty( aTableOp.aOld1 );
3635 if ( nParamCount == 5 )
3636 mrDoc.SetTableOpDirty( aTableOp.aOld2 );
3637 }
3638 aTableOp.bCollectNotifications = false;
3639
3640 ScRefCellValue aCell(mrDoc, aTableOp.aFormulaPos);
3641 if (aCell.getType() == CELLTYPE_FORMULA)
3642 aCell.getFormula()->SetDirtyVar();
3643 if (aCell.hasNumeric())
3644 {
3645 PushDouble(GetCellValue(aTableOp.aFormulaPos, aCell));
3646 }
3647 else
3648 {
3649 svl::SharedString aCellString;
3650 GetCellString(aCellString, aCell);
3651 PushString( aCellString );
3652 }
3653
3654 auto const itr =
3655 ::std::find(mrDoc.m_TableOpList.begin(), mrDoc.m_TableOpList.end(), &aTableOp);
3656 if (itr != mrDoc.m_TableOpList.end())
3657 {
3658 mrDoc.m_TableOpList.erase(itr);
3659 }
3660
3661 // set dirty again once more to be able to recalculate original
3662 for ( const auto& pCell : aTableOp.aNotifiedFormulaCells )
3663 {
3664 pCell->SetTableOpDirty();
3665 }
3666
3667 // save these params for next incarnation
3668 if ( !bReuseLastParams )
3669 mrDoc.aLastTableOpParams = aTableOp;
3670
3671 if (aCell.getType() == CELLTYPE_FORMULA)
3672 {
3673 aCell.getFormula()->SetDirtyVar();
3674 aCell.getFormula()->GetErrCode(); // recalculate original
3675 }
3676
3677 // Reset all dirty flags so next incarnation does really collect all cell
3678 // pointers during notifications and not just non-dirty ones, which may
3679 // happen if a formula cell is used by more than one TableOp block.
3680 for ( const auto& pCell : aTableOp.aNotifiedFormulaCells )
3681 {
3682 pCell->ResetTableOpDirtyVar();
3683 }
3684
3686}
3687
3689{
3691 if (pDBData)
3692 {
3693 ScComplexRefData aRefData;
3694 aRefData.InitFlags();
3695 ScRange aRange;
3696 pDBData->GetArea(aRange);
3697 aRange.aEnd.SetTab(aRange.aStart.Tab());
3698 aRefData.SetRange(mrDoc.GetSheetLimits(), aRange, aPos);
3699 PushTempToken( new ScDoubleRefToken( mrDoc.GetSheetLimits(), aRefData ) );
3700 }
3701 else
3702 PushError( FormulaError::NoName);
3703}
3704
3706{
3707 ScComplexRefData aRefData( *pCur->GetDoubleRef() );
3708 ScRange aAbs = aRefData.toAbs(mrDoc, aPos);
3709 if (!mrDoc.ValidRange(aAbs))
3710 {
3711 PushError( FormulaError::NoRef );
3712 return;
3713 }
3714
3715 SCCOL nStartCol;
3716 SCROW nStartRow;
3717
3718 // maybe remember limit by using defined ColRowNameRange
3719 SCCOL nCol2 = aAbs.aEnd.Col();
3720 SCROW nRow2 = aAbs.aEnd.Row();
3721 // DataArea of the first cell
3722 nStartCol = aAbs.aStart.Col();
3723 nStartRow = aAbs.aStart.Row();
3724 aAbs.aEnd = aAbs.aStart; // Shrink to the top-left cell.
3725
3726 {
3727 // Expand to the data area. Only modify the end position.
3728 SCCOL nDACol1 = aAbs.aStart.Col(), nDACol2 = aAbs.aEnd.Col();
3729 SCROW nDARow1 = aAbs.aStart.Row(), nDARow2 = aAbs.aEnd.Row();
3730 mrDoc.GetDataArea(aAbs.aStart.Tab(), nDACol1, nDARow1, nDACol2, nDARow2, true, false);
3731 aAbs.aEnd.SetCol(nDACol2);
3732 aAbs.aEnd.SetRow(nDARow2);
3733 }
3734
3735 // corresponds with ScCompiler::GetToken
3736 if ( aRefData.Ref1.IsColRel() )
3737 { // ColName
3738 aAbs.aEnd.SetCol(nStartCol);
3739 // maybe get previous limit by using defined ColRowNameRange
3740 if (aAbs.aEnd.Row() > nRow2)
3741 aAbs.aEnd.SetRow(nRow2);
3742 if ( aPos.Col() == nStartCol )
3743 {
3744 SCROW nMyRow = aPos.Row();
3745 if ( nStartRow <= nMyRow && nMyRow <= aAbs.aEnd.Row())
3746 { //Formula in the same column and within the range
3747 if ( nMyRow == nStartRow )
3748 { // take the rest under the name
3749 nStartRow++;
3750 if ( nStartRow > mrDoc.MaxRow() )
3751 nStartRow = mrDoc.MaxRow();
3752 aAbs.aStart.SetRow(nStartRow);
3753 }
3754 else
3755 { // below the name to the formula cell
3756 aAbs.aEnd.SetRow(nMyRow - 1);
3757 }
3758 }
3759 }
3760 }
3761 else
3762 { // RowName
3763 aAbs.aEnd.SetRow(nStartRow);
3764 // maybe get previous limit by using defined ColRowNameRange
3765 if (aAbs.aEnd.Col() > nCol2)
3766 aAbs.aEnd.SetCol(nCol2);
3767 if ( aPos.Row() == nStartRow )
3768 {
3769 SCCOL nMyCol = aPos.Col();
3770 if (nStartCol <= nMyCol && nMyCol <= aAbs.aEnd.Col())
3771 { //Formula in the same column and within the range
3772 if ( nMyCol == nStartCol )
3773 { // take the rest under the name
3774 nStartCol++;
3775 if ( nStartCol > mrDoc.MaxCol() )
3776 nStartCol = mrDoc.MaxCol();
3777 aAbs.aStart.SetCol(nStartCol);
3778 }
3779 else
3780 { // below the name to the formula cell
3781 aAbs.aEnd.SetCol(nMyCol - 1);
3782 }
3783 }
3784 }
3785 }
3786 aRefData.SetRange(mrDoc.GetSheetLimits(), aAbs, aPos);
3787 PushTempToken( new ScDoubleRefToken( mrDoc.GetSheetLimits(), aRefData ) );
3788}
3789
3790// --- internals ------------------------------------------------------------
3791
3793{ // temporary test, testing functions etc.
3794 sal_uInt8 nParamCount = GetByte();
3795 // do something, count down nParamCount with Pops!
3796
3797 // clean up Stack
3798 while ( nParamCount-- > 0)
3799 Pop();
3800 PushError(FormulaError::NoValue);
3801}
3802
3804 const ScAddress& rPos, ScTokenArray& r, bool bForGroupThreading )
3805 : aCode(r)
3806 , aPos(rPos)
3807 , pArr(&r)
3808 , mrContext(rContext)
3809 , mrDoc(rDoc)
3810 , mpLinkManager(rDoc.GetLinkManager())
3811 , mrStrPool(rDoc.GetSharedStringPool())
3812 , pJumpMatrix(nullptr)
3813 , pMyFormulaCell(pCell)
3814 , pFormatter(rContext.GetFormatTable())
3815 , pCur(nullptr)
3816 , nGlobalError(FormulaError::NONE)
3817 , sp(0)
3818 , maxsp(0)
3819 , nFuncFmtIndex(0)
3820 , nCurFmtIndex(0)
3821 , nRetFmtIndex(0)
3822 , nFuncFmtType(SvNumFormatType::ALL)
3823 , nCurFmtType(SvNumFormatType::ALL)
3824 , nRetFmtType(SvNumFormatType::ALL)
3825 , mnStringNoValueError(FormulaError::NoValue)
3826 , mnSubTotalFlags(SubtotalFlags::NONE)
3827 , cPar(0)
3828 , bCalcAsShown(rDoc.GetDocOptions().IsCalcAsShown())
3829 , meVolatileType(r.IsRecalcModeAlways() ? VOLATILE : NOT_VOLATILE)
3830{
3832
3833 if(pMyFormulaCell)
3834 {
3836 bMatrixFormula = ( cMatFlag == ScMatrixMode::Formula );
3837 }
3838 else
3839 bMatrixFormula = false;
3840
3841 // Lets not use the global stack while formula-group-threading.
3842 // as it complicates its life-cycle mgmt since for threading formula-groups,
3843 // ScInterpreter is preallocated (in main thread) for each worker thread.
3844 if (!bGlobalStackInUse && !bForGroupThreading)
3845 {
3846 bGlobalStackInUse = true;
3847 if (!pGlobalStack)
3848 pGlobalStack.reset(new ScTokenStack);
3849 pStackObj = pGlobalStack.get();
3850 }
3851 else
3852 {
3853 pStackObj = new ScTokenStack;
3854 }
3856}
3857
3859{
3860 if ( pStackObj == pGlobalStack.get() )
3861 bGlobalStackInUse = false;
3862 else
3863 delete pStackObj;
3864}
3865
3866void ScInterpreter::Init( ScFormulaCell* pCell, const ScAddress& rPos, ScTokenArray& rTokArray )
3867{
3868 aCode.ReInit(rTokArray);
3869 aPos = rPos;
3870 pArr = &rTokArray;
3871 xResult = nullptr;
3872 pJumpMatrix = nullptr;
3873 maTokenMatrixMap.clear();
3874 pMyFormulaCell = pCell;
3875 pCur = nullptr;
3876 nGlobalError = FormulaError::NONE;
3877 sp = 0;
3878 maxsp = 0;
3879 nFuncFmtIndex = 0;
3880 nCurFmtIndex = 0;
3881 nRetFmtIndex = 0;
3882 nFuncFmtType = SvNumFormatType::ALL;
3883 nCurFmtType = SvNumFormatType::ALL;
3884 nRetFmtType = SvNumFormatType::ALL;
3885 mnStringNoValueError = FormulaError::NoValue;
3887 cPar = 0;
3888}
3889
3891{
3892 if (!mpGlobalConfig)
3894 return *mpGlobalConfig;
3895}
3896
3898{
3899 GetOrCreateGlobalConfig() = rConfig;
3900}
3901
3903{
3904 return GetOrCreateGlobalConfig();
3905}
3906
3908{
3911}
3912
3914{
3915 OSL_ENSURE(!bGlobalStackInUse, "who is still using the TokenStack?");
3916 pGlobalStack.reset();
3917}
3918
3919namespace {
3920
3921double applyImplicitIntersection(const sc::RangeMatrix& rMat, const ScAddress& rPos)
3922{
3923 if (rMat.mnRow1 <= rPos.Row() && rPos.Row() <= rMat.mnRow2 && rMat.mnCol1 == rMat.mnCol2)
3924 {
3925 SCROW nOffset = rPos.Row() - rMat.mnRow1;
3926 return rMat.mpMat->GetDouble(0, nOffset);
3927 }
3928
3929 if (rMat.mnCol1 <= rPos.Col() && rPos.Col() <= rMat.mnCol2 && rMat.mnRow1 == rMat.mnRow2)
3930 {
3931 SCROW nOffset = rPos.Col() - rMat.mnCol1;
3932 return rMat.mpMat->GetDouble(nOffset, 0);
3933 }
3934
3935 return std::numeric_limits<double>::quiet_NaN();
3936}
3937
3938// Test for Functions that evaluate an error code and directly set nGlobalError to 0
3939bool IsErrFunc(OpCode oc)
3940{
3941 switch (oc)
3942 {
3943 case ocCount :
3944 case ocCount2 :
3945 case ocErrorType :
3946 case ocIsEmpty :
3947 case ocIsErr :
3948 case ocIsError :
3949 case ocIsFormula :
3950 case ocIsLogical :
3951 case ocIsNA :
3952 case ocIsNonString :
3953 case ocIsRef :
3954 case ocIsString :
3955 case ocIsValue :
3956 case ocN :
3957 case ocType :
3958 case ocIfError :
3959 case ocIfNA :
3960 case ocErrorType_ODF :
3961 case ocAggregate: // may ignore errors depending on option
3962 case ocIfs_MS:
3963 case ocSwitch_MS:
3964 return true;
3965 default:
3966 return false;
3967 }
3968}
3969
3970} //namespace
3971
3973{
3974 SvNumFormatType nRetTypeExpr = SvNumFormatType::UNDEFINED;
3975 sal_uInt32 nRetIndexExpr = 0;
3976 sal_uInt16 nErrorFunction = 0;
3977 sal_uInt16 nErrorFunctionCount = 0;
3978 std::vector<sal_uInt16> aErrorFunctionStack;
3979 sal_uInt16 nStackBase;
3980
3981 nGlobalError = FormulaError::NONE;
3982 nStackBase = sp = maxsp = 0;
3983 nRetFmtType = SvNumFormatType::UNDEFINED;
3984 nFuncFmtType = SvNumFormatType::UNDEFINED;
3986 xResult = nullptr;
3987 pJumpMatrix = nullptr;
3989 ScTokenMatrixMap::const_iterator aTokenMatrixMapIter;
3990
3991 // Once upon a time we used to have FP exceptions on, and there was a
3992 // Windows printer driver that kept switching off exceptions, so we had to
3993 // switch them back on again every time. Who knows if there isn't a driver
3994 // that keeps switching exceptions on, now that we run with exceptions off,
3995 // so reassure exceptions are really off.
3997
3998 OpCode eOp = ocNone;
3999 aCode.Reset();
4000 for (;;)
4001 {
4002 pCur = aCode.Next();
4003 if (!pCur || (nGlobalError != FormulaError::NONE && nErrorFunction > nErrorFunctionCount) )
4004 break;
4005 eOp = pCur->GetOpCode();
4006 cPar = pCur->GetByte();
4007 if ( eOp == ocPush )
4008 {
4009 // RPN code push without error
4011 nCurFmtType = SvNumFormatType::UNDEFINED;
4012 }
4013 else if (!FormulaCompiler::IsOpCodeJumpCommand( eOp ) &&
4014 ((aTokenMatrixMapIter = maTokenMatrixMap.find( pCur)) !=
4015 maTokenMatrixMap.end()) &&
4016 (*aTokenMatrixMapIter).second->GetType() != svJumpMatrix)
4017 {
4018 // Path already calculated, reuse result.
4019 if (sp >= pCur->GetParamCount())
4020 nStackBase = sp - pCur->GetParamCount();
4021 else
4022 {
4023 SAL_WARN("sc.core", "Stack anomaly with calculated path at "
4024 << aPos.Tab() << "," << aPos.Col() << "," << aPos.Row()
4025 << " " << aPos.Format(
4027 << " eOp: " << static_cast<int>(eOp)
4028 << " params: " << static_cast<int>(pCur->GetParamCount())
4029 << " nStackBase: " << nStackBase << " sp: " << sp);
4030 nStackBase = sp;
4031 assert(!"underflow");
4032 }
4033 sp = nStackBase;
4034 PushTokenRef( (*aTokenMatrixMapIter).second);
4035 }
4036 else
4037 {
4038 // previous expression determines the current number format
4039 nCurFmtType = nRetTypeExpr;
4040 nCurFmtIndex = nRetIndexExpr;
4041 // default function's format, others are set if needed
4042 nFuncFmtType = SvNumFormatType::NUMBER;
4043 nFuncFmtIndex = 0;
4044
4045 if (FormulaCompiler::IsOpCodeJumpCommand( eOp ))
4046 nStackBase = sp; // don't mess around with the jumps
4047 else
4048 {
4049 // Convert parameters to matrix if in array/matrix formula and
4050 // parameters of function indicate doing so. Create JumpMatrix
4051 // if necessary.
4053 {
4054 eOp = ocNone; // JumpMatrix created
4055 nStackBase = sp;
4056 }
4057 else if (sp >= pCur->GetParamCount())
4058 nStackBase = sp - pCur->GetParamCount();
4059 else
4060 {
4061 SAL_WARN("sc.core", "Stack anomaly at " << aPos.Tab() << "," << aPos.Col() << "," << aPos.Row()
4062 << " " << aPos.Format(
4064 << " eOp: " << static_cast<int>(eOp)
4065 << " params: " << static_cast<int>(pCur->GetParamCount())
4066 << " nStackBase: " << nStackBase << " sp: " << sp);
4067 nStackBase = sp;
4068 assert(!"underflow");
4069 }
4070 }
4071
4072 switch( eOp )
4073 {
4074 case ocSep:
4075 case ocClose: // pushed by the compiler
4076 case ocMissing : ScMissing(); break;
4077 case ocMacro : ScMacro(); break;
4078 case ocDBArea : ScDBArea(); break;
4079 case ocColRowNameAuto : ScColRowNameAuto(); break;
4080 case ocIf : ScIfJump(); break;
4081 case ocIfError : ScIfError( false ); break;
4082 case ocIfNA : ScIfError( true ); break;
4083 case ocChoose : ScChooseJump(); break;
4084 case ocAdd : ScAdd(); break;
4085 case ocSub : ScSub(); break;
4086 case ocMul : ScMul(); break;
4087 case ocDiv : ScDiv(); break;
4088 case ocAmpersand : ScAmpersand(); break;
4089 case ocPow : ScPow(); break;
4090 case ocEqual : ScEqual(); break;
4091 case ocNotEqual : ScNotEqual(); break;
4092 case ocLess : ScLess(); break;
4093 case ocGreater : ScGreater(); break;
4094 case ocLessEqual : ScLessEqual(); break;
4095 case ocGreaterEqual : ScGreaterEqual(); break;
4096 case ocAnd : ScAnd(); break;
4097 case ocOr : ScOr(); break;
4098 case ocXor : ScXor(); break;
4099 case ocIntersect : ScIntersect(); break;
4100 case ocRange : ScRangeFunc(); break;
4101 case ocUnion : ScUnionFunc(); break;
4102 case ocNot : ScNot(); break;
4103 case ocNegSub :
4104 case ocNeg : ScNeg(); break;
4105 case ocPercentSign : ScPercentSign(); break;
4106 case ocPi : ScPi(); break;
4107 case ocRandom : ScRandom(); break;
4108 case ocRandomNV : ScRandom(); break;
4109 case ocRandbetweenNV : ScRandbetween(); break;
4110 case ocTrue : ScTrue(); break;
4111 case ocFalse : ScFalse(); break;
4112 case ocGetActDate : ScGetActDate(); break;
4113 case ocGetActTime : ScGetActTime(); break;
4114 case ocNotAvail : PushError( FormulaError::NotAvailable); break;
4115 case ocDeg : ScDeg(); break;
4116 case ocRad : ScRad(); break;
4117 case ocSin : ScSin(); break;
4118 case ocCos : ScCos(); break;
4119 case ocTan : ScTan(); break;
4120 case ocCot : ScCot(); break;
4121 case ocArcSin : ScArcSin(); break;
4122 case ocArcCos : ScArcCos(); break;
4123 case ocArcTan : ScArcTan(); break;
4124 case ocArcCot : ScArcCot(); break;
4125 case ocSinHyp : ScSinHyp(); break;
4126 case ocCosHyp : ScCosHyp(); break;
4127 case ocTanHyp : ScTanHyp(); break;
4128 case ocCotHyp : ScCotHyp(); break;
4129 case ocArcSinHyp : ScArcSinHyp(); break;
4130 case ocArcCosHyp : ScArcCosHyp(); break;
4131 case ocArcTanHyp : ScArcTanHyp(); break;
4132 case ocArcCotHyp : ScArcCotHyp(); break;
4133 case ocCosecant : ScCosecant(); break;
4134 case ocSecant : ScSecant(); break;
4135 case ocCosecantHyp : ScCosecantHyp(); break;
4136 case ocSecantHyp : ScSecantHyp(); break;
4137 case ocExp : ScExp(); break;
4138 case ocLn : ScLn(); break;
4139 case ocLog10 : ScLog10(); break;
4140 case ocSqrt : ScSqrt(); break;
4141 case ocFact : ScFact(); break;
4142 case ocGetYear : ScGetYear(); break;
4143 case ocGetMonth : ScGetMonth(); break;
4144 case ocGetDay : ScGetDay(); break;
4145 case ocGetDayOfWeek : ScGetDayOfWeek(); break;
4146 case ocWeek : ScGetWeekOfYear(); break;
4147 case ocIsoWeeknum : ScGetIsoWeekOfYear(); break;
4148 case ocWeeknumOOo : ScWeeknumOOo(); break;
4149 case ocEasterSunday : ScEasterSunday(); break;
4150 case ocNetWorkdays : ScNetWorkdays( false); break;
4151 case ocNetWorkdays_MS : ScNetWorkdays( true ); break;
4152 case ocWorkday_MS : ScWorkday_MS(); break;
4153 case ocGetHour : ScGetHour(); break;
4154 case ocGetMin : ScGetMin(); break;
4155 case ocGetSec : ScGetSec(); break;
4156 case ocPlusMinus : ScPlusMinus(); break;
4157 case ocAbs : ScAbs(); break;
4158 case ocInt : ScInt(); break;
4159 case ocEven : ScEven(); break;
4160 case ocOdd : ScOdd(); break;
4161 case ocPhi : ScPhi(); break;
4162 case ocGauss : ScGauss(); break;
4163 case ocStdNormDist : ScStdNormDist(); break;
4164 case ocStdNormDist_MS : ScStdNormDist_MS(); break;
4165 case ocFisher : ScFisher(); break;
4166 case ocFisherInv : ScFisherInv(); break;
4167 case ocIsEmpty : ScIsEmpty(); break;
4168 case ocIsString : ScIsString(); break;
4169 case ocIsNonString : ScIsNonString(); break;
4170 case ocIsLogical : ScIsLogical(); break;
4171 case ocType : ScType(); break;
4172 case ocCell : ScCell(); break;
4173 case ocIsRef : ScIsRef(); break;
4174 case ocIsValue : ScIsValue(); break;
4175 case ocIsFormula : ScIsFormula(); break;
4176 case ocFormula : ScFormula(); break;
4177 case ocIsNA : ScIsNV(); break;
4178 case ocIsErr : ScIsErr(); break;
4179 case ocIsError : ScIsError(); break;
4180 case ocIsEven : ScIsEven(); break;
4181 case ocIsOdd : ScIsOdd(); break;
4182 case ocN : ScN(); break;
4183 case ocGetDateValue : ScGetDateValue(); break;
4184 case ocGetTimeValue : ScGetTimeValue(); break;
4185 case ocCode : ScCode(); break;
4186 case ocTrim : ScTrim(); break;
4187 case ocUpper : ScUpper(); break;
4188 case ocProper : ScProper(); break;
4189 case ocLower : ScLower(); break;
4190 case ocLen : ScLen(); break;
4191 case ocT : ScT(); break;
4192 case ocClean : ScClean(); break;
4193 case ocValue : ScValue(); break;
4194 case ocNumberValue : ScNumberValue(); break;
4195 case ocChar : ScChar(); break;
4196 case ocArcTan2 : ScArcTan2(); break;
4197 case ocMod : ScMod(); break;
4198 case ocPower : ScPower(); break;
4199 case ocRound : ScRound(); break;
4200 case ocRoundSig : ScRoundSignificant(); break;
4201 case ocRoundUp : ScRoundUp(); break;
4202 case ocTrunc :
4203 case ocRoundDown : ScRoundDown(); break;
4204 case ocCeil : ScCeil( true ); break;
4205 case ocCeil_MS : ScCeil_MS(); break;
4206 case ocCeil_Precise :
4207 case ocCeil_ISO : ScCeil_Precise(); break;
4208 case ocCeil_Math : ScCeil( false ); break;
4209 case ocFloor : ScFloor( true ); break;
4210 case ocFloor_MS : ScFloor_MS(); break;
4211 case ocFloor_Precise : ScFloor_Precise(); break;
4212 case ocFloor_Math : ScFloor( false ); break;
4213 case ocSumProduct : ScSumProduct(); break;
4214 case ocSumSQ : ScSumSQ(); break;
4215 case ocSumX2MY2 : ScSumX2MY2(); break;
4216 case ocSumX2DY2 : ScSumX2DY2(); break;
4217 case ocSumXMY2 : ScSumXMY2(); break;
4218 case ocRawSubtract : ScRawSubtract(); break;
4219 case ocLog : ScLog(); break;
4220 case ocGCD : ScGCD(); break;
4221 case ocLCM : ScLCM(); break;
4222 case ocGetDate : ScGetDate(); break;
4223 case ocGetTime : ScGetTime(); break;
4224 case ocGetDiffDate : ScGetDiffDate(); break;
4225 case ocGetDiffDate360 : ScGetDiffDate360(); break;
4226 case ocGetDateDif : ScGetDateDif(); break;
4227 case ocMin : ScMin() ; break;
4228 case ocMinA : ScMin( true ); break;
4229 case ocMax : ScMax(); break;
4230 case ocMaxA : ScMax( true ); break;
4231 case ocSum : ScSum(); break;
4232 case ocProduct : ScProduct(); break;
4233 case ocNPV : ScNPV(); break;
4234 case ocIRR : ScIRR(); break;
4235 case ocMIRR : ScMIRR(); break;
4236 case ocISPMT : ScISPMT(); break;
4237 case ocAverage : ScAverage() ; break;
4238 case ocAverageA : ScAverage( true ); break;
4239 case ocCount : ScCount(); break;
4240 case ocCount2 : ScCount2(); break;
4241 case ocVar :
4242 case ocVarS : ScVar(); break;
4243 case ocVarA : ScVar( true ); break;
4244 case ocVarP :
4245 case ocVarP_MS : ScVarP(); break;
4246 case ocVarPA : ScVarP( true ); break;
4247 case ocStDev :
4248 case ocStDevS : ScStDev(); break;
4249 case ocStDevA : ScStDev( true ); break;
4250 case ocStDevP :
4251 case ocStDevP_MS : ScStDevP(); break;
4252 case ocStDevPA : ScStDevP( true ); break;
4253 case ocPV : ScPV(); break;
4254 case ocSYD : ScSYD(); break;
4255 case ocDDB : ScDDB(); break;
4256 case ocDB : ScDB(); break;
4257 case ocVBD : ScVDB(); break;
4258 case ocPDuration : ScPDuration(); break;
4259 case ocSLN : ScSLN(); break;
4260 case ocPMT : ScPMT(); break;
4261 case ocColumns : ScColumns(); break;
4262 case ocRows : ScRows(); break;
4263 case ocSheets : ScSheets(); break;
4264 case ocColumn : ScColumn(); break;
4265 case ocRow : ScRow(); break;
4266 case ocSheet : ScSheet(); break;
4267 case ocRRI : ScRRI(); break;
4268 case ocFV : ScFV(); break;
4269 case ocNper : ScNper(); break;
4270 case ocRate : ScRate(); break;
4271 case ocFilterXML : ScFilterXML(); break;
4272 case ocWebservice : ScWebservice(); break;
4273 case ocEncodeURL : ScEncodeURL(); break;
4274 case ocColor : ScColor(); break;
4275 case ocErf_MS : ScErf(); break;
4276 case ocErfc_MS : ScErfc(); break;
4277 case ocIpmt : ScIpmt(); break;
4278 case ocPpmt : ScPpmt(); break;
4279 case ocCumIpmt : ScCumIpmt(); break;
4280 case ocCumPrinc : ScCumPrinc(); break;
4281 case ocEffect : ScEffect(); break;
4282 case ocNominal : ScNominal(); break;
4283 case ocSubTotal : ScSubTotal(); break;
4284 case ocAggregate : ScAggregate(); break;
4285 case ocDBSum : ScDBSum(); break;
4286 case ocDBCount : ScDBCount(); break;
4287 case ocDBCount2 : ScDBCount2(); break;
4288 case ocDBAverage : ScDBAverage(); break;
4289 case ocDBGet : ScDBGet(); break;
4290 case ocDBMax : ScDBMax(); break;
4291 case ocDBMin : ScDBMin(); break;
4292 case ocDBProduct : ScDBProduct(); break;
4293 case ocDBStdDev : ScDBStdDev(); break;
4294 case ocDBStdDevP : ScDBStdDevP(); break;
4295 case ocDBVar : ScDBVar(); break;
4296 case ocDBVarP : ScDBVarP(); break;
4297 case ocIndirect : ScIndirect(); break;
4298 case ocAddress : ScAddressFunc(); break;
4299 case ocMatch : ScMatch(); break;
4300 case ocCountEmptyCells : ScCountEmptyCells(); break;
4301 case ocCountIf : ScCountIf(); break;
4302 case ocSumIf : ScSumIf(); break;
4303 case ocAverageIf : ScAverageIf(); break;
4304 case ocSumIfs : ScSumIfs(); break;
4305 case ocAverageIfs : ScAverageIfs(); break;
4306 case ocCountIfs : ScCountIfs(); break;
4307 case ocLookup : ScLookup(); break;
4308 case ocVLookup : ScVLookup(); break;
4309 case ocHLookup : ScHLookup(); break;
4310 case ocIndex : ScIndex(); break;
4311 case ocMultiArea : ScMultiArea(); break;
4312 case ocOffset : ScOffset(); break;
4313 case ocAreas : ScAreas(); break;
4314 case ocCurrency : ScCurrency(); break;
4315 case ocReplace : ScReplace(); break;
4316 case ocFixed : ScFixed(); break;
4317 case ocFind : ScFind(); break;
4318 case ocExact : ScExact(); break;
4319 case ocLeft : ScLeft(); break;
4320 case ocRight : ScRight(); break;
4321 case ocSearch : ScSearch(); break;
4322 case ocMid : ScMid(); break;
4323 case ocText : ScText(); break;
4324 case ocSubstitute : ScSubstitute(); break;
4325 case ocRegex : ScRegex(); break;
4326 case ocRept : ScRept(); break;
4327 case ocConcat : ScConcat(); break;
4328 case ocConcat_MS : ScConcat_MS(); break;
4329 case ocTextJoin_MS : ScTextJoin_MS(); break;
4330 case ocIfs_MS : ScIfs_MS(); break;
4331 case ocSwitch_MS : ScSwitch_MS(); break;
4332 case ocMinIfs_MS : ScMinIfs_MS(); break;
4333 case ocMaxIfs_MS : ScMaxIfs_MS(); break;
4334 case ocMatValue : ScMatValue(); break;
4335 case ocMatrixUnit : ScEMat(); break;
4336 case ocMatDet : ScMatDet(); break;
4337 case ocMatInv : ScMatInv(); break;
4338 case ocMatMult : ScMatMult(); break;
4339 case ocMatTrans : ScMatTrans(); break;
4340 case ocMatRef : ScMatRef(); break;
4341 case ocB : ScB(); break;
4342 case ocNormDist : ScNormDist( 3 ); break;
4343 case ocNormDist_MS : ScNormDist( 4 ); break;
4344 case ocExpDist :
4345 case ocExpDist_MS : ScExpDist(); break;
4346 case ocBinomDist :
4347 case ocBinomDist_MS : ScBinomDist(); break;
4348 case ocPoissonDist : ScPoissonDist( true ); break;
4349 case ocPoissonDist_MS : ScPoissonDist( false ); break;
4350 case ocCombin : ScCombin(); break;
4351 case ocCombinA : ScCombinA(); break;
4352 case ocPermut : ScPermut(); break;
4353 case ocPermutationA : ScPermutationA(); break;
4354 case ocHypGeomDist : ScHypGeomDist( 4 ); break;
4355 case ocHypGeomDist_MS : ScHypGeomDist( 5 ); break;
4356 case ocLogNormDist : ScLogNormDist( 1 ); break;
4357 case ocLogNormDist_MS : ScLogNormDist( 4 ); break;
4358 case ocTDist : ScTDist(); break;
4359 case ocTDist_MS : ScTDist_MS(); break;
4360 case ocTDist_RT : ScTDist_T( 1 ); break;
4361 case ocTDist_2T : ScTDist_T( 2 ); break;
4362 case ocFDist :
4363 case ocFDist_RT : ScFDist(); break;
4364 case ocFDist_LT : ScFDist_LT(); break;
4365 case ocChiDist : ScChiDist( true ); break;
4366 case ocChiDist_MS : ScChiDist( false ); break;
4367 case ocChiSqDist : ScChiSqDist(); break;
4368 case ocChiSqDist_MS : ScChiSqDist_MS(); break;
4369 case ocStandard : ScStandard(); break;
4370 case ocAveDev : ScAveDev(); break;
4371 case ocDevSq : ScDevSq(); break;
4372 case ocKurt : ScKurt(); break;
4373 case ocSkew : ScSkew(); break;
4374 case ocSkewp : ScSkewp(); break;
4375 case ocModalValue : ScModalValue(); break;
4376 case ocModalValue_MS : ScModalValue_MS( true ); break;
4377 case ocModalValue_Multi : ScModalValue_MS( false ); break;
4378 case ocMedian : ScMedian(); break;
4379 case ocGeoMean : ScGeoMean(); break;
4380 case ocHarMean : ScHarMean(); break;
4381 case ocWeibull :
4382 case ocWeibull_MS : ScWeibull(); break;
4383 case ocBinomInv :
4384 case ocCritBinom : ScCritBinom(); break;
4385 case ocNegBinomVert : ScNegBinomDist(); break;
4386 case ocNegBinomDist_MS : ScNegBinomDist_MS(); break;
4387 case ocNoName : ScNoName(); break;
4388 case ocBad : ScBadName(); break;
4389 case ocZTest :
4390 case ocZTest_MS : ScZTest(); break;
4391 case ocTTest :
4392 case ocTTest_MS : ScTTest(); break;
4393 case ocFTest :
4394 case ocFTest_MS : ScFTest(); break;
4395 case ocRank :
4396 case ocRank_Eq : ScRank( false ); break;
4397 case ocRank_Avg : ScRank( true ); break;
4398 case ocPercentile :
4399 case ocPercentile_Inc : ScPercentile( true ); break;
4400 case ocPercentile_Exc : ScPercentile( false ); break;
4401 case ocPercentrank :
4402 case ocPercentrank_Inc : ScPercentrank( true ); break;
4403 case ocPercentrank_Exc : ScPercentrank( false ); break;
4404 case ocLarge : ScLarge(); break;
4405 case ocSmall : ScSmall(); break;
4406 case ocFrequency : ScFrequency(); break;
4407 case ocQuartile :
4408 case ocQuartile_Inc : ScQuartile( true ); break;
4409 case ocQuartile_Exc : ScQuartile( false ); break;
4410 case ocNormInv :
4411 case ocNormInv_MS : ScNormInv(); break;
4412 case ocSNormInv :
4413 case ocSNormInv_MS : ScSNormInv(); break;
4414 case ocConfidence :
4415 case ocConfidence_N : ScConfidence(); break;
4416 case ocConfidence_T : ScConfidenceT(); break;
4417 case ocTrimMean : ScTrimMean(); break;
4418 case ocProb : ScProbability(); break;
4419 case ocCorrel : ScCorrel(); break;
4420 case ocCovar :
4421 case ocCovarianceP : ScCovarianceP(); break;
4422 case ocCovarianceS : ScCovarianceS(); break;
4423 case ocPearson : ScPearson(); break;
4424 case ocRSQ : ScRSQ(); break;
4425 case ocSTEYX : ScSTEYX(); break;
4426 case ocSlope : ScSlope(); break;
4427 case ocIntercept : ScIntercept(); break;
4428 case ocTrend : ScTrend(); break;
4429 case ocGrowth : ScGrowth(); break;
4430 case ocLinest : ScLinest(); break;
4431 case ocLogest : ScLogest(); break;
4432 case ocForecast_LIN :
4433 case ocForecast : ScForecast(); break;
4434 case ocForecast_ETS_ADD : ScForecast_Ets( etsAdd ); break;
4436 case ocForecast_ETS_MUL : ScForecast_Ets( etsMult ); break;
4441 case ocGammaLn :
4442 case ocGammaLn_MS : ScLogGamma(); break;
4443 case ocGamma : ScGamma(); break;
4444 case ocGammaDist : ScGammaDist( true ); break;
4445 case ocGammaDist_MS : ScGammaDist( false ); break;
4446 case ocGammaInv :
4447 case ocGammaInv_MS : ScGammaInv(); break;
4448 case ocChiTest :
4449 case ocChiTest_MS : ScChiTest(); break;
4450 case ocChiInv :
4451 case ocChiInv_MS : ScChiInv(); break;
4452 case ocChiSqInv :
4453 case ocChiSqInv_MS : ScChiSqInv(); break;
4454 case ocTInv :
4455 case ocTInv_2T : ScTInv( 2 ); break;
4456 case ocTInv_MS : ScTInv( 4 ); break;
4457 case ocFInv :
4458 case ocFInv_RT : ScFInv(); break;
4459 case ocFInv_LT : ScFInv_LT(); break;
4460 case ocLogInv :
4461 case ocLogInv_MS : ScLogNormInv(); break;
4462 case ocBetaDist : ScBetaDist(); break;
4463 case ocBetaDist_MS : ScBetaDist_MS(); break;
4464 case ocBetaInv :
4465 case ocBetaInv_MS : ScBetaInv(); break;
4466 case ocFourier : ScFourier(); break;
4467 case ocExternal : ScExternal(); break;
4468 case ocTableOp : ScTableOp(); break;
4469 case ocStop : break;
4470 case ocErrorType : ScErrorType(); break;
4471 case ocErrorType_ODF : ScErrorType_ODF(); break;
4472 case ocCurrent : ScCurrent(); break;
4473 case ocStyle : ScStyle(); break;
4474 case ocDde : ScDde(); break;
4475 case ocBase : ScBase(); break;
4476 case ocDecimal : ScDecimal(); break;
4477 case ocConvertOOo : ScConvertOOo(); break;
4478 case ocEuroConvert : ScEuroConvert(); break;
4479 case ocRoman : ScRoman(); break;
4480 case ocArabic : ScArabic(); break;
4481 case ocInfo : ScInfo(); break;
4482 case ocHyperLink : ScHyperLink(); break;
4483 case ocBahtText : ScBahtText(); break;
4484 case ocGetPivotData : ScGetPivotData(); break;
4485 case ocJis : ScJis(); break;
4486 case ocAsc : ScAsc(); break;
4487 case ocLenB : ScLenB(); break;
4488 case ocRightB : ScRightB(); break;
4489 case ocLeftB : ScLeftB(); break;
4490 case ocMidB : ScMidB(); break;
4491 case ocReplaceB : ScReplaceB(); break;
4492 case ocFindB : ScFindB(); break;
4493 case ocSearchB : ScSearchB(); break;
4494 case ocUnicode : ScUnicode(); break;
4495 case ocUnichar : ScUnichar(); break;
4496 case ocBitAnd : ScBitAnd(); break;
4497 case ocBitOr : ScBitOr(); break;
4498 case ocBitXor : ScBitXor(); break;
4499 case ocBitRshift : ScBitRshift(); break;
4500 case ocBitLshift : ScBitLshift(); break;
4501 case ocTTT : ScTTT(); break;
4502 case ocDebugVar : ScDebugVar(); break;
4503 case ocNone : nFuncFmtType = SvNumFormatType::UNDEFINED; break;
4504 default : PushError( FormulaError::UnknownOpCode); break;
4505 }
4506
4507 // If the function pushed a subroutine as result, continue with
4508 // execution of the subroutine.
4509 if (sp > nStackBase && pStack[sp-1]->GetOpCode() == ocCall)
4510 {
4511 Pop(); continue;
4512 }
4513
4514 if (FormulaCompiler::IsOpCodeVolatile(eOp))
4516
4517 // Remember result matrix in case it could be reused.
4518 if (sp && GetStackType() == svMatrix)
4519 maTokenMatrixMap.emplace(pCur, pStack[sp-1]);
4520
4521 // outer function determines format of an expression
4522 if ( nFuncFmtType != SvNumFormatType::UNDEFINED )
4523 {
4524 nRetTypeExpr = nFuncFmtType;
4525 // Inherit the format index for currency, date or time formats.
4526 switch (nFuncFmtType)
4527 {
4528 case SvNumFormatType::CURRENCY:
4529 case SvNumFormatType::DATE:
4530 case SvNumFormatType::TIME:
4531 case SvNumFormatType::DATETIME:
4532 case SvNumFormatType::DURATION:
4533 nRetIndexExpr = nFuncFmtIndex;
4534 break;
4535 default:
4536 nRetIndexExpr = 0;
4537 }
4538 }
4539 }
4540
4541 // Need a clean stack environment for the JumpMatrix to work.
4542 if (nGlobalError != FormulaError::NONE && eOp != ocPush && sp > nStackBase + 1)
4543 {
4544 // Not all functions pop all parameters in case an error is
4545 // generated. Clean up stack. Assumes that every function pushes a
4546 // result, may be arbitrary in case of error.
4547 FormulaConstTokenRef xLocalResult = pStack[ sp - 1 ];
4548 while (sp > nStackBase)
4549 Pop();
4550 PushTokenRef( xLocalResult );
4551 }
4552
4553 bool bGotResult;
4554 do
4555 {
4556 bGotResult = false;
4557 sal_uInt8 nLevel = 0;
4558 if ( GetStackType( ++nLevel ) == svJumpMatrix )
4559 ; // nothing
4560 else if ( GetStackType( ++nLevel ) == svJumpMatrix )
4561 ; // nothing
4562 else
4563 nLevel = 0;
4564 if ( nLevel == 1 || (nLevel == 2 && aCode.IsEndOfPath()) )
4565 {
4566 if (nLevel == 1)
4567 aErrorFunctionStack.push_back( nErrorFunction);
4568 bGotResult = JumpMatrix( nLevel );
4569 if (aErrorFunctionStack.empty())
4570 assert(!"ScInterpreter::Interpret - aErrorFunctionStack empty in JumpMatrix context");
4571 else
4572 {
4573 nErrorFunction = aErrorFunctionStack.back();
4574 if (bGotResult)
4575 aErrorFunctionStack.pop_back();
4576 }
4577 }
4578 else
4579 pJumpMatrix = nullptr;
4580 } while ( bGotResult );
4581
4582 if( IsErrFunc(eOp) )
4583 ++nErrorFunction;
4584
4585 if ( nGlobalError != FormulaError::NONE )
4586 {
4587 if ( !nErrorFunctionCount )
4588 { // count of errorcode functions in formula
4590 for ( FormulaToken* t = aIter.FirstRPN(); t; t = aIter.NextRPN() )
4591 {
4592 if ( IsErrFunc(t->GetOpCode()) )
4593 ++nErrorFunctionCount;
4594 }
4595 }
4596 if ( nErrorFunction >= nErrorFunctionCount )
4597 ++nErrorFunction; // that's it, error => terminate
4598 else if (nErrorFunctionCount && sp && GetStackType() == svError)
4599 {
4600 // Clear global error if we have an individual error result, so
4601 // an error evaluating function can receive multiple arguments
4602 // and not all evaluated arguments inheriting the error.
4603 // This is important for at least IFS() and SWITCH() as long as
4604 // they are classified as error evaluating functions and not
4605 // implemented as short-cutting jump code paths, but also for
4606 // more than one evaluated argument to AGGREGATE() or COUNT()
4607 // that may ignore errors.
4608 nGlobalError = FormulaError::NONE;
4609 }
4610 }
4611 }
4612
4613 // End: obtain result
4614
4615 bool bForcedResultType;
4616 switch (eOp)
4617 {
4618 case ocGetDateValue:
4619 case ocGetTimeValue:
4620 // Force final result of DATEVALUE and TIMEVALUE to number type,
4621 // which so far was date or time for calculations.
4622 nRetTypeExpr = nFuncFmtType = SvNumFormatType::NUMBER;
4623 nRetIndexExpr = nFuncFmtIndex = 0;
4624 bForcedResultType = true;
4625 break;
4626 default:
4627 bForcedResultType = false;
4628 }
4629
4630 if (sp == 1)
4631 {
4632 pCur = pStack[ sp-1 ];
4633 if( pCur->GetOpCode() == ocPush )
4634 {
4635 // An svRefList can be resolved if it a) contains just one
4636 // reference, or b) in array context contains an array of single
4637 // cell references.
4638 if (pCur->GetType() == svRefList)
4639 {
4641 pCur = pStack[ sp-1 ];
4642 }
4643 switch( pCur->GetType() )
4644 {
4645 case svEmptyCell:
4646 ; // nothing
4647 break;
4648 case svError:
4650 break;
4651 case svDouble :
4652 {
4653 // If typed, pop token to obtain type information and
4654 // push a plain untyped double so the result token to
4655 // be transferred to the formula cell result does not
4656 // unnecessarily duplicate the information.
4657 if (pCur->GetDoubleType() != 0)
4658 {
4659 double fVal = PopDouble();
4660 if (!bForcedResultType)
4661 {
4663 nRetIndexExpr = 0; // carry format index only for matching type
4664 nRetTypeExpr = nFuncFmtType = nCurFmtType;
4665 }
4666 if (nRetTypeExpr == SvNumFormatType::DURATION)
4667 {
4668 // Round the duration in case a wall clock time
4669 // display format is used instead of a duration
4670 // format. To micro seconds which then catches
4671 // the converted hh:mm:ss.9999997 cases.
4672 if (fVal != 0.0)
4673 {
4674 fVal *= 86400.0;
4675 fVal = rtl::math::round( fVal, 6);
4676 fVal /= 86400.0;
4677 }
4678 }
4680 }
4681 if ( nFuncFmtType == SvNumFormatType::UNDEFINED )
4682 {
4683 nRetTypeExpr = SvNumFormatType::NUMBER;
4684 nRetIndexExpr = 0;
4685 }
4686 }
4687 break;
4688 case svString :
4689 nRetTypeExpr = SvNumFormatType::TEXT;
4690 nRetIndexExpr = 0;
4691 break;
4692 case svSingleRef :
4693 {
4694 ScAddress aAdr;
4695 PopSingleRef( aAdr );
4696 if( nGlobalError == FormulaError::NONE)
4697 PushCellResultToken( false, aAdr, &nRetTypeExpr, &nRetIndexExpr, true);
4698 }
4699 break;
4700 case svRefList :
4701 PopError(); // maybe #REF! takes precedence over #VALUE!
4702 PushError( FormulaError::NoValue);
4703 break;
4704 case svDoubleRef :
4705 {
4706 if ( bMatrixFormula )
4707 { // create matrix for {=A1:A5}
4709 ScMatrixRef xMat = PopMatrix();
4710 QueryMatrixType(xMat, nRetTypeExpr, nRetIndexExpr);
4711 }
4712 else
4713 {
4714 ScRange aRange;
4715 PopDoubleRef( aRange );
4716 ScAddress aAdr;
4717 if ( nGlobalError == FormulaError::NONE && DoubleRefToPosSingleRef( aRange, aAdr))
4718 PushCellResultToken( false, aAdr, &nRetTypeExpr, &nRetIndexExpr, true);
4719 }
4720 }
4721 break;
4723 {
4724 ScMatrixRef xMat;
4726 QueryMatrixType(xMat, nRetTypeExpr, nRetIndexExpr);
4727 }
4728 break;
4729 case svMatrix :
4730 {
4732 if (aMat.isRangeValid())
4733 {
4734 // This matrix represents a range reference. Apply implicit intersection.
4735 double fVal = applyImplicitIntersection(aMat, aPos);
4736 if (std::isnan(fVal))
4737 PushNoValue();
4738 else
4739 PushInt(fVal);
4740 }
4741 else
4742 // This is a normal matrix.
4743 QueryMatrixType(aMat.mpMat, nRetTypeExpr, nRetIndexExpr);
4744 }
4745 break;
4747 {
4748 FormulaTokenRef xToken;
4750 PopExternalSingleRef(xToken, &aFmt);
4751 if (nGlobalError != FormulaError::NONE)
4752 break;
4753
4754 PushTokenRef(xToken);
4755
4756 if (aFmt.mbIsSet)
4757 {
4758 nFuncFmtType = aFmt.mnType;
4759 nFuncFmtIndex = aFmt.mnIndex;
4760 }
4761 }
4762 break;
4763 default :
4764 SetError( FormulaError::UnknownStackVariable);
4765 }
4766 }
4767 else
4768 SetError( FormulaError::UnknownStackVariable);
4769 }
4770 else if (sp > 1)
4771 SetError( FormulaError::OperatorExpected);
4772 else
4773 SetError( FormulaError::NoCode);
4774
4775 if (bForcedResultType || nRetTypeExpr != SvNumFormatType::UNDEFINED)
4776 {
4777 nRetFmtType = nRetTypeExpr;
4778 nRetFmtIndex = nRetIndexExpr;
4779 }
4780 else if( nFuncFmtType != SvNumFormatType::UNDEFINED )
4781 {
4784 }
4785 else
4786 nRetFmtType = SvNumFormatType::NUMBER;
4787
4788 if (nGlobalError != FormulaError::NONE && GetStackType() != svError )
4790
4791 // THE final result.
4792 xResult = PopToken();
4793 if (!xResult)
4794 xResult = new FormulaErrorToken( FormulaError::UnknownStackVariable);
4795
4796 // release tokens in expression stack
4797 const FormulaToken** p = pStack;
4798 while( maxsp-- )
4799 (*p++)->DecRef();
4800
4801 StackVar eType = xResult->GetType();
4802 if (eType == svMatrix)
4803 // Results are immutable in case they would be reused as input for new
4804 // interpreters.
4805 xResult->GetMatrix()->SetImmutable();
4806 return eType;
4807}
4808
4810{
4811 bMatrixFormula = true;
4812}
4813
4815{
4816 return xResult->GetString();
4817}
4818
4819/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
XPropertyListType t
ScAddInArgumentType
Definition: addincol.hxx:52
@ SC_ADDINARG_VALUE_OR_ARRAY
any
Definition: addincol.hxx:61
@ SC_ADDINARG_INTEGER
long
Definition: addincol.hxx:54
@ SC_ADDINARG_STRING
string
Definition: addincol.hxx:56
@ SC_ADDINARG_STRING_ARRAY
sequence<sequence<string>>
Definition: addincol.hxx:59
@ SC_ADDINARG_INTEGER_ARRAY
sequence<sequence<long>>
Definition: addincol.hxx:57
@ SC_ADDINARG_DOUBLE
double
Definition: addincol.hxx:55
@ SC_ADDINARG_DOUBLE_ARRAY
sequence<sequence<double>>
Definition: addincol.hxx:58
@ SC_ADDINARG_CELLRANGE
XCellRange.
Definition: addincol.hxx:62
@ SC_ADDINARG_MIXED_ARRAY
sequence<sequence<any>>
Definition: addincol.hxx:60
bool ValidTab(SCTAB nTab)
Definition: address.hxx:111
const SCCOL MAXCOLCOUNT
Definition: address.hxx:63
const SCCOL MAXCOLCOUNT_JUMBO
Definition: address.hxx:73
size_t SCSIZE
size_t typedef to be able to find places where code was changed from USHORT to size_t and is used to ...
Definition: address.hxx:44
void PutInOrder(T &nStart, T &nEnd)
Definition: address.hxx:150
const NodeContext & mrContext
SfxApplication * SfxGetpApp()
AnyEventRef aEvent
#define MAXFUNCPARAM
Definition: callform.hxx:27
ParamType
Definition: callform.hxx:41
#define MAXARRSIZE
Definition: callform.hxx:28
StarBASIC * GetLib(sal_uInt16 nLib) const
const OUString & GetName() const
const LegacyFuncData * findByName(const OUString &rName) const
Definition: callform.cxx:384
ParamType GetParamType(sal_uInt16 nIndex) const
Definition: callform.hxx:76
ParamType GetAsyncType() const
Definition: callform.hxx:77
void Call(void **ppParam) const
Definition: callform.cxx:245
SbModule * GetModule()
css::uno::Reference< css::script::XInvocation > const & GetUnoModule()
bool IsVBASupport() const
static ErrCode const & GetError()
static void ResetError()
bool GetDim(sal_Int32, sal_Int32 &, sal_Int32 &) const
SbxVariable * Get(SbxArray *)
sal_Int32 GetDims() const
bool PutString(const OUString &)
bool PutDouble(double)
bool PutEmpty()
bool GetBool() const
bool PutObject(SbxBase *)
double GetDouble() const
const SbxObject * GetParent() const
virtual SbxDataType GetType() const override
const OUString & GetName(SbxNameType=SbxNameType::NONE) const
double GetValue() const
Definition: adiasync.hxx:59
static ScAddInAsync * Get(sal_uLong nHandle)
Definition: adiasync.cxx:62
ParamType GetType() const
Definition: adiasync.hxx:58
bool IsValid() const
Definition: adiasync.hxx:57
void AddDocument(ScDocument *pDoc)
Definition: adiasync.hxx:63
const OUString & GetString() const
Definition: adiasync.hxx:60
bool HasDocument(ScDocument *pDoc) const
Definition: adiasync.hxx:61
static ScAddInListener * CreateListener(const css::uno::Reference< css::sheet::XVolatileResult > &xVR, ScDocument *pDoc)
const css::uno::Any & GetResult() const
Definition: addinlis.hxx:67
virtual void SAL_CALL disposing(const css::lang::EventObject &Source) override
Definition: addinlis.cxx:122
static ScAddInListener * Get(const css::uno::Reference< css::sheet::XVolatileResult > &xVR)
Definition: addinlis.cxx:61
void AddDocument(ScDocument *pDoc)
Definition: addinlis.hxx:64
bool HasDocument(ScDocument *pDoc) const
Definition: addinlis.hxx:61
SCTAB Tab() const
Definition: address.hxx:283
void Set(SCCOL nCol, SCROW nRow, SCTAB nTab)
Definition: address.hxx:403
void SetCol(SCCOL nColP)
Definition: address.hxx:291
SC_DLLPUBLIC void Format(OStringBuffer &r, ScRefFlags nFlags, const ScDocument *pDocument=nullptr, const Details &rDetails=detailsOOOa1) const
Definition: address.cxx:2074
SCROW Row() const
Definition: address.hxx:274
void SetRow(SCROW nRowP)
Definition: address.hxx:287
void SetTab(SCTAB nTabP)
Definition: address.hxx:295
SCCOL Col() const
Definition: address.hxx:279
static css::uno::Reference< css::table::XCellRange > CreateRangeFromDoc(const ScDocument &rDoc, const ScRange &rR)
Definition: cellsuno.cxx:4471
static bool DoubleRefToPosSingleRefScalarCase(const ScRange &rRange, ScAddress &rAdr, const ScAddress &rFormulaPos)
TODO : Move this to somewhere appropriate.
Definition: compiler.cxx:6337
ScDBData * findByIndex(sal_uInt16 nIndex)
Definition: dbdata.cxx:1214
NamedDBs & getNamedDBs()
Definition: dbdata.hxx:324
void GetArea(SCTAB &rTab, SCCOL &rCol1, SCROW &rRow1, SCCOL &rCol2, SCROW &rRow2) const
Definition: dbdata.cxx:298
bool GetNext(Value &rValue)
Does NOT reset rValue if no value found!
Definition: dociter.cxx:762
bool GetFirst(Value &rValue)
Does NOT reset rValue if no value found!
Definition: dociter.cxx:757
Base class for abstracting range data backends for database functions.
Definition: doubleref.hxx:38
ScSheetLimits & GetSheetLimits() const
Definition: document.hxx:898
SC_DLLPUBLIC sal_uInt32 GetNumberFormat(SCCOL nCol, SCROW nRow, SCTAB nTab) const
Definition: document.cxx:3640
void IncInterpreterTableOpLevel()
Definition: document.hxx:2440
void IncMacroInterpretLevel()
Definition: document.hxx:2427
bool ValidRow(SCROW nRow) const
Definition: document.hxx:900
const ScCalcConfig & GetCalcConfig() const
Definition: document.hxx:2619
void DecInterpreterTableOpLevel()
Definition: document.hxx:2445
SC_DLLPUBLIC SCCOL MaxCol() const
Definition: document.hxx:892
ScInterpreterTableOpParams aLastTableOpParams
Definition: document.hxx:448
SC_DLLPUBLIC ScMacroManager * GetMacroManager()
Definition: documen8.cxx:377
SC_DLLPUBLIC SCROW MaxRow() const
Definition: document.hxx:893
void SetTableOpDirty(const ScRange &)
Definition: document.cxx:3862
std::vector< ScInterpreterTableOpParams * > m_TableOpList
list of ScInterpreterTableOpParams currently in use
Definition: document.hxx:447
SC_DLLPUBLIC double RoundValueAsShown(double fVal, sal_uInt32 nFormat, const ScInterpreterContext *pContext=nullptr) const
Definition: documen4.cxx:627
SC_DLLPUBLIC ScExternalRefManager * GetExternalRefManager() const
Definition: documen3.cxx:625
void GetNumberFormatInfo(const ScInterpreterContext &rContext, SvNumFormatType &nType, sal_uInt32 &nIndex, const ScAddress &rPos) const
Definition: document.cxx:3690
SC_DLLPUBLIC ScDBCollection * GetDBCollection() const
Definition: document.hxx:827
SfxObjectShell * GetDocumentShell() const
Definition: document.hxx:1083
bool ValidCol(SCCOL nCol) const
Definition: document.hxx:899
SC_DLLPUBLIC svl::SharedStringPool & GetSharedStringPool()
Definition: documen2.cxx:601
void LockTable(SCTAB nTab)
Definition: document.cxx:5297
void DecMacroInterpretLevel()
Definition: document.hxx:2433
SC_DLLPUBLIC void GetDataArea(SCTAB nTab, SCCOL &rStartCol, SCROW &rStartRow, SCCOL &rEndCol, SCROW &rEndRow, bool bIncludeOld, bool bOnlyDown) const
Return the smallest area containing at least all contiguous cells having data.
Definition: document.cxx:1072
void UnlockTable(SCTAB nTab)
Definition: document.cxx:5307
bool ValidRange(const ScRange &rRange) const
Definition: document.hxx:903
SC_DLLPUBLIC const ScDocOptions & GetDocOptions() const
Definition: documen3.cxx:1936
SC_DLLPUBLIC SCTAB GetTableCount() const
Definition: document.cxx:297
bool ValidColRow(SCCOL nCol, SCROW nRow) const
Definition: document.hxx:901
::formula::FormulaTokenRef TokenRef
std::shared_ptr< ScTokenArray > TokenArrayRef
const OUString * getExternalFileName(sal_uInt16 nFileId, bool bForceOriginal=false)
It returns a pointer to the name of the URI associated with a given external file ID.
ScExternalRefCache::TokenArrayRef getDoubleRefTokens(sal_uInt16 nFileId, const OUString &rTabName, const ScRange &rRange, const ScAddress *pCurPos)
Get an array of tokens that consist of the specified external cell range.
ScExternalRefCache::TokenRef getSingleRefToken(sal_uInt16 nFileId, const OUString &rTabName, const ScAddress &rCell, const ScAddress *pCurPos, SCTAB *pTab, ScExternalRefCache::CellFormat *pFmt=nullptr)
ScMatrixMode GetMatrixFlag() const
double GetValue()
const svl::SharedString & GetString()
void SetTableOpDirty()
FormulaError GetErrCode()
static LegacyFuncCollection * GetLegacyFuncCollection()
Definition: global.cxx:278
static double ConvertStringToValue(const OUString &rStr, const ScCalcConfig &rConfig, FormulaError &rError, FormulaError nStringNoValueError, SvNumberFormatter *pFormatter, SvNumFormatType &rCurFmtType)
Convert string content to numeric value.
Definition: global2.cxx:352
static SC_DLLPUBLIC LanguageType eLnge
Definition: global.hxx:560
static SC_DLLPUBLIC ScUnoAddInCollection * GetAddInCollection()
Definition: global.cxx:283
formula::FormulaConstTokenRef PopToken()
Definition: interpr4.cxx:766
static void SetGlobalConfig(const ScCalcConfig &rConfig)
Definition: interpr4.cxx:3897
void ScDevSq()
Definition: interpr3.cxx:4462
void ScSumX2MY2()
Definition: interpr5.cxx:1732
void ScNormDist(int nMinParamCount)
Definition: interpr3.cxx:1546
sal_uInt32 nCurFmtIndex
Definition: interpre.hxx:202
void ScStDev(bool bTextAsZero=false)
Definition: interpr1.cxx:4242
void ScSubstitute()
Definition: interpr1.cxx:9931
void ScSumXMY2()
Definition: interpr5.cxx:1782
void SetError(FormulaError nError)
Definition: interpre.hxx:1008
void ScProduct()
Definition: interpr6.cxx:963
void ScAveDev()
Definition: interpr3.cxx:4304
void ScMatDet()
Definition: interpr5.cxx:905
void ScTableOp()
Definition: interpr4.cxx:3598
bool bMatrixFormula
Definition: interpre.hxx:211
void ScIsOdd()
Definition: interpr1.cxx:3181
double ConvertStringToValue(const OUString &)
Definition: interpr4.cxx:163
void ScLarge()
Definition: interpr3.cxx:3724
ScCalcConfig maCalcConfig
Definition: interpre.hxx:181
formula::FormulaToken * CreateDoubleOrTypedToken(double fVal)
Definition: interpr4.cxx:1791
void ScFisherInv()
Definition: interpr3.cxx:1159
void ScCosecant()
Definition: interpr1.cxx:1945
svl::SharedString GetString()
Definition: interpr4.cxx:2334
void ScLookup()
Definition: interpr1.cxx:6721
void ScGetDiffDate()
Definition: interpr2.cxx:662
void ScLogGamma()
Definition: interpr3.cxx:791
void ScRoman()
Definition: interpr2.cxx:3041
void ScExpDist()
Definition: interpr3.cxx:1615
void ScGetIsoWeekOfYear()
Definition: interpr2.cxx:294
void ScForecast()
Definition: interpr3.cxx:4747
bool IsInArrayContext() const
Definition: interpre.hxx:1024
void ScTanHyp()
Definition: interpr1.cxx:1903
void ScIsEven()
Definition: interpr1.cxx:3176
void ScDBCount()
Definition: interpr1.cxx:8067
bool ConvertMatrixParameters()
Definition: interpr4.cxx:1457
void ScFloor_Precise()
Definition: interpr2.cxx:1237
static ScCalcConfig * mpGlobalConfig
Definition: interpre.hxx:176
void ScArcSin()
Definition: interpr1.cxx:1873
void ScGetPivotData()
Definition: interpr2.cxx:3550
void ScIsErr()
Definition: interpr1.cxx:2960
void ScLCM()
Definition: interpr5.cxx:189
void ScIsFormula()
Definition: interpr1.cxx:2756
void ScISPMT()
Definition: interpr2.cxx:1644
void ScColRowNameAuto()
Definition: interpr4.cxx:3705
void ScSheets()
Definition: interpr1.cxx:4397
void ScGetDateDif()
Definition: interpr2.cxx:763
void ScCritBinom()
Definition: interpr3.cxx:1410
void ScPlusMinus()
Definition: interpr2.cxx:934
void ScChiSqInv()
Definition: interpr3.cxx:2403
void ScSearch()
Definition: interpr1.cxx:9583
void ScMaxIfs_MS()
Definition: interpr1.cxx:6704
void ScNoName()
Definition: interpr3.cxx:180
void ScSum()
Definition: interpr6.cxx:958
void ScExternal()
Definition: interpr4.cxx:2541
void ScErfc()
Definition: interpr7.cxx:505
void ScGamma()
Definition: interpr3.cxx:774
formula::FormulaTokenIterator aCode
Definition: interpre.hxx:182
formula::FormulaToken * CreateFormulaDoubleToken(double fVal, SvNumFormatType nFmt=SvNumFormatType::NUMBER)
Definition: interpr4.cxx:1766
void ScStdNormDist_MS()
Definition: interpr3.cxx:1601
ScMatrixRef PopMatrix()
Definition: interpr4.cxx:1642
void ScGetHour()
Definition: interpr2.cxx:161
void ScDBStdDev()
Definition: interpr1.cxx:8216
void DoubleRefToVars(const formula::FormulaToken *p, SCCOL &rCol1, SCROW &rRow1, SCTAB &rTab1, SCCOL &rCol2, SCROW &rRow2, SCTAB &rTab2)
Definition: interpr4.cxx:944
void ScHLookup()
Definition: interpr1.cxx:7380
void ScIntercept()
Definition: interpr3.cxx:4742
void PopExternalSingleRef(sal_uInt16 &rFileId, OUString &rTabName, ScSingleRefData &rRef)
Definition: interpr4.cxx:1141
ScAddress aPos
Definition: interpre.hxx:183
ScDocument & mrDoc
Definition: interpre.hxx:186
static FormulaError GetCellErrCode(const ScRefCellValue &rCell)
Definition: interpr4.cxx:158
void ScErrorType_ODF()
Definition: interpr1.cxx:10107
void PushExternalDoubleRef(sal_uInt16 nFileId, const OUString &rTabName, SCCOL nCol1, SCROW nRow1, SCTAB nTab1, SCCOL nCol2, SCROW nRow2, SCTAB nTab2)
Definition: interpr4.cxx:1869
SubtotalFlags mnSubTotalFlags
Definition: interpre.hxx:208
void ScPermutationA()
Definition: interpr3.cxx:1219
void ScDBMin()
Definition: interpr1.cxx:8165
void AssertFormulaMatrix()
Definition: interpr4.cxx:4809
ScDBRangeBase * PopDBDoubleRef()
Definition: interpr4.cxx:962
void ScColor()
Definition: interpr7.cxx:512
void ScDBAverage()
Definition: interpr1.cxx:8155
void PushIllegalParameter()
Definition: interpr4.cxx:1938
void ScIsValue()
Definition: interpr1.cxx:2685
void ScRandom()
Definition: interpr1.cxx:1800
void ScArcCotHyp()
Definition: interpr1.cxx:1936
void ScIfs_MS()
Definition: interpr8.cxx:1830
bool JumpMatrix(short nStackLevel)
Definition: interpr1.cxx:545
bool GetDoubleOrString(double &rValue, svl::SharedString &rString)
returns TRUE if double (or error, check nGlobalError), else FALSE
Definition: interpr4.cxx:2274
void ScCotHyp()
Definition: interpr1.cxx:1908
static ScCalcConfig & GetOrCreateGlobalConfig()
Definition: interpr4.cxx:3890
FormulaError nGlobalError
Definition: interpre.hxx:198
void PushIllegalArgument()
Definition: interpr4.cxx:1943
sal_Int16 GetInt16()
if GetDouble() not within int16 limits sets nGlobalError and returns SAL_MAX_INT16
Definition: interpr4.cxx:2229
void ScWebservice()
Definition: interpr7.cxx:274
void ScInt()
Definition: interpr2.cxx:950
bool CreateDoubleArr(SCCOL nCol1, SCROW nRow1, SCTAB nTab1, SCCOL nCol2, SCROW nRow2, SCTAB nTab2, sal_uInt8 *pCellArr)
Definition: interpr4.cxx:280
static thread_local bool bGlobalStackInUse
Definition: interpre.hxx:179
void ScLogNormDist(int nMinParamCount)
Definition: interpr3.cxx:1566
formula::StackVar Interpret()
Definition: interpr4.cxx:3972
void ScRoundDown()
Definition: interpr2.cxx:1028
void ScMatch()
Definition: interpr1.cxx:4857
void ScLessEqual()
Definition: interpr1.cxx:1234
void ScTDist_T(int nTails)
Definition: interpr3.cxx:1656
void ScNumberValue()
Definition: interpr1.cxx:3414
void ScCount2()
Definition: interpr6.cxx:978
void ScSubTotal()
Definition: interpr1.cxx:7714
void DoubleRefToRange(const ScComplexRefData &, ScRange &, bool bDontCheckForTableOp=false)
Definition: interpr4.cxx:1026
void ScSearchB()
Definition: interpr1.cxx:9502
void ScCosHyp()
Definition: interpr1.cxx:1898
void ScMax(bool bTextAsZero=false)
Definition: interpr1.cxx:3842
void ScCeil_Precise()
Definition: interpr2.cxx:1146
void PushDoubleRef(SCCOL nCol1, SCROW nRow1, SCTAB nTab1, SCCOL nCol2, SCROW nRow2, SCTAB nTab2)
Definition: interpr4.cxx:1846
void Push(const formula::FormulaToken &r)
Does substitute with formula::FormulaErrorToken in case nGlobalError is set and the token passed is n...
Definition: interpr4.cxx:600
void ScCountIf()
Definition: interpr1.cxx:5702
void ScLogNormInv()
Definition: interpr3.cxx:2143
void ScErf()
Definition: interpr7.cxx:498
void PushExternalSingleRef(sal_uInt16 nFileId, const OUString &rTabName, SCCOL nCol, SCROW nRow, SCTAB nTab)
Definition: interpr4.cxx:1857
sal_uInt8 cPar
Definition: interpre.hxx:209
void ScGetDiffDate360()
Definition: interpr2.cxx:672
void ScIsRef()
Definition: interpr1.cxx:2633
void ReplaceCell(ScAddress &)
Definition: interpr4.cxx:88
const svl::SharedString & GetStringResult() const
Definition: interpr4.cxx:4814
void ScGetActDate()
Definition: interpr2.cxx:101
void ScModalValue()
Definition: interpr3.cxx:3505
void ScRank(bool bAverage)
Definition: interpr3.cxx:4237
formula::StackVar GetRawStackType()
Raw stack type without default replacements.
Definition: interpr4.cxx:1963
svl::SharedString GetStringFromDouble(const double fVal)
Definition: interpr4.cxx:2496
const formula::FormulaToken * pCur
Definition: interpre.hxx:195
ScInterpreterContext & mrContext
Definition: interpre.hxx:185
void ScEncodeURL()
Returns a string in which all non-alphanumeric characters except stroke and underscore (-_) have been...
Definition: interpr7.cxx:415
void ScRound()
Definition: interpr2.cxx:1023
void ScGetDate()
Definition: interpr2.cxx:629
SvNumFormatType nFuncFmtType
Definition: interpre.hxx:204
void ScGrowth()
Definition: interpr5.cxx:2861
void ScSNormInv()
Definition: interpr3.cxx:2132
void ScNegBinomDist()
Definition: interpr3.cxx:1500
bool DoubleRefToPosSingleRef(const ScRange &rRange, ScAddress &rAdr)
Definition: interpr4.cxx:2017
void ScLog10()
Definition: interpr2.cxx:1311
void ScProbability()
Definition: interpr3.cxx:4471
void ScIsEmpty()
Definition: interpr1.cxx:1979
void ScMatValue()
Definition: interpr5.cxx:615
sal_uInt32 GetUInt32()
if GetDouble() not within uint32 limits sets nGlobalError and returns SAL_MAX_UINT32
Definition: interpr4.cxx:2258
std::unique_ptr< ScDBQueryParamBase > GetDBParams(bool &rMissingField)
Definition: interpr1.cxx:7857
void ScEasterSunday()
Definition: interpr2.cxx:304
void ScDBSum()
Definition: interpr1.cxx:8062
void ScGetWeekOfYear()
Definition: interpr2.cxx:248
void ScReplaceB()
Definition: interpr1.cxx:9445
double GetValueCellValue(const ScAddress &, double fOrig)
Only ValueCell, formula cells already store the result rounded.
Definition: interpr4.cxx:148
void ScPower()
Definition: interpr5.cxx:1611
bool IsTableOpInRange(const ScRange &)
Definition: interpr4.cxx:107
void ScDBProduct()
Definition: interpr1.cxx:8170
void ScGammaInv()
Definition: interpr3.cxx:2172
sal_uInt32 nRetFmtIndex
Definition: interpre.hxx:203
const svl::SharedString & PopString()
Definition: interpr4.cxx:813
const ScComplexRefData * GetStackDoubleRef(size_t rRefInList=0)
Definition: interpr4.cxx:1118
void GetCellString(svl::SharedString &rStr, ScRefCellValue &rCell)
Definition: interpr4.cxx:245
void ScCumPrinc()
Definition: interpr2.cxx:2294
void ScHarMean()
Definition: interpr3.cxx:2903
void ScBetaDist_MS()
Microsoft version has parameters in different order Also, upper and lowerbound are optional and have ...
Definition: interpr3.cxx:1100
void ScBitOr()
Definition: interpr1.cxx:1658
bool PopDoubleRefOrSingleRef(ScAddress &rAdr)
Definition: interpr4.cxx:1342
void ScTrend()
Definition: interpr5.cxx:2856
bool CreateStringArr(SCCOL nCol1, SCROW nRow1, SCTAB nTab1, SCCOL nCol2, SCROW nRow2, SCTAB nTab2, sal_uInt8 *pCellArr)
Definition: interpr4.cxx:363
void ScTextJoin_MS()
Definition: interpr8.cxx:1507
void ValidateRef(const ScSingleRefData &rRef)
Definition: interpr4.cxx:841
void ScGreaterEqual()
Definition: interpr1.cxx:1251
void ScWeibull()
Definition: interpr3.cxx:1763
VolatileType meVolatileType
Definition: interpre.hxx:213
void ScSmall()
Definition: interpr3.cxx:3729
void GetExternalDoubleRef(sal_uInt16 nFileId, const OUString &rTabName, const ScComplexRefData &aData, ScExternalRefCache::TokenArrayRef &rArray)
Definition: interpr4.cxx:1284
double GetCellValueOrZero(const ScAddress &, ScRefCellValue &rCell)
Definition: interpr4.cxx:188
void PushError(FormulaError nError)
Definition: interpr4.cxx:1927
void PopRefListPushMatrixOrRef()
Definition: interpr4.cxx:1378
sal_uInt8 GetByte() const
Definition: interpre.hxx:416
void ScGetActTime()
Definition: interpr2.cxx:109
double GetDoubleFromMatrix(const ScMatrixRef &pMat)
Definition: interpr4.cxx:2056
static const ScCalcConfig & GetGlobalConfig()
Definition: interpr4.cxx:3902
sal_Int32 GetInt32WithDefault(sal_Int32 nDefault)
if GetDoubleWithDefault() not within int32 limits sets nGlobalError and returns SAL_MAX_INT32
Definition: interpr4.cxx:2220
void ScGCD()
Definition: interpr5.cxx:115
void ScPercentSign()
Definition: interpr1.cxx:1599
void PushWithoutError(const formula::FormulaToken &r)
Does not substitute with formula::FormulaErrorToken in case nGlobalError is set.
Definition: interpr4.cxx:584
void ScUnionFunc()
Definition: interpr2.cxx:2557
void ScForecast_Ets(ScETSType eETSType)
Definition: interpr8.cxx:1175
void ScEffect()
Definition: interpr2.cxx:2333
void Init(ScFormulaCell *pCell, const ScAddress &rPos, ScTokenArray &rTokArray)
Definition: interpr4.cxx:3866
void ScMultiArea()
Definition: interpr1.cxx:8998
void ScModalValue_MS(bool bSingle)
Definition: interpr3.cxx:3549
void ScWeeknumOOo()
Definition: interpr2.cxx:236
ScMatrixRef GetNewMat(SCSIZE nC, SCSIZE nR, bool bEmpty=false)
Definition: interpr5.cxx:284
void ScCovarianceS()
Definition: interpr3.cxx:4543
void ScMedian()
Definition: interpr3.cxx:3390
void PopDoubleRefPushMatrix()
Definition: interpr4.cxx:1364
ScMatValType GetDoubleOrStringFromMatrix(double &rDouble, svl::SharedString &rString)
Definition: interpr4.cxx:2435
double GetDouble()
Definition: interpr4.cxx:2097
void ScCountIfs()
Definition: interpr1.cxx:6669
void ScTTest()
Definition: interpr3.cxx:2647
void PushCellResultToken(bool bDisplayEmptyAsString, const ScAddress &rAddress, SvNumFormatType *pRetTypeExpr, sal_uInt32 *pRetIndexExpr, bool bFinalResult=false)
Obtain cell result / content from address and push as temp token.
Definition: interpr4.cxx:687
void ScFisher()
Definition: interpr3.cxx:1150
void ScGetTimeValue()
Definition: interpr2.cxx:912
void ScDBGet()
Definition: interpr4.cxx:2506
sal_uInt16 maxsp
Definition: interpre.hxx:200
void ScAverage(bool bTextAsZero=false)
Definition: interpr6.cxx:968
void ScGetMin()
Definition: interpr2.cxx:142
void ScIndirect()
Definition: interpr1.cxx:8250
void ScSumX2DY2()
Definition: interpr5.cxx:1777
void ScChiTest()
Definition: interpr3.cxx:2780
void ScSecantHyp()
Definition: interpr1.cxx:1960
void ScBinomDist()
Definition: interpr3.cxx:1346
void ScZTest()
Definition: interpr3.cxx:2453
void ScUnicode()
Definition: interpr1.cxx:3630
void ScChiDist(bool bODFF)
Definition: interpr3.cxx:1741
void ScIsString()
Definition: interpr1.cxx:2101
void ScGetDayOfWeek()
Definition: interpr2.cxx:189
void ScSumIf()
Definition: interpr1.cxx:5692
ScTokenMatrixMap & GetTokenMatrixMap()
Definition: interpre.hxx:1043
void ScVLookup()
Definition: interpr1.cxx:7709
void ConvertMatrixJumpConditionToMatrix()
Definition: interpr4.cxx:1438
void PushDouble(double nVal)
Definition: interpr4.cxx:1801
void ScGetDay()
Definition: interpr2.cxx:135
void ScMatInv()
Definition: interpr5.cxx:952
void ScDebugVar()
Definition: interpr7.cxx:452
void ScDBCount2()
Definition: interpr1.cxx:8125
void ScNominal()
Definition: interpr2.cxx:2352
void ScHyperLink()
Definition: interpr2.cxx:3182
void ScQuartile(bool bInclusive)
Definition: interpr3.cxx:3482
void ScLinest()
Definition: interpr5.cxx:2331
void ScFrequency()
Definition: interpr5.cxx:1814
sc::RangeMatrix PopRangeMatrix()
Definition: interpr4.cxx:1674
const formula::FormulaToken ** pStack
Definition: interpre.hxx:197
void ScFTest()
Definition: interpr3.cxx:2730
void ScMatTrans()
Definition: interpr5.cxx:1113
void ScCountEmptyCells()
Definition: interpr1.cxx:5207
void QueryMatrixType(const ScMatrixRef &xMat, SvNumFormatType &rRetTypeExpr, sal_uInt32 &rRetIndexExpr)
Definition: interpr4.cxx:1714
static void GlobalExit()
Definition: interpr4.cxx:3913
void PopSingleRef(ScAddress &)
Definition: interpr4.cxx:907
void ScStyle()
Definition: interpr2.cxx:2642
void ScArcCot()
Definition: interpr1.cxx:1888
double PopDouble()
Definition: interpr4.cxx:781
void ReverseStack(sal_uInt8 nParamCount)
Definition: interpr4.cxx:2009
void ScGreater()
Definition: interpr1.cxx:1217
ScTokenMatrixMap maTokenMatrixMap
Definition: interpre.hxx:191
void MergeCalcConfig()
Merge global and document specific settings.
Definition: interpr4.cxx:3907
ScTokenArray * pArr
Definition: interpre.hxx:184
void ScDBMax()
Definition: interpr1.cxx:8160
void ScRawSubtract()
The purpose of RAWSUBTRACT() is exactly to not apply any error correction, approximation etc.
Definition: interpr6.cxx:988
bool SetSbxVariable(SbxVariable *pVar, const ScAddress &)
void ScSumSQ()
Definition: interpr6.cxx:953
SvNumberFormatter * pFormatter
Definition: interpre.hxx:193
void ScBitLshift()
Definition: interpr1.cxx:1688
FormulaError mnStringNoValueError
Definition: interpre.hxx:207
void ScNormInv()
Definition: interpr3.cxx:2116
void ScDecimal()
Definition: interpr2.cxx:2962
void ScEMat()
Definition: interpr5.cxx:716
void ScBitAnd()
Definition: interpr1.cxx:1643
void ScTInv(int nType)
Definition: interpr3.cxx:2264
void ScSinHyp()
Definition: interpr1.cxx:1893
static thread_local std::unique_ptr< ScTokenStack > pGlobalStack
Definition: interpre.hxx:178
void ScRangeFunc()
Definition: interpr2.cxx:2537
void ScVar(bool bTextAsZero=false)
Definition: interpr1.cxx:4220
void PushTempTokenWithoutError(const formula::FormulaToken *)
Does not substitute with formula::FormulaErrorToken in case nGlobalError is set.
Definition: interpr4.cxx:647
ScMatrixRef GetMatrix()
Definition: interpr5.cxx:464
void ScBadName()
Definition: interpr3.cxx:185
void ScIndex()
Definition: interpr1.cxx:8753
void ScGetDateValue()
Definition: interpr2.cxx:169
void PushParameterExpected()
Definition: interpr4.cxx:1933
void ScGetYear()
Definition: interpr2.cxx:121
void ScConfidence()
Definition: interpr3.cxx:2423
void ScDBArea()
Definition: interpr4.cxx:3688
void TreatDoubleError(double &rVal)
Definition: interpre.hxx:1142
void ScGetTime()
Definition: interpr2.cxx:646
void ScArcCosHyp()
Definition: interpr1.cxx:1918
void ScFDist()
Definition: interpr3.cxx:1689
void ScCurrency()
Definition: interpr1.cxx:9047
void ScRightB()
Definition: interpr1.cxx:9355
void ScNegBinomDist_MS()
Definition: interpr3.cxx:1520
ScJumpMatrix * pJumpMatrix
Definition: interpre.hxx:190
void ScBitXor()
Definition: interpr1.cxx:1673
bool CreateCellArr(SCCOL nCol1, SCROW nRow1, SCTAB nTab1, SCCOL nCol2, SCROW nRow2, SCTAB nTab2, sal_uInt8 *pCellArr)
Definition: interpr4.cxx:461
sal_Int32 double_to_int32(double fVal)
Definition: interpr4.cxx:2187
void ScFormula()
Definition: interpr1.cxx:2825
void ScOffset()
Definition: interpr1.cxx:8591
void ScMatRef()
Definition: interpr5.cxx:3164
void ScMissing()
Definition: interpr4.cxx:3122
void ScDBStdDevP()
Definition: interpr1.cxx:8223
void ScEqual()
Definition: interpr1.cxx:1166
sal_uInt32 nFuncFmtIndex
Definition: interpre.hxx:201
void ScGetSec()
Definition: interpr2.cxx:150
void ScSkewp()
Definition: interpr3.cxx:3361
FormulaError GetError() const
Definition: interpre.hxx:1015
void ScConfidenceT()
Definition: interpr3.cxx:2437
sal_uInt32 GetCellNumberFormat(const ScAddress &rPos, ScRefCellValue &rCell)
Definition: interpr4.cxx:125
void ScWorkday_MS()
Definition: interpr2.cxx:557
void PopDoubleRef(ScRange &rRange, short &rParam, size_t &rRefInList)
If formula::StackVar formula::svDoubleRef pop ScDoubleRefToken and return values of ScComplexRefData.
Definition: interpr4.cxx:1044
void ScIsNonString()
Definition: interpr1.cxx:2106
void ScArabic()
Definition: interpr2.cxx:3125
void PushTokenRef(const formula::FormulaConstTokenRef &)
Pushes the token or substitutes with formula::FormulaErrorToken in case nGlobalError is set and the t...
Definition: interpr4.cxx:667
void ScPercentile(bool bInclusive)
Definition: interpr3.cxx:3459
void ScFalse()
Definition: interpr1.cxx:1837
void ScLogest()
Definition: interpr5.cxx:2337
void PushMatrix(const sc::RangeMatrix &rMat)
Definition: interpr4.cxx:1902
void ScFInv_LT()
Definition: interpr3.cxx:2333
void ScSumIfs()
Definition: interpr1.cxx:6634
void ScChiSqDist()
Definition: interpr3.cxx:727
void ScPDuration()
Definition: interpr2.cxx:1910
void ScCosecantHyp()
Definition: interpr1.cxx:1955
void ScGammaDist(bool bODFF)
Definition: interpr3.cxx:2091
void ScTrimMean()
Definition: interpr3.cxx:3829
void ScVarP(bool bTextAsZero=false)
Definition: interpr1.cxx:4232
void ScCeil(bool bODFF)
tdf69552 ODFF1.2 function CEILING and Excel function CEILING.MATH In essence, the difference between ...
Definition: interpr2.cxx:1088
void ScCombin()
Definition: interpr3.cxx:1173
void ScGetMonth()
Definition: interpr2.cxx:128
void ScCovarianceP()
Definition: interpr3.cxx:4538
void PopError()
Definition: interpr4.cxx:754
ScFormulaCell * pMyFormulaCell
Definition: interpre.hxx:192
void ScChooseJump()
Definition: interpr1.cxx:416
void ScEuroConvert()
Definition: interpr2.cxx:3312
void ScDBVarP()
Definition: interpr1.cxx:8237
void ScGauss()
Definition: interpr3.cxx:1145
void ScExact()
Definition: interpr1.cxx:9230
void ScReplace()
Definition: interpr1.cxx:9104
void ScColumn()
Definition: interpr1.cxx:4444
void ScRegex()
Definition: interpr1.cxx:9629
void ScUpper()
Definition: interpr1.cxx:3219
void ScCumIpmt()
Definition: interpr2.cxx:2253
void PopExternalDoubleRef(sal_uInt16 &rFileId, OUString &rTabName, ScComplexRefData &rRef)
Definition: interpr4.cxx:1220
void ScArcCos()
Definition: interpr1.cxx:1878
double GetCellValue(const ScAddress &, ScRefCellValue &rCell)
Definition: interpr4.cxx:178
bool MatrixParameterConversion()
Definition: interpre.hxx:1035
void ScRandbetween()
Definition: interpr1.cxx:1809
void PushTempToken(formula::FormulaToken *)
Does substitute with formula::FormulaErrorToken in case nGlobalError is set and the token passed is n...
Definition: interpr4.cxx:618
void ScAreas()
Definition: interpr1.cxx:9011
void ScSumProduct()
Definition: interpr5.cxx:1671
ScTokenStack * pStackObj
Definition: interpre.hxx:196
void ScConvertOOo()
Definition: interpr2.cxx:3018
void ScCeil_MS()
Definition: interpr2.cxx:1128
void ScFilterXML()
Definition: interpr7.cxx:39
void ScStDevP(bool bTextAsZero=false)
Definition: interpr1.cxx:4254
void ScSecant()
Definition: interpr1.cxx:1950
void PushSingleRef(SCCOL nCol, SCROW nRow, SCTAB nTab)
Definition: interpr4.cxx:1836
void ScFourier()
Definition: interpr3.cxx:5505
void ScMinIfs_MS()
Definition: interpr1.cxx:6686
void ScAverageIf()
Definition: interpr1.cxx:5697
void ScFDist_LT()
Definition: interpr3.cxx:1704
void ScMin(bool bTextAsZero=false)
Definition: interpr1.cxx:3685
void ScCount()
Definition: interpr6.cxx:973
void ScStdNormDist()
Definition: interpr3.cxx:1596
void ScIsLogical()
Definition: interpr1.cxx:2111
void ScArcSinHyp()
Definition: interpr1.cxx:1913
void ScHypGeomDist(int nMinParamCount)
Calculates a value of the hypergeometric distribution.
Definition: interpr3.cxx:1856
void ScConcat_MS()
Definition: interpr8.cxx:1382
void ScAbs()
Definition: interpr2.cxx:945
void ScNetWorkdays(bool bOOXML_Version)
Definition: interpr2.cxx:501
void ScBetaDist()
Definition: interpr3.cxx:1036
void ScProper()
Definition: interpr1.cxx:3225
void PushNoValue()
Definition: interpr4.cxx:1953
void ScTDist()
Definition: interpr3.cxx:1641
void SingleRefToVars(const ScSingleRefData &rRef, SCCOL &rCol, SCROW &rRow, SCTAB &rTab)
Definition: interpr4.cxx:863
void ScArcTan2()
Definition: interpr2.cxx:1278
bool IfErrorPushError()
If nGlobalError is set push formula::FormulaErrorToken.
Definition: interpre.hxx:293
void ScStandard()
Definition: interpr3.cxx:3196
void ScIsError()
Definition: interpr1.cxx:3023
void ScMacro()
Definition: interpr4.cxx:3219
void ScValue()
Definition: interpr1.cxx:3335
void ScLeftB()
Definition: interpr1.cxx:9404
double GetDoubleWithDefault(double nDefault)
Definition: interpr4.cxx:2178
void ScFloor(bool bODFF)
tdf69552 ODFF1.2 function FLOOR and Excel function FLOOR.MATH In essence, the difference between the ...
Definition: interpr2.cxx:1176
void ScSlope()
Definition: interpr3.cxx:4737
void ScLower()
Definition: interpr1.cxx:3249
void ScBetaInv()
Definition: interpr3.cxx:2212
void ScChiSqDist_MS()
Definition: interpr3.cxx:750
bool IsMissing() const
Definition: interpr4.cxx:1958
void ScErrorType()
Definition: interpr1.cxx:10093
void ScChiInv()
Definition: interpr3.cxx:2368
void ScPearson()
Definition: interpr3.cxx:4548
void ScIfError(bool bNAonly)
Definition: interpr1.cxx:249
void ScRoundSignificant()
Definition: interpr2.cxx:1058
sal_Int32 GetInt32()
if GetDouble() not within int32 limits sets nGlobalError and returns SAL_MAX_INT32
Definition: interpr4.cxx:2215
void ScTDist_MS()
Definition: interpr3.cxx:1674
formula::StackVar GetStackType()
Stack type with replacement of defaults, e.g. svMissing and formula::svEmptyCell will result in formu...
Definition: interpr4.cxx:1978
void ScRight()
Definition: interpr1.cxx:9547
formula::FormulaConstTokenRef xResult
Definition: interpre.hxx:189
void ScAmpersand()
Definition: interpr5.cxx:1360
void ScArcTan()
Definition: interpr1.cxx:1883
void ScFloor_MS()
Definition: interpr2.cxx:1216
svl::SharedStringPool & mrStrPool
Definition: interpre.hxx:188
void ScAddressFunc()
Definition: interpr1.cxx:8489
void ScAggregate()
Definition: interpr1.cxx:7761
svl::SharedString GetStringFromMatrix(const ScMatrixRef &pMat)
Definition: interpr4.cxx:2413
bool bCalcAsShown
Definition: interpre.hxx:210
void ScIfJump()
Definition: interpr1.cxx:87
void PushInt(int nVal)
Definition: interpr4.cxx:1808
void ScColumns()
Definition: interpr1.cxx:4283
void ScCombinA()
Definition: interpr3.cxx:1186
SvNumFormatType nCurFmtType
Definition: interpre.hxx:205
void ScNotEqual()
Definition: interpr1.cxx:1183
void ScSheet()
Definition: interpr1.cxx:4669
void ScAverageIfs()
Definition: interpr1.cxx:6652
SvNumFormatType nRetFmtType
Definition: interpre.hxx:206
void ScFixed()
Definition: interpr1.cxx:9141
void ScCorrel()
Definition: interpr3.cxx:4532
void ScRoundUp()
Definition: interpr2.cxx:1033
void PushString(const OUString &rStr)
Definition: interpr4.cxx:1825
void PushStringBuffer(const sal_Unicode *pString)
Definition: interpr4.cxx:1814
void ScBitRshift()
Definition: interpr1.cxx:1711
void ScGeoMean()
Definition: interpr3.cxx:3024
ScMatrixRef CreateMatrixFromDoubleRef(const formula::FormulaToken *pToken, SCCOL nCol1, SCROW nRow1, SCTAB nTab1, SCCOL nCol2, SCROW nRow2, SCTAB nTab2)
Definition: interpr5.cxx:302
void ScFindB()
Definition: interpr1.cxx:9468
void ScPercentrank(bool bInclusive)
Definition: interpr3.cxx:3734
void ScClean()
Definition: interpr1.cxx:3516
sal_uInt16 sp
Definition: interpre.hxx:199
void ScArcTanHyp()
Definition: interpr1.cxx:1927
void ScDBVar()
Definition: interpr1.cxx:8230
void ScSTEYX()
Definition: interpr3.cxx:4663
void ScPermut()
Definition: interpr3.cxx:1199
void ScBahtText()
Definition: interpr2.cxx:3483
void ScUnichar()
Definition: interpr1.cxx:3644
void ScSwitch_MS()
Definition: interpr8.cxx:1897
ScInterpreter(ScFormulaCell *pCell, ScDocument &rDoc, ScInterpreterContext &rContext, const ScAddress &, ScTokenArray &, bool bForGroupThreading=false)
Definition: interpr4.cxx:3803
void ScIntersect()
Definition: interpr2.cxx:2390
void ScMatMult()
Definition: interpr5.cxx:1064
void ScCurrent()
Definition: interpr2.cxx:2630
void ScPoissonDist(bool bODFF)
Definition: interpr3.cxx:1781
void GetPos(SCSIZE &rCol, SCSIZE &rRow) const
Definition: jumpmatrix.cxx:104
SC_DLLPUBLIC bool GetUserFuncVolatile(const OUString &sName)
Definition: macromgr.cxx:169
void AddDependentCell(const OUString &aModuleName, ScFormulaCell *pCell)
Definition: macromgr.cxx:177
Stores the matrix result at the formula cell, additionally the range the matrix formula occupies.
Definition: token.hxx:325
Token storing matrix that represents values in sheet range.
Definition: token.hxx:113
Matrix data type that can store values of mixed types.
Definition: scmatrix.hxx:101
void SetErrorInterpreter(ScInterpreter *p)
Definition: scmatrix.cxx:3138
static bool IsValueType(ScMatValType nType)
Value or boolean.
Definition: scmatrix.hxx:167
static bool IsNonValueType(ScMatValType nType)
String, empty or empty path, but not value nor boolean.
Definition: scmatrix.hxx:179
void GetDimensions(SCSIZE &rC, SCSIZE &rR) const
Definition: scmatrix.cxx:3143
static formula::ParamClass GetParameterType(const formula::FormulaToken *pToken, sal_uInt16 nParameter)
Get one parameter type for function eOp.
Definition: parclass.cxx:362
static bool FillMixedArray(css::uno::Any &rAny, ScDocument &rDoc, const ScRange &rRange, bool bAllowNV=false)
static bool FillDoubleArray(css::uno::Any &rAny, ScDocument &rDoc, const ScRange &rRange)
static bool FillLongArray(css::uno::Any &rAny, ScDocument &rDoc, const ScRange &rRange)
static bool FillStringArray(css::uno::Any &rAny, ScDocument &rDoc, const ScRange &rRange)
void PutInOrder()
Definition: address.hxx:622
ScAddress aEnd
Definition: address.hxx:498
bool Contains(const ScAddress &) const
is Address& fully in Range?
Definition: address.hxx:718
ScAddress aStart
Definition: address.hxx:497
const formula::FormulaToken * pPointer[MAXSTACK]
Definition: interpre.hxx:99
const ScMatrixRef & GetMatrix() const
Definition: addincol.hxx:238
FormulaError GetErrCode() const
Definition: addincol.hxx:232
void SetResult(const css::uno::Any &rNewRes)
Definition: addincol.cxx:1559
ScAddInArgumentType GetArgType(tools::Long nPos)
Definition: addincol.cxx:1397
const css::uno::Reference< css::sheet::XVolatileResult > & GetVarRes() const
Definition: addincol.hxx:240
bool NeedsCaller() const
Definition: addincol.cxx:1414
void ExecuteCall()
Definition: addincol.cxx:1458
void SetCaller(const css::uno::Reference< css::uno::XInterface > &rInterface)
Definition: addincol.cxx:1419
bool HasVarRes() const
Definition: addincol.hxx:235
const OUString & GetString() const
Definition: addincol.hxx:237
bool ValidParamCount()
Definition: addincol.hxx:224
bool HasString() const
Definition: addincol.hxx:233
double GetValue() const
Definition: addincol.hxx:236
void SetParam(tools::Long nPos, const css::uno::Any &rValue)
Definition: addincol.cxx:1433
void SetCallerFromObjectShell(const SfxObjectShell *pSh)
Definition: addincol.cxx:1424
bool HasMatrix() const
Definition: addincol.hxx:234
BasicManager * GetBasicManager() const
StarBASIC * GetBasic() const
ErrCode CallBasic(std::u16string_view rMacro, std::u16string_view rBasicName, SbxArray *pArgs, SbxValue *pRet=nullptr)
const OUString & GetName() const
virtual SbxVariable * Find(const OUString &, SbxClassType) override
SbModule * FindModule(std::u16string_view)
SbxObject * getVBAGlobals()
sal_uInt32 GetStandardFormat(SvNumFormatType eType, LanguageType eLnge=LANGUAGE_DONTKNOW)
void GetInputLineString(const double &fOutNumber, sal_uInt32 nFIndex, OUString &rOutString, bool bFiltering=false, bool bForceSystemLocale=false)
bool StartListening(SvtBroadcaster &rBroadcaster)
void AddRecalcMode(ScRecalcMode nBits)
void ReInit(const FormulaTokenArray &)
const FormulaToken * Next()
void Jump(short nStart, short nNext, short nStop=SHRT_MAX)
virtual sal_uInt8 GetByte() const
virtual sal_uInt16 GetIndex() const
virtual const OUString & GetExternal() const
OpCode GetOpCode() const
virtual const std::vector< ScComplexRefData > * GetRefList() const
StackVar GetType() const
virtual const ScComplexRefData * GetDoubleRef() const
virtual const ScMatrix * GetMatrix() const
sal_uInt8 GetParamCount() const
virtual FormulaError GetError() const
virtual sal_Int16 GetDoubleType() const
SharedString intern(const OUString &rStr)
const OUString & getString() const
static const SharedString & getEmptyString()
T * get() const
int nCount
float x
EmbeddedObjectRef * pObject
#define ERRCODE_NONE
FormulaError
FormulaError GetDoubleErrorValue(double fVal)
DocumentType eType
ScMatrixMode
CellType
Definition: global.hxx:272
@ CELLTYPE_EDIT
Definition: global.hxx:277
@ CELLTYPE_STRING
Definition: global.hxx:275
@ CELLTYPE_FORMULA
Definition: global.hxx:276
@ CELLTYPE_NONE
Definition: global.hxx:273
@ CELLTYPE_VALUE
Definition: global.hxx:274
SubtotalFlags
Definition: global.hxx:240
#define ADDIN_MAXSTRLEN
Definition: interpr4.cxx:81
@ etsAdd
Definition: interpre.hxx:121
@ etsStatMult
Definition: interpre.hxx:127
@ etsMult
Definition: interpre.hxx:122
@ etsSeason
Definition: interpre.hxx:123
@ etsPIMult
Definition: interpre.hxx:125
@ etsPIAdd
Definition: interpre.hxx:124
@ etsStatAdd
Definition: interpre.hxx:126
constexpr size_t MAXSTACK
Definition: interpre.hxx:94
#define TOKEN_CACHE_SIZE
sal_Int32 nIndex
void * p
::std::vector< const formula::FormulaToken * > ScTokenVec
Definition: jumpmatrix.hxx:30
sal_uInt16 nPos
#define SAL_WARN_IF(condition, area, stream)
#define SAL_WARN(area, stream)
#define SAL_MATH_FPEXCEPTIONS_OFF()
aStr
constexpr OUStringLiteral aData
size
OUString getString(const Any &_rAny)
::boost::intrusive_ptr< const FormulaToken > FormulaConstTokenRef
::boost::intrusive_ptr< FormulaToken > FormulaTokenRef
StackVar
svMissing
svExternalDoubleRef
svUnknown
svDouble
svJumpMatrix
svError
svDoubleRef
svExternalSingleRef
svString
svRefList
svMatrix
svEmptyCell
svSingleRef
int i
constexpr std::enable_if_t< std::is_signed_v< T >, std::make_unsigned_t< T > > make_unsigned(T value)
css::uno::Reference< css::uno::XInterface > createVBAUnoAPIServiceWithArgs(SfxObjectShell const *pShell, const char *_pAsciiName, const css::uno::Sequence< css::uno::Any > &aArgs)
OString OUStringToOString(std::u16string_view str, ConnectionSettings const *settings)
css::uno::Reference< css::linguistic2::XProofreadingIterator > get(css::uno::Reference< css::uno::XComponentContext > const &context)
OpCode
ocSumProduct
ocGetTimeValue
ocModalValue
ocCurrent
ocNot
ocBase
ocCosHyp
ocCombinA
ocCountIfs
ocNegSub
ocEasterSunday
ocChar
ocLen
ocSkew
ocQuartile_Exc
ocDebugVar
ocRank_Avg
ocPercentile_Exc
ocTanHyp
ocIsEven
ocSqrt
ocMatrixUnit
ocChiDist
ocB
ocNetWorkdays
ocBetaDist_MS
ocForecast_ETS_PIA
ocAsc
ocCeil_MS
ocChiSqInv_MS
ocTTT
ocDiv
ocAggregate
ocSmall
ocColumns
ocConcat
ocSumIf
ocMod
ocTTest
ocCot
ocChiInv_MS
ocIRR
ocValue
ocDBCount
ocDBMax
ocArcCosHyp
ocCountIf
ocCall
ocReplaceB
ocHypGeomDist
ocFalse
ocRoundUp
ocStyle
ocTrimMean
ocGauss
ocInfo
ocNPV
ocAmpersand
ocExpDist_MS
ocPercentrank_Inc
ocChiSqDist
ocSecant
ocFInv_LT
ocIsEmpty
ocEven
ocDDB
ocWebservice
ocRSQ
ocUnichar
ocBetaInv_MS
ocUnicode
ocIsRef
ocDde
ocTrunc
ocPermut
ocIndex
ocTDist_MS
ocPearson
ocFind
ocStDev
ocAreas
ocGrowth
ocCell
ocMultiArea
ocLessEqual
ocGetYear
ocWeibull
ocConvertOOo
ocCosecantHyp
ocNone
ocOr
ocFisherInv
ocNotEqual
ocAbs
ocPoissonDist_MS
ocAddress
ocSin
ocAverageIfs
ocArcTan2
ocLeftB
ocIntercept
ocDBVarP
ocClose
ocDeg
ocPMT
ocBetaInv
ocIsNA
ocFloor
ocCumIpmt
ocMatInv
ocN
ocSumSQ
ocHypGeomDist_MS
ocRegex
ocNormDist
ocIndirect
ocHLookup
ocSubTotal
ocChiSqInv
ocGeoMean
ocFV
ocBahtText
ocRound
ocLCM
ocVarS
ocFDist_LT
ocPpmt
ocRow
ocGetActTime
ocMacro
ocQuartile
ocRandomNV
ocNominal
ocProduct
ocForecast_ETS_ADD
ocGammaLn
ocSYD
ocGetMonth
ocChiSqDist_MS
ocExp
ocNegBinomDist_MS
ocAverageA
ocCode
ocRad
ocCountEmptyCells
ocCovarianceS
ocIsNonString
ocSLN
ocRept
ocAverage
ocStDevP_MS
ocMinA
ocSkewp
ocErrorType_ODF
ocTDist_RT
ocOffset
ocFixed
ocZTest_MS
ocWeibull_MS
ocNormDist_MS
ocIfNA
ocBetaDist
ocPermutationA
ocTrim
ocEncodeURL
ocXor
ocChiInv
ocStandard
ocMinIfs_MS
ocMatTrans
ocIsString
ocForecast_ETS_PIM
ocCeil_Precise
ocPow
ocGetDate
ocPercentile_Inc
ocArcSin
ocAdd
ocSNormInv
ocStop
ocPercentrank_Exc
ocPercentrank
ocRange
ocColor
ocUpper
ocGCD
ocWeek
ocLower
ocNormInv
ocCeil_ISO
ocCeil_Math
ocUnion
ocDBVar
ocFloor_Math
ocZTest
ocSecantHyp
ocHyperLink
ocSTEYX
ocRank
ocArcTan
ocChiTest_MS
ocEqual
ocLogest
ocQuartile_Inc
ocBinomInv
ocGammaLn_MS
ocFrequency
ocTextJoin_MS
ocTan
ocModalValue_Multi
ocSearch
ocForecast_ETS_STM
ocCosecant
ocSubstitute
ocNper
ocBitOr
ocGammaInv_MS
ocFInv
ocErrorType
ocDBGet
ocSlope
ocCumPrinc
ocMatMult
ocMatDet
ocIpmt
ocTInv_MS
ocLarge
ocRRI
ocGetActDate
ocFact
ocSub
ocMIRR
ocDecimal
ocTrend
ocAverageIf
ocErf_MS
ocGetDay
ocDBMin
ocVarPA
ocReplace
ocWeeknumOOo
ocLookup
ocFilterXML
ocFInv_RT
ocBinomDist_MS
ocGreater
ocHarMean
ocFloor_MS
ocRandom
ocStdNormDist
ocConfidence_T
ocCeil
ocColRowNameAuto
ocTrue
ocLinest
ocRows
ocArcCot
ocISPMT
ocGetHour
ocCorrel
ocArcTanHyp
ocExternal
ocNegBinomVert
ocLogInv_MS
ocBitAnd
ocAnd
ocPercentile
ocInt
ocPercentSign
ocCount2
ocArcSinHyp
ocTDist
ocLogNormDist_MS
ocMatValue
ocForecast_ETS_MUL
ocSep
ocMissing
ocConfidence_N
ocRandbetweenNV
ocTInv
ocMedian
ocBinomDist
ocVarP_MS
ocFloor_Precise
ocVarP
ocDBCount2
ocLn
ocDevSq
ocForecast_LIN
ocVBD
ocIntersect
ocTInv_2T
ocStDevS
ocRoundSig
ocPlusMinus
ocNormInv_MS
ocPush
ocCotHyp
ocNumberValue
ocGreaterEqual
ocBad
ocArcCotHyp
ocForecast_ETS_SEA
ocIsError
ocFTest
ocPDuration
ocDBArea
ocRawSubtract
ocRate
ocStDevP
ocType
ocForecast_ETS_STA
ocIfError
ocFDist_RT
ocKurt
ocRightB
ocPower
ocJis
ocMid
ocSumXMY2
ocSheets
ocGetDateValue
ocConfidence
ocRoundDown
ocMatRef
ocForecast
ocMin
ocFindB
ocLenB
ocLess
ocCurrency
ocSumX2MY2
ocFourier
ocPoissonDist
ocLogInv
ocIfs_MS
ocTTest_MS
ocRight
ocNoName
ocGetSec
ocCovarianceP
ocDB
ocIsFormula
ocArcCos
ocDBProduct
ocEuroConvert
ocNeg
ocLeft
ocDBAverage
ocBitLshift
ocGetPivotData
ocFisher
ocCombin
ocMul
ocRoman
ocPV
ocMatch
ocVLookup
ocStDevA
ocGetTime
ocSumIfs
ocChiDist_MS
ocPhi
ocMaxIfs_MS
ocArabic
ocNetWorkdays_MS
ocTableOp
ocDBSum
ocChoose
ocErfc_MS
ocWorkday_MS
ocVarA
ocBitXor
ocVar
ocSwitch_MS
ocCovar
ocColumn
ocGammaDist_MS
ocGetMin
ocGetDiffDate
ocGetDateDif
ocGetDayOfWeek
ocNotAvail
ocRank_Eq
ocGamma
ocSNormInv_MS
ocOdd
ocGammaInv
ocModalValue_MS
ocDBStdDev
ocStdNormDist_MS
ocT
ocExact
ocIf
ocFTest_MS
ocBitRshift
ocIsValue
ocSumX2DY2
ocLog10
ocSheet
ocText
ocMidB
ocProb
ocGetDiffDate360
ocFormula
ocChiTest
ocTDist_2T
ocConcat_MS
ocDBStdDevP
ocIsOdd
ocIsErr
ocExpDist
ocGammaDist
ocIsoWeeknum
ocClean
ocLog
ocMaxA
ocFDist
ocStDevPA
ocLogNormDist
ocSearchB
ocIsLogical
ocSinHyp
ocEffect
ocSum
ocAveDev
ocPi
ocCount
ocCritBinom
ocProper
ocCos
ocMax
QPRO_FUNC_TYPE nType
Definition: qproform.cxx:398
sal_Int32 nHandle
void SetSbUnoObjectDfltPropName(SbxObject *pObj)
SbxObjectRef GetSbUnoObject(const OUString &aName, const Any &aUnoObj_)
SbxBOOL
SbxDataType
SbxSALINT64
SbxLONG
SbxARRAY
SbxSALUINT64
SbxUINT
SbxDECIMAL
SbxVOID
SbxULONG
SbxUSHORT
SbxDATE
SbxCURRENCY
SbxINT
SbxSINGLE
SbxINTEGER
SbxDOUBLE
sal_uIntPtr sal_uLong
Configuration options for formula interpreter.
Definition: calcconfig.hxx:44
void MergeDocumentSpecific(const ScCalcConfig &r)
Definition: calcconfig.cxx:153
Complex reference (a range) into the sheet.
Definition: refdata.hxx:123
SC_DLLPUBLIC ScRange toAbs(const ScSheetLimits &rLimits, const ScAddress &rPos) const
Definition: refdata.cxx:493
void InitRange(const ScRange &rRange)
Definition: refdata.hxx:130
void InitFlags()
Definition: refdata.hxx:128
ScSingleRefData Ref2
Definition: refdata.hxx:125
bool IsDeleted() const
Definition: refdata.cxx:580
void SetRange(const ScSheetLimits &rLimits, const ScRange &rRange, const ScAddress &rPos)
Set a new range, assuming that the ordering of the range matches the ordering of the reference data f...
Definition: refdata.cxx:498
void InitFromRefAddresses(const ScDocument &rDoc, const ScRefAddress &rRef1, const ScRefAddress &rRef2, const ScAddress &rPos)
InitFlags and set range, relative to rPos if rRef1 and rRef2 say so.
Definition: refdata.cxx:380
ScSingleRefData Ref1
Definition: refdata.hxx:124
std::vector< formula::FormulaToken * > maTokens
SvNumFormatType GetNumberFormatType(sal_uInt32 nFIndex) const
::std::vector< ScAddress > aNotifiedFormulaPos
Definition: tabopparams.hxx:36
::std::vector< ScFormulaCell * > aNotifiedFormulaCells
Definition: tabopparams.hxx:35
Try NOT to use this struct.
Definition: scmatrix.hxx:53
ScMatValType nType
Definition: scmatrix.hxx:56
FormulaError GetError() const
Only valid if ScMatrix methods indicate that this is no string!
Definition: scmatrix.hxx:62
double fVal
Definition: scmatrix.hxx:54
const svl::SharedString & GetString() const
Only valid if ScMatrix methods indicate so!
Definition: scmatrix.hxx:59
This is very similar to ScCellValue, except that it references the original value instead of copying ...
Definition: cellvalue.hxx:108
ScFormulaCell * getFormula() const
Definition: cellvalue.hxx:137
bool hasError() const
Definition: cellvalue.cxx:624
bool hasEmptyValue()
Definition: cellvalue.cxx:672
double getDouble() const
Definition: cellvalue.hxx:134
bool isEmpty() const
Definition: cellvalue.cxx:667
OUString getString(const ScDocument *pDoc) const
Retrieve string value.
Definition: cellvalue.cxx:657
bool hasNumeric() const
Definition: cellvalue.cxx:619
double getValue()
Definition: cellvalue.cxx:629
bool hasString() const
Definition: cellvalue.cxx:614
CellType getType() const
Definition: cellvalue.hxx:133
Single reference (one address) into the sheet.
Definition: refdata.hxx:30
SCCOL Col() const
Definition: refdata.cxx:247
void InitAddress(const ScAddress &rAdr)
InitAddress: InitFlags and set address.
Definition: refdata.cxx:27
bool IsDeleted() const
Definition: refdata.cxx:125
bool IsRowDeleted() const
Definition: refdata.hxx:84
SCTAB Tab() const
Definition: refdata.cxx:254
bool IsTabRel() const
Definition: refdata.hxx:69
SCROW Row() const
Definition: refdata.cxx:240
bool IsRowRel() const
Definition: refdata.hxx:67
ScAddress toAbs(const ScSheetLimits &rLimits, const ScAddress &rPos) const
Definition: refdata.cxx:193
bool IsColRel() const
Definition: refdata.hxx:65
bool IsTabDeleted() const
Definition: refdata.hxx:86
void InitFromRefAddress(const ScDocument &rDoc, const ScRefAddress &rRef, const ScAddress &rPos)
InitFlags and set address, relative to rPos if rRef says so.
Definition: refdata.cxx:49
bool IsColDeleted() const
Definition: refdata.hxx:82
bool isRangeValid() const
Definition: types.cxx:18
sal_Int32 mnRow2
Definition: types.hxx:89
sal_Int32 mnCol1
Definition: types.hxx:85
ScMatrixRef mpMat
Definition: types.hxx:84
sal_Int32 mnCol2
Definition: types.hxx:88
sal_Int32 mnTab2
Definition: types.hxx:90
sal_Int32 mnTab1
Definition: types.hxx:87
sal_Int32 mnRow1
Definition: types.hxx:86
::std::vector< ScComplexRefData > ScRefList
Definition: token.hxx:37
#define MATRIX_TOKEN_HAS_RANGE
Definition: token.hxx:33
unsigned char sal_uInt8
#define SAL_MAX_UINT16
#define SAL_MAX_INT32
#define SAL_MIN_INT16
#define SAL_MAX_INT16
#define SAL_MIN_INT32
sal_uInt16 sal_Unicode
#define SAL_MAX_UINT32
sal_Int16 SCTAB
Definition: types.hxx:22
::boost::intrusive_ptr< const ScMatrix > ScConstMatrixRef
Definition: types.hxx:26
ScMatValType
Definition: types.hxx:31
sal_Int16 SCCOL
Definition: types.hxx:21
::boost::intrusive_ptr< ScMatrix > ScMatrixRef
Definition: types.hxx:25
sal_Int32 SCROW
Definition: types.hxx:17
SvNumFormatType