LCOV - code coverage report
Current view: top level - sc/source/core/tool - interpr4.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 817 2257 36.2 %
Date: 2012-08-25 Functions: 66 93 71.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 729 3772 19.3 %

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

Generated by: LCOV version 1.10