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

Generated by: LCOV version 1.10