LCOV - code coverage report
Current view: top level - sc/source/core/tool - interpr4.cxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 1185 2488 47.6 %
Date: 2014-11-03 Functions: 81 103 78.6 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10