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

Generated by: LCOV version 1.10