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