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

Generated by: LCOV version 1.11