LCOV - code coverage report
Current view: top level - sc/source/core/tool - interpr1.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 1105 4166 26.5 %
Date: 2012-08-25 Functions: 72 175 41.1 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 887 6680 13.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 "scitems.hxx"
      30                 :            : #include <editeng/langitem.hxx>
      31                 :            : #include <editeng/justifyitem.hxx>
      32                 :            : #include <svx/algitem.hxx>
      33                 :            : #include <unotools/textsearch.hxx>
      34                 :            : #include <svl/zforlist.hxx>
      35                 :            : #include <svl/zformat.hxx>
      36                 :            : #include <tools/urlobj.hxx>
      37                 :            : #include <unotools/charclass.hxx>
      38                 :            : #include <sfx2/docfile.hxx>
      39                 :            : #include <sfx2/printer.hxx>
      40                 :            : #include <unotools/collatorwrapper.hxx>
      41                 :            : #include <unotools/transliterationwrapper.hxx>
      42                 :            : #include <rtl/ustring.hxx>
      43                 :            : #include <rtl/logfile.hxx>
      44                 :            : 
      45                 :            : #include "interpre.hxx"
      46                 :            : #include "patattr.hxx"
      47                 :            : #include "global.hxx"
      48                 :            : #include "document.hxx"
      49                 :            : #include "dociter.hxx"
      50                 :            : #include "cell.hxx"
      51                 :            : #include "scmatrix.hxx"
      52                 :            : #include "docoptio.hxx"
      53                 :            : #include "globstr.hrc"
      54                 :            : #include "attrib.hxx"
      55                 :            : #include "jumpmatrix.hxx"
      56                 :            : 
      57                 :            : #include <comphelper/processfactory.hxx>
      58                 :            : #include <comphelper/string.hxx>
      59                 :            : 
      60                 :            : #include <stdlib.h>
      61                 :            : #include <string.h>
      62                 :            : #include <math.h>
      63                 :            : #include <vector>
      64                 :            : #include <memory>
      65                 :            : #include "cellkeytranslator.hxx"
      66                 :            : #include "lookupcache.hxx"
      67                 :            : #include "rangenam.hxx"
      68                 :            : #include "rangeutl.hxx"
      69                 :            : #include "compiler.hxx"
      70                 :            : #include "externalrefmgr.hxx"
      71                 :            : #include <basic/sbstar.hxx>
      72                 :            : #include "doubleref.hxx"
      73                 :            : #include "queryparam.hxx"
      74                 :            : #include "queryentry.hxx"
      75                 :            : 
      76                 :            : static const sal_uInt64 n2power48 = SAL_CONST_UINT64( 281474976710656); // 2^48
      77                 :            : 
      78                 :         51 : IMPL_FIXEDMEMPOOL_NEWDEL( ScTokenStack )
      79                 :         51 : IMPL_FIXEDMEMPOOL_NEWDEL( ScInterpreter )
      80                 :            : 
      81                 :         51 : ScCalcConfig ScInterpreter::maGlobalConfig;
      82                 :            : ScTokenStack* ScInterpreter::pGlobalStack = NULL;
      83                 :            : bool ScInterpreter::bGlobalStackInUse = false;
      84                 :            : 
      85                 :            : using namespace formula;
      86                 :            : using ::std::auto_ptr;
      87                 :            : using ::rtl::OUString;
      88                 :            : 
      89                 :            : struct ScCompare
      90                 :            : {
      91                 :            :     double  nVal[2];
      92                 :            :     String* pVal[2];
      93                 :            :     bool    bVal[2];
      94                 :            :     bool    bEmpty[2];
      95                 :         81 :         ScCompare( String* p1, String* p2 )
      96                 :            :         {
      97                 :         81 :             pVal[ 0 ] = p1;
      98                 :         81 :             pVal[ 1 ] = p2;
      99                 :         81 :             bEmpty[0] = false;
     100                 :         81 :             bEmpty[1] = false;
     101                 :         81 :         }
     102                 :            : };
     103                 :            : 
     104                 :          0 : struct ScCompareOptions
     105                 :            : {
     106                 :            :     ScQueryEntry        aQueryEntry;
     107                 :            :     bool                bRegEx;
     108                 :            :     bool                bMatchWholeCell;
     109                 :            :     bool                bIgnoreCase;
     110                 :            : 
     111                 :            :                         ScCompareOptions( ScDocument* pDoc, const ScQueryEntry& rEntry, bool bReg );
     112                 :            : private:
     113                 :            :                         // Not implemented, prevent usage.
     114                 :            :                         ScCompareOptions();
     115                 :            :                         ScCompareOptions( const ScCompareOptions & );
     116                 :            :      ScCompareOptions&  operator=( const ScCompareOptions & );
     117                 :            : };
     118                 :            : 
     119                 :            : //-----------------------------------------------------------------------------
     120                 :            : // Functions
     121                 :            : //-----------------------------------------------------------------------------
     122                 :            : 
     123                 :            : 
     124                 :         66 : void ScInterpreter::ScIfJump()
     125                 :            : {
     126                 :            :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScIfJump" );
     127                 :         66 :     const short* pJump = pCur->GetJump();
     128                 :         66 :     short nJumpCount = pJump[ 0 ];
     129                 :         66 :     MatrixDoubleRefToMatrix();
     130         [ -  + ]:         66 :     switch ( GetStackType() )
     131                 :            :     {
     132                 :            :         case svMatrix:
     133                 :            :         {
     134         [ #  # ]:          0 :             ScMatrixRef pMat = PopMatrix();
     135         [ #  # ]:          0 :             if ( !pMat )
     136         [ #  # ]:          0 :                 PushIllegalParameter();
     137                 :            :             else
     138                 :            :             {
     139                 :          0 :                 FormulaTokenRef xNew;
     140                 :          0 :                 ScTokenMatrixMap::const_iterator aMapIter;
     141                 :            :                 // DoubleError handled by JumpMatrix
     142         [ #  # ]:          0 :                 pMat->SetErrorInterpreter( NULL);
     143                 :            :                 SCSIZE nCols, nRows;
     144         [ #  # ]:          0 :                 pMat->GetDimensions( nCols, nRows );
     145 [ #  # ][ #  # ]:          0 :                 if ( nCols == 0 || nRows == 0 )
     146         [ #  # ]:          0 :                     PushIllegalArgument();
     147   [ #  #  #  # ]:          0 :                 else if (pTokenMatrixMap && ((aMapIter = pTokenMatrixMap->find(
                 [ #  # ]
     148 [ #  # ][ #  # ]:          0 :                                     pCur)) != pTokenMatrixMap->end()))
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  #  
          #  #  #  #  #  
                #  #  # ]
     149         [ #  # ]:          0 :                     xNew = (*aMapIter).second;
     150                 :            :                 else
     151                 :            :                 {
     152 [ #  # ][ #  # ]:          0 :                     ScJumpMatrix* pJumpMat = new ScJumpMatrix( nCols, nRows );
     153         [ #  # ]:          0 :                     for ( SCSIZE nC=0; nC < nCols; ++nC )
     154                 :            :                     {
     155         [ #  # ]:          0 :                         for ( SCSIZE nR=0; nR < nRows; ++nR )
     156                 :            :                         {
     157                 :            :                             double fVal;
     158                 :            :                             bool bTrue;
     159         [ #  # ]:          0 :                             bool bIsValue = pMat->IsValue(nC, nR);
     160         [ #  # ]:          0 :                             if (bIsValue)
     161                 :            :                             {
     162         [ #  # ]:          0 :                                 fVal = pMat->GetDouble(nC, nR);
     163                 :          0 :                                 bIsValue = ::rtl::math::isFinite(fVal);
     164 [ #  # ][ #  # ]:          0 :                                 bTrue = bIsValue && (fVal != 0.0);
     165         [ #  # ]:          0 :                                 if (bTrue)
     166                 :          0 :                                     fVal = 1.0;
     167                 :            :                             }
     168                 :            :                             else
     169                 :            :                             {
     170                 :            :                                 // Treat empty and empty path as 0, but string
     171                 :            :                                 // as error.
     172 [ #  # ][ #  # ]:          0 :                                 bIsValue = (!pMat->IsString(nC, nR) || pMat->IsEmpty(nC, nR));
         [ #  # ][ #  # ]
     173                 :          0 :                                 bTrue = false;
     174         [ #  # ]:          0 :                                 fVal = (bIsValue ? 0.0 : CreateDoubleError( errNoValue));
     175                 :            :                             }
     176         [ #  # ]:          0 :                             if ( bTrue )
     177                 :            :                             {   // TRUE
     178         [ #  # ]:          0 :                                 if( nJumpCount >= 2 )
     179                 :            :                                 {   // THEN path
     180                 :            :                                     pJumpMat->SetJump( nC, nR, fVal,
     181                 :          0 :                                             pJump[ 1 ],
     182                 :          0 :                                             pJump[ nJumpCount ]);
     183                 :            :                                 }
     184                 :            :                                 else
     185                 :            :                                 {   // no parameter given for THEN
     186                 :            :                                     pJumpMat->SetJump( nC, nR, fVal,
     187                 :          0 :                                             pJump[ nJumpCount ],
     188                 :          0 :                                             pJump[ nJumpCount ]);
     189                 :            :                                 }
     190                 :            :                             }
     191                 :            :                             else
     192                 :            :                             {   // FALSE
     193 [ #  # ][ #  # ]:          0 :                                 if( nJumpCount == 3 && bIsValue )
     194                 :            :                                 {   // ELSE path
     195                 :            :                                     pJumpMat->SetJump( nC, nR, fVal,
     196                 :          0 :                                             pJump[ 2 ],
     197                 :          0 :                                             pJump[ nJumpCount ]);
     198                 :            :                                 }
     199                 :            :                                 else
     200                 :            :                                 {   // no parameter given for ELSE,
     201                 :            :                                     // or DoubleError
     202                 :            :                                     pJumpMat->SetJump( nC, nR, fVal,
     203                 :          0 :                                             pJump[ nJumpCount ],
     204                 :          0 :                                             pJump[ nJumpCount ]);
     205                 :            :                                 }
     206                 :            :                             }
     207                 :            :                         }
     208                 :            :                     }
     209 [ #  # ][ #  # ]:          0 :                     xNew = new ScJumpMatrixToken( pJumpMat );
                 [ #  # ]
     210 [ #  # ][ #  # ]:          0 :                     GetTokenMatrixMap().insert( ScTokenMatrixMap::value_type(pCur, xNew));
         [ #  # ][ #  # ]
     211                 :            :                 }
     212         [ #  # ]:          0 :                 PushTempToken( xNew.get());
     213                 :            :                 // set endpoint of path for main code line
     214 [ #  # ][ #  # ]:          0 :                 aCode.Jump( pJump[ nJumpCount ], pJump[ nJumpCount ] );
     215         [ #  # ]:          0 :             }
     216                 :            :         }
     217                 :          0 :         break;
     218                 :            :         default:
     219                 :            :         {
     220         [ +  + ]:         66 :             if ( GetBool() )
     221                 :            :             {   // TRUE
     222         [ +  + ]:         42 :                 if( nJumpCount >= 2 )
     223                 :            :                 {   // THEN path
     224                 :         24 :                     aCode.Jump( pJump[ 1 ], pJump[ nJumpCount ] );
     225                 :            :                 }
     226                 :            :                 else
     227                 :            :                 {   // no parameter given for THEN
     228                 :         18 :                     nFuncFmtType = NUMBERFORMAT_LOGICAL;
     229                 :         18 :                     PushInt(1);
     230                 :         18 :                     aCode.Jump( pJump[ nJumpCount ], pJump[ nJumpCount ] );
     231                 :            :                 }
     232                 :            :             }
     233                 :            :             else
     234                 :            :             {   // FALSE
     235         [ +  + ]:         24 :                 if( nJumpCount == 3 )
     236                 :            :                 {   // ELSE path
     237                 :         21 :                     aCode.Jump( pJump[ 2 ], pJump[ nJumpCount ] );
     238                 :            :                 }
     239                 :            :                 else
     240                 :            :                 {   // no parameter given for ELSE
     241                 :          3 :                     nFuncFmtType = NUMBERFORMAT_LOGICAL;
     242                 :          3 :                     PushInt(0);
     243                 :          3 :                     aCode.Jump( pJump[ nJumpCount ], pJump[ nJumpCount ] );
     244                 :            :                 }
     245                 :            :             }
     246                 :            :         }
     247                 :            :     }
     248                 :         66 : }
     249                 :            : 
     250                 :            : 
     251                 :          0 : void ScInterpreter::ScChoseJump()
     252                 :            : {
     253                 :            :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScChoseJump" );
     254                 :            :     // We have to set a jump, if there was none chosen because of an error set
     255                 :            :     // it to endpoint.
     256                 :          0 :     bool bHaveJump = false;
     257                 :          0 :     const short* pJump = pCur->GetJump();
     258                 :          0 :     short nJumpCount = pJump[ 0 ];
     259                 :          0 :     MatrixDoubleRefToMatrix();
     260         [ #  # ]:          0 :     switch ( GetStackType() )
     261                 :            :     {
     262                 :            :         case svMatrix:
     263                 :            :         {
     264         [ #  # ]:          0 :             ScMatrixRef pMat = PopMatrix();
     265         [ #  # ]:          0 :             if ( !pMat )
     266         [ #  # ]:          0 :                 PushIllegalParameter();
     267                 :            :             else
     268                 :            :             {
     269                 :          0 :                 FormulaTokenRef xNew;
     270                 :          0 :                 ScTokenMatrixMap::const_iterator aMapIter;
     271                 :            :                 // DoubleError handled by JumpMatrix
     272         [ #  # ]:          0 :                 pMat->SetErrorInterpreter( NULL);
     273                 :            :                 SCSIZE nCols, nRows;
     274         [ #  # ]:          0 :                 pMat->GetDimensions( nCols, nRows );
     275 [ #  # ][ #  # ]:          0 :                 if ( nCols == 0 || nRows == 0 )
     276         [ #  # ]:          0 :                     PushIllegalParameter();
     277   [ #  #  #  # ]:          0 :                 else if (pTokenMatrixMap && ((aMapIter = pTokenMatrixMap->find(
                 [ #  # ]
     278 [ #  # ][ #  # ]:          0 :                                     pCur)) != pTokenMatrixMap->end()))
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  #  
          #  #  #  #  #  
                #  #  # ]
     279         [ #  # ]:          0 :                     xNew = (*aMapIter).second;
     280                 :            :                 else
     281                 :            :                 {
     282 [ #  # ][ #  # ]:          0 :                     ScJumpMatrix* pJumpMat = new ScJumpMatrix( nCols, nRows );
     283         [ #  # ]:          0 :                     for ( SCSIZE nC=0; nC < nCols; ++nC )
     284                 :            :                     {
     285         [ #  # ]:          0 :                         for ( SCSIZE nR=0; nR < nRows; ++nR )
     286                 :            :                         {
     287                 :            :                             double fVal;
     288         [ #  # ]:          0 :                             bool bIsValue = pMat->IsValue(nC, nR);
     289         [ #  # ]:          0 :                             if ( bIsValue )
     290                 :            :                             {
     291         [ #  # ]:          0 :                                 fVal = pMat->GetDouble(nC, nR);
     292                 :          0 :                                 bIsValue = ::rtl::math::isFinite( fVal );
     293         [ #  # ]:          0 :                                 if ( bIsValue )
     294                 :            :                                 {
     295                 :          0 :                                     fVal = ::rtl::math::approxFloor( fVal);
     296 [ #  # ][ #  # ]:          0 :                                     if ( (fVal < 1) || (fVal >= nJumpCount))
     297                 :            :                                     {
     298                 :          0 :                                         bIsValue = false;
     299                 :            :                                         fVal = CreateDoubleError(
     300                 :          0 :                                                 errIllegalArgument);
     301                 :            :                                     }
     302                 :            :                                 }
     303                 :            :                             }
     304                 :            :                             else
     305                 :            :                             {
     306                 :          0 :                                 fVal = CreateDoubleError( errNoValue);
     307                 :            :                             }
     308         [ #  # ]:          0 :                             if ( bIsValue )
     309                 :            :                             {
     310                 :            :                                 pJumpMat->SetJump( nC, nR, fVal,
     311                 :          0 :                                         pJump[ (short)fVal ],
     312                 :          0 :                                         pJump[ nJumpCount ]);
     313                 :            :                             }
     314                 :            :                             else
     315                 :            :                             {
     316                 :            :                                 pJumpMat->SetJump( nC, nR, fVal,
     317                 :          0 :                                         pJump[ nJumpCount ],
     318                 :          0 :                                         pJump[ nJumpCount ]);
     319                 :            :                             }
     320                 :            :                         }
     321                 :            :                     }
     322 [ #  # ][ #  # ]:          0 :                     xNew = new ScJumpMatrixToken( pJumpMat );
                 [ #  # ]
     323         [ #  # ]:          0 :                     GetTokenMatrixMap().insert( ScTokenMatrixMap::value_type(
     324 [ #  # ][ #  # ]:          0 :                                 pCur, xNew));
                 [ #  # ]
     325                 :            :                 }
     326         [ #  # ]:          0 :                 PushTempToken( xNew.get());
     327                 :            :                 // set endpoint of path for main code line
     328         [ #  # ]:          0 :                 aCode.Jump( pJump[ nJumpCount ], pJump[ nJumpCount ] );
     329         [ #  # ]:          0 :                 bHaveJump = true;
     330         [ #  # ]:          0 :             }
     331                 :            :         }
     332                 :          0 :         break;
     333                 :            :         default:
     334                 :            :         {
     335                 :          0 :             double nJumpIndex = ::rtl::math::approxFloor( GetDouble() );
     336 [ #  # ][ #  # ]:          0 :             if (!nGlobalError && (nJumpIndex >= 1) && (nJumpIndex < nJumpCount))
                 [ #  # ]
     337                 :            :             {
     338                 :          0 :                 aCode.Jump( pJump[ (short) nJumpIndex ], pJump[ nJumpCount ] );
     339                 :          0 :                 bHaveJump = true;
     340                 :            :             }
     341                 :            :             else
     342                 :          0 :                 PushIllegalArgument();
     343                 :            :         }
     344                 :            :     }
     345         [ #  # ]:          0 :     if (!bHaveJump)
     346                 :          0 :         aCode.Jump( pJump[ nJumpCount ], pJump[ nJumpCount ] );
     347                 :          0 : }
     348                 :            : 
     349                 :          0 : void lcl_AdjustJumpMatrix( ScJumpMatrix* pJumpM, ScMatrixRef& pResMat, SCSIZE nParmCols, SCSIZE nParmRows )
     350                 :            : {
     351                 :            :     SCSIZE nJumpCols, nJumpRows;
     352                 :            :     SCSIZE nResCols, nResRows;
     353                 :            :     SCSIZE nAdjustCols, nAdjustRows;
     354                 :          0 :     pJumpM->GetDimensions( nJumpCols, nJumpRows );
     355                 :          0 :     pJumpM->GetResMatDimensions( nResCols, nResRows );
     356 [ #  # ][ #  # ]:          0 :     if (( nJumpCols == 1 && nParmCols > nResCols ) ||
         [ #  # ][ #  # ]
     357                 :            :         ( nJumpRows == 1 && nParmRows > nResRows ))
     358                 :            :     {
     359 [ #  # ][ #  # ]:          0 :         if ( nJumpCols == 1 && nJumpRows == 1 )
     360                 :            :         {
     361         [ #  # ]:          0 :             nAdjustCols = nParmCols > nResCols ? nParmCols : nResCols;
     362         [ #  # ]:          0 :             nAdjustRows = nParmRows > nResRows ? nParmRows : nResRows;
     363                 :            :         }
     364         [ #  # ]:          0 :         else if ( nJumpCols == 1 )
     365                 :            :         {
     366                 :          0 :             nAdjustCols = nParmCols;
     367                 :          0 :             nAdjustRows = nResRows;
     368                 :            :         }
     369                 :            :         else
     370                 :            :         {
     371                 :          0 :             nAdjustCols = nResCols;
     372                 :          0 :             nAdjustRows = nParmRows;
     373                 :            :         }
     374         [ #  # ]:          0 :         pJumpM->SetNewResMat( nAdjustCols, nAdjustRows );
     375 [ #  # ][ #  # ]:          0 :         pResMat = pJumpM->GetResultMatrix();
     376                 :            :     }
     377                 :          0 : }
     378                 :            : 
     379                 :          0 : bool ScInterpreter::JumpMatrix( short nStackLevel )
     380                 :            : {
     381                 :            :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::JumpMatrix" );
     382         [ #  # ]:          0 :     pJumpMatrix = static_cast<ScToken*>(pStack[sp-nStackLevel])->GetJumpMatrix();
     383         [ #  # ]:          0 :     ScMatrixRef pResMat = pJumpMatrix->GetResultMatrix();
     384                 :            :     SCSIZE nC, nR;
     385         [ #  # ]:          0 :     if ( nStackLevel == 2 )
     386                 :            :     {
     387         [ #  # ]:          0 :         if ( aCode.HasStacked() )
     388         [ #  # ]:          0 :             aCode.Pop();    // pop what Jump() pushed
     389                 :            :         else
     390                 :            :         {
     391                 :            :             OSL_FAIL( "ScInterpreter::JumpMatrix: pop goes the weasel" );
     392                 :            :         }
     393                 :            : 
     394         [ #  # ]:          0 :         if ( !pResMat )
     395                 :            :         {
     396         [ #  # ]:          0 :             Pop();
     397                 :          0 :             SetError( errUnknownStackVariable );
     398                 :            :         }
     399                 :            :         else
     400                 :            :         {
     401                 :          0 :             pJumpMatrix->GetPos( nC, nR );
     402   [ #  #  #  #  :          0 :             switch ( GetStackType() )
                #  #  # ]
                 [ #  # ]
     403                 :            :             {
     404                 :            :                 case svDouble:
     405                 :            :                 {
     406         [ #  # ]:          0 :                     double fVal = GetDouble();
     407         [ #  # ]:          0 :                     if ( nGlobalError )
     408                 :            :                     {
     409                 :          0 :                         fVal = CreateDoubleError( nGlobalError );
     410                 :          0 :                         nGlobalError = 0;
     411                 :            :                     }
     412         [ #  # ]:          0 :                     pResMat->PutDouble( fVal, nC, nR );
     413                 :            :                 }
     414                 :          0 :                 break;
     415                 :            :                 case svString:
     416                 :            :                 {
     417         [ #  # ]:          0 :                     const String& rStr = GetString();
     418         [ #  # ]:          0 :                     if ( nGlobalError )
     419                 :            :                     {
     420                 :            :                         pResMat->PutDouble( CreateDoubleError( nGlobalError),
     421         [ #  # ]:          0 :                                 nC, nR);
     422                 :          0 :                         nGlobalError = 0;
     423                 :            :                     }
     424                 :            :                     else
     425 [ #  # ][ #  # ]:          0 :                         pResMat->PutString( rStr, nC, nR );
     426                 :            :                 }
     427                 :          0 :                 break;
     428                 :            :                 case svSingleRef:
     429                 :            :                 {
     430                 :          0 :                     ScAddress aAdr;
     431         [ #  # ]:          0 :                     PopSingleRef( aAdr );
     432         [ #  # ]:          0 :                     if ( nGlobalError )
     433                 :            :                     {
     434                 :            :                         pResMat->PutDouble( CreateDoubleError( nGlobalError),
     435         [ #  # ]:          0 :                                 nC, nR);
     436                 :          0 :                         nGlobalError = 0;
     437                 :            :                     }
     438                 :            :                     else
     439                 :            :                     {
     440         [ #  # ]:          0 :                         ScBaseCell* pCell = GetCell( aAdr );
     441 [ #  # ][ #  # ]:          0 :                         if (HasCellEmptyData( pCell))
     442         [ #  # ]:          0 :                             pResMat->PutEmpty( nC, nR );
     443 [ #  # ][ #  # ]:          0 :                         else if (HasCellValueData( pCell))
     444                 :            :                         {
     445         [ #  # ]:          0 :                             double fVal = GetCellValue( aAdr, pCell);
     446         [ #  # ]:          0 :                             if ( nGlobalError )
     447                 :            :                             {
     448                 :            :                                 fVal = CreateDoubleError(
     449                 :          0 :                                         nGlobalError);
     450                 :          0 :                                 nGlobalError = 0;
     451                 :            :                             }
     452         [ #  # ]:          0 :                             pResMat->PutDouble( fVal, nC, nR );
     453                 :            :                         }
     454                 :            :                         else
     455                 :            :                         {
     456         [ #  # ]:          0 :                             String aStr;
     457         [ #  # ]:          0 :                             GetCellString( aStr, pCell );
     458         [ #  # ]:          0 :                             if ( nGlobalError )
     459                 :            :                             {
     460                 :            :                                 pResMat->PutDouble( CreateDoubleError(
     461         [ #  # ]:          0 :                                             nGlobalError), nC, nR);
     462                 :          0 :                                 nGlobalError = 0;
     463                 :            :                             }
     464                 :            :                             else
     465 [ #  # ][ #  # ]:          0 :                                 pResMat->PutString( aStr, nC, nR);
                 [ #  # ]
     466                 :            :                         }
     467                 :            :                     }
     468                 :            :                 }
     469                 :          0 :                 break;
     470                 :            :                 case svDoubleRef:
     471                 :            :                 {   // upper left plus offset within matrix
     472                 :            :                     double fVal;
     473                 :          0 :                     ScRange aRange;
     474         [ #  # ]:          0 :                     PopDoubleRef( aRange );
     475         [ #  # ]:          0 :                     if ( nGlobalError )
     476                 :            :                     {
     477                 :          0 :                         fVal = CreateDoubleError( nGlobalError );
     478                 :          0 :                         nGlobalError = 0;
     479         [ #  # ]:          0 :                         pResMat->PutDouble( fVal, nC, nR );
     480                 :            :                     }
     481                 :            :                     else
     482                 :            :                     {
     483                 :            :                         // Do not modify the original range because we use it
     484                 :            :                         // to adjust the size of the result matrix if necessary.
     485                 :          0 :                         ScAddress aAdr( aRange.aStart);
     486                 :          0 :                         sal_uLong nCol = (sal_uLong)aAdr.Col() + nC;
     487                 :          0 :                         sal_uLong nRow = (sal_uLong)aAdr.Row() + nR;
     488 [ #  # ][ #  #  :          0 :                         if ((nCol > static_cast<sal_uLong>(aRange.aEnd.Col()) &&
          #  #  #  #  #  
                      # ]
     489                 :          0 :                                     aRange.aEnd.Col() != aRange.aStart.Col())
     490                 :          0 :                                 || (nRow > static_cast<sal_uLong>(aRange.aEnd.Row()) &&
     491                 :          0 :                                     aRange.aEnd.Row() != aRange.aStart.Row()))
     492                 :            :                           {
     493                 :          0 :                             fVal = CreateDoubleError( NOTAVAILABLE );
     494         [ #  # ]:          0 :                             pResMat->PutDouble( fVal, nC, nR );
     495                 :            :                           }
     496                 :            :                           else
     497                 :            :                           {
     498                 :            :                             // Replicate column and/or row of a vector if it is
     499                 :            :                             // one. Note that this could be a range reference
     500                 :            :                             // that in fact consists of only one cell, e.g. A1:A1
     501         [ #  # ]:          0 :                             if (aRange.aEnd.Col() == aRange.aStart.Col())
     502                 :          0 :                                 nCol = aRange.aStart.Col();
     503         [ #  # ]:          0 :                             if (aRange.aEnd.Row() == aRange.aStart.Row())
     504                 :          0 :                                 nRow = aRange.aStart.Row();
     505                 :          0 :                             aAdr.SetCol( static_cast<SCCOL>(nCol) );
     506                 :          0 :                             aAdr.SetRow( static_cast<SCROW>(nRow) );
     507         [ #  # ]:          0 :                             ScBaseCell* pCell = GetCell( aAdr );
     508 [ #  # ][ #  # ]:          0 :                             if (HasCellEmptyData( pCell))
     509         [ #  # ]:          0 :                                 pResMat->PutEmpty( nC, nR );
     510 [ #  # ][ #  # ]:          0 :                             else if (HasCellValueData( pCell))
     511                 :            :                               {
     512         [ #  # ]:          0 :                                 double fCellVal = GetCellValue( aAdr, pCell);
     513         [ #  # ]:          0 :                                 if ( nGlobalError )
     514                 :            :                                 {
     515                 :            :                                     fCellVal = CreateDoubleError(
     516                 :          0 :                                             nGlobalError);
     517                 :          0 :                                     nGlobalError = 0;
     518                 :            :                                 }
     519         [ #  # ]:          0 :                                 pResMat->PutDouble( fCellVal, nC, nR );
     520                 :            :                               }
     521                 :            :                               else
     522                 :            :                             {
     523         [ #  # ]:          0 :                                 String aStr;
     524         [ #  # ]:          0 :                                 GetCellString( aStr, pCell );
     525         [ #  # ]:          0 :                                 if ( nGlobalError )
     526                 :            :                                 {
     527                 :            :                                     pResMat->PutDouble( CreateDoubleError(
     528         [ #  # ]:          0 :                                                 nGlobalError), nC, nR);
     529                 :          0 :                                     nGlobalError = 0;
     530                 :            :                                 }
     531                 :            :                                 else
     532 [ #  # ][ #  # ]:          0 :                                     pResMat->PutString( aStr, nC, nR );
                 [ #  # ]
     533                 :            :                             }
     534                 :            :                           }
     535                 :          0 :                         SCSIZE nParmCols = aRange.aEnd.Col() - aRange.aStart.Col() + 1;
     536                 :          0 :                         SCSIZE nParmRows = aRange.aEnd.Row() - aRange.aStart.Row() + 1;
     537         [ #  # ]:          0 :                         lcl_AdjustJumpMatrix( pJumpMatrix, pResMat, nParmCols, nParmRows );
     538                 :            :                     }
     539                 :            :                 }
     540                 :          0 :                 break;
     541                 :            :                 case svMatrix:
     542                 :            :                 {   // match matrix offsets
     543                 :            :                     double fVal;
     544         [ #  # ]:          0 :                     ScMatrixRef pMat = PopMatrix();
     545         [ #  # ]:          0 :                     if ( nGlobalError )
     546                 :            :                     {
     547                 :          0 :                         fVal = CreateDoubleError( nGlobalError );
     548                 :          0 :                         nGlobalError = 0;
     549         [ #  # ]:          0 :                         pResMat->PutDouble( fVal, nC, nR );
     550                 :            :                     }
     551         [ #  # ]:          0 :                     else if ( !pMat )
     552                 :            :                     {
     553                 :          0 :                         fVal = CreateDoubleError( errUnknownVariable );
     554         [ #  # ]:          0 :                         pResMat->PutDouble( fVal, nC, nR );
     555                 :            :                     }
     556                 :            :                     else
     557                 :            :                     {
     558                 :            :                         SCSIZE nCols, nRows;
     559         [ #  # ]:          0 :                         pMat->GetDimensions( nCols, nRows );
     560 [ #  # ][ #  # ]:          0 :                         if ((nCols <= nC && nCols != 1) ||
         [ #  # ][ #  # ]
     561                 :            :                             (nRows <= nR && nRows != 1))
     562                 :            :                         {
     563                 :          0 :                             fVal = CreateDoubleError( NOTAVAILABLE );
     564         [ #  # ]:          0 :                             pResMat->PutDouble( fVal, nC, nR );
     565                 :            :                         }
     566                 :            :                         else
     567                 :            :                         {
     568 [ #  # ][ #  # ]:          0 :                             if ( pMat->IsValue( nC, nR ) )
     569                 :            :                             {
     570         [ #  # ]:          0 :                                 fVal = pMat->GetDouble( nC, nR );
     571         [ #  # ]:          0 :                                 pResMat->PutDouble( fVal, nC, nR );
     572                 :            :                             }
     573 [ #  # ][ #  # ]:          0 :                             else if ( pMat->IsEmpty( nC, nR ) )
     574         [ #  # ]:          0 :                                 pResMat->PutEmpty( nC, nR );
     575                 :            :                             else
     576                 :            :                             {
     577 [ #  # ][ #  # ]:          0 :                                 const String& rStr = pMat->GetString( nC, nR );
     578 [ #  # ][ #  # ]:          0 :                                 pResMat->PutString( rStr, nC, nR );
                 [ #  # ]
     579                 :            :                             }
     580                 :            :                         }
     581         [ #  # ]:          0 :                         lcl_AdjustJumpMatrix( pJumpMatrix, pResMat, nCols, nRows );
     582         [ #  # ]:          0 :                     }
     583                 :            :                 }
     584                 :          0 :                 break;
     585                 :            :                 case svError:
     586                 :            :                 {
     587         [ #  # ]:          0 :                     PopError();
     588                 :          0 :                     double fVal = CreateDoubleError( nGlobalError);
     589                 :          0 :                     nGlobalError = 0;
     590         [ #  # ]:          0 :                     pResMat->PutDouble( fVal, nC, nR );
     591                 :            :                 }
     592                 :          0 :                 break;
     593                 :            :                 default:
     594                 :            :                 {
     595         [ #  # ]:          0 :                     Pop();
     596                 :          0 :                     double fVal = CreateDoubleError( errIllegalArgument);
     597         [ #  # ]:          0 :                     pResMat->PutDouble( fVal, nC, nR );
     598                 :            :                 }
     599                 :            :             }
     600                 :            :         }
     601                 :            :     }
     602                 :          0 :     bool bCont = pJumpMatrix->Next( nC, nR );
     603         [ #  # ]:          0 :     if ( bCont )
     604                 :            :     {
     605                 :            :         double fBool;
     606                 :            :         short nStart, nNext, nStop;
     607                 :          0 :         pJumpMatrix->GetJump( nC, nR, fBool, nStart, nNext, nStop );
     608 [ #  # ][ #  # ]:          0 :         while ( bCont && nStart == nNext )
                 [ #  # ]
     609                 :            :         {   // push all results that have no jump path
     610         [ #  # ]:          0 :             if ( pResMat )
     611                 :            :             {
     612                 :            :                 // a false without path results in an empty path value
     613         [ #  # ]:          0 :                 if ( fBool == 0.0 )
     614         [ #  # ]:          0 :                     pResMat->PutEmptyPath( nC, nR );
     615                 :            :                 else
     616         [ #  # ]:          0 :                     pResMat->PutDouble( fBool, nC, nR );
     617                 :            :             }
     618                 :          0 :             bCont = pJumpMatrix->Next( nC, nR );
     619         [ #  # ]:          0 :             if ( bCont )
     620                 :          0 :                 pJumpMatrix->GetJump( nC, nR, fBool, nStart, nNext, nStop );
     621                 :            :         }
     622 [ #  # ][ #  # ]:          0 :         if ( bCont && nStart != nNext )
     623                 :            :         {
     624                 :          0 :             const ScTokenVec* pParams = pJumpMatrix->GetJumpParameters();
     625         [ #  # ]:          0 :             if ( pParams )
     626                 :            :             {
     627   [ #  #  #  # ]:          0 :                 for ( ScTokenVec::const_iterator i = pParams->begin();
                 [ #  # ]
     628                 :          0 :                         i != pParams->end(); ++i )
     629                 :            :                 {
     630                 :            :                     // This is not the current state of the interpreter, so
     631                 :            :                     // push without error, and elements' errors are coded into
     632                 :            :                     // double.
     633 [ #  # ][ #  # ]:          0 :                     PushWithoutError( *(*i));
     634                 :            :                 }
     635                 :            :             }
     636         [ #  # ]:          0 :             aCode.Jump( nStart, nNext, nStop );
     637                 :            :         }
     638                 :            :     }
     639         [ #  # ]:          0 :     if ( !bCont )
     640                 :            :     {   // we're done with it, throw away jump matrix, keep result
     641                 :          0 :         pJumpMatrix = NULL;
     642         [ #  # ]:          0 :         Pop();
     643         [ #  # ]:          0 :         PushMatrix( pResMat );
     644                 :            :         // Remove jump matrix from map and remember result matrix in case it
     645                 :            :         // could be reused in another path of the same condition.
     646         [ #  # ]:          0 :         if (pTokenMatrixMap)
     647                 :            :         {
     648 [ #  # ][ #  # ]:          0 :             pTokenMatrixMap->erase( pCur);
     649                 :            :             pTokenMatrixMap->insert( ScTokenMatrixMap::value_type( pCur,
     650 [ #  # ][ #  # ]:          0 :                         pStack[sp-1]));
                 [ #  # ]
     651                 :            :         }
     652                 :          0 :         return true;
     653                 :            :     }
     654         [ #  # ]:          0 :     return false;
     655                 :            : }
     656                 :            : 
     657                 :            : 
     658                 :          0 : ScCompareOptions::ScCompareOptions( ScDocument* pDoc, const ScQueryEntry& rEntry, bool bReg ) :
     659                 :            :     aQueryEntry(rEntry),
     660                 :            :     bRegEx(bReg),
     661         [ #  # ]:          0 :     bMatchWholeCell(pDoc->GetDocOptions().IsMatchWholeCell()),
     662                 :          0 :     bIgnoreCase(true)
     663                 :            : {
     664 [ #  # ][ #  # ]:          0 :     bRegEx = (bRegEx && (aQueryEntry.eOp == SC_EQUAL || aQueryEntry.eOp == SC_NOT_EQUAL));
                 [ #  # ]
     665                 :            :     // Interpreter functions usually are case insensitive, except the simple
     666                 :            :     // comparison operators, for which these options aren't used. Override in
     667                 :            :     // struct if needed.
     668                 :          0 : }
     669                 :            : 
     670                 :            : 
     671                 :        201 : double ScInterpreter::CompareFunc( const ScCompare& rComp, ScCompareOptions* pOptions )
     672                 :            : {
     673                 :            :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::CompareFunc" );
     674                 :            :     // Keep DoubleError if encountered
     675                 :            :     // #i40539# if bEmpty is set, bVal/nVal are uninitialized
     676 [ +  - ][ +  + ]:        201 :     if ( !rComp.bEmpty[0] && rComp.bVal[0] && !::rtl::math::isFinite( rComp.nVal[0]))
         [ -  + ][ -  + ]
     677                 :          0 :         return rComp.nVal[0];
     678 [ +  - ][ +  + ]:        201 :     if ( !rComp.bEmpty[1] && rComp.bVal[1] && !::rtl::math::isFinite( rComp.nVal[1]))
         [ -  + ][ -  + ]
     679                 :          0 :         return rComp.nVal[1];
     680                 :            : 
     681                 :        201 :     double fRes = 0;
     682         [ -  + ]:        201 :     if ( rComp.bEmpty[ 0 ] )
     683                 :            :     {
     684         [ #  # ]:          0 :         if ( rComp.bEmpty[ 1 ] )
     685                 :            :             ;       // empty cell == empty cell, fRes 0
     686         [ #  # ]:          0 :         else if( rComp.bVal[ 1 ] )
     687                 :            :         {
     688         [ #  # ]:          0 :             if ( !::rtl::math::approxEqual( rComp.nVal[ 1 ], 0.0 ) )
     689                 :            :             {
     690         [ #  # ]:          0 :                 if ( rComp.nVal[ 1 ] < 0.0 )
     691                 :          0 :                     fRes = 1;       // empty cell > -x
     692                 :            :                 else
     693                 :          0 :                     fRes = -1;      // empty cell < x
     694                 :            :             }
     695                 :            :             // else: empty cell == 0.0
     696                 :            :         }
     697                 :            :         else
     698                 :            :         {
     699         [ #  # ]:          0 :             if ( rComp.pVal[ 1 ]->Len() )
     700                 :          0 :                 fRes = -1;      // empty cell < "..."
     701                 :            :             // else: empty cell == ""
     702                 :            :         }
     703                 :            :     }
     704         [ -  + ]:        201 :     else if ( rComp.bEmpty[ 1 ] )
     705                 :            :     {
     706         [ #  # ]:          0 :         if( rComp.bVal[ 0 ] )
     707                 :            :         {
     708         [ #  # ]:          0 :             if ( !::rtl::math::approxEqual( rComp.nVal[ 0 ], 0.0 ) )
     709                 :            :             {
     710         [ #  # ]:          0 :                 if ( rComp.nVal[ 0 ] < 0.0 )
     711                 :          0 :                     fRes = -1;      // -x < empty cell
     712                 :            :                 else
     713                 :          0 :                     fRes = 1;       // x > empty cell
     714                 :            :             }
     715                 :            :             // else: empty cell == 0.0
     716                 :            :         }
     717                 :            :         else
     718                 :            :         {
     719         [ #  # ]:          0 :             if ( rComp.pVal[ 0 ]->Len() )
     720                 :          0 :                 fRes = 1;       // "..." > empty cell
     721                 :            :             // else: "" == empty cell
     722                 :            :         }
     723                 :            :     }
     724         [ +  + ]:        201 :     else if( rComp.bVal[ 0 ] )
     725                 :            :     {
     726         [ +  + ]:        105 :         if( rComp.bVal[ 1 ] )
     727                 :            :         {
     728         [ +  + ]:         69 :             if ( !::rtl::math::approxEqual( rComp.nVal[ 0 ], rComp.nVal[ 1 ] ) )
     729                 :            :             {
     730         [ +  + ]:         48 :                 if( rComp.nVal[ 0 ] - rComp.nVal[ 1 ] < 0 )
     731                 :         12 :                     fRes = -1;
     732                 :            :                 else
     733                 :         36 :                     fRes = 1;
     734                 :            :             }
     735                 :            :         }
     736                 :            :         else
     737                 :         36 :             fRes = -1;  // number is less than string
     738                 :            :     }
     739         [ +  + ]:         96 :     else if( rComp.bVal[ 1 ] )
     740                 :         36 :         fRes = 1;   // number is less than string
     741                 :            :     else
     742                 :            :     {
     743                 :            :         // Both strings.
     744         [ -  + ]:         60 :         if (pOptions)
     745                 :            :         {
     746                 :            :             // All similar to Sctable::ValidQuery(), *rComp.pVal[1] actually
     747                 :            :             // is/must be identical to *rEntry.pStr, which is essential for
     748                 :            :             // regex to work through GetSearchTextPtr().
     749                 :          0 :             ScQueryEntry& rEntry = pOptions->aQueryEntry;
     750                 :            :             OSL_ENSURE(rEntry.GetQueryItem().maString.equals(*rComp.pVal[1]), "ScInterpreter::CompareFunc: broken options");
     751         [ #  # ]:          0 :             if (pOptions->bRegEx)
     752                 :            :             {
     753                 :          0 :                 xub_StrLen nStart = 0;
     754                 :          0 :                 xub_StrLen nStop  = rComp.pVal[0]->Len();
     755                 :            :                 bool bMatch = rEntry.GetSearchTextPtr(
     756                 :          0 :                         !pOptions->bIgnoreCase)->SearchFrwrd( *rComp.pVal[0],
     757 [ #  # ][ #  # ]:          0 :                             &nStart, &nStop);
     758 [ #  # ][ #  # ]:          0 :                 if (bMatch && pOptions->bMatchWholeCell && (nStart != 0 || nStop != rComp.pVal[0]->Len()))
         [ #  # ][ #  # ]
                 [ #  # ]
     759                 :          0 :                     bMatch = false;     // RegEx must match entire string.
     760         [ #  # ]:          0 :                 fRes = (bMatch ? 0 : 1);
     761                 :            :             }
     762 [ #  # ][ #  # ]:          0 :             else if (rEntry.eOp == SC_EQUAL || rEntry.eOp == SC_NOT_EQUAL)
     763                 :            :             {
     764                 :            :                 ::utl::TransliterationWrapper* pTransliteration =
     765                 :            :                     (pOptions->bIgnoreCase ? ScGlobal::GetpTransliteration() :
     766         [ #  # ]:          0 :                      ScGlobal::GetCaseTransliteration());
     767                 :            :                 bool bMatch;
     768         [ #  # ]:          0 :                 if (pOptions->bMatchWholeCell)
     769                 :          0 :                     bMatch = pTransliteration->isEqual( *rComp.pVal[0], *rComp.pVal[1]);
     770                 :            :                 else
     771                 :            :                 {
     772                 :            :                     String aCell( pTransliteration->transliterate(
     773                 :          0 :                                 *rComp.pVal[0], ScGlobal::eLnge, 0,
     774         [ #  # ]:          0 :                                 rComp.pVal[0]->Len(), NULL));
     775                 :            :                     String aQuer( pTransliteration->transliterate(
     776                 :          0 :                                 *rComp.pVal[1], ScGlobal::eLnge, 0,
     777         [ #  # ]:          0 :                                 rComp.pVal[1]->Len(), NULL));
     778 [ #  # ][ #  # ]:          0 :                     bMatch = (aCell.Search( aQuer ) != STRING_NOTFOUND);
                 [ #  # ]
     779                 :            :                 }
     780         [ #  # ]:          0 :                 fRes = (bMatch ? 0 : 1);
     781                 :            :             }
     782         [ #  # ]:          0 :             else if (pOptions->bIgnoreCase)
     783                 :            :                 fRes = (double) ScGlobal::GetCollator()->compareString(
     784 [ #  # ][ #  # ]:          0 :                         *rComp.pVal[ 0 ], *rComp.pVal[ 1 ] );
                 [ #  # ]
     785                 :            :             else
     786                 :            :                 fRes = (double) ScGlobal::GetCaseCollator()->compareString(
     787 [ #  # ][ #  # ]:          0 :                         *rComp.pVal[ 0 ], *rComp.pVal[ 1 ] );
                 [ #  # ]
     788                 :            :         }
     789         [ -  + ]:         60 :         else if (pDok->GetDocOptions().IsIgnoreCase())
     790                 :            :             fRes = (double) ScGlobal::GetCollator()->compareString(
     791 [ #  # ][ #  # ]:          0 :                 *rComp.pVal[ 0 ], *rComp.pVal[ 1 ] );
                 [ #  # ]
     792                 :            :         else
     793                 :            :             fRes = (double) ScGlobal::GetCaseCollator()->compareString(
     794 [ +  - ][ +  - ]:         60 :                 *rComp.pVal[ 0 ], *rComp.pVal[ 1 ] );
                 [ +  - ]
     795                 :            :     }
     796                 :        201 :     return fRes;
     797                 :            : }
     798                 :            : 
     799                 :            : 
     800                 :          9 : double ScInterpreter::Compare()
     801                 :            : {
     802                 :            :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::Compare" );
     803 [ +  - ][ +  - ]:          9 :     String aVal1, aVal2;
     804                 :          9 :     ScCompare aComp( &aVal1, &aVal2 );
     805         [ +  + ]:         27 :     for( short i = 1; i >= 0; i-- )
     806                 :            :     {
     807 [ +  - ][ -  +  :         18 :         switch ( GetRawStackType() )
             -  +  -  - ]
     808                 :            :         {
     809                 :            :             case svEmptyCell:
     810         [ #  # ]:          0 :                 Pop();
     811                 :          0 :                 aComp.bEmpty[ i ] = true;
     812                 :          0 :                 break;
     813                 :            :             case svMissing:
     814                 :            :             case svDouble:
     815         [ +  - ]:          9 :                 aComp.nVal[ i ] = GetDouble();
     816                 :          9 :                 aComp.bVal[ i ] = true;
     817                 :          9 :                 break;
     818                 :            :             case svString:
     819 [ #  # ][ #  # ]:          0 :                 *aComp.pVal[ i ] = GetString();
     820                 :          0 :                 aComp.bVal[ i ] = false;
     821                 :          0 :                 break;
     822                 :            :             case svDoubleRef :
     823                 :            :             case svSingleRef :
     824                 :            :             {
     825                 :          9 :                 ScAddress aAdr;
     826 [ +  - ][ +  - ]:          9 :                 if ( !PopDoubleRefOrSingleRef( aAdr ) )
     827                 :            :                     break;
     828         [ +  - ]:          9 :                 ScBaseCell* pCell = GetCell( aAdr );
     829 [ +  - ][ -  + ]:          9 :                 if (HasCellEmptyData( pCell))
     830                 :          0 :                     aComp.bEmpty[ i ] = true;
     831 [ +  - ][ -  + ]:          9 :                 else if (HasCellStringData( pCell))
     832                 :            :                 {
     833         [ #  # ]:          0 :                     GetCellString( *aComp.pVal[ i ], pCell);
     834                 :          0 :                     aComp.bVal[ i ] = false;
     835                 :            :                 }
     836                 :            :                 else
     837                 :            :                 {
     838         [ +  - ]:          9 :                     aComp.nVal[ i ] = GetCellValue( aAdr, pCell );
     839                 :          9 :                     aComp.bVal[ i ] = true;
     840                 :            :                 }
     841                 :            :             }
     842                 :          9 :             break;
     843                 :            :             case svExternalSingleRef:
     844                 :            :             {
     845         [ #  # ]:          0 :                 ScMatrixRef pMat = GetMatrix();
     846         [ #  # ]:          0 :                 if (!pMat)
     847                 :            :                 {
     848                 :          0 :                     SetError( errIllegalParameter);
     849                 :            :                     break;
     850                 :            :                 }
     851                 :            : 
     852                 :            :                 SCSIZE nC, nR;
     853         [ #  # ]:          0 :                 pMat->GetDimensions(nC, nR);
     854 [ #  # ][ #  # ]:          0 :                 if (!nC || !nR)
     855                 :            :                 {
     856                 :          0 :                     SetError( errIllegalParameter);
     857                 :            :                     break;
     858                 :            :                 }
     859 [ #  # ][ #  # ]:          0 :                 if (pMat->IsEmpty(0, 0))
     860                 :          0 :                     aComp.bEmpty[i] = true;
     861 [ #  # ][ #  # ]:          0 :                 else if (pMat->IsString(0, 0))
     862                 :            :                 {
     863 [ #  # ][ #  # ]:          0 :                     *aComp.pVal[i] = pMat->GetString(0, 0);
     864                 :          0 :                     aComp.bVal[i] = false;
     865                 :            :                 }
     866                 :            :                 else
     867                 :            :                 {
     868         [ #  # ]:          0 :                     aComp.nVal[i] = pMat->GetDouble(0, 0);
     869                 :          0 :                     aComp.bVal[i] = true;
     870 [ #  # ][ #  # ]:          0 :                 }
     871                 :            :             }
     872                 :          0 :             break;
     873                 :            :             case svExternalDoubleRef:
     874                 :            :                 // TODO: Find out how to handle this...
     875                 :            :             default:
     876                 :          0 :                 SetError( errIllegalParameter);
     877                 :          0 :             break;
     878                 :            :         }
     879                 :            :     }
     880         [ -  + ]:          9 :     if( nGlobalError )
     881                 :          0 :         return 0;
     882                 :          9 :     nCurFmtType = nFuncFmtType = NUMBERFORMAT_LOGICAL;
     883 [ +  - ][ +  - ]:          9 :     return CompareFunc( aComp );
                 [ +  - ]
     884                 :            : }
     885                 :            : 
     886                 :            : 
     887                 :         72 : ScMatrixRef ScInterpreter::CompareMat( ScCompareOptions* pOptions )
     888                 :            : {
     889                 :            :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::CompareMat" );
     890 [ +  - ][ +  - ]:         72 :     String aVal1, aVal2;
     891                 :         72 :     ScCompare aComp( &aVal1, &aVal2 );
     892 [ +  + ][ +  - ]:        360 :     ScMatrixRef pMat[2];
     893                 :         72 :     ScAddress aAdr;
     894         [ +  + ]:        216 :     for( short i = 1; i >= 0; i-- )
     895                 :            :     {
     896 [ +  - ][ -  -  :        144 :         switch (GetRawStackType())
             -  +  +  - ]
     897                 :            :         {
     898                 :            :             case svEmptyCell:
     899         [ #  # ]:          0 :                 Pop();
     900                 :          0 :                 aComp.bEmpty[ i ] = true;
     901                 :          0 :                 break;
     902                 :            :             case svMissing:
     903                 :            :             case svDouble:
     904         [ #  # ]:          0 :                 aComp.nVal[ i ] = GetDouble();
     905                 :          0 :                 aComp.bVal[ i ] = true;
     906                 :          0 :                 break;
     907                 :            :             case svString:
     908 [ #  # ][ #  # ]:          0 :                 *aComp.pVal[ i ] = GetString();
     909                 :          0 :                 aComp.bVal[ i ] = false;
     910                 :          0 :                 break;
     911                 :            :             case svSingleRef:
     912                 :            :             {
     913         [ +  - ]:         72 :                 PopSingleRef( aAdr );
     914         [ +  - ]:         72 :                 ScBaseCell* pCell = GetCell( aAdr );
     915 [ +  - ][ -  + ]:         72 :                 if (HasCellEmptyData( pCell))
     916                 :          0 :                     aComp.bEmpty[ i ] = true;
     917 [ +  - ][ +  + ]:         72 :                 else if (HasCellStringData( pCell))
     918                 :            :                 {
     919         [ +  - ]:         36 :                     GetCellString( *aComp.pVal[ i ], pCell);
     920                 :         36 :                     aComp.bVal[ i ] = false;
     921                 :            :                 }
     922                 :            :                 else
     923                 :            :                 {
     924         [ +  - ]:         36 :                     aComp.nVal[ i ] = GetCellValue( aAdr, pCell );
     925                 :         36 :                     aComp.bVal[ i ] = true;
     926                 :            :                 }
     927                 :            :             }
     928                 :         72 :             break;
     929                 :            :             case svDoubleRef:
     930                 :            :             case svMatrix:
     931 [ +  - ][ +  - ]:         72 :                 pMat[ i ] = GetMatrix();
                 [ +  - ]
     932         [ -  + ]:         72 :                 if ( !pMat[ i ] )
     933                 :          0 :                     SetError( errIllegalParameter);
     934                 :            :                 else
     935         [ +  - ]:         72 :                     pMat[i]->SetErrorInterpreter( NULL);
     936                 :            :                     // errors are transported as DoubleError inside matrix
     937                 :         72 :                 break;
     938                 :            :             default:
     939                 :          0 :                 SetError( errIllegalParameter);
     940                 :          0 :             break;
     941                 :            :         }
     942                 :            :     }
     943                 :         72 :     ScMatrixRef pResMat = NULL;
     944         [ +  - ]:         72 :     if( !nGlobalError )
     945                 :            :     {
     946 [ -  + ][ #  # ]:         72 :         if ( pMat[0] && pMat[1] )
                 [ -  + ]
     947                 :            :         {
     948                 :            :             SCSIZE nC0, nC1;
     949                 :            :             SCSIZE nR0, nR1;
     950         [ #  # ]:          0 :             pMat[0]->GetDimensions( nC0, nR0 );
     951         [ #  # ]:          0 :             pMat[1]->GetDimensions( nC1, nR1 );
     952                 :          0 :             SCSIZE nC = Max( nC0, nC1 );
     953                 :          0 :             SCSIZE nR = Max( nR0, nR1 );
     954 [ #  # ][ #  # ]:          0 :             pResMat = GetNewMat( nC, nR);
                 [ #  # ]
     955         [ #  # ]:          0 :             if ( !pResMat )
     956                 :          0 :                 return NULL;
     957         [ #  # ]:          0 :             for ( SCSIZE j=0; j<nC; j++ )
     958                 :            :             {
     959         [ #  # ]:          0 :                 for ( SCSIZE k=0; k<nR; k++ )
     960                 :            :                 {
     961                 :          0 :                     SCSIZE nCol = j, nRow = k;
     962 [ #  # ][ #  # ]:          0 :                     if (    pMat[0]->ValidColRowOrReplicated( nCol, nRow ) &&
         [ #  # ][ #  # ]
     963         [ #  # ]:          0 :                             pMat[1]->ValidColRowOrReplicated( nCol, nRow ))
     964                 :            :                     {
     965         [ #  # ]:          0 :                         for ( short i=1; i>=0; i-- )
     966                 :            :                         {
     967 [ #  # ][ #  # ]:          0 :                             if ( pMat[i]->IsString(j,k) )
     968                 :            :                             {
     969                 :          0 :                                 aComp.bVal[i] = false;
     970 [ #  # ][ #  # ]:          0 :                                 *aComp.pVal[i] = pMat[i]->GetString(j,k);
     971         [ #  # ]:          0 :                                 aComp.bEmpty[i] = pMat[i]->IsEmpty(j,k);
     972                 :            :                             }
     973                 :            :                             else
     974                 :            :                             {
     975                 :          0 :                                 aComp.bVal[i] = true;
     976         [ #  # ]:          0 :                                 aComp.nVal[i] = pMat[i]->GetDouble(j,k);
     977                 :          0 :                                 aComp.bEmpty[i] = false;
     978                 :            :                             }
     979                 :            :                         }
     980 [ #  # ][ #  # ]:          0 :                         pResMat->PutDouble( CompareFunc( aComp, pOptions ), j,k );
     981                 :            :                     }
     982                 :            :                     else
     983 [ #  # ][ #  # ]:          0 :                         pResMat->PutString( ScGlobal::GetRscString(STR_NO_VALUE), j,k );
                 [ #  # ]
     984                 :            :                 }
     985                 :            :             }
     986                 :            :         }
     987 [ +  - ][ +  - ]:         72 :         else if ( pMat[0] || pMat[1] )
                 [ +  - ]
     988                 :            :         {
     989                 :         72 :             short i = ( pMat[0] ? 0 : 1);
     990                 :            :             SCSIZE nC, nR;
     991         [ +  - ]:         72 :             pMat[i]->GetDimensions( nC, nR );
     992 [ +  - ][ +  - ]:         72 :             pResMat = GetNewMat( nC, nR);
                 [ +  - ]
     993         [ -  + ]:         72 :             if ( !pResMat )
     994                 :          0 :                 return NULL;
     995                 :            : 
     996         [ +  + ]:        144 :             for (SCSIZE j = 0; j < nC; ++j)
     997                 :            :             {
     998         [ +  + ]:        264 :                 for (SCSIZE k = 0; k < nR; ++k)
     999                 :            :                 {
    1000 [ +  - ][ +  + ]:        192 :                     if ( pMat[i]->IsValue(j,k) )
    1001                 :            :                     {
    1002                 :         96 :                         aComp.bVal[i] = true;
    1003         [ +  - ]:         96 :                         aComp.nVal[i] = pMat[i]->GetDouble(j,k);
    1004                 :         96 :                         aComp.bEmpty[i] = false;
    1005                 :            :                     }
    1006                 :            :                     else
    1007                 :            :                     {
    1008                 :         96 :                         aComp.bVal[i] = false;
    1009 [ +  - ][ +  - ]:         96 :                         *aComp.pVal[i] = pMat[i]->GetString(j,k);
    1010         [ +  - ]:         96 :                         aComp.bEmpty[i] = pMat[i]->IsEmpty(j,k);
    1011                 :            :                     }
    1012 [ +  - ][ +  - ]:        192 :                     pResMat->PutDouble( CompareFunc(aComp, pOptions), j, k);
    1013                 :            :                 }
    1014                 :            :             }
    1015                 :            :         }
    1016                 :            :     }
    1017                 :         72 :     nCurFmtType = nFuncFmtType = NUMBERFORMAT_LOGICAL;
    1018 [ +  - ][ +  + ]:        216 :     return pResMat;
         [ +  - ][ +  - ]
                 [ #  # ]
    1019                 :            : }
    1020                 :            : 
    1021                 :            : 
    1022                 :          0 : ScMatrixRef ScInterpreter::QueryMat( const ScMatrixRef& pMat, ScCompareOptions& rOptions )
    1023                 :            : {
    1024                 :          0 :     short nSaveCurFmtType = nCurFmtType;
    1025                 :          0 :     short nSaveFuncFmtType = nFuncFmtType;
    1026                 :          0 :     PushMatrix( pMat);
    1027                 :          0 :     const ScQueryEntry::Item& rItem = rOptions.aQueryEntry.GetQueryItem();
    1028         [ #  # ]:          0 :     if (rItem.meType == ScQueryEntry::ByString)
    1029         [ #  # ]:          0 :         PushString(rItem.maString);
    1030                 :            :     else
    1031                 :          0 :         PushDouble(rItem.mfVal);
    1032                 :          0 :     ScMatrixRef pResultMatrix = CompareMat( &rOptions);
    1033                 :          0 :     nCurFmtType = nSaveCurFmtType;
    1034                 :          0 :     nFuncFmtType = nSaveFuncFmtType;
    1035 [ #  # ][ #  # ]:          0 :     if (nGlobalError || !pResultMatrix)
                 [ #  # ]
    1036                 :            :     {
    1037                 :          0 :         SetError( errIllegalParameter);
    1038                 :          0 :         return pResultMatrix;
    1039                 :            :     }
    1040                 :            : 
    1041   [ #  #  #  #  :          0 :     switch (rOptions.aQueryEntry.eOp)
                #  #  # ]
    1042                 :            :     {
    1043                 :            :         case SC_EQUAL:
    1044         [ #  # ]:          0 :             pResultMatrix->CompareEqual();
    1045                 :          0 :             break;
    1046                 :            :         case SC_LESS:
    1047         [ #  # ]:          0 :             pResultMatrix->CompareLess();
    1048                 :          0 :             break;
    1049                 :            :         case SC_GREATER:
    1050         [ #  # ]:          0 :             pResultMatrix->CompareGreater();
    1051                 :          0 :             break;
    1052                 :            :         case SC_LESS_EQUAL:
    1053         [ #  # ]:          0 :             pResultMatrix->CompareLessEqual();
    1054                 :          0 :             break;
    1055                 :            :         case SC_GREATER_EQUAL:
    1056         [ #  # ]:          0 :             pResultMatrix->CompareGreaterEqual();
    1057                 :          0 :             break;
    1058                 :            :         case SC_NOT_EQUAL:
    1059         [ #  # ]:          0 :             pResultMatrix->CompareNotEqual();
    1060                 :          0 :             break;
    1061                 :            :         default:
    1062                 :          0 :             SetError( errIllegalArgument);
    1063                 :            :             OSL_TRACE( "ScInterpreter::QueryMat: unhandled comparison operator: %d", (int)rOptions.aQueryEntry.eOp);
    1064                 :            :     }
    1065                 :          0 :     return pResultMatrix;
    1066                 :            : }
    1067                 :            : 
    1068                 :            : 
    1069                 :         72 : void ScInterpreter::ScEqual()
    1070                 :            : {
    1071                 :            :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScEqual" );
    1072 [ -  + ][ #  # ]:         72 :     if ( GetStackType(1) == svMatrix || GetStackType(2) == svMatrix )
                 [ +  - ]
    1073                 :            :     {
    1074         [ +  - ]:         72 :         ScMatrixRef pMat = CompareMat();
    1075         [ -  + ]:         72 :         if ( !pMat )
    1076         [ #  # ]:          0 :             PushIllegalParameter();
    1077                 :            :         else
    1078                 :            :         {
    1079         [ +  - ]:         72 :             pMat->CompareEqual();
    1080         [ +  - ]:         72 :             PushMatrix( pMat );
    1081         [ +  - ]:         72 :         }
    1082                 :            :     }
    1083                 :            :     else
    1084                 :          0 :         PushInt( Compare() == 0 );
    1085                 :         72 : }
    1086                 :            : 
    1087                 :            : 
    1088                 :          0 : void ScInterpreter::ScNotEqual()
    1089                 :            : {
    1090                 :            :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScNotEqual" );
    1091 [ #  # ][ #  # ]:          0 :     if ( GetStackType(1) == svMatrix || GetStackType(2) == svMatrix )
                 [ #  # ]
    1092                 :            :     {
    1093         [ #  # ]:          0 :         ScMatrixRef pMat = CompareMat();
    1094         [ #  # ]:          0 :         if ( !pMat )
    1095         [ #  # ]:          0 :             PushIllegalParameter();
    1096                 :            :         else
    1097                 :            :         {
    1098         [ #  # ]:          0 :             pMat->CompareNotEqual();
    1099         [ #  # ]:          0 :             PushMatrix( pMat );
    1100         [ #  # ]:          0 :         }
    1101                 :            :     }
    1102                 :            :     else
    1103                 :          0 :         PushInt( Compare() != 0 );
    1104                 :          0 : }
    1105                 :            : 
    1106                 :            : 
    1107                 :          0 : void ScInterpreter::ScLess()
    1108                 :            : {
    1109                 :            :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScLess" );
    1110 [ #  # ][ #  # ]:          0 :     if ( GetStackType(1) == svMatrix || GetStackType(2) == svMatrix )
                 [ #  # ]
    1111                 :            :     {
    1112         [ #  # ]:          0 :         ScMatrixRef pMat = CompareMat();
    1113         [ #  # ]:          0 :         if ( !pMat )
    1114         [ #  # ]:          0 :             PushIllegalParameter();
    1115                 :            :         else
    1116                 :            :         {
    1117         [ #  # ]:          0 :             pMat->CompareLess();
    1118         [ #  # ]:          0 :             PushMatrix( pMat );
    1119         [ #  # ]:          0 :         }
    1120                 :            :     }
    1121                 :            :     else
    1122                 :          0 :         PushInt( Compare() < 0 );
    1123                 :          0 : }
    1124                 :            : 
    1125                 :            : 
    1126                 :          9 : void ScInterpreter::ScGreater()
    1127                 :            : {
    1128                 :            :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScGreater" );
    1129 [ +  - ][ -  + ]:          9 :     if ( GetStackType(1) == svMatrix || GetStackType(2) == svMatrix )
                 [ -  + ]
    1130                 :            :     {
    1131         [ #  # ]:          0 :         ScMatrixRef pMat = CompareMat();
    1132         [ #  # ]:          0 :         if ( !pMat )
    1133         [ #  # ]:          0 :             PushIllegalParameter();
    1134                 :            :         else
    1135                 :            :         {
    1136         [ #  # ]:          0 :             pMat->CompareGreater();
    1137         [ #  # ]:          0 :             PushMatrix( pMat );
    1138         [ #  # ]:          0 :         }
    1139                 :            :     }
    1140                 :            :     else
    1141                 :          9 :         PushInt( Compare() > 0 );
    1142                 :          9 : }
    1143                 :            : 
    1144                 :            : 
    1145                 :          0 : void ScInterpreter::ScLessEqual()
    1146                 :            : {
    1147                 :            :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScLessEqual" );
    1148 [ #  # ][ #  # ]:          0 :     if ( GetStackType(1) == svMatrix || GetStackType(2) == svMatrix )
                 [ #  # ]
    1149                 :            :     {
    1150         [ #  # ]:          0 :         ScMatrixRef pMat = CompareMat();
    1151         [ #  # ]:          0 :         if ( !pMat )
    1152         [ #  # ]:          0 :             PushIllegalParameter();
    1153                 :            :         else
    1154                 :            :         {
    1155         [ #  # ]:          0 :             pMat->CompareLessEqual();
    1156         [ #  # ]:          0 :             PushMatrix( pMat );
    1157         [ #  # ]:          0 :         }
    1158                 :            :     }
    1159                 :            :     else
    1160                 :          0 :         PushInt( Compare() <= 0 );
    1161                 :          0 : }
    1162                 :            : 
    1163                 :            : 
    1164                 :          0 : void ScInterpreter::ScGreaterEqual()
    1165                 :            : {
    1166                 :            :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScGreaterEqual" );
    1167 [ #  # ][ #  # ]:          0 :     if ( GetStackType(1) == svMatrix || GetStackType(2) == svMatrix )
                 [ #  # ]
    1168                 :            :     {
    1169         [ #  # ]:          0 :         ScMatrixRef pMat = CompareMat();
    1170         [ #  # ]:          0 :         if ( !pMat )
    1171         [ #  # ]:          0 :             PushIllegalParameter();
    1172                 :            :         else
    1173                 :            :         {
    1174         [ #  # ]:          0 :             pMat->CompareGreaterEqual();
    1175         [ #  # ]:          0 :             PushMatrix( pMat );
    1176         [ #  # ]:          0 :         }
    1177                 :            :     }
    1178                 :            :     else
    1179                 :          0 :         PushInt( Compare() >= 0 );
    1180                 :          0 : }
    1181                 :            : 
    1182                 :            : 
    1183                 :         27 : void ScInterpreter::ScAnd()
    1184                 :            : {
    1185                 :            :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScAnd" );
    1186                 :         27 :     nFuncFmtType = NUMBERFORMAT_LOGICAL;
    1187                 :         27 :     short nParamCount = GetByte();
    1188 [ +  - ][ +  - ]:         27 :     if ( MustHaveParamCountMin( nParamCount, 1 ) )
    1189                 :            :     {
    1190                 :         27 :         bool bHaveValue = false;
    1191                 :         27 :         short nRes = true;
    1192                 :         27 :         size_t nRefInList = 0;
    1193         [ +  + ]:         90 :         while( nParamCount-- > 0)
    1194                 :            :         {
    1195         [ +  - ]:         63 :             if ( !nGlobalError )
    1196                 :            :             {
    1197 [ +  - ][ +  -  :         63 :                 switch ( GetStackType() )
             -  -  +  - ]
    1198                 :            :                 {
    1199                 :            :                     case svDouble :
    1200                 :         39 :                         bHaveValue = true;
    1201         [ +  - ]:         39 :                         nRes &= ( PopDouble() != 0.0 );
    1202                 :         39 :                     break;
    1203                 :            :                     case svString :
    1204         [ #  # ]:          0 :                         Pop();
    1205                 :          0 :                         SetError( errNoValue );
    1206                 :          0 :                     break;
    1207                 :            :                     case svSingleRef :
    1208                 :            :                     {
    1209                 :          0 :                         ScAddress aAdr;
    1210         [ #  # ]:          0 :                         PopSingleRef( aAdr );
    1211         [ #  # ]:          0 :                         if ( !nGlobalError )
    1212                 :            :                         {
    1213         [ #  # ]:          0 :                             ScBaseCell* pCell = GetCell( aAdr );
    1214 [ #  # ][ #  # ]:          0 :                             if ( HasCellValueData( pCell ) )
    1215                 :            :                             {
    1216                 :          0 :                                 bHaveValue = true;
    1217         [ #  # ]:          0 :                                 nRes &= ( GetCellValue( aAdr, pCell ) != 0.0 );
    1218                 :            :                             }
    1219                 :            :                             // else: Xcl raises no error here
    1220                 :            :                         }
    1221                 :            :                     }
    1222                 :          0 :                     break;
    1223                 :            :                     case svDoubleRef:
    1224                 :            :                     case svRefList:
    1225                 :            :                     {
    1226                 :          0 :                         ScRange aRange;
    1227         [ #  # ]:          0 :                         PopDoubleRef( aRange, nParamCount, nRefInList);
    1228         [ #  # ]:          0 :                         if ( !nGlobalError )
    1229                 :            :                         {
    1230                 :            :                             double fVal;
    1231                 :          0 :                             sal_uInt16 nErr = 0;
    1232         [ #  # ]:          0 :                             ScValueIterator aValIter( pDok, aRange );
    1233 [ #  # ][ #  # ]:          0 :                             if ( aValIter.GetFirst( fVal, nErr ) )
    1234                 :            :                             {
    1235                 :          0 :                                 bHaveValue = true;
    1236 [ #  # ][ #  # ]:          0 :                                 do
                 [ #  # ]
    1237                 :            :                                 {
    1238                 :          0 :                                     nRes &= ( fVal != 0.0 );
    1239                 :            :                                 } while ( (nErr == 0) &&
    1240         [ #  # ]:          0 :                                     aValIter.GetNext( fVal, nErr ) );
    1241                 :            :                             }
    1242                 :          0 :                             SetError( nErr );
    1243                 :            :                         }
    1244                 :            :                     }
    1245                 :          0 :                     break;
    1246                 :            :                     case svExternalSingleRef:
    1247                 :            :                     case svExternalDoubleRef:
    1248                 :            :                     case svMatrix:
    1249                 :            :                     {
    1250         [ +  - ]:         24 :                         ScMatrixRef pMat = GetMatrix();
    1251         [ +  - ]:         24 :                         if ( pMat )
    1252                 :            :                         {
    1253                 :         24 :                             bHaveValue = true;
    1254         [ +  - ]:         24 :                             double fVal = pMat->And();
    1255                 :         24 :                             sal_uInt16 nErr = GetDoubleErrorValue( fVal );
    1256         [ -  + ]:         24 :                             if ( nErr )
    1257                 :            :                             {
    1258                 :          0 :                                 SetError( nErr );
    1259                 :          0 :                                 nRes = false;
    1260                 :            :                             }
    1261                 :            :                             else
    1262                 :         24 :                                 nRes &= (fVal != 0.0);
    1263         [ +  - ]:         24 :                         }
    1264                 :            :                         // else: GetMatrix did set errIllegalParameter
    1265                 :            :                     }
    1266                 :         24 :                     break;
    1267                 :            :                     default:
    1268         [ #  # ]:          0 :                         Pop();
    1269                 :         63 :                         SetError( errIllegalParameter);
    1270                 :            :                 }
    1271                 :            :             }
    1272                 :            :             else
    1273         [ #  # ]:          0 :                 Pop();
    1274                 :            :         }
    1275         [ +  - ]:         27 :         if ( bHaveValue )
    1276         [ +  - ]:         27 :             PushInt( nRes );
    1277                 :            :         else
    1278         [ #  # ]:         27 :             PushNoValue();
    1279                 :            :     }
    1280                 :         27 : }
    1281                 :            : 
    1282                 :            : 
    1283                 :         39 : void ScInterpreter::ScOr()
    1284                 :            : {
    1285                 :            :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScOr" );
    1286                 :         39 :     nFuncFmtType = NUMBERFORMAT_LOGICAL;
    1287                 :         39 :     short nParamCount = GetByte();
    1288 [ +  - ][ +  - ]:         39 :     if ( MustHaveParamCountMin( nParamCount, 1 ) )
    1289                 :            :     {
    1290                 :         39 :         bool bHaveValue = false;
    1291                 :         39 :         short nRes = false;
    1292                 :         39 :         size_t nRefInList = 0;
    1293         [ +  + ]:        123 :         while( nParamCount-- > 0)
    1294                 :            :         {
    1295         [ +  - ]:         84 :             if ( !nGlobalError )
    1296                 :            :             {
    1297 [ +  - ][ +  -  :         84 :                 switch ( GetStackType() )
             -  -  +  - ]
    1298                 :            :                 {
    1299                 :            :                     case svDouble :
    1300                 :         36 :                         bHaveValue = true;
    1301         [ +  - ]:         36 :                         nRes |= ( PopDouble() != 0.0 );
    1302                 :         36 :                     break;
    1303                 :            :                     case svString :
    1304         [ #  # ]:          0 :                         Pop();
    1305                 :          0 :                         SetError( errNoValue );
    1306                 :          0 :                     break;
    1307                 :            :                     case svSingleRef :
    1308                 :            :                     {
    1309                 :          0 :                         ScAddress aAdr;
    1310         [ #  # ]:          0 :                         PopSingleRef( aAdr );
    1311         [ #  # ]:          0 :                         if ( !nGlobalError )
    1312                 :            :                         {
    1313         [ #  # ]:          0 :                             ScBaseCell* pCell = GetCell( aAdr );
    1314 [ #  # ][ #  # ]:          0 :                             if ( HasCellValueData( pCell ) )
    1315                 :            :                             {
    1316                 :          0 :                                 bHaveValue = true;
    1317         [ #  # ]:          0 :                                 nRes |= ( GetCellValue( aAdr, pCell ) != 0.0 );
    1318                 :            :                             }
    1319                 :            :                             // else: Xcl raises no error here
    1320                 :            :                         }
    1321                 :            :                     }
    1322                 :          0 :                     break;
    1323                 :            :                     case svDoubleRef:
    1324                 :            :                     case svRefList:
    1325                 :            :                     {
    1326                 :          0 :                         ScRange aRange;
    1327         [ #  # ]:          0 :                         PopDoubleRef( aRange, nParamCount, nRefInList);
    1328         [ #  # ]:          0 :                         if ( !nGlobalError )
    1329                 :            :                         {
    1330                 :            :                             double fVal;
    1331                 :          0 :                             sal_uInt16 nErr = 0;
    1332         [ #  # ]:          0 :                             ScValueIterator aValIter( pDok, aRange );
    1333 [ #  # ][ #  # ]:          0 :                             if ( aValIter.GetFirst( fVal, nErr ) )
    1334                 :            :                             {
    1335                 :          0 :                                 bHaveValue = true;
    1336 [ #  # ][ #  # ]:          0 :                                 do
                 [ #  # ]
    1337                 :            :                                 {
    1338                 :          0 :                                     nRes |= ( fVal != 0.0 );
    1339                 :            :                                 } while ( (nErr == 0) &&
    1340         [ #  # ]:          0 :                                     aValIter.GetNext( fVal, nErr ) );
    1341                 :            :                             }
    1342                 :          0 :                             SetError( nErr );
    1343                 :            :                         }
    1344                 :            :                     }
    1345                 :          0 :                     break;
    1346                 :            :                     case svExternalSingleRef:
    1347                 :            :                     case svExternalDoubleRef:
    1348                 :            :                     case svMatrix:
    1349                 :            :                     {
    1350                 :         48 :                         bHaveValue = true;
    1351         [ +  - ]:         48 :                         ScMatrixRef pMat = GetMatrix();
    1352         [ +  - ]:         48 :                         if ( pMat )
    1353                 :            :                         {
    1354                 :         48 :                             bHaveValue = true;
    1355         [ +  - ]:         48 :                             double fVal = pMat->Or();
    1356                 :         48 :                             sal_uInt16 nErr = GetDoubleErrorValue( fVal );
    1357         [ -  + ]:         48 :                             if ( nErr )
    1358                 :            :                             {
    1359                 :          0 :                                 SetError( nErr );
    1360                 :          0 :                                 nRes = false;
    1361                 :            :                             }
    1362                 :            :                             else
    1363                 :         48 :                                 nRes |= (fVal != 0.0);
    1364         [ +  - ]:         48 :                         }
    1365                 :            :                         // else: GetMatrix did set errIllegalParameter
    1366                 :            :                     }
    1367                 :         48 :                     break;
    1368                 :            :                     default:
    1369         [ #  # ]:          0 :                         Pop();
    1370                 :         84 :                         SetError( errIllegalParameter);
    1371                 :            :                 }
    1372                 :            :             }
    1373                 :            :             else
    1374         [ #  # ]:          0 :                 Pop();
    1375                 :            :         }
    1376         [ +  - ]:         39 :         if ( bHaveValue )
    1377         [ +  - ]:         39 :             PushInt( nRes );
    1378                 :            :         else
    1379         [ #  # ]:         39 :             PushNoValue();
    1380                 :            :     }
    1381                 :         39 : }
    1382                 :            : 
    1383                 :            : 
    1384                 :          0 : void ScInterpreter::ScXor()
    1385                 :            : {
    1386                 :            :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScXor" );
    1387                 :            : 
    1388                 :          0 :     nFuncFmtType = NUMBERFORMAT_LOGICAL;
    1389                 :          0 :     short nParamCount = GetByte();
    1390 [ #  # ][ #  # ]:          0 :     if ( MustHaveParamCountMin( nParamCount, 1 ) )
    1391                 :            :     {
    1392                 :          0 :         bool bHaveValue = false;
    1393                 :          0 :         short nRes = false;
    1394                 :          0 :         size_t nRefInList = 0;
    1395         [ #  # ]:          0 :         while( nParamCount-- > 0)
    1396                 :            :         {
    1397         [ #  # ]:          0 :             if ( !nGlobalError )
    1398                 :            :             {
    1399 [ #  # ][ #  #  :          0 :                 switch ( GetStackType() )
             #  #  #  # ]
    1400                 :            :                 {
    1401                 :            :                     case svDouble :
    1402                 :          0 :                         bHaveValue = true;
    1403         [ #  # ]:          0 :                         nRes ^= ( PopDouble() != 0.0 );
    1404                 :          0 :                     break;
    1405                 :            :                     case svString :
    1406         [ #  # ]:          0 :                         Pop();
    1407                 :          0 :                         SetError( errNoValue );
    1408                 :          0 :                     break;
    1409                 :            :                     case svSingleRef :
    1410                 :            :                     {
    1411                 :          0 :                         ScAddress aAdr;
    1412         [ #  # ]:          0 :                         PopSingleRef( aAdr );
    1413         [ #  # ]:          0 :                         if ( !nGlobalError )
    1414                 :            :                         {
    1415         [ #  # ]:          0 :                             ScBaseCell* pCell = GetCell( aAdr );
    1416 [ #  # ][ #  # ]:          0 :                             if ( HasCellValueData( pCell ) )
    1417                 :            :                             {
    1418                 :          0 :                                 bHaveValue = true;
    1419         [ #  # ]:          0 :                                 nRes ^= ( GetCellValue( aAdr, pCell ) != 0.0 );
    1420                 :            :                             }
    1421                 :            :                             // else: Xcl raises no error here
    1422                 :            :                         }
    1423                 :            :                     }
    1424                 :          0 :                     break;
    1425                 :            :                     case svDoubleRef:
    1426                 :            :                     case svRefList:
    1427                 :            :                     {
    1428                 :          0 :                         ScRange aRange;
    1429         [ #  # ]:          0 :                         PopDoubleRef( aRange, nParamCount, nRefInList);
    1430         [ #  # ]:          0 :                         if ( !nGlobalError )
    1431                 :            :                         {
    1432                 :            :                             double fVal;
    1433                 :          0 :                             sal_uInt16 nErr = 0;
    1434         [ #  # ]:          0 :                             ScValueIterator aValIter( pDok, aRange );
    1435 [ #  # ][ #  # ]:          0 :                             if ( aValIter.GetFirst( fVal, nErr ) )
    1436                 :            :                             {
    1437                 :          0 :                                 bHaveValue = true;
    1438 [ #  # ][ #  # ]:          0 :                                 do
                 [ #  # ]
    1439                 :            :                                 {
    1440                 :          0 :                                     nRes ^= ( fVal != 0.0 );
    1441                 :            :                                 } while ( (nErr == 0) &&
    1442         [ #  # ]:          0 :                                     aValIter.GetNext( fVal, nErr ) );
    1443                 :            :                             }
    1444                 :          0 :                             SetError( nErr );
    1445                 :            :                         }
    1446                 :            :                     }
    1447                 :          0 :                     break;
    1448                 :            :                     case svExternalSingleRef:
    1449                 :            :                     case svExternalDoubleRef:
    1450                 :            :                     case svMatrix:
    1451                 :            :                     {
    1452                 :          0 :                         bHaveValue = true;
    1453         [ #  # ]:          0 :                         ScMatrixRef pMat = GetMatrix();
    1454         [ #  # ]:          0 :                         if ( pMat )
    1455                 :            :                         {
    1456                 :          0 :                             bHaveValue = true;
    1457         [ #  # ]:          0 :                             double fVal = pMat->Or();
    1458                 :          0 :                             sal_uInt16 nErr = GetDoubleErrorValue( fVal );
    1459         [ #  # ]:          0 :                             if ( nErr )
    1460                 :            :                             {
    1461                 :          0 :                                 SetError( nErr );
    1462                 :            :                             }
    1463                 :            :                             else
    1464                 :          0 :                                 nRes ^= ( fVal != 0.0 );
    1465         [ #  # ]:          0 :                         }
    1466                 :            :                         // else: GetMatrix did set errIllegalParameter
    1467                 :            :                     }
    1468                 :          0 :                     break;
    1469                 :            :                     default:
    1470         [ #  # ]:          0 :                         Pop();
    1471                 :          0 :                         SetError( errIllegalParameter);
    1472                 :            :                 }
    1473                 :            :             }
    1474                 :            :             else
    1475         [ #  # ]:          0 :                 Pop();
    1476                 :            :         }
    1477         [ #  # ]:          0 :         if ( bHaveValue )
    1478         [ #  # ]:          0 :             PushInt( nRes );
    1479                 :            :         else
    1480         [ #  # ]:          0 :             PushNoValue();
    1481                 :            :     }
    1482                 :          0 : }
    1483                 :            : 
    1484                 :            : 
    1485                 :        133 : void ScInterpreter::ScNeg()
    1486                 :            : {
    1487                 :            :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScNeg" );
    1488                 :            :     // Simple negation doesn't change current format type to number, keep
    1489                 :            :     // current type.
    1490                 :        133 :     nFuncFmtType = nCurFmtType;
    1491         [ -  + ]:        133 :     switch ( GetStackType() )
    1492                 :            :     {
    1493                 :            :         case svMatrix :
    1494                 :            :         {
    1495         [ #  # ]:          0 :             ScMatrixRef pMat = GetMatrix();
    1496         [ #  # ]:          0 :             if ( !pMat )
    1497         [ #  # ]:          0 :                 PushIllegalParameter();
    1498                 :            :             else
    1499                 :            :             {
    1500                 :            :                 SCSIZE nC, nR;
    1501         [ #  # ]:          0 :                 pMat->GetDimensions( nC, nR );
    1502         [ #  # ]:          0 :                 ScMatrixRef pResMat = GetNewMat( nC, nR);
    1503         [ #  # ]:          0 :                 if ( !pResMat )
    1504         [ #  # ]:          0 :                     PushIllegalArgument();
    1505                 :            :                 else
    1506                 :            :                 {
    1507         [ #  # ]:          0 :                     for (SCSIZE i = 0; i < nC; ++i)
    1508                 :            :                     {
    1509         [ #  # ]:          0 :                         for (SCSIZE j = 0; j < nR; ++j)
    1510                 :            :                         {
    1511 [ #  # ][ #  # ]:          0 :                             if ( pMat->IsValueOrEmpty(i,j) )
    1512 [ #  # ][ #  # ]:          0 :                                 pResMat->PutDouble( -pMat->GetDouble(i,j), i, j );
    1513                 :            :                             else
    1514                 :            :                                 pResMat->PutString(
    1515 [ #  # ][ #  # ]:          0 :                                     ScGlobal::GetRscString( STR_NO_VALUE ), i, j );
                 [ #  # ]
    1516                 :            :                         }
    1517                 :            :                     }
    1518         [ #  # ]:          0 :                     PushMatrix( pResMat );
    1519         [ #  # ]:          0 :                 }
    1520         [ #  # ]:          0 :             }
    1521                 :            :         }
    1522                 :          0 :         break;
    1523                 :            :         default:
    1524                 :        133 :             PushDouble( -GetDouble() );
    1525                 :            :     }
    1526                 :        133 : }
    1527                 :            : 
    1528                 :            : 
    1529                 :          0 : void ScInterpreter::ScPercentSign()
    1530                 :            : {
    1531                 :            :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScPercentSign" );
    1532                 :          0 :     nFuncFmtType = NUMBERFORMAT_PERCENT;
    1533                 :          0 :     const FormulaToken* pSaveCur = pCur;
    1534                 :          0 :     sal_uInt8 nSavePar = cPar;
    1535         [ #  # ]:          0 :     PushInt( 100 );
    1536                 :          0 :     cPar = 2;
    1537         [ #  # ]:          0 :     FormulaByteToken aDivOp( ocDiv, cPar );
    1538                 :          0 :     pCur = &aDivOp;
    1539         [ #  # ]:          0 :     ScDiv();
    1540                 :          0 :     pCur = pSaveCur;
    1541         [ #  # ]:          0 :     cPar = nSavePar;
    1542                 :          0 : }
    1543                 :            : 
    1544                 :            : 
    1545                 :         21 : void ScInterpreter::ScNot()
    1546                 :            : {
    1547                 :            :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScNot" );
    1548                 :         21 :     nFuncFmtType = NUMBERFORMAT_LOGICAL;
    1549         [ -  + ]:         21 :     switch ( GetStackType() )
    1550                 :            :     {
    1551                 :            :         case svMatrix :
    1552                 :            :         {
    1553         [ #  # ]:          0 :             ScMatrixRef pMat = GetMatrix();
    1554         [ #  # ]:          0 :             if ( !pMat )
    1555         [ #  # ]:          0 :                 PushIllegalParameter();
    1556                 :            :             else
    1557                 :            :             {
    1558                 :            :                 SCSIZE nC, nR;
    1559         [ #  # ]:          0 :                 pMat->GetDimensions( nC, nR );
    1560         [ #  # ]:          0 :                 ScMatrixRef pResMat = GetNewMat( nC, nR);
    1561         [ #  # ]:          0 :                 if ( !pResMat )
    1562         [ #  # ]:          0 :                     PushIllegalArgument();
    1563                 :            :                 else
    1564                 :            :                 {
    1565         [ #  # ]:          0 :                     for (SCSIZE i = 0; i < nC; ++i)
    1566                 :            :                     {
    1567         [ #  # ]:          0 :                         for (SCSIZE j = 0; j < nR; ++j)
    1568                 :            :                         {
    1569 [ #  # ][ #  # ]:          0 :                             if ( pMat->IsValueOrEmpty(i,j) )
    1570 [ #  # ][ #  # ]:          0 :                                 pResMat->PutDouble( (pMat->GetDouble(i,j) == 0.0), i, j );
                 [ #  # ]
    1571                 :            :                             else
    1572                 :            :                                 pResMat->PutString(
    1573 [ #  # ][ #  # ]:          0 :                                     ScGlobal::GetRscString( STR_NO_VALUE ), i, j );
                 [ #  # ]
    1574                 :            :                         }
    1575                 :            :                     }
    1576         [ #  # ]:          0 :                     PushMatrix( pResMat );
    1577         [ #  # ]:          0 :                 }
    1578         [ #  # ]:          0 :             }
    1579                 :            :         }
    1580                 :          0 :         break;
    1581                 :            :         default:
    1582                 :         21 :             PushInt( GetDouble() == 0.0 );
    1583                 :            :     }
    1584                 :         21 : }
    1585                 :            : 
    1586                 :            : 
    1587                 :          9 : void ScInterpreter::ScBitAnd()
    1588                 :            : {
    1589                 :            :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "pechlaner", "ScInterpreter::ScBitAnd" );
    1590                 :            : 
    1591         [ -  + ]:          9 :     if ( !MustHaveParamCount( GetByte(), 2 ) )
    1592                 :          9 :         return;
    1593                 :            : 
    1594                 :          9 :     double num1 = ::rtl::math::approxFloor( GetDouble());
    1595                 :          9 :     double num2 = ::rtl::math::approxFloor( GetDouble());
    1596 [ +  - ][ +  + ]:          9 :     if (    (num1 >= n2power48) || (num1 < 0) ||
         [ +  + ][ +  - ]
    1597                 :            :             (num2 >= n2power48) || (num2 < 0))
    1598                 :          6 :         PushIllegalArgument();
    1599                 :            :     else
    1600                 :          3 :         PushDouble ((sal_uInt64) num1 & (sal_uInt64) num2);
    1601                 :            : }
    1602                 :            : 
    1603                 :            : 
    1604                 :          6 : void ScInterpreter::ScBitOr()
    1605                 :            : {
    1606                 :            :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "pechlaner", "ScInterpreter::ScBitOr" );
    1607                 :            : 
    1608         [ -  + ]:          6 :     if ( !MustHaveParamCount( GetByte(), 2 ) )
    1609                 :          6 :         return;
    1610                 :            : 
    1611                 :          6 :     double num1 = ::rtl::math::approxFloor( GetDouble());
    1612                 :          6 :     double num2 = ::rtl::math::approxFloor( GetDouble());
    1613 [ +  - ][ +  - ]:          6 :     if (    (num1 >= n2power48) || (num1 < 0) ||
         [ +  + ][ +  - ]
    1614                 :            :             (num2 >= n2power48) || (num2 < 0))
    1615                 :          3 :         PushIllegalArgument();
    1616                 :            :     else
    1617                 :          3 :         PushDouble ((sal_uInt64) num1 | (sal_uInt64) num2);
    1618                 :            : }
    1619                 :            : 
    1620                 :            : 
    1621                 :          6 : void ScInterpreter::ScBitXor()
    1622                 :            : {
    1623                 :            :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "pechlaner", "ScInterpreter::ScBitXor" );
    1624                 :            : 
    1625         [ -  + ]:          6 :     if ( !MustHaveParamCount( GetByte(), 2 ) )
    1626                 :          6 :         return;
    1627                 :            : 
    1628                 :          6 :     double num1 = ::rtl::math::approxFloor( GetDouble());
    1629                 :          6 :     double num2 = ::rtl::math::approxFloor( GetDouble());
    1630 [ +  - ][ +  - ]:          6 :     if (    (num1 >= n2power48) || (num1 < 0) ||
         [ +  + ][ +  - ]
    1631                 :            :             (num2 >= n2power48) || (num2 < 0))
    1632                 :          3 :         PushIllegalArgument();
    1633                 :            :     else
    1634                 :          3 :         PushDouble ((sal_uInt64) num1 ^ (sal_uInt64) num2);
    1635                 :            : }
    1636                 :            : 
    1637                 :            : 
    1638                 :          6 : void ScInterpreter::ScBitLshift()
    1639                 :            : {
    1640                 :            :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "pechlaner", "ScInterpreter::ScBitLshift" );
    1641                 :            : 
    1642         [ -  + ]:          6 :     if ( !MustHaveParamCount( GetByte(), 2 ) )
    1643                 :          6 :         return;
    1644                 :            : 
    1645                 :          6 :     double fShift = ::rtl::math::approxFloor( GetDouble());
    1646                 :          6 :     double num = ::rtl::math::approxFloor( GetDouble());
    1647 [ -  + ][ +  - ]:          6 :     if ((num >= n2power48) || (num < 0))
    1648                 :          0 :         PushIllegalArgument();
    1649                 :            :     else
    1650                 :            :     {
    1651                 :            :         double fRes;
    1652         [ +  + ]:          6 :         if (fShift < 0)
    1653                 :          3 :             fRes = ::rtl::math::approxFloor( num / pow( 2.0, -fShift));
    1654         [ -  + ]:          3 :         else if (fShift == 0)
    1655                 :          0 :             fRes = num;
    1656                 :            :         else
    1657                 :          3 :             fRes = num * pow( 2.0, fShift);
    1658                 :          6 :         PushDouble( fRes);
    1659                 :            :     }
    1660                 :            : }
    1661                 :            : 
    1662                 :            : 
    1663                 :          6 : void ScInterpreter::ScBitRshift()
    1664                 :            : {
    1665                 :            :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "pechlaner", "ScInterpreter::ScBitRshift" );
    1666                 :            : 
    1667         [ -  + ]:          6 :     if ( !MustHaveParamCount( GetByte(), 2 ) )
    1668                 :          6 :         return;
    1669                 :            : 
    1670                 :          6 :     double fShift = ::rtl::math::approxFloor( GetDouble());
    1671                 :          6 :     double num = ::rtl::math::approxFloor( GetDouble());
    1672 [ -  + ][ +  - ]:          6 :     if ((num >= n2power48) || (num < 0))
    1673                 :          0 :         PushIllegalArgument();
    1674                 :            :     else
    1675                 :            :     {
    1676                 :            :         double fRes;
    1677         [ +  + ]:          6 :         if (fShift < 0)
    1678                 :          3 :             fRes = num * pow( 2.0, -fShift);
    1679         [ -  + ]:          3 :         else if (fShift == 0)
    1680                 :          0 :             fRes = num;
    1681                 :            :         else
    1682                 :          3 :             fRes = ::rtl::math::approxFloor( num / pow( 2.0, fShift));
    1683                 :          6 :         PushDouble( fRes);
    1684                 :            :     }
    1685                 :            : }
    1686                 :            : 
    1687                 :            : 
    1688                 :         30 : void ScInterpreter::ScPi()
    1689                 :            : {
    1690                 :            :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScPi" );
    1691                 :         30 :     PushDouble(F_PI);
    1692                 :         30 : }
    1693                 :            : 
    1694                 :            : 
    1695                 :          0 : void ScInterpreter::ScRandom()
    1696                 :            : {
    1697                 :            :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScRandom" );
    1698                 :          0 :     PushDouble((double)rand() / ((double)RAND_MAX+1.0));
    1699                 :          0 : }
    1700                 :            : 
    1701                 :            : 
    1702                 :         27 : void ScInterpreter::ScTrue()
    1703                 :            : {
    1704                 :            :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScTrue" );
    1705                 :         27 :     nFuncFmtType = NUMBERFORMAT_LOGICAL;
    1706                 :         27 :     PushInt(1);
    1707                 :         27 : }
    1708                 :            : 
    1709                 :            : 
    1710                 :         12 : void ScInterpreter::ScFalse()
    1711                 :            : {
    1712                 :            :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScFalse" );
    1713                 :         12 :     nFuncFmtType = NUMBERFORMAT_LOGICAL;
    1714                 :         12 :     PushInt(0);
    1715                 :         12 : }
    1716                 :            : 
    1717                 :            : 
    1718                 :          0 : void ScInterpreter::ScDeg()
    1719                 :            : {
    1720                 :            :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScDeg" );
    1721                 :          0 :     PushDouble((GetDouble() / F_PI) * 180.0);
    1722                 :          0 : }
    1723                 :            : 
    1724                 :            : 
    1725                 :          0 : void ScInterpreter::ScRad()
    1726                 :            : {
    1727                 :            :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScRad" );
    1728                 :          0 :     PushDouble(GetDouble() * (F_PI / 180));
    1729                 :          0 : }
    1730                 :            : 
    1731                 :            : 
    1732                 :          6 : void ScInterpreter::ScSin()
    1733                 :            : {
    1734                 :            :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScSin" );
    1735                 :          6 :     PushDouble(::rtl::math::sin(GetDouble()));
    1736                 :          6 : }
    1737                 :            : 
    1738                 :            : 
    1739                 :          6 : void ScInterpreter::ScCos()
    1740                 :            : {
    1741                 :            :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScCos" );
    1742                 :          6 :     PushDouble(::rtl::math::cos(GetDouble()));
    1743                 :          6 : }
    1744                 :            : 
    1745                 :            : 
    1746                 :          0 : void ScInterpreter::ScTan()
    1747                 :            : {
    1748                 :            :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScTan" );
    1749                 :          0 :     PushDouble(::rtl::math::tan(GetDouble()));
    1750                 :          0 : }
    1751                 :            : 
    1752                 :            : 
    1753                 :          0 : void ScInterpreter::ScCot()
    1754                 :            : {
    1755                 :            :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScCot" );
    1756                 :          0 :     PushDouble(1.0 / ::rtl::math::tan(GetDouble()));
    1757                 :          0 : }
    1758                 :            : 
    1759                 :            : 
    1760                 :          0 : void ScInterpreter::ScArcSin()
    1761                 :            : {
    1762                 :            :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScArcSin" );
    1763                 :          0 :     PushDouble(asin(GetDouble()));
    1764                 :          0 : }
    1765                 :            : 
    1766                 :            : 
    1767                 :          9 : void ScInterpreter::ScArcCos()
    1768                 :            : {
    1769                 :            :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScArcCos" );
    1770                 :          9 :     PushDouble(acos(GetDouble()));
    1771                 :          9 : }
    1772                 :            : 
    1773                 :            : 
    1774                 :          0 : void ScInterpreter::ScArcTan()
    1775                 :            : {
    1776                 :            :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScArcTan" );
    1777                 :          0 :     PushDouble(atan(GetDouble()));
    1778                 :          0 : }
    1779                 :            : 
    1780                 :            : 
    1781                 :          9 : void ScInterpreter::ScArcCot()
    1782                 :            : {
    1783                 :            :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScArcCot" );
    1784                 :          9 :     PushDouble((F_PI2) - atan(GetDouble()));
    1785                 :          9 : }
    1786                 :            : 
    1787                 :            : 
    1788                 :          0 : void ScInterpreter::ScSinHyp()
    1789                 :            : {
    1790                 :            :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScSinHyp" );
    1791                 :          0 :     PushDouble(sinh(GetDouble()));
    1792                 :          0 : }
    1793                 :            : 
    1794                 :            : 
    1795                 :          0 : void ScInterpreter::ScCosHyp()
    1796                 :            : {
    1797                 :            :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScCosHyp" );
    1798                 :          0 :     PushDouble(cosh(GetDouble()));
    1799                 :          0 : }
    1800                 :            : 
    1801                 :            : 
    1802                 :          0 : void ScInterpreter::ScTanHyp()
    1803                 :            : {
    1804                 :            :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScTanHyp" );
    1805                 :          0 :     PushDouble(tanh(GetDouble()));
    1806                 :          0 : }
    1807                 :            : 
    1808                 :            : 
    1809                 :          0 : void ScInterpreter::ScCotHyp()
    1810                 :            : {
    1811                 :            :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScCotHyp" );
    1812                 :          0 :     PushDouble(1.0 / tanh(GetDouble()));
    1813                 :          0 : }
    1814                 :            : 
    1815                 :            : 
    1816                 :          0 : void ScInterpreter::ScArcSinHyp()
    1817                 :            : {
    1818                 :            :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScArcSinHyp" );
    1819                 :          0 :     PushDouble( ::rtl::math::asinh( GetDouble()));
    1820                 :          0 : }
    1821                 :            : 
    1822                 :          6 : void ScInterpreter::ScArcCosHyp()
    1823                 :            : {
    1824                 :            :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScArcCosHyp" );
    1825                 :          6 :     double fVal = GetDouble();
    1826         [ +  + ]:          6 :     if (fVal < 1.0)
    1827                 :          3 :         PushIllegalArgument();
    1828                 :            :     else
    1829                 :          3 :         PushDouble( ::rtl::math::acosh( fVal));
    1830                 :          6 : }
    1831                 :            : 
    1832                 :          0 : void ScInterpreter::ScArcTanHyp()
    1833                 :            : {
    1834                 :            :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScArcTanHyp" );
    1835                 :          0 :     double fVal = GetDouble();
    1836         [ #  # ]:          0 :     if (fabs(fVal) >= 1.0)
    1837                 :          0 :         PushIllegalArgument();
    1838                 :            :     else
    1839                 :          0 :         PushDouble( ::rtl::math::atanh( fVal));
    1840                 :          0 : }
    1841                 :            : 
    1842                 :            : 
    1843                 :          0 : void ScInterpreter::ScArcCotHyp()
    1844                 :            : {
    1845                 :            :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScArcCotHyp" );
    1846                 :          0 :     double nVal = GetDouble();
    1847         [ #  # ]:          0 :     if (fabs(nVal) <= 1.0)
    1848                 :          0 :         PushIllegalArgument();
    1849                 :            :     else
    1850                 :          0 :         PushDouble(0.5 * log((nVal + 1.0) / (nVal - 1.0)));
    1851                 :          0 : }
    1852                 :            : 
    1853                 :          0 : void ScInterpreter::ScCosecant()
    1854                 :            : {
    1855                 :            :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "regina", "ScInterpreter::ScCosecant" );
    1856                 :          0 :     PushDouble(1.0 / ::rtl::math::sin(GetDouble()));
    1857                 :          0 : }
    1858                 :            : 
    1859                 :          0 : void ScInterpreter::ScSecant()
    1860                 :            : {
    1861                 :            :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "regina", "ScInterpreter::ScSecant" );
    1862                 :          0 :     PushDouble(1.0 / ::rtl::math::cos(GetDouble()));
    1863                 :          0 : }
    1864                 :            : 
    1865                 :          0 : void ScInterpreter::ScCosecantHyp()
    1866                 :            : {
    1867                 :            :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "regina", "ScInterpreter::ScCosecantHyp" );
    1868                 :          0 :     PushDouble(1.0 / sinh(GetDouble()));
    1869                 :          0 : }
    1870                 :            : 
    1871                 :          0 : void ScInterpreter::ScSecantHyp()
    1872                 :            : {
    1873                 :            :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "regina", "ScInterpreter::ScSecantHyp" );
    1874                 :          0 :     PushDouble(1.0 / cosh(GetDouble()));
    1875                 :          0 : }
    1876                 :            : 
    1877                 :            : 
    1878                 :          0 : void ScInterpreter::ScExp()
    1879                 :            : {
    1880                 :            :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScExp" );
    1881                 :          0 :     PushDouble(exp(GetDouble()));
    1882                 :          0 : }
    1883                 :            : 
    1884                 :            : 
    1885                 :        148 : void ScInterpreter::ScSqrt()
    1886                 :            : {
    1887                 :            :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScSqrt" );
    1888                 :        148 :     double fVal = GetDouble();
    1889         [ +  + ]:        148 :     if (fVal >= 0.0)
    1890                 :         37 :         PushDouble(sqrt(fVal));
    1891                 :            :     else
    1892                 :        111 :         PushIllegalArgument();
    1893                 :        148 : }
    1894                 :            : 
    1895                 :            : 
    1896                 :         15 : void ScInterpreter::ScIsEmpty()
    1897                 :            : {
    1898                 :            :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScIsEmpty" );
    1899                 :         15 :     short nRes = 0;
    1900                 :         15 :     nFuncFmtType = NUMBERFORMAT_LOGICAL;
    1901   [ -  +  -  - ]:         15 :     switch ( GetRawStackType() )
    1902                 :            :     {
    1903                 :            :         case svEmptyCell:
    1904                 :            :         {
    1905         [ #  # ]:          0 :             FormulaTokenRef p = PopToken();
    1906         [ #  # ]:          0 :             if (!static_cast<const ScEmptyCellToken*>(p.get())->IsInherited())
    1907         [ #  # ]:          0 :                 nRes = 1;
    1908                 :            :         }
    1909                 :          0 :         break;
    1910                 :            :         case svDoubleRef :
    1911                 :            :         case svSingleRef :
    1912                 :            :         {
    1913                 :         15 :             ScAddress aAdr;
    1914 [ +  - ][ +  - ]:         15 :             if ( !PopDoubleRefOrSingleRef( aAdr ) )
    1915                 :            :                 break;
    1916                 :            :             // NOTE: this could test also on inherited emptiness, but then the
    1917                 :            :             // cell tested wouldn't be empty. Must correspond with
    1918                 :            :             // ScCountEmptyCells().
    1919                 :            :             // if (HasCellEmptyData( GetCell( aAdr)))
    1920         [ +  - ]:         15 :             CellType eCellType = GetCellType( GetCell( aAdr ) );
    1921 [ +  + ][ +  - ]:         15 :             if((eCellType == CELLTYPE_NONE) || (eCellType == CELLTYPE_NOTE))
    1922                 :          3 :                 nRes = 1;
    1923                 :            :         }
    1924                 :         15 :         break;
    1925                 :            :         case svExternalSingleRef:
    1926                 :            :         case svExternalDoubleRef:
    1927                 :            :         case svMatrix:
    1928                 :            :         {
    1929         [ #  # ]:          0 :             ScMatrixRef pMat = GetMatrix();
    1930         [ #  # ]:          0 :             if ( !pMat )
    1931                 :            :                 ;   // nothing
    1932         [ #  # ]:          0 :             else if ( !pJumpMatrix )
    1933         [ #  # ]:          0 :                 nRes = pMat->IsEmpty( 0, 0);
    1934                 :            :             else
    1935                 :            :             {
    1936                 :            :                 SCSIZE nCols, nRows, nC, nR;
    1937         [ #  # ]:          0 :                 pMat->GetDimensions( nCols, nRows);
    1938                 :          0 :                 pJumpMatrix->GetPos( nC, nR);
    1939 [ #  # ][ #  # ]:          0 :                 if ( nC < nCols && nR < nRows )
    1940         [ #  # ]:          0 :                     nRes = pMat->IsEmpty( nC, nR);
    1941                 :            :                 // else: false, not empty (which is what Xcl does)
    1942         [ #  # ]:          0 :             }
    1943                 :            :         }
    1944                 :          0 :         break;
    1945                 :            :         default:
    1946                 :          0 :             Pop();
    1947                 :            :     }
    1948                 :         15 :     nGlobalError = 0;
    1949                 :         15 :     PushInt( nRes );
    1950                 :         15 : }
    1951                 :            : 
    1952                 :            : 
    1953                 :         27 : short ScInterpreter::IsString()
    1954                 :            : {
    1955                 :            :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::IsString" );
    1956                 :         27 :     nFuncFmtType = NUMBERFORMAT_LOGICAL;
    1957                 :         27 :     short nRes = 0;
    1958   [ +  +  -  + ]:         27 :     switch ( GetRawStackType() )
    1959                 :            :     {
    1960                 :            :         case svString:
    1961                 :          3 :             Pop();
    1962                 :          3 :             nRes = 1;
    1963                 :          3 :         break;
    1964                 :            :         case svDoubleRef :
    1965                 :            :         case svSingleRef :
    1966                 :            :         {
    1967                 :         21 :             ScAddress aAdr;
    1968 [ +  - ][ +  - ]:         21 :             if ( !PopDoubleRefOrSingleRef( aAdr ) )
    1969                 :            :                 break;
    1970         [ +  - ]:         21 :             ScBaseCell* pCell = GetCell( aAdr );
    1971 [ +  - ][ +  - ]:         21 :             if (GetCellErrCode( pCell ) == 0)
    1972                 :            :             {
    1973      [ -  +  - ]:         21 :                 switch ( GetCellType( pCell ) )
    1974                 :            :                 {
    1975                 :            :                     case CELLTYPE_STRING :
    1976                 :            :                     case CELLTYPE_EDIT :
    1977                 :          0 :                         nRes = 1;
    1978                 :          0 :                         break;
    1979                 :            :                     case CELLTYPE_FORMULA :
    1980 [ +  - ][ +  - ]:         21 :                         nRes = !((ScFormulaCell*)pCell)->IsValue() &&
    1981 [ +  + ][ +  - ]:         21 :                             !((ScFormulaCell*)pCell)->IsEmpty();
         [ +  - ][ +  - ]
    1982                 :         21 :                         break;
    1983                 :            :                     default:
    1984                 :            :                         ; // nothing
    1985                 :            :                 }
    1986                 :            :             }
    1987                 :            :         }
    1988                 :         21 :         break;
    1989                 :            :         case svMatrix:
    1990                 :            :         {
    1991         [ #  # ]:          0 :             ScMatrixRef pMat = PopMatrix();
    1992         [ #  # ]:          0 :             if ( !pMat )
    1993                 :            :                 ;   // nothing
    1994         [ #  # ]:          0 :             else if ( !pJumpMatrix )
    1995 [ #  # ][ #  # ]:          0 :                 nRes = pMat->IsString(0, 0) && !pMat->IsEmpty(0, 0);
         [ #  # ][ #  # ]
    1996                 :            :             else
    1997                 :            :             {
    1998                 :            :                 SCSIZE nCols, nRows, nC, nR;
    1999         [ #  # ]:          0 :                 pMat->GetDimensions( nCols, nRows);
    2000                 :          0 :                 pJumpMatrix->GetPos( nC, nR);
    2001 [ #  # ][ #  # ]:          0 :                 if ( nC < nCols && nR < nRows )
    2002 [ #  # ][ #  # ]:          0 :                     nRes = pMat->IsString( nC, nR) && !pMat->IsEmpty( nC, nR);
         [ #  # ][ #  # ]
    2003         [ #  # ]:          0 :             }
    2004                 :            :         }
    2005                 :          0 :         break;
    2006                 :            :         default:
    2007                 :          3 :             Pop();
    2008                 :            :     }
    2009                 :         27 :     nGlobalError = 0;
    2010                 :         27 :     return nRes;
    2011                 :            : }
    2012                 :            : 
    2013                 :            : 
    2014                 :         18 : void ScInterpreter::ScIsString()
    2015                 :            : {
    2016                 :            :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScIsString" );
    2017                 :         18 :     PushInt( IsString() );
    2018                 :         18 : }
    2019                 :            : 
    2020                 :            : 
    2021                 :          9 : void ScInterpreter::ScIsNonString()
    2022                 :            : {
    2023                 :            :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScIsNonString" );
    2024                 :          9 :     PushInt( !IsString() );
    2025                 :          9 : }
    2026                 :            : 
    2027                 :            : 
    2028                 :         12 : void ScInterpreter::ScIsLogical()
    2029                 :            : {
    2030                 :            :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScIsLogical" );
    2031                 :         12 :     short nRes = 0;
    2032         [ +  + ]:         12 :     switch ( GetStackType() )
    2033                 :            :     {
    2034                 :            :         case svDoubleRef :
    2035                 :            :         case svSingleRef :
    2036                 :            :         {
    2037                 :          3 :             ScAddress aAdr;
    2038 [ +  - ][ +  - ]:          3 :             if ( !PopDoubleRefOrSingleRef( aAdr ) )
    2039                 :            :                 break;
    2040         [ +  - ]:          3 :             ScBaseCell* pCell = GetCell( aAdr );
    2041 [ +  - ][ +  - ]:          3 :             if (GetCellErrCode( pCell ) == 0)
    2042                 :            :             {
    2043 [ +  - ][ +  - ]:          3 :                 if (HasCellValueData(pCell))
    2044                 :            :                 {
    2045         [ +  - ]:          3 :                     sal_uLong nFormat = GetCellNumberFormat( aAdr, pCell );
    2046         [ +  - ]:          3 :                     nRes = ( pFormatter->GetType(nFormat)
    2047                 :          3 :                                                  == NUMBERFORMAT_LOGICAL);
    2048                 :            :                 }
    2049                 :            :             }
    2050                 :            :         }
    2051                 :          3 :         break;
    2052                 :            :         case svMatrix:
    2053                 :            :             // TODO: we don't have type information for arrays except
    2054                 :            :             // numerical/string.
    2055                 :            :         // Fall thru
    2056                 :            :         default:
    2057                 :          9 :             PopError();
    2058         [ +  - ]:          9 :             if ( !nGlobalError )
    2059                 :          9 :                 nRes = ( nCurFmtType == NUMBERFORMAT_LOGICAL );
    2060                 :            :     }
    2061                 :         12 :     nCurFmtType = nFuncFmtType = NUMBERFORMAT_LOGICAL;
    2062                 :         12 :     nGlobalError = 0;
    2063                 :         12 :     PushInt( nRes );
    2064                 :         12 : }
    2065                 :            : 
    2066                 :            : 
    2067                 :         15 : void ScInterpreter::ScType()
    2068                 :            : {
    2069                 :            :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScType" );
    2070                 :         15 :     short nType = 0;
    2071   [ +  +  +  + ]:         15 :     switch ( GetStackType() )
    2072                 :            :     {
    2073                 :            :         case svDoubleRef :
    2074                 :            :         case svSingleRef :
    2075                 :            :         {
    2076                 :          3 :             ScAddress aAdr;
    2077 [ +  - ][ +  - ]:          3 :             if ( !PopDoubleRefOrSingleRef( aAdr ) )
    2078                 :            :                 break;
    2079         [ +  - ]:          3 :             ScBaseCell* pCell = GetCell( aAdr );
    2080 [ +  - ][ +  - ]:          3 :             if (GetCellErrCode( pCell ) == 0)
    2081                 :            :             {
    2082   [ -  -  -  +  :          3 :                 switch ( GetCellType( pCell ) )
                      - ]
    2083                 :            :                 {
    2084                 :            :                     // NOTE: this is Xcl nonsense!
    2085                 :            :                     case CELLTYPE_NOTE :
    2086                 :          0 :                         nType = 1;      // empty cell is value (0)
    2087                 :          0 :                         break;
    2088                 :            :                     case CELLTYPE_STRING :
    2089                 :            :                     case CELLTYPE_EDIT :
    2090                 :          0 :                         nType = 2;
    2091                 :          0 :                         break;
    2092                 :            :                     case CELLTYPE_VALUE :
    2093                 :            :                         {
    2094         [ #  # ]:          0 :                             sal_uLong nFormat = GetCellNumberFormat( aAdr, pCell );
    2095 [ #  # ][ #  # ]:          0 :                             if (pFormatter->GetType(nFormat)
    2096                 :            :                                                      == NUMBERFORMAT_LOGICAL)
    2097                 :          0 :                                 nType = 4;
    2098                 :            :                             else
    2099                 :          0 :                                 nType = 1;
    2100                 :            :                         }
    2101                 :          0 :                         break;
    2102                 :            :                     case CELLTYPE_FORMULA :
    2103                 :          3 :                         nType = 8;
    2104                 :          3 :                         break;
    2105                 :            :                     default:
    2106         [ #  # ]:          3 :                         PushIllegalArgument();
    2107                 :            :                 }
    2108                 :            :             }
    2109                 :            :             else
    2110                 :          0 :                 nType = 16;
    2111                 :            :         }
    2112                 :          3 :         break;
    2113                 :            :         case svString:
    2114                 :          3 :             PopError();
    2115         [ -  + ]:          3 :             if ( nGlobalError )
    2116                 :            :             {
    2117                 :          0 :                 nType = 16;
    2118                 :          0 :                 nGlobalError = 0;
    2119                 :            :             }
    2120                 :            :             else
    2121                 :          3 :                 nType = 2;
    2122                 :          3 :         break;
    2123                 :            :         case svMatrix:
    2124                 :          3 :             PopMatrix();
    2125         [ -  + ]:          3 :             if ( nGlobalError )
    2126                 :            :             {
    2127                 :          0 :                 nType = 16;
    2128                 :          0 :                 nGlobalError = 0;
    2129                 :            :             }
    2130                 :            :             else
    2131                 :          3 :                 nType = 64;
    2132                 :            :                 // we could return the type of one element if in JumpMatrix or
    2133                 :            :                 // ForceArray mode, but Xcl doesn't ...
    2134                 :          3 :         break;
    2135                 :            :         default:
    2136                 :          6 :             PopError();
    2137         [ +  + ]:          6 :             if ( nGlobalError )
    2138                 :            :             {
    2139                 :          3 :                 nType = 16;
    2140                 :          3 :                 nGlobalError = 0;
    2141                 :            :             }
    2142                 :            :             else
    2143                 :          3 :                 nType = 1;
    2144                 :            :     }
    2145                 :         15 :     PushInt( nType );
    2146                 :         15 : }
    2147                 :            : 
    2148                 :            : 
    2149                 :          3 : inline bool lcl_FormatHasNegColor( const SvNumberformat* pFormat )
    2150                 :            : {
    2151 [ +  - ][ -  + ]:          3 :     return pFormat && pFormat->GetColor( 1 );
    2152                 :            : }
    2153                 :            : 
    2154                 :            : 
    2155                 :          3 : inline bool lcl_FormatHasOpenPar( const SvNumberformat* pFormat )
    2156                 :            : {
    2157 [ +  - ][ -  + ]:          3 :     return pFormat && (pFormat->GetFormatstring().Search( '(' ) != STRING_NOTFOUND);
    2158                 :            : }
    2159                 :            : 
    2160                 :            : namespace {
    2161                 :            : 
    2162                 :          0 : void getFormatString(SvNumberFormatter* pFormatter, sal_uLong nFormat, String& rFmtStr)
    2163                 :            : {
    2164                 :          0 :     bool        bAppendPrec = true;
    2165                 :            :     sal_uInt16  nPrec, nLeading;
    2166                 :            :     bool        bThousand, bIsRed;
    2167         [ #  # ]:          0 :     pFormatter->GetFormatSpecialInfo( nFormat, bThousand, bIsRed, nPrec, nLeading );
    2168                 :            : 
    2169 [ #  # ][ #  #  :          0 :     switch( pFormatter->GetType( nFormat ) )
                #  #  # ]
    2170                 :            :     {
    2171 [ #  # ][ #  # ]:          0 :         case NUMBERFORMAT_NUMBER:       rFmtStr = (bThousand ? ',' : 'F');  break;
    2172         [ #  # ]:          0 :         case NUMBERFORMAT_CURRENCY:     rFmtStr = 'C';                      break;
    2173         [ #  # ]:          0 :         case NUMBERFORMAT_SCIENTIFIC:   rFmtStr = 'S';                      break;
    2174         [ #  # ]:          0 :         case NUMBERFORMAT_PERCENT:      rFmtStr = 'P';                      break;
    2175                 :            :         default:
    2176                 :            :         {
    2177                 :          0 :             bAppendPrec = false;
    2178 [ #  # ][ #  #  :          0 :             switch( pFormatter->GetIndexTableOffset( nFormat ) )
          #  #  #  #  #  
                #  #  # ]
    2179                 :            :             {
    2180                 :            :                 case NF_DATE_SYSTEM_SHORT:
    2181                 :            :                 case NF_DATE_SYS_DMMMYY:
    2182                 :            :                 case NF_DATE_SYS_DDMMYY:
    2183                 :            :                 case NF_DATE_SYS_DDMMYYYY:
    2184                 :            :                 case NF_DATE_SYS_DMMMYYYY:
    2185                 :            :                 case NF_DATE_DIN_DMMMYYYY:
    2186                 :            :                 case NF_DATE_SYS_DMMMMYYYY:
    2187         [ #  # ]:          0 :                 case NF_DATE_DIN_DMMMMYYYY: rFmtStr.AssignAscii( RTL_CONSTASCII_STRINGPARAM( "D1" ) );  break;
    2188         [ #  # ]:          0 :                 case NF_DATE_SYS_DDMMM:     rFmtStr.AssignAscii( RTL_CONSTASCII_STRINGPARAM( "D2" ) );  break;
    2189         [ #  # ]:          0 :                 case NF_DATE_SYS_MMYY:      rFmtStr.AssignAscii( RTL_CONSTASCII_STRINGPARAM( "D3" ) );  break;
    2190                 :            :                 case NF_DATETIME_SYSTEM_SHORT_HHMM:
    2191                 :            :                 case NF_DATETIME_SYS_DDMMYYYY_HHMMSS:
    2192         [ #  # ]:          0 :                                             rFmtStr.AssignAscii( RTL_CONSTASCII_STRINGPARAM( "D4" ) );  break;
    2193         [ #  # ]:          0 :                 case NF_DATE_DIN_MMDD:      rFmtStr.AssignAscii( RTL_CONSTASCII_STRINGPARAM( "D5" ) );  break;
    2194         [ #  # ]:          0 :                 case NF_TIME_HHMMSSAMPM:    rFmtStr.AssignAscii( RTL_CONSTASCII_STRINGPARAM( "D6" ) );  break;
    2195         [ #  # ]:          0 :                 case NF_TIME_HHMMAMPM:      rFmtStr.AssignAscii( RTL_CONSTASCII_STRINGPARAM( "D7" ) );  break;
    2196         [ #  # ]:          0 :                 case NF_TIME_HHMMSS:        rFmtStr.AssignAscii( RTL_CONSTASCII_STRINGPARAM( "D8" ) );  break;
    2197         [ #  # ]:          0 :                 case NF_TIME_HHMM:          rFmtStr.AssignAscii( RTL_CONSTASCII_STRINGPARAM( "D9" ) );  break;
    2198         [ #  # ]:          0 :                 default:                    rFmtStr = 'G';
    2199                 :            :             }
    2200                 :            :         }
    2201                 :            :     }
    2202         [ #  # ]:          0 :     if( bAppendPrec )
    2203         [ #  # ]:          0 :         rFmtStr += rtl::OUString::valueOf(static_cast<sal_Int32>(nPrec));
    2204         [ #  # ]:          0 :     const SvNumberformat* pFormat = pFormatter->GetEntry( nFormat );
    2205 [ #  # ][ #  # ]:          0 :     if( lcl_FormatHasNegColor( pFormat ) )
    2206         [ #  # ]:          0 :         rFmtStr += '-';
    2207 [ #  # ][ #  # ]:          0 :     if( lcl_FormatHasOpenPar( pFormat ) )
    2208         [ #  # ]:          0 :         rFmtStr.AppendAscii( RTL_CONSTASCII_STRINGPARAM( "()" ) );
    2209                 :          0 : }
    2210                 :            : 
    2211                 :            : }
    2212                 :            : 
    2213                 :         57 : void ScInterpreter::ScCell()
    2214                 :            : {   // ATTRIBUTE ; [REF]
    2215                 :         57 :     sal_uInt8 nParamCount = GetByte();
    2216         [ +  - ]:         57 :     if( MustHaveParamCount( nParamCount, 1, 2 ) )
    2217                 :            :     {
    2218                 :         57 :         ScAddress aCellPos( aPos );
    2219                 :         57 :         bool bError = false;
    2220         [ +  - ]:         57 :         if( nParamCount == 2 )
    2221                 :            :         {
    2222 [ +  - ][ -  + ]:         57 :             switch (GetStackType())
    2223                 :            :             {
    2224                 :            :                 case svExternalSingleRef:
    2225                 :            :                 case svExternalDoubleRef:
    2226                 :            :                 {
    2227                 :            :                     // Let's handle external reference separately...
    2228         [ #  # ]:          0 :                     ScCellExternal();
    2229                 :         57 :                     return;
    2230                 :            :                 }
    2231                 :            :                 default:
    2232                 :            :                     ;
    2233                 :            :             }
    2234         [ +  - ]:         57 :             bError = !PopDoubleRefOrSingleRef( aCellPos );
    2235                 :            :         }
    2236 [ +  - ][ +  - ]:         57 :         String aInfoType( GetString() );
    2237 [ +  - ][ -  + ]:         57 :         if( bError || nGlobalError )
    2238         [ #  # ]:          0 :             PushIllegalParameter();
    2239                 :            :         else
    2240                 :            :         {
    2241         [ +  - ]:         57 :             ScBaseCell*     pCell = GetCell( aCellPos );
    2242                 :            : 
    2243 [ +  - ][ +  - ]:         57 :             ScCellKeywordTranslator::transKeyword(aInfoType, ScGlobal::GetLocale(), ocCell);
    2244                 :            : 
    2245                 :            : // *** ADDRESS INFO ***
    2246 [ +  - ][ +  + ]:         57 :             if( aInfoType.EqualsAscii( "COL" ) )
    2247                 :            :             {   // column number (1-based)
    2248         [ +  - ]:          6 :                 PushInt( aCellPos.Col() + 1 );
    2249                 :            :             }
    2250 [ +  - ][ +  + ]:         51 :             else if( aInfoType.EqualsAscii( "ROW" ) )
    2251                 :            :             {   // row number (1-based)
    2252         [ +  - ]:          6 :                 PushInt( aCellPos.Row() + 1 );
    2253                 :            :             }
    2254 [ +  - ][ +  + ]:         45 :             else if( aInfoType.EqualsAscii( "SHEET" ) )
    2255                 :            :             {   // table number (1-based)
    2256         [ +  - ]:          6 :                 PushInt( aCellPos.Tab() + 1 );
    2257                 :            :             }
    2258 [ +  - ][ +  + ]:         39 :             else if( aInfoType.EqualsAscii( "ADDRESS" ) )
    2259                 :            :             {   // address formatted as [['FILENAME'#]$TABLE.]$COL$ROW
    2260         [ +  + ]:          9 :                 sal_uInt16 nFlags = (aCellPos.Tab() == aPos.Tab()) ? (SCA_ABS) : (SCA_ABS_3D);
    2261                 :          9 :                 rtl::OUString aStr;
    2262 [ +  - ][ +  - ]:          9 :                 aCellPos.Format( aStr, nFlags, pDok, pDok->GetAddressConvention() );
    2263 [ +  - ][ +  - ]:          9 :                 PushString(aStr);
                 [ +  - ]
    2264                 :            :             }
    2265 [ +  - ][ -  + ]:         30 :             else if( aInfoType.EqualsAscii( "FILENAME" ) )
    2266                 :            :             {   // file name and table name: 'FILENAME'#$TABLE
    2267                 :          0 :                 SCTAB nTab = aCellPos.Tab();
    2268                 :          0 :                 rtl::OUString aFuncResult;
    2269 [ #  # ][ #  # ]:          0 :                 if( nTab < pDok->GetTableCount() )
    2270                 :            :                 {
    2271 [ #  # ][ #  # ]:          0 :                     if( pDok->GetLinkMode( nTab ) == SC_LINK_VALUE )
    2272         [ #  # ]:          0 :                         pDok->GetName( nTab, aFuncResult );
    2273                 :            :                     else
    2274                 :            :                     {
    2275                 :          0 :                         SfxObjectShell* pShell = pDok->GetDocumentShell();
    2276 [ #  # ][ #  # ]:          0 :                         if( pShell && pShell->GetMedium() )
                 [ #  # ]
    2277                 :            :                         {
    2278                 :          0 :                             rtl::OUStringBuffer aBuf;
    2279         [ #  # ]:          0 :                             aBuf.append(sal_Unicode('\''));
    2280         [ #  # ]:          0 :                             const INetURLObject& rURLObj = pShell->GetMedium()->GetURLObject();
    2281 [ #  # ][ #  # ]:          0 :                             aBuf.append(rURLObj.GetMainURL(INetURLObject::DECODE_UNAMBIGUOUS));
    2282         [ #  # ]:          0 :                             aBuf.appendAscii("'#$");
    2283                 :          0 :                             rtl::OUString aTabName;
    2284         [ #  # ]:          0 :                             pDok->GetName( nTab, aTabName );
    2285         [ #  # ]:          0 :                             aBuf.append(aTabName);
    2286         [ #  # ]:          0 :                             aFuncResult = aBuf.makeStringAndClear();
    2287                 :            :                         }
    2288                 :            :                     }
    2289                 :            :                 }
    2290 [ #  # ][ #  # ]:          0 :                 PushString( aFuncResult );
                 [ #  # ]
    2291                 :            :             }
    2292 [ +  - ][ -  + ]:         30 :             else if( aInfoType.EqualsAscii( "COORD" ) )
    2293                 :            :             {   // address, lotus 1-2-3 formatted: $TABLE:$COL$ROW
    2294                 :            :                 // Yes, passing tab as col is intentional!
    2295                 :          0 :                 rtl::OUStringBuffer aFuncResult;
    2296                 :          0 :                 rtl::OUString aCellStr;
    2297                 :          0 :                 ScAddress( static_cast<SCCOL>(aCellPos.Tab()), 0, 0 ).Format(
    2298 [ #  # ][ #  # ]:          0 :                     aCellStr, (SCA_COL_ABSOLUTE|SCA_VALID_COL), NULL, pDok->GetAddressConvention() );
    2299         [ #  # ]:          0 :                 aFuncResult.append(aCellStr);
    2300         [ #  # ]:          0 :                 aFuncResult.append(sal_Unicode(':'));
    2301                 :            :                 aCellPos.Format( aCellStr, (SCA_COL_ABSOLUTE|SCA_VALID_COL|SCA_ROW_ABSOLUTE|SCA_VALID_ROW),
    2302 [ #  # ][ #  # ]:          0 :                                  NULL, pDok->GetAddressConvention() );
    2303         [ #  # ]:          0 :                 aFuncResult.append(aCellStr);
    2304 [ #  # ][ #  # ]:          0 :                 PushString( aFuncResult.makeStringAndClear() );
         [ #  # ][ #  # ]
    2305                 :            :             }
    2306                 :            : 
    2307                 :            : // *** CELL PROPERTIES ***
    2308 [ +  - ][ +  + ]:         30 :             else if( aInfoType.EqualsAscii( "CONTENTS" ) )
    2309                 :            :             {   // contents of the cell, no formatting
    2310 [ +  - ][ +  - ]:          6 :                 if( pCell && pCell->HasStringData() )
         [ +  + ][ +  + ]
    2311                 :            :                 {
    2312         [ +  - ]:          3 :                     String aStr;
    2313         [ +  - ]:          3 :                     GetCellString( aStr, pCell );
    2314 [ +  - ][ +  - ]:          3 :                     PushString( aStr );
    2315                 :            :                 }
    2316                 :            :                 else
    2317 [ +  - ][ +  - ]:          3 :                     PushDouble( GetCellValue( aCellPos, pCell ) );
    2318                 :            :             }
    2319 [ +  - ][ +  + ]:         24 :             else if( aInfoType.EqualsAscii( "TYPE" ) )
    2320                 :            :             {   // b = blank; l = string (label); v = otherwise (value)
    2321                 :            :                 sal_Unicode c;
    2322 [ +  - ][ +  + ]:         18 :                 if( HasCellStringData( pCell ) )
    2323                 :          6 :                     c = 'l';
    2324                 :            :                 else
    2325 [ +  - ][ +  + ]:         12 :                     c = HasCellValueData( pCell ) ? 'v' : 'b';
    2326 [ +  - ][ +  - ]:         18 :                 PushString( rtl::OUString(c) );
                 [ +  - ]
    2327                 :            :             }
    2328 [ +  - ][ -  + ]:          6 :             else if( aInfoType.EqualsAscii( "WIDTH" ) )
    2329                 :            :             {   // column width (rounded off as count of zero characters in standard font and size)
    2330         [ #  # ]:          0 :                 Printer*    pPrinter = pDok->GetPrinter();
    2331         [ #  # ]:          0 :                 MapMode     aOldMode( pPrinter->GetMapMode() );
    2332         [ #  # ]:          0 :                 Font        aOldFont( pPrinter->GetFont() );
    2333         [ #  # ]:          0 :                 Font        aDefFont;
    2334                 :            : 
    2335 [ #  # ][ #  # ]:          0 :                 pPrinter->SetMapMode( MAP_TWIP );
                 [ #  # ]
    2336                 :            :                 // font color doesn't matter here
    2337 [ #  # ][ #  # ]:          0 :                 pDok->GetDefPattern()->GetFont( aDefFont, SC_AUTOCOL_BLACK, pPrinter );
    2338         [ #  # ]:          0 :                 pPrinter->SetFont( aDefFont );
    2339 [ #  # ][ #  # ]:          0 :                 long nZeroWidth = pPrinter->GetTextWidth( rtl::OUString( '0' ) );
                 [ #  # ]
    2340         [ #  # ]:          0 :                 pPrinter->SetFont( aOldFont );
    2341         [ #  # ]:          0 :                 pPrinter->SetMapMode( aOldMode );
    2342         [ #  # ]:          0 :                 int nZeroCount = (int)(pDok->GetColWidth( aCellPos.Col(), aCellPos.Tab() ) / nZeroWidth);
    2343 [ #  # ][ #  # ]:          0 :                 PushInt( nZeroCount );
         [ #  # ][ #  # ]
    2344                 :            :             }
    2345 [ +  - ][ -  + ]:          6 :             else if( aInfoType.EqualsAscii( "PREFIX" ) )
    2346                 :            :             {   // ' = left; " = right; ^ = centered
    2347                 :          0 :                 sal_Unicode c = 0;
    2348 [ #  # ][ #  # ]:          0 :                 if( HasCellStringData( pCell ) )
    2349                 :            :                 {
    2350                 :            :                     const SvxHorJustifyItem* pJustAttr = (const SvxHorJustifyItem*)
    2351         [ #  # ]:          0 :                         pDok->GetAttr( aCellPos.Col(), aCellPos.Row(), aCellPos.Tab(), ATTR_HOR_JUSTIFY );
    2352   [ #  #  #  #  :          0 :                     switch( pJustAttr->GetValue() )
                      # ]
    2353                 :            :                     {
    2354                 :            :                         case SVX_HOR_JUSTIFY_STANDARD:
    2355                 :            :                         case SVX_HOR_JUSTIFY_LEFT:
    2356                 :          0 :                         case SVX_HOR_JUSTIFY_BLOCK:     c = '\''; break;
    2357                 :          0 :                         case SVX_HOR_JUSTIFY_CENTER:    c = '^';  break;
    2358                 :          0 :                         case SVX_HOR_JUSTIFY_RIGHT:     c = '"';  break;
    2359                 :          0 :                         case SVX_HOR_JUSTIFY_REPEAT:    c = '\\'; break;
    2360                 :            :                     }
    2361                 :            :                 }
    2362 [ #  # ][ #  # ]:          0 :                 PushString( rtl::OUString(c) );
                 [ #  # ]
    2363                 :            :             }
    2364 [ +  - ][ -  + ]:          6 :             else if( aInfoType.EqualsAscii( "PROTECT" ) )
    2365                 :            :             {   // 1 = cell locked
    2366                 :            :                 const ScProtectionAttr* pProtAttr = (const ScProtectionAttr*)
    2367         [ #  # ]:          0 :                     pDok->GetAttr( aCellPos.Col(), aCellPos.Row(), aCellPos.Tab(), ATTR_PROTECTION );
    2368 [ #  # ][ #  # ]:          0 :                 PushInt( pProtAttr->GetProtection() ? 1 : 0 );
    2369                 :            :             }
    2370                 :            : 
    2371                 :            : // *** FORMATTING ***
    2372 [ +  - ][ -  + ]:          6 :             else if( aInfoType.EqualsAscii( "FORMAT" ) )
    2373                 :            :             {   // specific format code for standard formats
    2374         [ #  # ]:          0 :                 String aFuncResult;
    2375         [ #  # ]:          0 :                 sal_uLong   nFormat = pDok->GetNumberFormat( aCellPos );
    2376         [ #  # ]:          0 :                 getFormatString(pFormatter, nFormat, aFuncResult);
    2377 [ #  # ][ #  # ]:          0 :                 PushString( aFuncResult );
    2378                 :            :             }
    2379 [ +  - ][ +  + ]:          6 :             else if( aInfoType.EqualsAscii( "COLOR" ) )
    2380                 :            :             {   // 1 = negative values are colored, otherwise 0
    2381 [ +  - ][ +  - ]:          3 :                 const SvNumberformat* pFormat = pFormatter->GetEntry( pDok->GetNumberFormat( aCellPos ) );
    2382 [ +  - ][ -  + ]:          3 :                 PushInt( lcl_FormatHasNegColor( pFormat ) ? 1 : 0 );
                 [ +  - ]
    2383                 :            :             }
    2384 [ +  - ][ +  - ]:          3 :             else if( aInfoType.EqualsAscii( "PARENTHESES" ) )
    2385                 :            :             {   // 1 = format string contains a '(' character, otherwise 0
    2386 [ +  - ][ +  - ]:          3 :                 const SvNumberformat* pFormat = pFormatter->GetEntry( pDok->GetNumberFormat( aCellPos ) );
    2387 [ +  - ][ -  + ]:          3 :                 PushInt( lcl_FormatHasOpenPar( pFormat ) ? 1 : 0 );
                 [ +  - ]
    2388                 :            :             }
    2389                 :            :             else
    2390         [ #  # ]:          0 :                 PushIllegalArgument();
    2391         [ +  - ]:         57 :         }
    2392                 :            :     }
    2393                 :            : }
    2394                 :            : 
    2395                 :          0 : void ScInterpreter::ScCellExternal()
    2396                 :            : {
    2397                 :            :     sal_uInt16 nFileId;
    2398         [ #  # ]:          0 :     String aTabName;
    2399                 :            :     ScSingleRefData aRef;
    2400                 :          0 :     ScExternalRefCache::TokenRef pToken;
    2401         [ #  # ]:          0 :     ScExternalRefCache::CellFormat aFmt;
    2402         [ #  # ]:          0 :     PopExternalSingleRef(nFileId, aTabName, aRef, pToken, &aFmt);
    2403         [ #  # ]:          0 :     if (nGlobalError)
    2404                 :            :     {
    2405         [ #  # ]:          0 :         PushIllegalParameter();
    2406                 :            :         return;
    2407                 :            :     }
    2408                 :            : 
    2409 [ #  # ][ #  # ]:          0 :     rtl::OUString aInfoType = GetString();
    2410         [ #  # ]:          0 :     if (nGlobalError)
    2411                 :            :     {
    2412         [ #  # ]:          0 :         PushIllegalParameter();
    2413                 :            :         return;
    2414                 :            :     }
    2415                 :            : 
    2416                 :            :     SCCOL nCol;
    2417                 :            :     SCROW nRow;
    2418                 :            :     SCTAB nTab;
    2419                 :          0 :     aRef.nTab = 0; // external ref has a tab index of -1, which SingleRefToVars() don't like.
    2420         [ #  # ]:          0 :     SingleRefToVars(aRef, nCol, nRow, nTab);
    2421         [ #  # ]:          0 :     if (nGlobalError)
    2422                 :            :     {
    2423         [ #  # ]:          0 :         PushIllegalParameter();
    2424                 :            :         return;
    2425                 :            :     }
    2426                 :          0 :     aRef.nTab = -1; // revert the value.
    2427                 :            : 
    2428 [ #  # ][ #  # ]:          0 :     ScCellKeywordTranslator::transKeyword(aInfoType, ScGlobal::GetLocale(), ocCell);
    2429         [ #  # ]:          0 :     ScExternalRefManager* pRefMgr = pDok->GetExternalRefManager();
    2430                 :            : 
    2431         [ #  # ]:          0 :     if ( aInfoType == "COL" )
    2432         [ #  # ]:          0 :         PushInt(nCol + 1);
    2433         [ #  # ]:          0 :     else if ( aInfoType == "ROW" )
    2434         [ #  # ]:          0 :         PushInt(nRow + 1);
    2435         [ #  # ]:          0 :     else if ( aInfoType == "SHEET" )
    2436                 :            :     {
    2437                 :            :         // For SHEET, No idea what number we should set, but let's always set
    2438                 :            :         // 1 if the external sheet exists, no matter what sheet.  Excel does
    2439                 :            :         // the same.
    2440 [ #  # ][ #  # ]:          0 :         if (pRefMgr->hasCacheTable(nFileId, aTabName))
                 [ #  # ]
    2441         [ #  # ]:          0 :             PushInt(1);
    2442                 :            :         else
    2443                 :          0 :             SetError(errNoName);
    2444                 :            :     }
    2445         [ #  # ]:          0 :     else if ( aInfoType == "ADDRESS" )
    2446                 :            :     {
    2447                 :            :         // ODF 1.2 says we need to always display address using the ODF A1 grammar.
    2448         [ #  # ]:          0 :         ScTokenArray aArray;
    2449         [ #  # ]:          0 :         aArray.AddExternalSingleReference(nFileId, aTabName, aRef);
    2450         [ #  # ]:          0 :         ScCompiler aComp(pDok, aPos, aArray);
    2451         [ #  # ]:          0 :         aComp.SetGrammar(formula::FormulaGrammar::GRAM_ODFF_A1);
    2452         [ #  # ]:          0 :         String aStr;
    2453         [ #  # ]:          0 :         aComp.CreateStringFromTokenArray(aStr);
    2454 [ #  # ][ #  # ]:          0 :         PushString(aStr);
         [ #  # ][ #  # ]
    2455                 :            :     }
    2456         [ #  # ]:          0 :     else if ( aInfoType == "FILENAME" )
    2457                 :            :     {
    2458                 :            :         // 'file URI'#$SheetName
    2459                 :            : 
    2460         [ #  # ]:          0 :         const rtl::OUString* p = pRefMgr->getExternalFileName(nFileId);
    2461         [ #  # ]:          0 :         if (!p)
    2462                 :            :         {
    2463                 :            :             // In theory this should never happen...
    2464                 :          0 :             SetError(errNoName);
    2465                 :            :             return;
    2466                 :            :         }
    2467                 :            : 
    2468                 :          0 :         rtl::OUStringBuffer aBuf;
    2469         [ #  # ]:          0 :         aBuf.append(sal_Unicode('\''));
    2470         [ #  # ]:          0 :         aBuf.append(*p);
    2471         [ #  # ]:          0 :         aBuf.appendAscii("'#$");
    2472 [ #  # ][ #  # ]:          0 :         aBuf.append(aTabName);
    2473 [ #  # ][ #  # ]:          0 :         PushString(aBuf.makeStringAndClear());
         [ #  # ][ #  # ]
    2474                 :            :     }
    2475         [ #  # ]:          0 :     else if ( aInfoType == "CONTENTS" )
    2476                 :            :     {
    2477   [ #  #  #  # ]:          0 :         switch (pToken->GetType())
    2478                 :            :         {
    2479                 :            :             case svString:
    2480 [ #  # ][ #  # ]:          0 :                 PushString(pToken->GetString());
    2481                 :          0 :             break;
    2482                 :            :             case svDouble:
    2483 [ #  # ][ #  # ]:          0 :                 PushString(rtl::OUString::valueOf(pToken->GetDouble()));
         [ #  # ][ #  # ]
    2484                 :          0 :             break;
    2485                 :            :             case svError:
    2486 [ #  # ][ #  # ]:          0 :                 PushString(ScGlobal::GetErrorString(pToken->GetError()));
         [ #  # ][ #  # ]
    2487                 :          0 :             break;
    2488                 :            :             default:
    2489 [ #  # ][ #  # ]:          0 :                 PushString(ScGlobal::GetEmptyString());
    2490                 :            :         }
    2491                 :            :     }
    2492         [ #  # ]:          0 :     else if ( aInfoType == "TYPE" )
    2493                 :            :     {
    2494                 :          0 :         sal_Unicode c = 'v';
    2495      [ #  #  # ]:          0 :         switch (pToken->GetType())
    2496                 :            :         {
    2497                 :            :             case svString:
    2498                 :          0 :                 c = 'l';
    2499                 :          0 :             break;
    2500                 :            :             case svEmptyCell:
    2501                 :          0 :                 c = 'b';
    2502                 :          0 :             break;
    2503                 :            :             default:
    2504                 :            :                 ;
    2505                 :            :         }
    2506 [ #  # ][ #  # ]:          0 :         PushString(rtl::OUString(c));
                 [ #  # ]
    2507                 :            :     }
    2508         [ #  # ]:          0 :     else if ( aInfoType == "FORMAT" )
    2509                 :            :     {
    2510         [ #  # ]:          0 :         String aFmtStr;
    2511         [ #  # ]:          0 :         sal_uLong nFmt = aFmt.mbIsSet ? aFmt.mnIndex : 0;
    2512         [ #  # ]:          0 :         getFormatString(pFormatter, nFmt, aFmtStr);
    2513 [ #  # ][ #  # ]:          0 :         PushString(aFmtStr);
    2514                 :            :     }
    2515         [ #  # ]:          0 :     else if ( aInfoType == "COLOR" )
    2516                 :            :     {
    2517                 :            :         // 1 = negative values are colored, otherwise 0
    2518                 :          0 :         int nVal = 0;
    2519         [ #  # ]:          0 :         if (aFmt.mbIsSet)
    2520                 :            :         {
    2521         [ #  # ]:          0 :             const SvNumberformat* pFormat = pFormatter->GetEntry(aFmt.mnIndex);
    2522 [ #  # ][ #  # ]:          0 :             nVal = lcl_FormatHasNegColor(pFormat) ? 1 : 0;
    2523                 :            :         }
    2524         [ #  # ]:          0 :         PushInt(nVal);
    2525                 :            :     }
    2526         [ #  # ]:          0 :     else if ( aInfoType == "PARENTHESES" )
    2527                 :            :     {
    2528                 :            :         // 1 = format string contains a '(' character, otherwise 0
    2529                 :          0 :         int nVal = 0;
    2530         [ #  # ]:          0 :         if (aFmt.mbIsSet)
    2531                 :            :         {
    2532         [ #  # ]:          0 :             const SvNumberformat* pFormat = pFormatter->GetEntry(aFmt.mnIndex);
    2533 [ #  # ][ #  # ]:          0 :             nVal = lcl_FormatHasOpenPar(pFormat) ? 1 : 0;
    2534                 :            :         }
    2535         [ #  # ]:          0 :         PushInt(nVal);
    2536                 :            :     }
    2537                 :            :     else
    2538 [ #  # ][ #  # ]:          0 :         PushIllegalParameter();
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
    2539                 :            : }
    2540                 :            : 
    2541                 :         24 : void ScInterpreter::ScIsRef()
    2542                 :            : {
    2543                 :            :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScCell" );
    2544                 :         24 :     nFuncFmtType = NUMBERFORMAT_LOGICAL;
    2545                 :         24 :     short nRes = 0;
    2546   [ +  +  -  + ]:         24 :     switch ( GetStackType() )
    2547                 :            :     {
    2548                 :            :         case svSingleRef :
    2549                 :            :         {
    2550                 :          3 :             ScAddress aAdr;
    2551         [ +  - ]:          3 :             PopSingleRef( aAdr );
    2552         [ +  - ]:          3 :             if ( !nGlobalError )
    2553                 :          3 :                 nRes = 1;
    2554                 :            :         }
    2555                 :          3 :         break;
    2556                 :            :         case svDoubleRef :
    2557                 :            :         {
    2558                 :          9 :             ScRange aRange;
    2559         [ +  - ]:          9 :             PopDoubleRef( aRange );
    2560         [ +  - ]:          9 :             if ( !nGlobalError )
    2561                 :          9 :                 nRes = 1;
    2562                 :            :         }
    2563                 :          9 :         break;
    2564                 :            :         case svRefList :
    2565                 :            :         {
    2566         [ #  # ]:          0 :             FormulaTokenRef x = PopToken();
    2567         [ #  # ]:          0 :             if ( !nGlobalError )
    2568 [ #  # ][ #  # ]:          0 :                 nRes = !static_cast<ScToken*>(x.get())->GetRefList()->empty();
    2569                 :            :         }
    2570                 :          0 :         break;
    2571                 :            :         default:
    2572                 :         12 :             Pop();
    2573                 :            :     }
    2574                 :         24 :     nGlobalError = 0;
    2575                 :         24 :     PushInt( nRes );
    2576                 :         24 : }
    2577                 :            : 
    2578                 :            : 
    2579                 :         15 : void ScInterpreter::ScIsValue()
    2580                 :            : {
    2581                 :            :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScIsValue" );
    2582                 :         15 :     nFuncFmtType = NUMBERFORMAT_LOGICAL;
    2583                 :         15 :     short nRes = 0;
    2584   [ -  +  -  - ]:         15 :     switch ( GetRawStackType() )
    2585                 :            :     {
    2586                 :            :         case svDouble:
    2587                 :          0 :             Pop();
    2588                 :          0 :             nRes = 1;
    2589                 :          0 :         break;
    2590                 :            :         case svDoubleRef :
    2591                 :            :         case svSingleRef :
    2592                 :            :         {
    2593                 :         15 :             ScAddress aAdr;
    2594 [ +  - ][ +  - ]:         15 :             if ( !PopDoubleRefOrSingleRef( aAdr ) )
    2595                 :            :                 break;
    2596         [ +  - ]:         15 :             ScBaseCell* pCell = GetCell( aAdr );
    2597 [ +  - ][ +  - ]:         15 :             if (GetCellErrCode( pCell ) == 0)
    2598                 :            :             {
    2599      [ -  +  - ]:         15 :                 switch ( GetCellType( pCell ) )
    2600                 :            :                 {
    2601                 :            :                     case CELLTYPE_VALUE :
    2602                 :          0 :                         nRes = 1;
    2603                 :          0 :                         break;
    2604                 :            :                     case CELLTYPE_FORMULA :
    2605 [ +  - ][ +  - ]:         15 :                         nRes = ((ScFormulaCell*)pCell)->IsValue() &&
    2606 [ +  + ][ +  - ]:         15 :                             !((ScFormulaCell*)pCell)->IsEmpty();
         [ +  - ][ +  - ]
    2607                 :         15 :                         break;
    2608                 :            :                     default:
    2609                 :            :                         ; // nothing
    2610                 :            :                 }
    2611                 :            :             }
    2612                 :            :         }
    2613                 :         15 :         break;
    2614                 :            :         case svMatrix:
    2615                 :            :         {
    2616         [ #  # ]:          0 :             ScMatrixRef pMat = PopMatrix();
    2617         [ #  # ]:          0 :             if ( !pMat )
    2618                 :            :                 ;   // nothing
    2619         [ #  # ]:          0 :             else if ( !pJumpMatrix )
    2620                 :            :             {
    2621 [ #  # ][ #  # ]:          0 :                 if (pMat->GetErrorIfNotString( 0, 0) == 0)
    2622         [ #  # ]:          0 :                     nRes = pMat->IsValue( 0, 0);
    2623                 :            :             }
    2624                 :            :             else
    2625                 :            :             {
    2626                 :            :                 SCSIZE nCols, nRows, nC, nR;
    2627         [ #  # ]:          0 :                 pMat->GetDimensions( nCols, nRows);
    2628                 :          0 :                 pJumpMatrix->GetPos( nC, nR);
    2629 [ #  # ][ #  # ]:          0 :                 if ( nC < nCols && nR < nRows )
    2630 [ #  # ][ #  # ]:          0 :                     if (pMat->GetErrorIfNotString( nC, nR) == 0)
    2631         [ #  # ]:          0 :                         nRes = pMat->IsValue( nC, nR);
    2632         [ #  # ]:          0 :             }
    2633                 :            :         }
    2634                 :          0 :         break;
    2635                 :            :         default:
    2636                 :          0 :             Pop();
    2637                 :            :     }
    2638                 :         15 :     nGlobalError = 0;
    2639                 :         15 :     PushInt( nRes );
    2640                 :         15 : }
    2641                 :            : 
    2642                 :            : 
    2643                 :          9 : void ScInterpreter::ScIsFormula()
    2644                 :            : {
    2645                 :            :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScIsFormula" );
    2646                 :          9 :     nFuncFmtType = NUMBERFORMAT_LOGICAL;
    2647                 :          9 :     short nRes = 0;
    2648         [ +  - ]:          9 :     switch ( GetStackType() )
    2649                 :            :     {
    2650                 :            :         case svDoubleRef :
    2651                 :            :         case svSingleRef :
    2652                 :            :         {
    2653                 :          9 :             ScAddress aAdr;
    2654 [ +  - ][ +  - ]:          9 :             if ( !PopDoubleRefOrSingleRef( aAdr ) )
    2655                 :            :                 break;
    2656         [ +  - ]:          9 :             nRes = (GetCellType( GetCell( aAdr ) ) == CELLTYPE_FORMULA);
    2657                 :            :         }
    2658                 :          9 :         break;
    2659                 :            :         default:
    2660                 :          0 :             Pop();
    2661                 :            :     }
    2662                 :          9 :     nGlobalError = 0;
    2663                 :          9 :     PushInt( nRes );
    2664                 :          9 : }
    2665                 :            : 
    2666                 :            : 
    2667                 :         18 : void ScInterpreter::ScFormula()
    2668                 :            : {
    2669                 :            :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScFormula" );
    2670                 :         18 :     rtl::OUString aFormula;
    2671 [ +  - ][ +  - ]:         18 :     switch ( GetStackType() )
    2672                 :            :     {
    2673                 :            :         case svDoubleRef :
    2674                 :            :         case svSingleRef :
    2675                 :            :         {
    2676                 :         18 :             ScAddress aAdr;
    2677 [ +  - ][ +  - ]:         18 :             if ( !PopDoubleRefOrSingleRef( aAdr ) )
    2678                 :            :                 break;
    2679         [ +  - ]:         18 :             ScBaseCell* pCell = GetCell( aAdr );
    2680         [ +  - ]:         18 :             switch ( GetCellType( pCell ) )
    2681                 :            :             {
    2682                 :            :                 case CELLTYPE_FORMULA :
    2683 [ +  - ][ +  - ]:         18 :                     ((ScFormulaCell*)pCell)->GetFormula( aFormula );
    2684                 :         18 :                 break;
    2685                 :            :                 default:
    2686                 :          0 :                     SetError( NOTAVAILABLE );
    2687                 :            :             }
    2688                 :            :         }
    2689                 :         18 :         break;
    2690                 :            :         default:
    2691         [ #  # ]:          0 :             Pop();
    2692                 :          0 :             SetError( NOTAVAILABLE );
    2693                 :            :     }
    2694 [ +  - ][ +  - ]:         18 :     PushString( aFormula );
                 [ +  - ]
    2695                 :         18 : }
    2696                 :            : 
    2697                 :            : 
    2698                 :            : 
    2699                 :         18 : void ScInterpreter::ScIsNV()
    2700                 :            : {
    2701                 :            :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScIsNV" );
    2702                 :         18 :     nFuncFmtType = NUMBERFORMAT_LOGICAL;
    2703                 :         18 :     short nRes = 0;
    2704      [ +  -  + ]:         18 :     switch ( GetStackType() )
    2705                 :            :     {
    2706                 :            :         case svDoubleRef :
    2707                 :            :         case svSingleRef :
    2708                 :            :         {
    2709                 :         12 :             ScAddress aAdr;
    2710         [ +  - ]:         12 :             PopDoubleRefOrSingleRef( aAdr );
    2711         [ -  + ]:         12 :             if ( nGlobalError == NOTAVAILABLE )
    2712                 :          0 :                 nRes = 1;
    2713                 :            :             else
    2714                 :            :             {
    2715         [ +  - ]:         12 :                 ScBaseCell* pCell = GetCell( aAdr );
    2716         [ +  - ]:         12 :                 sal_uInt16 nErr = GetCellErrCode( pCell );
    2717                 :         12 :                 nRes = (nErr == NOTAVAILABLE);
    2718                 :            :             }
    2719                 :            :         }
    2720                 :         12 :         break;
    2721                 :            :         case svMatrix:
    2722                 :            :         {
    2723         [ #  # ]:          0 :             ScMatrixRef pMat = PopMatrix();
    2724         [ #  # ]:          0 :             if ( !pMat )
    2725                 :            :                 ;   // nothing
    2726         [ #  # ]:          0 :             else if ( !pJumpMatrix )
    2727         [ #  # ]:          0 :                 nRes = (pMat->GetErrorIfNotString( 0, 0) == NOTAVAILABLE);
    2728                 :            :             else
    2729                 :            :             {
    2730                 :            :                 SCSIZE nCols, nRows, nC, nR;
    2731         [ #  # ]:          0 :                 pMat->GetDimensions( nCols, nRows);
    2732                 :          0 :                 pJumpMatrix->GetPos( nC, nR);
    2733 [ #  # ][ #  # ]:          0 :                 if ( nC < nCols && nR < nRows )
    2734         [ #  # ]:          0 :                     nRes = (pMat->GetErrorIfNotString( nC, nR) == NOTAVAILABLE);
    2735         [ #  # ]:          0 :             }
    2736                 :            :         }
    2737                 :          0 :         break;
    2738                 :            :         default:
    2739                 :          6 :             PopError();
    2740         [ +  + ]:          6 :             if ( nGlobalError == NOTAVAILABLE )
    2741                 :          3 :                 nRes = 1;
    2742                 :            :     }
    2743                 :         18 :     nGlobalError = 0;
    2744                 :         18 :     PushInt( nRes );
    2745                 :         18 : }
    2746                 :            : 
    2747                 :            : 
    2748                 :         12 : void ScInterpreter::ScIsErr()
    2749                 :            : {
    2750                 :            :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScIsErr" );
    2751                 :         12 :     nFuncFmtType = NUMBERFORMAT_LOGICAL;
    2752                 :         12 :     short nRes = 0;
    2753      [ +  -  + ]:         12 :     switch ( GetStackType() )
    2754                 :            :     {
    2755                 :            :         case svDoubleRef :
    2756                 :            :         case svSingleRef :
    2757                 :            :         {
    2758                 :          6 :             ScAddress aAdr;
    2759         [ +  - ]:          6 :             PopDoubleRefOrSingleRef( aAdr );
    2760 [ -  + ][ #  # ]:          6 :             if ( nGlobalError && nGlobalError != NOTAVAILABLE )
    2761                 :          0 :                 nRes = 1;
    2762                 :            :             else
    2763                 :            :             {
    2764         [ +  - ]:          6 :                 ScBaseCell* pCell = GetCell( aAdr );
    2765         [ +  - ]:          6 :                 sal_uInt16 nErr = GetCellErrCode( pCell );
    2766 [ +  + ][ +  - ]:          6 :                 nRes = (nErr && nErr != NOTAVAILABLE);
    2767                 :            :             }
    2768                 :            :         }
    2769                 :          6 :         break;
    2770                 :            :         case svMatrix:
    2771                 :            :         {
    2772         [ #  # ]:          0 :             ScMatrixRef pMat = PopMatrix();
    2773 [ #  # ][ #  # ]:          0 :             if ( nGlobalError || !pMat )
                 [ #  # ]
    2774 [ #  # ][ #  # ]:          0 :                 nRes = ((nGlobalError && nGlobalError != NOTAVAILABLE) || !pMat);
                 [ #  # ]
    2775         [ #  # ]:          0 :             else if ( !pJumpMatrix )
    2776                 :            :             {
    2777         [ #  # ]:          0 :                 sal_uInt16 nErr = pMat->GetErrorIfNotString( 0, 0);
    2778 [ #  # ][ #  # ]:          0 :                 nRes = (nErr && nErr != NOTAVAILABLE);
    2779                 :            :             }
    2780                 :            :             else
    2781                 :            :             {
    2782                 :            :                 SCSIZE nCols, nRows, nC, nR;
    2783         [ #  # ]:          0 :                 pMat->GetDimensions( nCols, nRows);
    2784                 :          0 :                 pJumpMatrix->GetPos( nC, nR);
    2785 [ #  # ][ #  # ]:          0 :                 if ( nC < nCols && nR < nRows )
    2786                 :            :                 {
    2787         [ #  # ]:          0 :                     sal_uInt16 nErr = pMat->GetErrorIfNotString( nC, nR);
    2788 [ #  # ][ #  # ]:          0 :                     nRes = (nErr && nErr != NOTAVAILABLE);
    2789                 :            :                 }
    2790         [ #  # ]:          0 :             }
    2791                 :            :         }
    2792                 :          0 :         break;
    2793                 :            :         default:
    2794                 :          6 :             PopError();
    2795 [ +  + ][ +  - ]:          6 :             if ( nGlobalError && nGlobalError != NOTAVAILABLE )
    2796                 :          3 :                 nRes = 1;
    2797                 :            :     }
    2798                 :         12 :     nGlobalError = 0;
    2799                 :         12 :     PushInt( nRes );
    2800                 :         12 : }
    2801                 :            : 
    2802                 :            : 
    2803                 :         18 : void ScInterpreter::ScIsError()
    2804                 :            : {
    2805                 :            :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScIsError" );
    2806                 :         18 :     nFuncFmtType = NUMBERFORMAT_LOGICAL;
    2807                 :         18 :     short nRes = 0;
    2808      [ +  -  + ]:         18 :     switch ( GetStackType() )
    2809                 :            :     {
    2810                 :            :         case svDoubleRef :
    2811                 :            :         case svSingleRef :
    2812                 :            :         {
    2813                 :         12 :             ScAddress aAdr;
    2814 [ -  + ][ +  - ]:         12 :             if ( !PopDoubleRefOrSingleRef( aAdr ) )
    2815                 :            :             {
    2816                 :          0 :                 nRes = 1;
    2817                 :            :                 break;
    2818                 :            :             }
    2819         [ -  + ]:         12 :             if ( nGlobalError )
    2820                 :          0 :                 nRes = 1;
    2821                 :            :             else
    2822                 :            :             {
    2823         [ +  - ]:         12 :                 ScBaseCell* pCell = GetCell( aAdr );
    2824         [ +  - ]:         12 :                 nRes = (GetCellErrCode( pCell ) != 0);
    2825                 :            :             }
    2826                 :            :         }
    2827                 :         12 :         break;
    2828                 :            :         case svMatrix:
    2829                 :            :         {
    2830         [ #  # ]:          0 :             ScMatrixRef pMat = PopMatrix();
    2831 [ #  # ][ #  # ]:          0 :             if ( nGlobalError || !pMat )
                 [ #  # ]
    2832                 :          0 :                 nRes = 1;
    2833         [ #  # ]:          0 :             else if ( !pJumpMatrix )
    2834         [ #  # ]:          0 :                 nRes = (pMat->GetErrorIfNotString( 0, 0) != 0);
    2835                 :            :             else
    2836                 :            :             {
    2837                 :            :                 SCSIZE nCols, nRows, nC, nR;
    2838         [ #  # ]:          0 :                 pMat->GetDimensions( nCols, nRows);
    2839                 :          0 :                 pJumpMatrix->GetPos( nC, nR);
    2840 [ #  # ][ #  # ]:          0 :                 if ( nC < nCols && nR < nRows )
    2841         [ #  # ]:          0 :                     nRes = (pMat->GetErrorIfNotString( nC, nR) != 0);
    2842         [ #  # ]:          0 :             }
    2843                 :            :         }
    2844                 :          0 :         break;
    2845                 :            :         default:
    2846                 :          6 :             PopError();
    2847         [ +  - ]:          6 :             if ( nGlobalError )
    2848                 :          6 :                 nRes = 1;
    2849                 :            :     }
    2850                 :         18 :     nGlobalError = 0;
    2851                 :         18 :     PushInt( nRes );
    2852                 :         18 : }
    2853                 :            : 
    2854                 :            : 
    2855                 :         27 : short ScInterpreter::IsEven()
    2856                 :            : {
    2857                 :            :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::IsEven" );
    2858                 :         27 :     nFuncFmtType = NUMBERFORMAT_LOGICAL;
    2859                 :         27 :     short nRes = 0;
    2860                 :         27 :     double fVal = 0.0;
    2861   [ -  +  -  - ]:         27 :     switch ( GetStackType() )
    2862                 :            :     {
    2863                 :            :         case svDoubleRef :
    2864                 :            :         case svSingleRef :
    2865                 :            :         {
    2866                 :          0 :             ScAddress aAdr;
    2867 [ #  # ][ #  # ]:          0 :             if ( !PopDoubleRefOrSingleRef( aAdr ) )
    2868                 :            :                 break;
    2869         [ #  # ]:          0 :             ScBaseCell* pCell = GetCell( aAdr );
    2870         [ #  # ]:          0 :             sal_uInt16 nErr = GetCellErrCode( pCell );
    2871         [ #  # ]:          0 :             if (nErr != 0)
    2872                 :          0 :                 SetError(nErr);
    2873                 :            :             else
    2874                 :            :             {
    2875      [ #  #  # ]:          0 :                 switch ( GetCellType( pCell ) )
    2876                 :            :                 {
    2877                 :            :                     case CELLTYPE_VALUE :
    2878         [ #  # ]:          0 :                         fVal = GetCellValue( aAdr, pCell );
    2879                 :          0 :                         nRes = 1;
    2880                 :          0 :                     break;
    2881                 :            :                     case CELLTYPE_FORMULA :
    2882 [ #  # ][ #  # ]:          0 :                         if( ((ScFormulaCell*)pCell)->IsValue() )
                 [ #  # ]
    2883                 :            :                         {
    2884         [ #  # ]:          0 :                             fVal = GetCellValue( aAdr, pCell );
    2885                 :          0 :                             nRes = 1;
    2886                 :            :                         }
    2887                 :          0 :                     break;
    2888                 :            :                     default:
    2889                 :            :                         ; // nothing
    2890                 :            :                 }
    2891                 :            :             }
    2892                 :            :         }
    2893                 :          0 :         break;
    2894                 :            :         case svDouble:
    2895                 :            :         {
    2896                 :         27 :             fVal = PopDouble();
    2897                 :         27 :             nRes = 1;
    2898                 :            :         }
    2899                 :         27 :         break;
    2900                 :            :         case svMatrix:
    2901                 :            :         {
    2902         [ #  # ]:          0 :             ScMatrixRef pMat = PopMatrix();
    2903         [ #  # ]:          0 :             if ( !pMat )
    2904                 :            :                 ;   // nothing
    2905         [ #  # ]:          0 :             else if ( !pJumpMatrix )
    2906                 :            :             {
    2907         [ #  # ]:          0 :                 nRes = pMat->IsValue( 0, 0);
    2908         [ #  # ]:          0 :                 if ( nRes )
    2909         [ #  # ]:          0 :                     fVal = pMat->GetDouble( 0, 0);
    2910                 :            :             }
    2911                 :            :             else
    2912                 :            :             {
    2913                 :            :                 SCSIZE nCols, nRows, nC, nR;
    2914         [ #  # ]:          0 :                 pMat->GetDimensions( nCols, nRows);
    2915                 :          0 :                 pJumpMatrix->GetPos( nC, nR);
    2916 [ #  # ][ #  # ]:          0 :                 if ( nC < nCols && nR < nRows )
    2917                 :            :                 {
    2918         [ #  # ]:          0 :                     nRes = pMat->IsValue( nC, nR);
    2919         [ #  # ]:          0 :                     if ( nRes )
    2920         [ #  # ]:          0 :                         fVal = pMat->GetDouble( nC, nR);
    2921                 :            :                 }
    2922                 :            :                 else
    2923                 :          0 :                     SetError( errNoValue);
    2924         [ #  # ]:          0 :             }
    2925                 :            :         }
    2926                 :          0 :         break;
    2927                 :            :         default:
    2928                 :            :             ; // nothing
    2929                 :            :     }
    2930         [ -  + ]:         27 :     if ( !nRes )
    2931                 :          0 :         SetError( errIllegalParameter);
    2932                 :            :     else
    2933                 :         27 :         nRes = ( fmod( ::rtl::math::approxFloor( fabs( fVal ) ), 2.0 ) < 0.5 );
    2934                 :         27 :     return nRes;
    2935                 :            : }
    2936                 :            : 
    2937                 :            : 
    2938                 :         12 : void ScInterpreter::ScIsEven()
    2939                 :            : {
    2940                 :            :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScIsEven" );
    2941                 :         12 :     PushInt( IsEven() );
    2942                 :         12 : }
    2943                 :            : 
    2944                 :            : 
    2945                 :         15 : void ScInterpreter::ScIsOdd()
    2946                 :            : {
    2947                 :            :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScIsOdd" );
    2948                 :         15 :     PushInt( !IsEven() );
    2949                 :         15 : }
    2950                 :            : 
    2951                 :        180 : void ScInterpreter::ScN()
    2952                 :            : {
    2953                 :            :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScN" );
    2954                 :        180 :     sal_uInt16 nErr = nGlobalError;
    2955                 :        180 :     nGlobalError = 0;
    2956                 :            :     // Temporarily override the ConvertStringToValue() error for
    2957                 :            :     // GetCellValue() / GetCellValueOrZero()
    2958                 :        180 :     sal_uInt16 nSErr = mnStringNoValueError;
    2959                 :        180 :     mnStringNoValueError = errCellNoValue;
    2960                 :        180 :     double fVal = GetDouble();
    2961                 :        180 :     mnStringNoValueError = nSErr;
    2962         [ -  + ]:        180 :     if (nErr)
    2963                 :          0 :         nGlobalError = nErr;    // preserve previous error if any
    2964         [ +  + ]:        180 :     else if (nGlobalError == errCellNoValue)
    2965                 :         30 :         nGlobalError = 0;       // reset temporary detection error
    2966                 :        180 :     PushDouble(fVal);
    2967                 :        180 : }
    2968                 :            : 
    2969                 :          0 : void ScInterpreter::ScTrim()
    2970                 :            : {
    2971                 :            :     // Doesn't only trim but also removes duplicated blanks within!
    2972 [ #  # ][ #  # ]:          0 :     String aVal = comphelper::string::strip(GetString(), ' ');
         [ #  # ][ #  # ]
    2973         [ #  # ]:          0 :     String aStr;
    2974                 :          0 :     register const sal_Unicode* p = aVal.GetBuffer();
    2975                 :          0 :     register const sal_Unicode* const pEnd = p + aVal.Len();
    2976         [ #  # ]:          0 :     while ( p < pEnd )
    2977                 :            :     {
    2978 [ #  # ][ #  # ]:          0 :         if ( *p != ' ' || p[-1] != ' ' )    // first can't be ' ', so -1 is fine
    2979         [ #  # ]:          0 :             aStr += *p;
    2980                 :          0 :         p++;
    2981                 :            :     }
    2982 [ #  # ][ #  # ]:          0 :     PushString( aStr );
                 [ #  # ]
    2983                 :          0 : }
    2984                 :            : 
    2985                 :            : 
    2986                 :          0 : void ScInterpreter::ScUpper()
    2987                 :            : {
    2988                 :            :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScTrim" );
    2989 [ #  # ][ #  # ]:          0 :     String aString = ScGlobal::pCharClass->uppercase(GetString());
         [ #  # ][ #  # ]
    2990 [ #  # ][ #  # ]:          0 :     PushString(aString);
    2991                 :          0 : }
    2992                 :            : 
    2993                 :            : 
    2994                 :          0 : void ScInterpreter::ScPropper()
    2995                 :            : {
    2996                 :            :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScPropper" );
    2997                 :            : //2do: what to do with I18N-CJK ?!?
    2998 [ #  # ][ #  # ]:          0 :     String aStr( GetString() );
    2999                 :          0 :     const xub_StrLen nLen = aStr.Len();
    3000                 :            :     // #i82487# don't try to write to empty string's BufferAccess
    3001                 :            :     // (would crash now that the empty string is const)
    3002         [ #  # ]:          0 :     if ( nLen > 0 )
    3003                 :            :     {
    3004 [ #  # ][ #  # ]:          0 :         String aUpr( ScGlobal::pCharClass->uppercase( aStr ) );
                 [ #  # ]
    3005 [ #  # ][ #  # ]:          0 :         String aLwr( ScGlobal::pCharClass->lowercase( aStr ) );
                 [ #  # ]
    3006         [ #  # ]:          0 :         register sal_Unicode* pStr = aStr.GetBufferAccess();
    3007                 :          0 :         const sal_Unicode* pUpr = aUpr.GetBuffer();
    3008                 :          0 :         const sal_Unicode* pLwr = aLwr.GetBuffer();
    3009                 :          0 :         *pStr = *pUpr;
    3010                 :          0 :         xub_StrLen nPos = 1;
    3011         [ #  # ]:          0 :         while( nPos < nLen )
    3012                 :            :         {
    3013                 :          0 :             rtl::OUString aTmpStr( pStr[nPos-1] );
    3014 [ #  # ][ #  # ]:          0 :             if ( !ScGlobal::pCharClass->isLetter( aTmpStr, 0 ) )
         [ #  # ][ #  # ]
    3015                 :          0 :                 pStr[nPos] = pUpr[nPos];
    3016                 :            :             else
    3017                 :          0 :                 pStr[nPos] = pLwr[nPos];
    3018                 :          0 :             nPos++;
    3019                 :          0 :         }
    3020 [ #  # ][ #  # ]:          0 :         aStr.ReleaseBufferAccess( nLen );
                 [ #  # ]
    3021                 :            :     }
    3022 [ #  # ][ #  # ]:          0 :     PushString( aStr );
    3023                 :          0 : }
    3024                 :            : 
    3025                 :            : 
    3026                 :          0 : void ScInterpreter::ScLower()
    3027                 :            : {
    3028                 :            :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScLower" );
    3029 [ #  # ][ #  # ]:          0 :     String aString = ScGlobal::pCharClass->lowercase(GetString());
         [ #  # ][ #  # ]
    3030 [ #  # ][ #  # ]:          0 :     PushString(aString);
    3031                 :          0 : }
    3032                 :            : 
    3033                 :            : 
    3034                 :          0 : void ScInterpreter::ScLen()
    3035                 :            : {
    3036                 :            :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScLen" );
    3037 [ #  # ][ #  # ]:          0 :     String aStr( GetString() );
    3038 [ #  # ][ #  # ]:          0 :     PushDouble( aStr.Len() );
    3039                 :          0 : }
    3040                 :            : 
    3041                 :            : 
    3042                 :          9 : void ScInterpreter::ScT()
    3043                 :            : {
    3044                 :            :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScT" );
    3045   [ -  +  -  -  :          9 :     switch ( GetStackType() )
                      - ]
    3046                 :            :     {
    3047                 :            :         case svDoubleRef :
    3048                 :            :         case svSingleRef :
    3049                 :            :         {
    3050                 :          0 :             ScAddress aAdr;
    3051 [ #  # ][ #  # ]:          0 :             if ( !PopDoubleRefOrSingleRef( aAdr ) )
    3052                 :            :             {
    3053         [ #  # ]:          0 :                 PushInt(0);
    3054                 :          9 :                 return ;
    3055                 :            :             }
    3056                 :          0 :             bool bValue = false;
    3057         [ #  # ]:          0 :             ScBaseCell* pCell = GetCell( aAdr );
    3058 [ #  # ][ #  # ]:          0 :             if ( GetCellErrCode( pCell ) == 0 )
    3059                 :            :             {
    3060      [ #  #  # ]:          0 :                 switch ( GetCellType( pCell ) )
    3061                 :            :                 {
    3062                 :            :                     case CELLTYPE_VALUE :
    3063                 :          0 :                         bValue = true;
    3064                 :          0 :                         break;
    3065                 :            :                     case CELLTYPE_FORMULA :
    3066 [ #  # ][ #  # ]:          0 :                         bValue = ((ScFormulaCell*)pCell)->IsValue();
    3067                 :          0 :                         break;
    3068                 :            :                     default:
    3069                 :            :                         ; // nothing
    3070                 :            :                 }
    3071                 :            :             }
    3072         [ #  # ]:          0 :             if ( bValue )
    3073 [ #  # ][ #  # ]:          0 :                 PushString( EMPTY_STRING );
    3074                 :            :             else
    3075                 :            :             {
    3076                 :            :                 // like GetString()
    3077         [ #  # ]:          0 :                 GetCellString( aTempStr, pCell );
    3078         [ #  # ]:          0 :                 PushString( aTempStr );
    3079                 :            :             }
    3080                 :            :         }
    3081                 :          0 :         break;
    3082                 :            :         case svMatrix:
    3083                 :            :         case svExternalSingleRef:
    3084                 :            :         case svExternalDoubleRef:
    3085                 :            :         {
    3086                 :            :             double fVal;
    3087         [ +  - ]:          9 :             String aStr;
    3088         [ +  - ]:          9 :             ScMatValType nMatValType = GetDoubleOrStringFromMatrix( fVal, aStr);
    3089         [ +  + ]:          9 :             if (ScMatrix::IsValueType( nMatValType))
    3090 [ +  - ][ +  - ]:          3 :                 PushString( EMPTY_STRING);
    3091                 :            :             else
    3092 [ +  - ][ +  - ]:          9 :                 PushString( aStr);
    3093                 :            :         }
    3094                 :          9 :         break;
    3095                 :            :         case svDouble :
    3096                 :            :         {
    3097                 :          0 :             PopError();
    3098                 :          0 :             PushString( EMPTY_STRING );
    3099                 :            :         }
    3100                 :          0 :         break;
    3101                 :            :         case svString :
    3102                 :            :             ;   // leave on stack
    3103                 :          0 :         break;
    3104                 :            :         default :
    3105                 :          0 :             PushError( errUnknownOpCode);
    3106                 :            :     }
    3107                 :            : }
    3108                 :            : 
    3109                 :            : 
    3110                 :          0 : void ScInterpreter::ScValue()
    3111                 :            : {
    3112                 :            :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScValue" );
    3113         [ #  # ]:          0 :     String aInputString;
    3114                 :            :     double fVal;
    3115                 :            : 
    3116 [ #  # ][ #  #  :          0 :     switch ( GetRawStackType() )
                #  #  # ]
    3117                 :            :     {
    3118                 :            :         case svMissing:
    3119                 :            :         case svEmptyCell:
    3120         [ #  # ]:          0 :             Pop();
    3121         [ #  # ]:          0 :             PushInt(0);
    3122                 :            :             return;
    3123                 :            :         case svDouble:
    3124                 :            :             return;     // leave on stack
    3125                 :            :             //break;
    3126                 :            : 
    3127                 :            :         case svSingleRef:
    3128                 :            :         case svDoubleRef:
    3129                 :            :             {
    3130                 :          0 :                 ScAddress aAdr;
    3131 [ #  # ][ #  # ]:          0 :                 if ( !PopDoubleRefOrSingleRef( aAdr ) )
    3132                 :            :                 {
    3133         [ #  # ]:          0 :                     PushInt(0);
    3134                 :            :                     return;
    3135                 :            :                 }
    3136         [ #  # ]:          0 :                 ScBaseCell* pCell = GetCell( aAdr );
    3137 [ #  # ][ #  # ]:          0 :                 if ( pCell && pCell->HasStringData() )
         [ #  # ][ #  # ]
    3138         [ #  # ]:          0 :                     GetCellString( aInputString, pCell );
    3139 [ #  # ][ #  # ]:          0 :                 else if ( pCell && pCell->HasValueData() )
         [ #  # ][ #  # ]
    3140                 :            :                 {
    3141 [ #  # ][ #  # ]:          0 :                     PushDouble( GetCellValue(aAdr, pCell) );
    3142                 :            :                     return;
    3143                 :            :                 }
    3144                 :            :                 else
    3145                 :            :                 {
    3146         [ #  # ]:          0 :                     PushDouble(0.0);
    3147                 :            :                     return;
    3148                 :            :                 }
    3149                 :            :             }
    3150                 :          0 :             break;
    3151                 :            :         case svMatrix:
    3152                 :            :             {
    3153                 :            :                 ScMatValType nType = GetDoubleOrStringFromMatrix( fVal,
    3154         [ #  # ]:          0 :                         aInputString);
    3155   [ #  #  #  # ]:          0 :                 switch (nType)
    3156                 :            :                 {
    3157                 :            :                     case SC_MATVAL_EMPTY:
    3158                 :          0 :                         fVal = 0.0;
    3159                 :            :                         // fallthru
    3160                 :            :                     case SC_MATVAL_VALUE:
    3161                 :            :                     case SC_MATVAL_BOOLEAN:
    3162         [ #  # ]:          0 :                         PushDouble( fVal);
    3163                 :            :                         return;
    3164                 :            :                         //break;
    3165                 :            :                     case SC_MATVAL_STRING:
    3166                 :            :                         // evaluated below
    3167                 :          0 :                         break;
    3168                 :            :                     default:
    3169         [ #  # ]:          0 :                         PushIllegalArgument();
    3170                 :            :                 }
    3171                 :            :             }
    3172                 :          0 :             break;
    3173                 :            :         default:
    3174 [ #  # ][ #  # ]:          0 :             aInputString = GetString();
    3175                 :          0 :             break;
    3176                 :            :     }
    3177                 :            : 
    3178                 :          0 :     sal_uInt32 nFIndex = 0;     // 0 for default locale
    3179 [ #  # ][ #  # ]:          0 :     if (pFormatter->IsNumberFormat(aInputString, nFIndex, fVal))
    3180         [ #  # ]:          0 :         PushDouble(fVal);
    3181                 :            :     else
    3182 [ #  # ][ #  # ]:          0 :         PushIllegalArgument();
                 [ #  # ]
    3183                 :            : }
    3184                 :            : 
    3185                 :            : 
    3186                 :            : //2do: this should be a proper unicode string method
    3187                 :          0 : inline bool lcl_ScInterpreter_IsPrintable( sal_Unicode c )
    3188                 :            : {
    3189 [ #  # ][ #  # ]:          0 :     return 0x20 <= c && c != 0x7f;
    3190                 :            : }
    3191                 :            : 
    3192                 :          0 : void ScInterpreter::ScClean()
    3193                 :            : {
    3194                 :            :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScClean" );
    3195 [ #  # ][ #  # ]:          0 :     String aStr( GetString() );
    3196         [ #  # ]:          0 :     for ( xub_StrLen i = 0; i < aStr.Len(); i++ )
    3197                 :            :     {
    3198         [ #  # ]:          0 :         if ( !lcl_ScInterpreter_IsPrintable( aStr.GetChar( i ) ) )
    3199         [ #  # ]:          0 :             aStr.Erase(i,1);
    3200                 :            :     }
    3201 [ #  # ][ #  # ]:          0 :     PushString(aStr);
    3202                 :          0 : }
    3203                 :            : 
    3204                 :            : 
    3205                 :          0 : void ScInterpreter::ScCode()
    3206                 :            : {
    3207                 :            :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScCode" );
    3208                 :            : //2do: make it full range unicode?
    3209                 :          0 :     const String& rStr = GetString();
    3210                 :            :     //"classic" ByteString conversion flags
    3211                 :            :     const sal_uInt32 convertFlags =
    3212                 :            :         RTL_UNICODETOTEXT_FLAGS_NONSPACING_IGNORE |
    3213                 :            :         RTL_UNICODETOTEXT_FLAGS_CONTROL_IGNORE |
    3214                 :            :         RTL_UNICODETOTEXT_FLAGS_FLUSH |
    3215                 :            :         RTL_UNICODETOTEXT_FLAGS_UNDEFINED_DEFAULT |
    3216                 :            :         RTL_UNICODETOTEXT_FLAGS_INVALID_DEFAULT |
    3217                 :          0 :         RTL_UNICODETOTEXT_FLAGS_UNDEFINED_REPLACE;
    3218 [ #  # ][ #  # ]:          0 :     PushInt( (sal_uChar) rtl::OUStringToOString(rtl::OUString(rStr.GetChar(0)), osl_getThreadTextEncoding(), convertFlags).toChar() );
    3219                 :          0 : }
    3220                 :            : 
    3221                 :            : 
    3222                 :          0 : void ScInterpreter::ScChar()
    3223                 :            : {
    3224                 :            :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScChar" );
    3225                 :            : //2do: make it full range unicode?
    3226                 :          0 :     double fVal = GetDouble();
    3227 [ #  # ][ #  # ]:          0 :     if (fVal < 0.0 || fVal >= 256.0)
    3228                 :          0 :         PushIllegalArgument();
    3229                 :            :     else
    3230                 :            :     {
    3231                 :            :         //"classic" ByteString conversion flags
    3232                 :            :         const sal_uInt32 convertFlags =
    3233                 :            :             RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_DEFAULT |
    3234                 :            :             RTL_TEXTTOUNICODE_FLAGS_MBUNDEFINED_DEFAULT |
    3235                 :          0 :             RTL_TEXTTOUNICODE_FLAGS_INVALID_DEFAULT;
    3236                 :            : 
    3237                 :          0 :         sal_Char cEncodedChar = static_cast<sal_Char>(fVal);
    3238 [ #  # ][ #  # ]:          0 :         rtl::OUString aStr(&cEncodedChar, 1,  osl_getThreadTextEncoding(), convertFlags);
    3239 [ #  # ][ #  # ]:          0 :         PushString(aStr);
                 [ #  # ]
    3240                 :            :     }
    3241                 :          0 : }
    3242                 :            : 
    3243                 :            : 
    3244                 :            : /* #i70213# fullwidth/halfwidth conversion provided by
    3245                 :            :  * Takashi Nakamoto <bluedwarf@ooo>
    3246                 :            :  * erAck: added Excel compatibility conversions as seen in issue's test case. */
    3247                 :            : 
    3248                 :          0 : static ::rtl::OUString lcl_convertIntoHalfWidth( const ::rtl::OUString & rStr )
    3249                 :            : {
    3250                 :            :     static bool bFirstASCCall = true;
    3251 [ #  # ][ #  # ]:          0 :     static utl::TransliterationWrapper aTrans( ::comphelper::getProcessServiceFactory(), 0 );
         [ #  # ][ #  # ]
                 [ #  # ]
    3252                 :            : 
    3253         [ #  # ]:          0 :     if( bFirstASCCall )
    3254                 :            :     {
    3255 [ #  # ][ #  # ]:          0 :         aTrans.loadModuleByImplName( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "FULLWIDTH_HALFWIDTH_LIKE_ASC" )), LANGUAGE_SYSTEM );
                 [ #  # ]
    3256                 :          0 :         bFirstASCCall = false;
    3257                 :            :     }
    3258                 :            : 
    3259 [ #  # ][ #  # ]:          0 :     return aTrans.transliterate( rStr, 0, sal_uInt16( rStr.getLength() ), NULL );
                 [ #  # ]
    3260                 :            : }
    3261                 :            : 
    3262                 :            : 
    3263                 :          0 : static ::rtl::OUString lcl_convertIntoFullWidth( const ::rtl::OUString & rStr )
    3264                 :            : {
    3265                 :            :     static bool bFirstJISCall = true;
    3266 [ #  # ][ #  # ]:          0 :     static utl::TransliterationWrapper aTrans( ::comphelper::getProcessServiceFactory(), 0 );
         [ #  # ][ #  # ]
                 [ #  # ]
    3267                 :            : 
    3268         [ #  # ]:          0 :     if( bFirstJISCall )
    3269                 :            :     {
    3270 [ #  # ][ #  # ]:          0 :         aTrans.loadModuleByImplName( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "HALFWIDTH_FULLWIDTH_LIKE_JIS" )), LANGUAGE_SYSTEM );
                 [ #  # ]
    3271                 :          0 :         bFirstJISCall = false;
    3272                 :            :     }
    3273                 :            : 
    3274 [ #  # ][ #  # ]:          0 :     return aTrans.transliterate( rStr, 0, sal_uInt16( rStr.getLength() ), NULL );
                 [ #  # ]
    3275                 :            : }
    3276                 :            : 
    3277                 :            : 
    3278                 :            : /* ODFF:
    3279                 :            :  * Summary: Converts half-width to full-width ASCII and katakana characters.
    3280                 :            :  * Semantics: Conversion is done for half-width ASCII and katakana characters,
    3281                 :            :  * other characters are simply copied from T to the result. This is the
    3282                 :            :  * complementary function to ASC.
    3283                 :            :  * For references regarding halfwidth and fullwidth characters see
    3284                 :            :  * http://www.unicode.org/reports/tr11/
    3285                 :            :  * http://www.unicode.org/charts/charindex2.html#H
    3286                 :            :  * http://www.unicode.org/charts/charindex2.html#F
    3287                 :            :  */
    3288                 :          0 : void ScInterpreter::ScJis()
    3289                 :            : {
    3290                 :            :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScJis" );
    3291         [ #  # ]:          0 :     if (MustHaveParamCount( GetByte(), 1))
    3292 [ #  # ][ #  # ]:          0 :         PushString( lcl_convertIntoFullWidth( GetString()));
         [ #  # ][ #  # ]
    3293                 :          0 : }
    3294                 :            : 
    3295                 :            : 
    3296                 :            : /* ODFF:
    3297                 :            :  * Summary: Converts full-width to half-width ASCII and katakana characters.
    3298                 :            :  * Semantics: Conversion is done for full-width ASCII and katakana characters,
    3299                 :            :  * other characters are simply copied from T to the result. This is the
    3300                 :            :  * complementary function to JIS.
    3301                 :            :  */
    3302                 :          0 : void ScInterpreter::ScAsc()
    3303                 :            : {
    3304                 :            :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScAsc" );
    3305         [ #  # ]:          0 :     if (MustHaveParamCount( GetByte(), 1))
    3306 [ #  # ][ #  # ]:          0 :         PushString( lcl_convertIntoHalfWidth( GetString()));
         [ #  # ][ #  # ]
    3307                 :          0 : }
    3308                 :            : 
    3309                 :          0 : void ScInterpreter::ScUnicode()
    3310                 :            : {
    3311                 :            :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScUnicode" );
    3312         [ #  # ]:          0 :     if ( MustHaveParamCount( GetByte(), 1 ) )
    3313                 :            :     {
    3314                 :          0 :         const rtl::OUString& rStr = GetString();
    3315         [ #  # ]:          0 :         if (rStr.isEmpty())
    3316         [ #  # ]:          0 :             PushIllegalParameter();
    3317                 :            :         else
    3318                 :            :         {
    3319                 :          0 :             sal_Int32 i = 0;
    3320 [ #  # ][ #  # ]:          0 :             PushDouble( rStr.iterateCodePoints(&i) );
    3321                 :          0 :         }
    3322                 :            :     }
    3323                 :          0 : }
    3324                 :            : 
    3325                 :          0 : void ScInterpreter::ScUnichar()
    3326                 :            : {
    3327                 :            :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScUnichar" );
    3328         [ #  # ]:          0 :     if ( MustHaveParamCount( GetByte(), 1 ) )
    3329                 :            :     {
    3330                 :          0 :         double dVal = ::rtl::math::approxFloor( GetDouble() );
    3331 [ #  # ][ #  # ]:          0 :         if ((dVal < 0x000000) || (dVal > 0x10FFFF))
    3332                 :          0 :             PushIllegalArgument();
    3333                 :            :         else
    3334                 :            :         {
    3335                 :          0 :             sal_uInt32 nCodePoint = static_cast<sal_uInt32>( dVal );
    3336         [ #  # ]:          0 :             rtl::OUString aStr( &nCodePoint, 1 );
    3337 [ #  # ][ #  # ]:          0 :             PushString( aStr );
                 [ #  # ]
    3338                 :            :         }
    3339                 :            :     }
    3340                 :          0 : }
    3341                 :            : 
    3342                 :            : 
    3343                 :          0 : void ScInterpreter::ScMin( bool bTextAsZero )
    3344                 :            : {
    3345                 :            :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScMin" );
    3346                 :          0 :     short nParamCount = GetByte();
    3347 [ #  # ][ #  # ]:          0 :     if (!MustHaveParamCountMin( nParamCount, 1))
    3348                 :          0 :         return;
    3349                 :          0 :     double nMin = ::std::numeric_limits<double>::max();
    3350                 :          0 :     double nVal = 0.0;
    3351                 :          0 :     ScAddress aAdr;
    3352                 :          0 :     ScRange aRange;
    3353                 :          0 :     size_t nRefInList = 0;
    3354         [ #  # ]:          0 :     while (nParamCount-- > 0)
    3355                 :            :     {
    3356 [ #  # ][ #  #  :          0 :         switch (GetStackType())
             #  #  #  # ]
    3357                 :            :         {
    3358                 :            :             case svDouble :
    3359                 :            :             {
    3360         [ #  # ]:          0 :                 nVal = GetDouble();
    3361         [ #  # ]:          0 :                 if (nMin > nVal) nMin = nVal;
    3362                 :          0 :                 nFuncFmtType = NUMBERFORMAT_NUMBER;
    3363                 :            :             }
    3364                 :          0 :             break;
    3365                 :            :             case svSingleRef :
    3366                 :            :             {
    3367         [ #  # ]:          0 :                 PopSingleRef( aAdr );
    3368         [ #  # ]:          0 :                 ScBaseCell* pCell = GetCell( aAdr );
    3369 [ #  # ][ #  # ]:          0 :                 if (HasCellValueData(pCell))
    3370                 :            :                 {
    3371         [ #  # ]:          0 :                     nVal = GetCellValue( aAdr, pCell );
    3372                 :          0 :                     CurFmtToFuncFmt();
    3373         [ #  # ]:          0 :                     if (nMin > nVal) nMin = nVal;
    3374                 :            :                 }
    3375 [ #  # ][ #  # ]:          0 :                 else if ( bTextAsZero && HasCellStringData( pCell ) )
         [ #  # ][ #  # ]
    3376                 :            :                 {
    3377         [ #  # ]:          0 :                     if ( nMin > 0.0 )
    3378                 :          0 :                         nMin = 0.0;
    3379                 :            :                 }
    3380                 :            :             }
    3381                 :          0 :             break;
    3382                 :            :             case svDoubleRef :
    3383                 :            :             case svRefList :
    3384                 :            :             {
    3385                 :          0 :                 sal_uInt16 nErr = 0;
    3386         [ #  # ]:          0 :                 PopDoubleRef( aRange, nParamCount, nRefInList);
    3387         [ #  # ]:          0 :                 ScValueIterator aValIter( pDok, aRange, glSubTotal, bTextAsZero );
    3388 [ #  # ][ #  # ]:          0 :                 if (aValIter.GetFirst(nVal, nErr))
    3389                 :            :                 {
    3390         [ #  # ]:          0 :                     if (nMin > nVal)
    3391                 :          0 :                         nMin = nVal;
    3392         [ #  # ]:          0 :                     aValIter.GetCurNumFmtInfo( nFuncFmtType, nFuncFmtIndex );
    3393 [ #  # ][ #  # ]:          0 :                     while ((nErr == 0) && aValIter.GetNext(nVal, nErr))
         [ #  # ][ #  # ]
    3394                 :            :                     {
    3395         [ #  # ]:          0 :                         if (nMin > nVal)
    3396                 :          0 :                             nMin = nVal;
    3397                 :            :                     }
    3398                 :          0 :                     SetError(nErr);
    3399                 :            :                 }
    3400                 :            :             }
    3401                 :          0 :             break;
    3402                 :            :             case svMatrix :
    3403                 :            :             case svExternalSingleRef:
    3404                 :            :             case svExternalDoubleRef:
    3405                 :            :             {
    3406         [ #  # ]:          0 :                 ScMatrixRef pMat = GetMatrix();
    3407         [ #  # ]:          0 :                 if (pMat)
    3408                 :            :                 {
    3409                 :            :                     SCSIZE nC, nR;
    3410                 :          0 :                     nFuncFmtType = NUMBERFORMAT_NUMBER;
    3411         [ #  # ]:          0 :                     pMat->GetDimensions(nC, nR);
    3412 [ #  # ][ #  # ]:          0 :                     if (pMat->IsNumeric())
    3413                 :            :                     {
    3414         [ #  # ]:          0 :                         for (SCSIZE nMatCol = 0; nMatCol < nC; nMatCol++)
    3415         [ #  # ]:          0 :                             for (SCSIZE nMatRow = 0; nMatRow < nR; nMatRow++)
    3416                 :            :                             {
    3417         [ #  # ]:          0 :                                 nVal = pMat->GetDouble(nMatCol,nMatRow);
    3418         [ #  # ]:          0 :                                 if (nMin > nVal) nMin = nVal;
    3419                 :            :                             }
    3420                 :            :                     }
    3421                 :            :                     else
    3422                 :            :                     {
    3423         [ #  # ]:          0 :                         for (SCSIZE nMatCol = 0; nMatCol < nC; nMatCol++)
    3424                 :            :                         {
    3425         [ #  # ]:          0 :                             for (SCSIZE nMatRow = 0; nMatRow < nR; nMatRow++)
    3426                 :            :                             {
    3427 [ #  # ][ #  # ]:          0 :                                 if (!pMat->IsString(nMatCol,nMatRow))
    3428                 :            :                                 {
    3429         [ #  # ]:          0 :                                     nVal = pMat->GetDouble(nMatCol,nMatRow);
    3430         [ #  # ]:          0 :                                     if (nMin > nVal) nMin = nVal;
    3431                 :            :                                 }
    3432         [ #  # ]:          0 :                                 else if ( bTextAsZero )
    3433                 :            :                                 {
    3434         [ #  # ]:          0 :                                     if ( nMin > 0.0 )
    3435                 :          0 :                                         nMin = 0.0;
    3436                 :            :                                 }
    3437                 :            :                             }
    3438                 :            :                          }
    3439                 :            :                     }
    3440         [ #  # ]:          0 :                 }
    3441                 :            :             }
    3442                 :          0 :             break;
    3443                 :            :             case svString :
    3444                 :            :             {
    3445         [ #  # ]:          0 :                 Pop();
    3446         [ #  # ]:          0 :                 if ( bTextAsZero )
    3447                 :            :                 {
    3448         [ #  # ]:          0 :                     if ( nMin > 0.0 )
    3449                 :          0 :                         nMin = 0.0;
    3450                 :            :                 }
    3451                 :            :                 else
    3452                 :          0 :                     SetError(errIllegalParameter);
    3453                 :            :             }
    3454                 :          0 :             break;
    3455                 :            :             default :
    3456         [ #  # ]:          0 :                 Pop();
    3457                 :          0 :                 SetError(errIllegalParameter);
    3458                 :            :         }
    3459                 :            :     }
    3460         [ #  # ]:          0 :     if ( nVal < nMin  )
    3461         [ #  # ]:          0 :         PushDouble(0.0);
    3462                 :            :     else
    3463         [ #  # ]:          0 :         PushDouble(nMin);
    3464                 :            : }
    3465                 :            : 
    3466                 :          0 : void ScInterpreter::ScMax( bool bTextAsZero )
    3467                 :            : {
    3468                 :            :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScMax" );
    3469                 :          0 :     short nParamCount = GetByte();
    3470 [ #  # ][ #  # ]:          0 :     if (!MustHaveParamCountMin( nParamCount, 1))
    3471                 :          0 :         return;
    3472                 :          0 :     double nMax = -(::std::numeric_limits<double>::max());
    3473                 :          0 :     double nVal = 0.0;
    3474                 :          0 :     ScAddress aAdr;
    3475                 :          0 :     ScRange aRange;
    3476                 :          0 :     size_t nRefInList = 0;
    3477         [ #  # ]:          0 :     while (nParamCount-- > 0)
    3478                 :            :     {
    3479 [ #  # ][ #  #  :          0 :         switch (GetStackType())
             #  #  #  # ]
    3480                 :            :         {
    3481                 :            :             case svDouble :
    3482                 :            :             {
    3483         [ #  # ]:          0 :                 nVal = GetDouble();
    3484         [ #  # ]:          0 :                 if (nMax < nVal) nMax = nVal;
    3485                 :          0 :                 nFuncFmtType = NUMBERFORMAT_NUMBER;
    3486                 :            :             }
    3487                 :          0 :             break;
    3488                 :            :             case svSingleRef :
    3489                 :            :             {
    3490         [ #  # ]:          0 :                 PopSingleRef( aAdr );
    3491         [ #  # ]:          0 :                 ScBaseCell* pCell = GetCell( aAdr );
    3492 [ #  # ][ #  # ]:          0 :                 if (HasCellValueData(pCell))
    3493                 :            :                 {
    3494         [ #  # ]:          0 :                     nVal = GetCellValue( aAdr, pCell );
    3495                 :          0 :                     CurFmtToFuncFmt();
    3496         [ #  # ]:          0 :                     if (nMax < nVal) nMax = nVal;
    3497                 :            :                 }
    3498 [ #  # ][ #  # ]:          0 :                 else if ( bTextAsZero && HasCellStringData( pCell ) )
         [ #  # ][ #  # ]
    3499                 :            :                 {
    3500         [ #  # ]:          0 :                     if ( nMax < 0.0 )
    3501                 :          0 :                         nMax = 0.0;
    3502                 :            :                 }
    3503                 :            :             }
    3504                 :          0 :             break;
    3505                 :            :             case svDoubleRef :
    3506                 :            :             case svRefList :
    3507                 :            :             {
    3508                 :          0 :                 sal_uInt16 nErr = 0;
    3509         [ #  # ]:          0 :                 PopDoubleRef( aRange, nParamCount, nRefInList);
    3510         [ #  # ]:          0 :                 ScValueIterator aValIter( pDok, aRange, glSubTotal, bTextAsZero );
    3511 [ #  # ][ #  # ]:          0 :                 if (aValIter.GetFirst(nVal, nErr))
    3512                 :            :                 {
    3513         [ #  # ]:          0 :                     if (nMax < nVal)
    3514                 :          0 :                         nMax = nVal;
    3515         [ #  # ]:          0 :                     aValIter.GetCurNumFmtInfo( nFuncFmtType, nFuncFmtIndex );
    3516 [ #  # ][ #  # ]:          0 :                     while ((nErr == 0) && aValIter.GetNext(nVal, nErr))
         [ #  # ][ #  # ]
    3517                 :            :                     {
    3518         [ #  # ]:          0 :                         if (nMax < nVal)
    3519                 :          0 :                             nMax = nVal;
    3520                 :            :                     }
    3521                 :          0 :                     SetError(nErr);
    3522                 :            :                 }
    3523                 :            :             }
    3524                 :          0 :             break;
    3525                 :            :             case svMatrix :
    3526                 :            :             case svExternalSingleRef:
    3527                 :            :             case svExternalDoubleRef:
    3528                 :            :             {
    3529         [ #  # ]:          0 :                 ScMatrixRef pMat = GetMatrix();
    3530         [ #  # ]:          0 :                 if (pMat)
    3531                 :            :                 {
    3532                 :          0 :                     nFuncFmtType = NUMBERFORMAT_NUMBER;
    3533                 :            :                     SCSIZE nC, nR;
    3534         [ #  # ]:          0 :                     pMat->GetDimensions(nC, nR);
    3535 [ #  # ][ #  # ]:          0 :                     if (pMat->IsNumeric())
    3536                 :            :                     {
    3537         [ #  # ]:          0 :                         for (SCSIZE nMatCol = 0; nMatCol < nC; nMatCol++)
    3538         [ #  # ]:          0 :                             for (SCSIZE nMatRow = 0; nMatRow < nR; nMatRow++)
    3539                 :            :                             {
    3540         [ #  # ]:          0 :                                 nVal = pMat->GetDouble(nMatCol,nMatRow);
    3541         [ #  # ]:          0 :                                 if (nMax < nVal) nMax = nVal;
    3542                 :            :                             }
    3543                 :            :                     }
    3544                 :            :                     else
    3545                 :            :                     {
    3546         [ #  # ]:          0 :                         for (SCSIZE nMatCol = 0; nMatCol < nC; nMatCol++)
    3547                 :            :                         {
    3548         [ #  # ]:          0 :                             for (SCSIZE nMatRow = 0; nMatRow < nR; nMatRow++)
    3549                 :            :                             {
    3550 [ #  # ][ #  # ]:          0 :                                 if (!pMat->IsString(nMatCol,nMatRow))
    3551                 :            :                                 {
    3552         [ #  # ]:          0 :                                     nVal = pMat->GetDouble(nMatCol,nMatRow);
    3553         [ #  # ]:          0 :                                     if (nMax < nVal) nMax = nVal;
    3554                 :            :                                 }
    3555         [ #  # ]:          0 :                                 else if ( bTextAsZero )
    3556                 :            :                                 {
    3557         [ #  # ]:          0 :                                     if ( nMax < 0.0 )
    3558                 :          0 :                                         nMax = 0.0;
    3559                 :            :                                 }
    3560                 :            :                             }
    3561                 :            :                         }
    3562                 :            :                     }
    3563         [ #  # ]:          0 :                 }
    3564                 :            :             }
    3565                 :          0 :             break;
    3566                 :            :             case svString :
    3567                 :            :             {
    3568         [ #  # ]:          0 :                 Pop();
    3569         [ #  # ]:          0 :                 if ( bTextAsZero )
    3570                 :            :                 {
    3571         [ #  # ]:          0 :                     if ( nMax < 0.0 )
    3572                 :          0 :                         nMax = 0.0;
    3573                 :            :                 }
    3574                 :            :                 else
    3575                 :          0 :                     SetError(errIllegalParameter);
    3576                 :            :             }
    3577                 :          0 :             break;
    3578                 :            :             default :
    3579         [ #  # ]:          0 :                 Pop();
    3580                 :          0 :                 SetError(errIllegalParameter);
    3581                 :            :         }
    3582                 :            :     }
    3583         [ #  # ]:          0 :     if ( nVal > nMax  )
    3584         [ #  # ]:          0 :         PushDouble(0.0);
    3585                 :            :     else
    3586         [ #  # ]:          0 :         PushDouble(nMax);
    3587                 :            : }
    3588                 :            : #if defined(WIN) && defined(MSC)
    3589                 :            : #pragma optimize("",on)
    3590                 :            : #endif
    3591                 :            : 
    3592                 :            : namespace {
    3593                 :            : 
    3594                 :         21 : void IterateMatrix(
    3595                 :            :     const ScMatrixRef& pMat, ScIterFunc eFunc, bool bTextAsZero,
    3596                 :            :     sal_uLong& rCount, short& rFuncFmtType, double& fRes, double& fMem, bool& bNull)
    3597                 :            : {
    3598         [ -  + ]:         21 :     if (!pMat)
    3599                 :         21 :         return;
    3600                 :            : 
    3601                 :         21 :     rFuncFmtType = NUMBERFORMAT_NUMBER;
    3602   [ +  +  -  +  :         21 :     switch (eFunc)
                   -  - ]
    3603                 :            :     {
    3604                 :            :         case ifAVERAGE:
    3605                 :            :         case ifSUM:
    3606                 :            :         {
    3607         [ +  - ]:         12 :             ScMatrix::IterateResult aRes = pMat->Sum(bTextAsZero);
    3608         [ +  - ]:         12 :             if (bNull)
    3609                 :            :             {
    3610                 :         12 :                 bNull = false;
    3611                 :         12 :                 fMem = aRes.mfFirst;
    3612                 :         12 :                 fRes += aRes.mfRest;
    3613                 :            :             }
    3614                 :            :             else
    3615                 :          0 :                 fRes += aRes.mfFirst + aRes.mfRest;
    3616                 :         12 :             rCount += aRes.mnCount;
    3617                 :            :         }
    3618                 :         12 :         break;
    3619                 :            :         case ifCOUNT:
    3620                 :          6 :             rCount += pMat->Count(bTextAsZero);
    3621                 :          6 :         break;
    3622                 :            :         case ifCOUNT2:
    3623                 :          0 :             rCount += pMat->Count(true);
    3624                 :          0 :         break;
    3625                 :            :         case ifPRODUCT:
    3626                 :            :         {
    3627         [ +  - ]:          3 :             ScMatrix::IterateResult aRes = pMat->Product(bTextAsZero);
    3628                 :          3 :             fRes *= aRes.mfRest;
    3629                 :          3 :             rCount += aRes.mnCount;
    3630                 :            :         }
    3631                 :          3 :         break;
    3632                 :            :         case ifSUMSQ:
    3633                 :            :         {
    3634         [ #  # ]:          0 :             ScMatrix::IterateResult aRes = pMat->SumSquare(bTextAsZero);
    3635                 :          0 :             fRes += aRes.mfRest;
    3636                 :          0 :             rCount += aRes.mnCount;
    3637                 :            :         }
    3638                 :          0 :         break;
    3639                 :            :         default:
    3640                 :            :             ;
    3641                 :            :     }
    3642                 :            : }
    3643                 :            : 
    3644                 :            : }
    3645                 :            : 
    3646                 :        135 : double ScInterpreter::IterateParameters( ScIterFunc eFunc, bool bTextAsZero )
    3647                 :            : {
    3648                 :            :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::IterateParameters" );
    3649                 :        135 :     short nParamCount = GetByte();
    3650         [ +  + ]:        135 :     double fRes = ( eFunc == ifPRODUCT ) ? 1.0 : 0.0;
    3651                 :        135 :     double fVal = 0.0;
    3652                 :        135 :     double fMem = 0.0; // first numeric value.
    3653                 :        135 :     bool bNull = true;
    3654                 :        135 :     sal_uLong nCount = 0;
    3655                 :        135 :     ScAddress aAdr;
    3656                 :        135 :     ScRange aRange;
    3657                 :        135 :     size_t nRefInList = 0;
    3658 [ #  # ][ #  # ]:        135 :     if ( nGlobalError && ( eFunc == ifCOUNT2 || eFunc == ifCOUNT ) )
                 [ -  + ]
    3659                 :          0 :         nGlobalError = 0;
    3660         [ +  + ]:        288 :     while (nParamCount-- > 0)
    3661                 :            :     {
    3662 [ +  - ][ -  +  :        153 :         switch (GetStackType())
          -  -  +  +  +  
                   -  - ]
    3663                 :            :         {
    3664                 :            : 
    3665                 :            :             case svString:
    3666                 :            :             {
    3667         [ #  # ]:          0 :                 if( eFunc == ifCOUNT )
    3668                 :            :                 {
    3669 [ #  # ][ #  # ]:          0 :                     String aStr( PopString() );
    3670                 :          0 :                     sal_uInt32 nFIndex = 0;                 // damit default Land/Spr.
    3671 [ #  # ][ #  # ]:          0 :                     if ( bTextAsZero || pFormatter->IsNumberFormat(aStr, nFIndex, fVal))
         [ #  # ][ #  # ]
    3672         [ #  # ]:          0 :                         nCount++;
    3673                 :            :                 }
    3674                 :            :                 else
    3675                 :            :                 {
    3676         [ #  # ]:          0 :                     switch ( eFunc )
    3677                 :            :                     {
    3678                 :            :                         case ifAVERAGE:
    3679                 :            :                         case ifSUM:
    3680                 :            :                         case ifSUMSQ:
    3681                 :            :                         case ifPRODUCT:
    3682                 :            :                         {
    3683         [ #  # ]:          0 :                             if ( bTextAsZero )
    3684                 :            :                             {
    3685         [ #  # ]:          0 :                                 Pop();
    3686                 :          0 :                                 nCount++;
    3687         [ #  # ]:          0 :                                 if ( eFunc == ifPRODUCT )
    3688                 :          0 :                                     fRes = 0.0;
    3689                 :            :                             }
    3690                 :            :                             else
    3691                 :            :                             {
    3692         [ #  # ]:          0 :                                 while (nParamCount-- > 0)
    3693         [ #  # ]:          0 :                                     Pop();
    3694                 :          0 :                                 SetError( errNoValue );
    3695                 :            :                             }
    3696                 :            :                         }
    3697                 :          0 :                         break;
    3698                 :            :                         default:
    3699         [ #  # ]:          0 :                             Pop();
    3700                 :          0 :                             nCount++;
    3701                 :            :                     }
    3702                 :            :                 }
    3703                 :            :             }
    3704                 :          0 :             break;
    3705                 :            :             case svDouble    :
    3706         [ +  - ]:         27 :                 fVal = GetDouble();
    3707                 :         27 :                 nCount++;
    3708   [ +  -  -  - ]:         27 :                 switch( eFunc )
    3709                 :            :                 {
    3710                 :            :                     case ifAVERAGE:
    3711                 :            :                     case ifSUM:
    3712 [ +  + ][ +  + ]:         27 :                         if ( bNull && fVal != 0.0 )
    3713                 :            :                         {
    3714                 :          9 :                             bNull = false;
    3715                 :          9 :                             fMem = fVal;
    3716                 :            :                         }
    3717                 :            :                         else
    3718                 :         18 :                             fRes += fVal;
    3719                 :         27 :                         break;
    3720                 :          0 :                     case ifSUMSQ:   fRes += fVal * fVal; break;
    3721                 :          0 :                     case ifPRODUCT: fRes *= fVal; break;
    3722                 :            :                     default: ; // nothing
    3723                 :            :                 }
    3724                 :         27 :                 nFuncFmtType = NUMBERFORMAT_NUMBER;
    3725                 :         27 :                 break;
    3726                 :            :             case svExternalSingleRef:
    3727                 :            :             {
    3728                 :          0 :                 ScExternalRefCache::TokenRef pToken;
    3729         [ #  # ]:          0 :                 ScExternalRefCache::CellFormat aFmt;
    3730         [ #  # ]:          0 :                 PopExternalSingleRef(pToken, &aFmt);
    3731 [ #  # ][ #  # ]:          0 :                 if (nGlobalError && (eFunc == ifCOUNT2 || eFunc == ifCOUNT))
                 [ #  # ]
    3732                 :            :                 {
    3733                 :          0 :                     nGlobalError = 0;
    3734         [ #  # ]:          0 :                     if ( eFunc == ifCOUNT2 )
    3735                 :          0 :                         ++nCount;
    3736                 :            :                     break;
    3737                 :            :                 }
    3738                 :            : 
    3739         [ #  # ]:          0 :                 if (!pToken)
    3740                 :            :                     break;
    3741                 :            : 
    3742                 :          0 :                 StackVar eType = pToken->GetType();
    3743         [ #  # ]:          0 :                 if (eFunc == ifCOUNT2)
    3744                 :            :                 {
    3745         [ #  # ]:          0 :                     if (eType != formula::svEmptyCell)
    3746                 :          0 :                         nCount++;
    3747         [ #  # ]:          0 :                     if (nGlobalError)
    3748                 :          0 :                         nGlobalError = 0;
    3749                 :            :                 }
    3750         [ #  # ]:          0 :                 else if (eType == formula::svDouble)
    3751                 :            :                 {
    3752                 :          0 :                     nCount++;
    3753         [ #  # ]:          0 :                     fVal = pToken->GetDouble();
    3754         [ #  # ]:          0 :                     if (aFmt.mbIsSet)
    3755                 :            :                     {
    3756                 :          0 :                         nFuncFmtType = aFmt.mnType;
    3757                 :          0 :                         nFuncFmtIndex = aFmt.mnIndex;
    3758                 :            :                     }
    3759   [ #  #  #  #  :          0 :                     switch( eFunc )
                      # ]
    3760                 :            :                     {
    3761                 :            :                         case ifAVERAGE:
    3762                 :            :                         case ifSUM:
    3763 [ #  # ][ #  # ]:          0 :                             if ( bNull && fVal != 0.0 )
    3764                 :            :                             {
    3765                 :          0 :                                 bNull = false;
    3766                 :          0 :                                 fMem = fVal;
    3767                 :            :                             }
    3768                 :            :                             else
    3769                 :          0 :                                 fRes += fVal;
    3770                 :          0 :                             break;
    3771                 :          0 :                         case ifSUMSQ:   fRes += fVal * fVal; break;
    3772                 :          0 :                         case ifPRODUCT: fRes *= fVal; break;
    3773                 :            :                         case ifCOUNT:
    3774         [ #  # ]:          0 :                             if ( nGlobalError )
    3775                 :            :                             {
    3776                 :          0 :                                 nGlobalError = 0;
    3777                 :          0 :                                 nCount--;
    3778                 :            :                             }
    3779                 :          0 :                             break;
    3780                 :            :                         default: ; // nothing
    3781                 :            :                     }
    3782                 :            :                 }
    3783 [ #  # ][ #  # ]:          0 :                 else if (bTextAsZero && eType == formula::svString)
    3784                 :            :                 {
    3785                 :          0 :                     nCount++;
    3786         [ #  # ]:          0 :                     if ( eFunc == ifPRODUCT )
    3787                 :          0 :                         fRes = 0.0;
    3788 [ #  # ][ #  # ]:          0 :                 }
    3789                 :            :             }
    3790                 :          0 :             break;
    3791                 :            :             case svSingleRef :
    3792                 :            :             {
    3793         [ #  # ]:          0 :                 PopSingleRef( aAdr );
    3794 [ #  # ][ #  # ]:          0 :                 if ( nGlobalError && ( eFunc == ifCOUNT2 || eFunc == ifCOUNT ) )
                 [ #  # ]
    3795                 :            :                 {
    3796                 :          0 :                     nGlobalError = 0;
    3797         [ #  # ]:          0 :                     if ( eFunc == ifCOUNT2 )
    3798                 :          0 :                         ++nCount;
    3799                 :          0 :                     break;
    3800                 :            :                 }
    3801         [ #  # ]:          0 :                 ScBaseCell* pCell = GetCell( aAdr );
    3802         [ #  # ]:          0 :                 if ( pCell )
    3803                 :            :                 {
    3804         [ #  # ]:          0 :                     if( eFunc == ifCOUNT2 )
    3805                 :            :                     {
    3806                 :          0 :                         CellType eCellType = pCell->GetCellType();
    3807 [ #  # ][ #  # ]:          0 :                         if (eCellType != CELLTYPE_NONE && eCellType != CELLTYPE_NOTE)
    3808                 :          0 :                             nCount++;
    3809         [ #  # ]:          0 :                         if ( nGlobalError )
    3810                 :          0 :                             nGlobalError = 0;
    3811                 :            :                     }
    3812 [ #  # ][ #  # ]:          0 :                     else if ( pCell->HasValueData() )
    3813                 :            :                     {
    3814                 :          0 :                         nCount++;
    3815         [ #  # ]:          0 :                         fVal = GetCellValue( aAdr, pCell );
    3816                 :          0 :                         CurFmtToFuncFmt();
    3817   [ #  #  #  #  :          0 :                         switch( eFunc )
                      # ]
    3818                 :            :                         {
    3819                 :            :                             case ifAVERAGE:
    3820                 :            :                             case ifSUM:
    3821 [ #  # ][ #  # ]:          0 :                                 if ( bNull && fVal != 0.0 )
    3822                 :            :                                 {
    3823                 :          0 :                                     bNull = false;
    3824                 :          0 :                                     fMem = fVal;
    3825                 :            :                                 }
    3826                 :            :                                 else
    3827                 :          0 :                                     fRes += fVal;
    3828                 :          0 :                                 break;
    3829                 :          0 :                             case ifSUMSQ:   fRes += fVal * fVal; break;
    3830                 :          0 :                             case ifPRODUCT: fRes *= fVal; break;
    3831                 :            :                             case ifCOUNT:
    3832         [ #  # ]:          0 :                                 if ( nGlobalError )
    3833                 :            :                                 {
    3834                 :          0 :                                     nGlobalError = 0;
    3835                 :          0 :                                     nCount--;
    3836                 :            :                                 }
    3837                 :          0 :                                 break;
    3838                 :            :                             default: ; // nothing
    3839                 :            :                         }
    3840                 :            :                     }
    3841 [ #  # ][ #  # ]:          0 :                     else if ( bTextAsZero && pCell->HasStringData() )
         [ #  # ][ #  # ]
    3842                 :            :                     {
    3843                 :          0 :                         nCount++;
    3844         [ #  # ]:          0 :                         if ( eFunc == ifPRODUCT )
    3845                 :          0 :                             fRes = 0.0;
    3846                 :            :                     }
    3847                 :            :                 }
    3848                 :            :             }
    3849                 :          0 :             break;
    3850                 :            :             case svDoubleRef :
    3851                 :            :             case svRefList :
    3852                 :            :             {
    3853         [ +  - ]:        105 :                 PopDoubleRef( aRange, nParamCount, nRefInList);
    3854 [ -  + ][ #  # ]:        105 :                 if ( nGlobalError && ( eFunc == ifCOUNT2 || eFunc == ifCOUNT ) )
                 [ #  # ]
    3855                 :            :                 {
    3856                 :          0 :                     nGlobalError = 0;
    3857         [ #  # ]:          0 :                     if ( eFunc == ifCOUNT2 )
    3858                 :          0 :                         ++nCount;
    3859                 :          0 :                     break;
    3860                 :            :                 }
    3861         [ +  + ]:        105 :                 if( eFunc == ifCOUNT2 )
    3862                 :            :                 {
    3863                 :            :                     ScBaseCell* pCell;
    3864         [ +  - ]:          3 :                     ScCellIterator aIter( pDok, aRange, glSubTotal );
    3865 [ +  - ][ +  - ]:          3 :                     if ( (pCell = aIter.GetFirst()) != NULL )
    3866                 :            :                     {
    3867 [ +  - ][ +  + ]:         36 :                         do
    3868                 :            :                         {
    3869                 :         36 :                             CellType eType = pCell->GetCellType();
    3870 [ +  - ][ +  - ]:         36 :                             if( eType != CELLTYPE_NONE && eType != CELLTYPE_NOTE )
    3871                 :         36 :                                 nCount++;
    3872                 :            :                         }
    3873                 :            :                         while ( (pCell = aIter.GetNext()) != NULL );
    3874                 :            :                     }
    3875         [ -  + ]:          3 :                     if ( nGlobalError )
    3876                 :          3 :                         nGlobalError = 0;
    3877                 :            :                 }
    3878                 :            :                 else
    3879                 :            :                 {
    3880         [ +  - ]:        102 :                     ScValueIterator aValIter( pDok, aRange, glSubTotal, bTextAsZero );
    3881                 :        102 :                     sal_uInt16 nErr = 0;
    3882 [ +  - ][ +  + ]:        102 :                     if (aValIter.GetFirst(fVal, nErr))
    3883                 :            :                     {
    3884                 :            :                         // placed the loop on the inside for performance reasons:
    3885         [ +  - ]:         81 :                         aValIter.GetCurNumFmtInfo( nFuncFmtType, nFuncFmtIndex );
    3886   [ +  -  +  +  :         81 :                         switch( eFunc )
                      - ]
    3887                 :            :                         {
    3888                 :            :                             case ifAVERAGE:
    3889                 :            :                             case ifSUM:
    3890 [ +  - ][ +  + ]:        427 :                                     do
    3891                 :            :                                     {
    3892                 :        427 :                                         SetError(nErr);
    3893 [ +  + ][ +  + ]:        427 :                                         if ( bNull && fVal != 0.0 )
    3894                 :            :                                         {
    3895                 :         72 :                                             bNull = false;
    3896                 :         72 :                                             fMem = fVal;
    3897                 :            :                                         }
    3898                 :            :                                         else
    3899                 :        355 :                                             fRes += fVal;
    3900                 :        427 :                                         nCount++;
    3901                 :            :                                     }
    3902                 :            :                                     while (aValIter.GetNext(fVal, nErr));
    3903                 :         72 :                                     break;
    3904                 :            :                             case ifSUMSQ:
    3905 [ #  # ][ #  # ]:          0 :                                     do
    3906                 :            :                                     {
    3907                 :          0 :                                         SetError(nErr);
    3908                 :          0 :                                         fRes += fVal * fVal;
    3909                 :          0 :                                         nCount++;
    3910                 :            :                                     }
    3911                 :            :                                     while (aValIter.GetNext(fVal, nErr));
    3912                 :          0 :                                     break;
    3913                 :            :                             case ifPRODUCT:
    3914 [ +  + ][ +  - ]:         18 :                                     do
    3915                 :            :                                     {
    3916                 :         18 :                                         SetError(nErr);
    3917                 :         18 :                                         fRes *= fVal;
    3918                 :         18 :                                         nCount++;
    3919                 :            :                                     }
    3920                 :            :                                     while (aValIter.GetNext(fVal, nErr));
    3921                 :          6 :                                     break;
    3922                 :            :                             case ifCOUNT:
    3923 [ +  - ][ +  + ]:         18 :                                     do
    3924                 :            :                                     {
    3925         [ +  + ]:         18 :                                         if ( !nErr )
    3926                 :         15 :                                             nCount++;
    3927                 :            :                                     }
    3928                 :            :                                     while (aValIter.GetNext(fVal, nErr));
    3929                 :          3 :                                     break;
    3930                 :            :                             default: ;  // nothing
    3931                 :            :                         }
    3932                 :        102 :                         SetError( nErr );
    3933                 :            :                     }
    3934                 :            :                 }
    3935                 :            :             }
    3936                 :        105 :             break;
    3937                 :            :             case svExternalDoubleRef:
    3938                 :            :             {
    3939                 :         18 :                 ScMatrixRef pMat;
    3940         [ +  - ]:         18 :                 PopExternalDoubleRef(pMat);
    3941         [ -  + ]:         18 :                 if (nGlobalError)
    3942                 :            :                     break;
    3943                 :            : 
    3944 [ +  - ][ +  - ]:         18 :                 IterateMatrix(pMat, eFunc, bTextAsZero, nCount, nFuncFmtType, fRes, fMem, bNull);
                 [ +  - ]
    3945                 :            :             }
    3946                 :         18 :             break;
    3947                 :            :             case svMatrix :
    3948                 :            :             {
    3949         [ +  - ]:          3 :                 ScMatrixRef pMat = PopMatrix();
    3950 [ +  - ][ +  - ]:          3 :                 IterateMatrix(pMat, eFunc, bTextAsZero, nCount, nFuncFmtType, fRes, fMem, bNull);
    3951                 :            :             }
    3952                 :          3 :             break;
    3953                 :            :             case svError:
    3954                 :            :             {
    3955         [ #  # ]:          0 :                 PopError();
    3956         [ #  # ]:          0 :                 if ( eFunc == ifCOUNT )
    3957                 :            :                 {
    3958                 :          0 :                     nGlobalError = 0;
    3959                 :            :                 }
    3960         [ #  # ]:          0 :                 else if ( eFunc == ifCOUNT2 )
    3961                 :            :                 {
    3962                 :          0 :                     nCount++;
    3963                 :          0 :                     nGlobalError = 0;
    3964                 :            :                 }
    3965                 :            :             }
    3966                 :          0 :             break;
    3967                 :            :             default :
    3968         [ #  # ]:          0 :                 while (nParamCount-- > 0)
    3969         [ #  # ]:          0 :                     PopError();
    3970                 :          0 :                 SetError(errIllegalParameter);
    3971                 :            :         }
    3972                 :            :     }
    3973   [ +  +  +  +  :        135 :     switch( eFunc )
                      - ]
    3974                 :            :     {
    3975                 :        102 :         case ifSUM:     fRes = ::rtl::math::approxAdd( fRes, fMem ); break;
    3976                 :         12 :         case ifAVERAGE: fRes = div(::rtl::math::approxAdd( fRes, fMem ), nCount); break;
    3977                 :            :         case ifCOUNT2:
    3978                 :         12 :         case ifCOUNT:   fRes  = nCount; break;
    3979         [ -  + ]:          9 :         case ifPRODUCT: if ( !nCount ) fRes = 0.0; break;
    3980                 :            :         default: ; // nothing
    3981                 :            :     }
    3982                 :            :     // Bei Summen etc. macht ein bool-Ergebnis keinen Sinn
    3983                 :            :     // und Anzahl ist immer Number (#38345#)
    3984 [ +  + ][ -  + ]:        135 :     if( eFunc == ifCOUNT || nFuncFmtType == NUMBERFORMAT_LOGICAL )
    3985                 :          9 :         nFuncFmtType = NUMBERFORMAT_NUMBER;
    3986                 :        135 :     return fRes;
    3987                 :            : }
    3988                 :            : 
    3989                 :            : 
    3990                 :          0 : void ScInterpreter::ScSumSQ()
    3991                 :            : {
    3992                 :            :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScSumSQ" );
    3993                 :          0 :     PushDouble( IterateParameters( ifSUMSQ ) );
    3994                 :          0 : }
    3995                 :            : 
    3996                 :            : 
    3997                 :        102 : void ScInterpreter::ScSum()
    3998                 :            : {
    3999                 :            :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScSum" );
    4000                 :        102 :     PushDouble( IterateParameters( ifSUM ) );
    4001                 :        102 : }
    4002                 :            : 
    4003                 :            : 
    4004                 :          9 : void ScInterpreter::ScProduct()
    4005                 :            : {
    4006                 :            :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScProduct" );
    4007                 :          9 :     PushDouble( IterateParameters( ifPRODUCT ) );
    4008                 :          9 : }
    4009                 :            : 
    4010                 :            : 
    4011                 :         12 : void ScInterpreter::ScAverage( bool bTextAsZero )
    4012                 :            : {
    4013                 :            :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScAverage" );
    4014                 :         12 :     PushDouble( IterateParameters( ifAVERAGE, bTextAsZero ) );
    4015                 :         12 : }
    4016                 :            : 
    4017                 :            : 
    4018                 :          9 : void ScInterpreter::ScCount()
    4019                 :            : {
    4020                 :            :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScCount" );
    4021                 :          9 :     PushDouble( IterateParameters( ifCOUNT ) );
    4022                 :          9 : }
    4023                 :            : 
    4024                 :            : 
    4025                 :          3 : void ScInterpreter::ScCount2()
    4026                 :            : {
    4027                 :            :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScCount2" );
    4028                 :          3 :     PushDouble( IterateParameters( ifCOUNT2 ) );
    4029                 :          3 : }
    4030                 :            : 
    4031                 :            : 
    4032                 :          0 : void ScInterpreter::GetStVarParams( double& rVal, double& rValCount,
    4033                 :            :                 bool bTextAsZero )
    4034                 :            : {
    4035                 :            :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::GetStVarParams" );
    4036                 :          0 :     short nParamCount = GetByte();
    4037                 :            : 
    4038         [ #  # ]:          0 :     std::vector<double> values;
    4039                 :          0 :     double fSum    = 0.0;
    4040                 :          0 :     double vSum    = 0.0;
    4041                 :          0 :     double vMean    = 0.0;
    4042                 :          0 :     double fVal = 0.0;
    4043                 :          0 :     rValCount = 0.0;
    4044                 :          0 :     ScAddress aAdr;
    4045                 :          0 :     ScRange aRange;
    4046                 :          0 :     size_t nRefInList = 0;
    4047         [ #  # ]:          0 :     while (nParamCount-- > 0)
    4048                 :            :     {
    4049 [ #  # ][ #  #  :          0 :         switch (GetStackType())
             #  #  #  # ]
    4050                 :            :         {
    4051                 :            :             case svDouble :
    4052                 :            :             {
    4053         [ #  # ]:          0 :                 fVal = GetDouble();
    4054         [ #  # ]:          0 :                 values.push_back(fVal);
    4055                 :          0 :                 fSum    += fVal;
    4056                 :          0 :                 rValCount++;
    4057                 :            :             }
    4058                 :          0 :             break;
    4059                 :            :             case svSingleRef :
    4060                 :            :             {
    4061         [ #  # ]:          0 :                 PopSingleRef( aAdr );
    4062         [ #  # ]:          0 :                 ScBaseCell* pCell = GetCell( aAdr );
    4063 [ #  # ][ #  # ]:          0 :                 if (HasCellValueData(pCell))
    4064                 :            :                 {
    4065         [ #  # ]:          0 :                     fVal = GetCellValue( aAdr, pCell );
    4066         [ #  # ]:          0 :                     values.push_back(fVal);
    4067                 :          0 :                     fSum += fVal;
    4068                 :          0 :                     rValCount++;
    4069                 :            :                 }
    4070 [ #  # ][ #  # ]:          0 :                 else if ( bTextAsZero && HasCellStringData( pCell ) )
         [ #  # ][ #  # ]
    4071                 :            :                 {
    4072         [ #  # ]:          0 :                     values.push_back(0.0);
    4073                 :          0 :                     rValCount++;
    4074                 :            :                 }
    4075                 :            :             }
    4076                 :          0 :             break;
    4077                 :            :             case svDoubleRef :
    4078                 :            :             case svRefList :
    4079                 :            :             {
    4080                 :          0 :                 sal_uInt16 nErr = 0;
    4081         [ #  # ]:          0 :                 PopDoubleRef( aRange, nParamCount, nRefInList);
    4082         [ #  # ]:          0 :                 ScValueIterator aValIter( pDok, aRange, glSubTotal, bTextAsZero );
    4083 [ #  # ][ #  # ]:          0 :                 if (aValIter.GetFirst(fVal, nErr))
    4084                 :            :                 {
    4085 [ #  # ][ #  # ]:          0 :                     do
                 [ #  # ]
    4086                 :            :                     {
    4087         [ #  # ]:          0 :                         values.push_back(fVal);
    4088                 :          0 :                         fSum += fVal;
    4089                 :          0 :                         rValCount++;
    4090                 :            :                     }
    4091         [ #  # ]:          0 :                     while ((nErr == 0) && aValIter.GetNext(fVal, nErr));
    4092                 :            :                 }
    4093                 :            :             }
    4094                 :          0 :             break;
    4095                 :            :             case svMatrix :
    4096                 :            :             {
    4097         [ #  # ]:          0 :                 ScMatrixRef pMat = PopMatrix();
    4098         [ #  # ]:          0 :                 if (pMat)
    4099                 :            :                 {
    4100                 :            :                     SCSIZE nC, nR;
    4101         [ #  # ]:          0 :                     pMat->GetDimensions(nC, nR);
    4102         [ #  # ]:          0 :                     for (SCSIZE nMatCol = 0; nMatCol < nC; nMatCol++)
    4103                 :            :                     {
    4104         [ #  # ]:          0 :                         for (SCSIZE nMatRow = 0; nMatRow < nR; nMatRow++)
    4105                 :            :                         {
    4106 [ #  # ][ #  # ]:          0 :                             if (!pMat->IsString(nMatCol,nMatRow))
    4107                 :            :                             {
    4108         [ #  # ]:          0 :                                 fVal= pMat->GetDouble(nMatCol,nMatRow);
    4109         [ #  # ]:          0 :                                 values.push_back(fVal);
    4110                 :          0 :                                 fSum += fVal;
    4111                 :          0 :                                 rValCount++;
    4112                 :            :                             }
    4113         [ #  # ]:          0 :                             else if ( bTextAsZero )
    4114                 :            :                             {
    4115         [ #  # ]:          0 :                                 values.push_back(0.0);
    4116                 :          0 :                                 rValCount++;
    4117                 :            :                             }
    4118                 :            :                         }
    4119                 :            :                     }
    4120         [ #  # ]:          0 :                 }
    4121                 :            :             }
    4122                 :          0 :             break;
    4123                 :            :             case svString :
    4124                 :            :             {
    4125         [ #  # ]:          0 :                 Pop();
    4126         [ #  # ]:          0 :                 if ( bTextAsZero )
    4127                 :            :                 {
    4128         [ #  # ]:          0 :                     values.push_back(0.0);
    4129                 :          0 :                     rValCount++;
    4130                 :            :                 }
    4131                 :            :                 else
    4132                 :          0 :                     SetError(errIllegalParameter);
    4133                 :            :             }
    4134                 :          0 :             break;
    4135                 :            :             default :
    4136         [ #  # ]:          0 :                 Pop();
    4137                 :          0 :                 SetError(errIllegalParameter);
    4138                 :            :         }
    4139                 :            :     }
    4140                 :            : 
    4141                 :          0 :     ::std::vector<double>::size_type n = values.size();
    4142                 :          0 :     vMean = fSum / n;
    4143         [ #  # ]:          0 :     for (::std::vector<double>::size_type i = 0; i < n; i++)
    4144 [ #  # ][ #  # ]:          0 :         vSum += ::rtl::math::approxSub( values[i], vMean) * ::rtl::math::approxSub( values[i], vMean);
    4145                 :          0 :     rVal = vSum;
    4146                 :          0 : }
    4147                 :            : 
    4148                 :            : 
    4149                 :          0 : void ScInterpreter::ScVar( bool bTextAsZero )
    4150                 :            : {
    4151                 :            :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScVar" );
    4152                 :            :     double nVal;
    4153                 :            :     double nValCount;
    4154         [ #  # ]:          0 :     GetStVarParams( nVal, nValCount, bTextAsZero );
    4155                 :            : 
    4156         [ #  # ]:          0 :     if (nValCount <= 1.0)
    4157         [ #  # ]:          0 :         PushError( errDivisionByZero );
    4158                 :            :     else
    4159         [ #  # ]:          0 :         PushDouble( nVal / (nValCount - 1.0));
    4160                 :          0 : }
    4161                 :            : 
    4162                 :            : 
    4163                 :          0 : void ScInterpreter::ScVarP( bool bTextAsZero )
    4164                 :            : {
    4165                 :            :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScVarP" );
    4166                 :            :     double nVal;
    4167                 :            :     double nValCount;
    4168         [ #  # ]:          0 :     GetStVarParams( nVal, nValCount, bTextAsZero );
    4169                 :            : 
    4170         [ #  # ]:          0 :     PushDouble( div( nVal, nValCount));
    4171                 :          0 : }
    4172                 :            : 
    4173                 :            : 
    4174                 :          0 : void ScInterpreter::ScStDev( bool bTextAsZero )
    4175                 :            : {
    4176                 :            :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScStDev" );
    4177                 :            :     double nVal;
    4178                 :            :     double nValCount;
    4179         [ #  # ]:          0 :     GetStVarParams( nVal, nValCount, bTextAsZero );
    4180         [ #  # ]:          0 :     if (nValCount <= 1.0)
    4181         [ #  # ]:          0 :         PushError( errDivisionByZero );
    4182                 :            :     else
    4183         [ #  # ]:          0 :         PushDouble( sqrt( nVal / (nValCount - 1.0)));
    4184                 :          0 : }
    4185                 :            : 
    4186                 :            : 
    4187                 :          0 : void ScInterpreter::ScStDevP( bool bTextAsZero )
    4188                 :            : {
    4189                 :            :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScStDevP" );
    4190                 :            :     double nVal;
    4191                 :            :     double nValCount;
    4192         [ #  # ]:          0 :     GetStVarParams( nVal, nValCount, bTextAsZero );
    4193         [ #  # ]:          0 :     if (nValCount == 0.0)
    4194         [ #  # ]:          0 :         PushError( errDivisionByZero );
    4195                 :            :     else
    4196         [ #  # ]:          0 :         PushDouble( sqrt( nVal / nValCount));
    4197                 :            : 
    4198                 :            :     /* this was: PushDouble( sqrt( div( nVal, nValCount)));
    4199                 :            :      *
    4200                 :            :      * Besides that the special NAN gets lost in the call through sqrt(),
    4201                 :            :      * unxlngi6.pro then looped back and forth somewhere between div() and
    4202                 :            :      * ::rtl::math::setNan(). Tests showed that
    4203                 :            :      *
    4204                 :            :      *      sqrt( div( 1, 0));
    4205                 :            :      *
    4206                 :            :      * produced a loop, but
    4207                 :            :      *
    4208                 :            :      *      double f1 = div( 1, 0);
    4209                 :            :      *      sqrt( f1 );
    4210                 :            :      *
    4211                 :            :      * was fine. There seems to be some compiler optimization problem. It does
    4212                 :            :      * not occur when compiled with debug=t.
    4213                 :            :      */
    4214                 :          0 : }
    4215                 :            : 
    4216                 :            : 
    4217                 :          0 : void ScInterpreter::ScColumns()
    4218                 :            : {
    4219                 :            :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScColumns" );
    4220                 :          0 :     sal_uInt8 nParamCount = GetByte();
    4221                 :          0 :     sal_uLong nVal = 0;
    4222                 :            :     SCCOL nCol1;
    4223                 :            :     SCROW nRow1;
    4224                 :            :     SCTAB nTab1;
    4225                 :            :     SCCOL nCol2;
    4226                 :            :     SCROW nRow2;
    4227                 :            :     SCTAB nTab2;
    4228         [ #  # ]:          0 :     while (nParamCount-- > 0)
    4229                 :            :     {
    4230 [ #  # ][ #  #  :          0 :         switch ( GetStackType() )
             #  #  #  # ]
    4231                 :            :         {
    4232                 :            :             case svSingleRef:
    4233         [ #  # ]:          0 :                 PopError();
    4234                 :          0 :                 nVal++;
    4235                 :          0 :                 break;
    4236                 :            :             case svDoubleRef:
    4237         [ #  # ]:          0 :                 PopDoubleRef(nCol1, nRow1, nTab1, nCol2, nRow2, nTab2);
    4238                 :            :                 nVal += static_cast<sal_uLong>(nTab2 - nTab1 + 1) *
    4239                 :          0 :                     static_cast<sal_uLong>(nCol2 - nCol1 + 1);
    4240                 :          0 :                 break;
    4241                 :            :             case svMatrix:
    4242                 :            :             {
    4243         [ #  # ]:          0 :                 ScMatrixRef pMat = PopMatrix();
    4244         [ #  # ]:          0 :                 if (pMat)
    4245                 :            :                 {
    4246                 :            :                     SCSIZE nC, nR;
    4247         [ #  # ]:          0 :                     pMat->GetDimensions(nC, nR);
    4248                 :          0 :                     nVal += nC;
    4249         [ #  # ]:          0 :                 }
    4250                 :            :             }
    4251                 :          0 :             break;
    4252                 :            :             case svExternalSingleRef:
    4253         [ #  # ]:          0 :                 PopError();
    4254                 :          0 :                 nVal++;
    4255                 :          0 :             break;
    4256                 :            :             case svExternalDoubleRef:
    4257                 :            :             {
    4258                 :            :                 sal_uInt16 nFileId;
    4259         [ #  # ]:          0 :                 String aTabName;
    4260                 :            :                 ScComplexRefData aRef;
    4261         [ #  # ]:          0 :                 PopExternalDoubleRef( nFileId, aTabName, aRef);
    4262                 :            :                 nVal += static_cast<sal_uLong>(aRef.Ref2.nTab - aRef.Ref1.nTab + 1) *
    4263         [ #  # ]:          0 :                     static_cast<sal_uLong>(aRef.Ref2.nCol - aRef.Ref1.nCol + 1);
    4264                 :            :             }
    4265                 :          0 :             break;
    4266                 :            :             default:
    4267         [ #  # ]:          0 :                 PopError();
    4268                 :          0 :                 SetError(errIllegalParameter);
    4269                 :            :         }
    4270                 :            :     }
    4271         [ #  # ]:          0 :     PushDouble((double)nVal);
    4272                 :          0 : }
    4273                 :            : 
    4274                 :            : 
    4275                 :          0 : void ScInterpreter::ScRows()
    4276                 :            : {
    4277                 :            :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScRows" );
    4278                 :          0 :     sal_uInt8 nParamCount = GetByte();
    4279                 :          0 :     sal_uLong nVal = 0;
    4280                 :            :     SCCOL nCol1;
    4281                 :            :     SCROW nRow1;
    4282                 :            :     SCTAB nTab1;
    4283                 :            :     SCCOL nCol2;
    4284                 :            :     SCROW nRow2;
    4285                 :            :     SCTAB nTab2;
    4286         [ #  # ]:          0 :     while (nParamCount-- > 0)
    4287                 :            :     {
    4288 [ #  # ][ #  #  :          0 :         switch ( GetStackType() )
             #  #  #  # ]
    4289                 :            :         {
    4290                 :            :             case svSingleRef:
    4291         [ #  # ]:          0 :                 PopError();
    4292                 :          0 :                 nVal++;
    4293                 :          0 :                 break;
    4294                 :            :             case svDoubleRef:
    4295         [ #  # ]:          0 :                 PopDoubleRef(nCol1, nRow1, nTab1, nCol2, nRow2, nTab2);
    4296                 :            :                 nVal += static_cast<sal_uLong>(nTab2 - nTab1 + 1) *
    4297                 :          0 :                     static_cast<sal_uLong>(nRow2 - nRow1 + 1);
    4298                 :          0 :                 break;
    4299                 :            :             case svMatrix:
    4300                 :            :             {
    4301         [ #  # ]:          0 :                 ScMatrixRef pMat = PopMatrix();
    4302         [ #  # ]:          0 :                 if (pMat)
    4303                 :            :                 {
    4304                 :            :                     SCSIZE nC, nR;
    4305         [ #  # ]:          0 :                     pMat->GetDimensions(nC, nR);
    4306                 :          0 :                     nVal += nR;
    4307         [ #  # ]:          0 :                 }
    4308                 :            :             }
    4309                 :          0 :             break;
    4310                 :            :             case svExternalSingleRef:
    4311         [ #  # ]:          0 :                 PopError();
    4312                 :          0 :                 nVal++;
    4313                 :          0 :             break;
    4314                 :            :             case svExternalDoubleRef:
    4315                 :            :             {
    4316                 :            :                 sal_uInt16 nFileId;
    4317         [ #  # ]:          0 :                 String aTabName;
    4318                 :            :                 ScComplexRefData aRef;
    4319         [ #  # ]:          0 :                 PopExternalDoubleRef( nFileId, aTabName, aRef);
    4320                 :            :                 nVal += static_cast<sal_uLong>(aRef.Ref2.nTab - aRef.Ref1.nTab + 1) *
    4321         [ #  # ]:          0 :                     static_cast<sal_uLong>(aRef.Ref2.nRow - aRef.Ref1.nRow + 1);
    4322                 :            :             }
    4323                 :          0 :             break;
    4324                 :            :             default:
    4325         [ #  # ]:          0 :                 PopError();
    4326                 :          0 :                 SetError(errIllegalParameter);
    4327                 :            :         }
    4328                 :            :     }
    4329         [ #  # ]:          0 :     PushDouble((double)nVal);
    4330                 :          0 : }
    4331                 :            : 
    4332                 :          9 : void ScInterpreter::ScTables()
    4333                 :            : {
    4334                 :            :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScTables" );
    4335                 :          9 :     sal_uInt8 nParamCount = GetByte();
    4336                 :            :     sal_uLong nVal;
    4337         [ +  - ]:          9 :     if ( nParamCount == 0 )
    4338                 :          9 :         nVal = pDok->GetTableCount();
    4339                 :            :     else
    4340                 :            :     {
    4341                 :          0 :         nVal = 0;
    4342                 :            :         SCCOL nCol1;
    4343                 :            :         SCROW nRow1;
    4344                 :            :         SCTAB nTab1;
    4345                 :            :         SCCOL nCol2;
    4346                 :            :         SCROW nRow2;
    4347                 :            :         SCTAB nTab2;
    4348         [ #  # ]:          0 :         while (nParamCount-- > 0)
    4349                 :            :         {
    4350 [ #  # ][ #  #  :          0 :             switch ( GetStackType() )
             #  #  #  # ]
    4351                 :            :             {
    4352                 :            :                 case svSingleRef:
    4353         [ #  # ]:          0 :                     PopError();
    4354                 :          0 :                     nVal++;
    4355                 :          0 :                 break;
    4356                 :            :                 case svDoubleRef:
    4357         [ #  # ]:          0 :                     PopDoubleRef(nCol1, nRow1, nTab1, nCol2, nRow2, nTab2);
    4358                 :          0 :                     nVal += static_cast<sal_uLong>(nTab2 - nTab1 + 1);
    4359                 :          0 :                 break;
    4360                 :            :                 case svMatrix:
    4361         [ #  # ]:          0 :                     PopError();
    4362                 :          0 :                     nVal++;
    4363                 :          0 :                 break;
    4364                 :            :                 case svExternalSingleRef:
    4365         [ #  # ]:          0 :                     PopError();
    4366                 :          0 :                     nVal++;
    4367                 :          0 :                 break;
    4368                 :            :                 case svExternalDoubleRef:
    4369                 :            :                 {
    4370                 :            :                     sal_uInt16 nFileId;
    4371         [ #  # ]:          0 :                     String aTabName;
    4372                 :            :                     ScComplexRefData aRef;
    4373         [ #  # ]:          0 :                     PopExternalDoubleRef( nFileId, aTabName, aRef);
    4374         [ #  # ]:          0 :                     nVal += static_cast<sal_uLong>(aRef.Ref2.nTab - aRef.Ref1.nTab + 1);
    4375                 :            :                 }
    4376                 :          0 :                 break;
    4377                 :            :                 default:
    4378         [ #  # ]:          0 :                     PopError();
    4379                 :          0 :                     SetError( errIllegalParameter );
    4380                 :            :             }
    4381                 :            :         }
    4382                 :            :     }
    4383                 :          9 :     PushDouble( (double) nVal );
    4384                 :          9 : }
    4385                 :            : 
    4386                 :            : 
    4387                 :         54 : void ScInterpreter::ScColumn()
    4388                 :            : {
    4389                 :            :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScColumn" );
    4390                 :         54 :     sal_uInt8 nParamCount = GetByte();
    4391         [ +  - ]:         54 :     if ( MustHaveParamCount( nParamCount, 0, 1 ) )
    4392                 :            :     {
    4393                 :         54 :         double nVal = 0;
    4394         [ +  + ]:         54 :         if (nParamCount == 0)
    4395                 :            :         {
    4396                 :          9 :             nVal = aPos.Col() + 1;
    4397         [ +  - ]:          9 :             if (bMatrixFormula)
    4398                 :            :             {
    4399                 :            :                 SCCOL nCols;
    4400                 :            :                 SCROW nRows;
    4401         [ +  - ]:          9 :                 pMyFormulaCell->GetMatColsRows( nCols, nRows);
    4402         [ +  - ]:          9 :                 ScMatrixRef pResMat = GetNewMat( static_cast<SCSIZE>(nCols), 1);
    4403         [ +  - ]:          9 :                 if (pResMat)
    4404                 :            :                 {
    4405         [ +  + ]:         18 :                     for (SCCOL i=0; i < nCols; ++i)
    4406         [ +  - ]:          9 :                         pResMat->PutDouble( nVal + i, static_cast<SCSIZE>(i), 0);
    4407         [ +  - ]:          9 :                     PushMatrix( pResMat);
    4408                 :            :                     return;
    4409 [ +  - ][ -  + ]:          9 :                 }
    4410                 :            :             }
    4411                 :            :         }
    4412                 :            :         else
    4413                 :            :         {
    4414      [ +  +  - ]:         45 :             switch ( GetStackType() )
    4415                 :            :             {
    4416                 :            :                 case svSingleRef :
    4417                 :            :                 {
    4418                 :            :                     SCCOL nCol1;
    4419                 :            :                     SCROW nRow1;
    4420                 :            :                     SCTAB nTab1;
    4421         [ +  - ]:         27 :                     PopSingleRef( nCol1, nRow1, nTab1 );
    4422                 :         27 :                     nVal = (double) (nCol1 + 1);
    4423                 :            :                 }
    4424                 :         27 :                 break;
    4425                 :            :                 case svDoubleRef :
    4426                 :            :                 {
    4427                 :            :                     SCCOL nCol1;
    4428                 :            :                     SCROW nRow1;
    4429                 :            :                     SCTAB nTab1;
    4430                 :            :                     SCCOL nCol2;
    4431                 :            :                     SCROW nRow2;
    4432                 :            :                     SCTAB nTab2;
    4433         [ +  - ]:         18 :                     PopDoubleRef( nCol1, nRow1, nTab1, nCol2, nRow2, nTab2 );
    4434         [ +  - ]:         18 :                     if (nCol2 > nCol1)
    4435                 :            :                     {
    4436                 :            :                         ScMatrixRef pResMat = GetNewMat(
    4437         [ +  - ]:         18 :                                 static_cast<SCSIZE>(nCol2-nCol1+1), 1);
    4438         [ +  - ]:         18 :                         if (pResMat)
    4439                 :            :                         {
    4440         [ +  + ]:         72 :                             for (SCCOL i = nCol1; i <= nCol2; i++)
    4441                 :            :                                 pResMat->PutDouble((double)(i+1),
    4442         [ +  - ]:         54 :                                         static_cast<SCSIZE>(i-nCol1), 0);
    4443         [ +  - ]:         18 :                             PushMatrix(pResMat);
    4444                 :            :                             return;
    4445                 :            :                         }
    4446                 :            :                         else
    4447 [ +  - ][ -  + ]:         18 :                             nVal = 0.0;
    4448                 :            :                     }
    4449                 :            :                     else
    4450                 :          0 :                         nVal = (double) (nCol1 + 1);
    4451                 :            :                 }
    4452                 :          0 :                 break;
    4453                 :            :                 default:
    4454                 :          0 :                     SetError( errIllegalParameter );
    4455                 :          0 :                     nVal = 0.0;
    4456                 :            :             }
    4457                 :            :         }
    4458                 :         54 :         PushDouble( nVal );
    4459                 :            :     }
    4460                 :            : }
    4461                 :            : 
    4462                 :            : 
    4463                 :         27 : void ScInterpreter::ScRow()
    4464                 :            : {
    4465                 :            :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScRow" );
    4466                 :         27 :     sal_uInt8 nParamCount = GetByte();
    4467         [ +  - ]:         27 :     if ( MustHaveParamCount( nParamCount, 0, 1 ) )
    4468                 :            :     {
    4469                 :         27 :         double nVal = 0;
    4470         [ +  + ]:         27 :         if (nParamCount == 0)
    4471                 :            :         {
    4472                 :          9 :             nVal = aPos.Row() + 1;
    4473         [ +  - ]:          9 :             if (bMatrixFormula)
    4474                 :            :             {
    4475                 :            :                 SCCOL nCols;
    4476                 :            :                 SCROW nRows;
    4477         [ +  - ]:          9 :                 pMyFormulaCell->GetMatColsRows( nCols, nRows);
    4478         [ +  - ]:          9 :                 ScMatrixRef pResMat = GetNewMat( 1, static_cast<SCSIZE>(nRows));
    4479         [ +  - ]:          9 :                 if (pResMat)
    4480                 :            :                 {
    4481         [ +  + ]:         18 :                     for (SCROW i=0; i < nRows; i++)
    4482         [ +  - ]:          9 :                         pResMat->PutDouble( nVal + i, 0, static_cast<SCSIZE>(i));
    4483         [ +  - ]:          9 :                     PushMatrix( pResMat);
    4484                 :            :                     return;
    4485 [ +  - ][ -  + ]:          9 :                 }
    4486                 :            :             }
    4487                 :            :         }
    4488                 :            :         else
    4489                 :            :         {
    4490      [ +  +  - ]:         18 :             switch ( GetStackType() )
    4491                 :            :             {
    4492                 :            :                 case svSingleRef :
    4493                 :            :                 {
    4494                 :            :                     SCCOL nCol1;
    4495                 :            :                     SCROW nRow1;
    4496                 :            :                     SCTAB nTab1;
    4497         [ +  - ]:         15 :                     PopSingleRef( nCol1, nRow1, nTab1 );
    4498                 :         15 :                     nVal = (double) (nRow1 + 1);
    4499                 :            :                 }
    4500                 :         15 :                 break;
    4501                 :            :                 case svDoubleRef :
    4502                 :            :                 {
    4503                 :            :                     SCCOL nCol1;
    4504                 :            :                     SCROW nRow1;
    4505                 :            :                     SCTAB nTab1;
    4506                 :            :                     SCCOL nCol2;
    4507                 :            :                     SCROW nRow2;
    4508                 :            :                     SCTAB nTab2;
    4509         [ +  - ]:          3 :                     PopDoubleRef( nCol1, nRow1, nTab1, nCol2, nRow2, nTab2 );
    4510         [ +  - ]:          3 :                     if (nRow2 > nRow1)
    4511                 :            :                     {
    4512                 :            :                         ScMatrixRef pResMat = GetNewMat( 1,
    4513         [ +  - ]:          3 :                                 static_cast<SCSIZE>(nRow2-nRow1+1));
    4514         [ +  - ]:          3 :                         if (pResMat)
    4515                 :            :                         {
    4516         [ +  + ]:          9 :                             for (SCROW i = nRow1; i <= nRow2; i++)
    4517                 :            :                                 pResMat->PutDouble((double)(i+1), 0,
    4518         [ +  - ]:          6 :                                         static_cast<SCSIZE>(i-nRow1));
    4519         [ +  - ]:          3 :                             PushMatrix(pResMat);
    4520                 :            :                             return;
    4521                 :            :                         }
    4522                 :            :                         else
    4523 [ +  - ][ -  + ]:          3 :                             nVal = 0.0;
    4524                 :            :                     }
    4525                 :            :                     else
    4526                 :          0 :                         nVal = (double) (nRow1 + 1);
    4527                 :            :                 }
    4528                 :          0 :                 break;
    4529                 :            :                 default:
    4530                 :          0 :                     SetError( errIllegalParameter );
    4531                 :          0 :                     nVal = 0.0;
    4532                 :            :             }
    4533                 :            :         }
    4534                 :         27 :         PushDouble( nVal );
    4535                 :            :     }
    4536                 :            : }
    4537                 :            : 
    4538                 :          0 : void ScInterpreter::ScTable()
    4539                 :            : {
    4540                 :            :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScTable" );
    4541                 :          0 :     sal_uInt8 nParamCount = GetByte();
    4542         [ #  # ]:          0 :     if ( MustHaveParamCount( nParamCount, 0, 1 ) )
    4543                 :            :     {
    4544                 :          0 :         SCTAB nVal = 0;
    4545         [ #  # ]:          0 :         if ( nParamCount == 0 )
    4546                 :          0 :             nVal = aPos.Tab() + 1;
    4547                 :            :         else
    4548                 :            :         {
    4549         [ #  # ]:          0 :             switch ( GetStackType() )
           [ #  #  #  # ]
    4550                 :            :             {
    4551                 :            :                 case svString :
    4552                 :            :                 {
    4553 [ #  # ][ #  # ]:          0 :                     String aStr( PopString() );
    4554 [ #  # ][ #  # ]:          0 :                     if ( pDok->GetTable( aStr, nVal ) )
                 [ #  # ]
    4555                 :          0 :                         ++nVal;
    4556                 :            :                     else
    4557         [ #  # ]:          0 :                         SetError( errIllegalArgument );
    4558                 :            :                 }
    4559                 :          0 :                 break;
    4560                 :            :                 case svSingleRef :
    4561                 :            :                 {
    4562                 :            :                     SCCOL nCol1;
    4563                 :            :                     SCROW nRow1;
    4564                 :            :                     SCTAB nTab1;
    4565         [ #  # ]:          0 :                     PopSingleRef( nCol1, nRow1, nTab1 );
    4566                 :          0 :                     nVal = nTab1 + 1;
    4567                 :            :                 }
    4568                 :          0 :                 break;
    4569                 :            :                 case svDoubleRef :
    4570                 :            :                 {
    4571                 :            :                     SCCOL nCol1;
    4572                 :            :                     SCROW nRow1;
    4573                 :            :                     SCTAB nTab1;
    4574                 :            :                     SCCOL nCol2;
    4575                 :            :                     SCROW nRow2;
    4576                 :            :                     SCTAB nTab2;
    4577         [ #  # ]:          0 :                     PopDoubleRef( nCol1, nRow1, nTab1, nCol2, nRow2, nTab2 );
    4578                 :          0 :                     nVal = nTab1 + 1;
    4579                 :            :                 }
    4580                 :          0 :                 break;
    4581                 :            :                 default:
    4582                 :          0 :                     SetError( errIllegalParameter );
    4583                 :            :             }
    4584         [ #  # ]:          0 :             if ( nGlobalError )
    4585                 :          0 :                 nVal = 0;
    4586                 :            :         }
    4587         [ #  # ]:          0 :         PushDouble( (double) nVal );
    4588                 :            :     }
    4589                 :          0 : }
    4590                 :            : 
    4591                 :            : namespace {
    4592                 :            : 
    4593                 :            : class VectorMatrixAccessor
    4594                 :            : {
    4595                 :            : public:
    4596                 :          0 :     VectorMatrixAccessor(const ScMatrix& rMat, bool bColVec) :
    4597                 :          0 :         mrMat(rMat), mbColVec(bColVec) {}
    4598                 :            : 
    4599                 :          0 :     bool IsEmpty(SCSIZE i) const
    4600                 :            :     {
    4601         [ #  # ]:          0 :         return mbColVec ? mrMat.IsEmpty(0, i) : mrMat.IsEmpty(i, 0);
    4602                 :            :     }
    4603                 :            : 
    4604                 :          0 :     bool IsEmptyPath(SCSIZE i) const
    4605                 :            :     {
    4606         [ #  # ]:          0 :         return mbColVec ? mrMat.IsEmptyPath(0, i) : mrMat.IsEmptyPath(i, 0);
    4607                 :            :     }
    4608                 :            : 
    4609                 :          0 :     bool IsValue(SCSIZE i) const
    4610                 :            :     {
    4611         [ #  # ]:          0 :         return mbColVec ? mrMat.IsValue(0, i) : mrMat.IsValue(i, 0);
    4612                 :            :     }
    4613                 :            : 
    4614                 :          0 :     bool IsString(SCSIZE i) const
    4615                 :            :     {
    4616         [ #  # ]:          0 :         return mbColVec ? mrMat.IsString(0, i) : mrMat.IsString(i, 0);
    4617                 :            :     }
    4618                 :            : 
    4619                 :          0 :     double GetDouble(SCSIZE i) const
    4620                 :            :     {
    4621         [ #  # ]:          0 :         return mbColVec ? mrMat.GetDouble(0, i) : mrMat.GetDouble(i, 0);
    4622                 :            :     }
    4623                 :            : 
    4624                 :          0 :     rtl::OUString GetString(SCSIZE i) const
    4625                 :            :     {
    4626         [ #  # ]:          0 :         return mbColVec ? mrMat.GetString(0, i) : mrMat.GetString(i, 0);
    4627                 :            :     }
    4628                 :            : 
    4629                 :          0 :     SCSIZE GetElementCount() const
    4630                 :            :     {
    4631                 :            :         SCSIZE nC, nR;
    4632         [ #  # ]:          0 :         mrMat.GetDimensions(nC, nR);
    4633         [ #  # ]:          0 :         return mbColVec ? nR : nC;
    4634                 :            :     }
    4635                 :            : 
    4636                 :            : private:
    4637                 :            :     const ScMatrix& mrMat;
    4638                 :            :     bool mbColVec;
    4639                 :            : };
    4640                 :            : 
    4641                 :            : /** returns -1 when the matrix value is smaller than the query value, 0 when
    4642                 :            :     they are equal, and 1 when the matrix value is larger than the query
    4643                 :            :     value. */
    4644                 :          0 : static sal_Int32 lcl_CompareMatrix2Query(
    4645                 :            :     SCSIZE i, const VectorMatrixAccessor& rMat, const ScQueryEntry& rEntry)
    4646                 :            : {
    4647 [ #  # ][ #  # ]:          0 :     if (rMat.IsEmpty(i))
    4648                 :            :     {
    4649                 :            :         /* TODO: in case we introduced query for real empty this would have to
    4650                 :            :          * be changed! */
    4651                 :          0 :         return -1;      // empty always less than anything else
    4652                 :            :     }
    4653                 :            : 
    4654                 :            :     /* FIXME: what is an empty path (result of IF(false;true_path) in
    4655                 :            :      * comparisons? */
    4656                 :            : 
    4657         [ #  # ]:          0 :     bool bByString = rEntry.GetQueryItem().meType == ScQueryEntry::ByString;
    4658 [ #  # ][ #  # ]:          0 :     if (rMat.IsValue(i))
    4659                 :            :     {
    4660         [ #  # ]:          0 :         if (bByString)
    4661                 :          0 :             return -1;  // numeric always less than string
    4662                 :            : 
    4663         [ #  # ]:          0 :         const double nVal1 = rMat.GetDouble(i);
    4664         [ #  # ]:          0 :         const double nVal2 = rEntry.GetQueryItem().mfVal;
    4665         [ #  # ]:          0 :         if (nVal1 == nVal2)
    4666                 :          0 :             return 0;
    4667                 :            : 
    4668         [ #  # ]:          0 :         return nVal1 < nVal2 ? -1 : 1;
    4669                 :            :     }
    4670                 :            : 
    4671         [ #  # ]:          0 :     if (!bByString)
    4672                 :          0 :         return 1;       // string always greater than numeric
    4673                 :            : 
    4674         [ #  # ]:          0 :     const rtl::OUString aStr1 = rMat.GetString(i);
    4675         [ #  # ]:          0 :     const rtl::OUString& rStr2 = rEntry.GetQueryItem().maString;
    4676                 :            : 
    4677 [ #  # ][ #  # ]:          0 :     return ScGlobal::GetCollator()->compareString(aStr1, rStr2); // case-insensitive
    4678                 :            : }
    4679                 :            : 
    4680                 :            : /** returns the last item with the identical value as the original item
    4681                 :            :     value. */
    4682                 :          0 : static void lcl_GetLastMatch( SCSIZE& rIndex, const VectorMatrixAccessor& rMat,
    4683                 :            :         SCSIZE nMatCount, bool bReverse)
    4684                 :            : {
    4685         [ #  # ]:          0 :     if (rMat.IsValue(rIndex))
    4686                 :            :     {
    4687                 :          0 :         double nVal = rMat.GetDouble(rIndex);
    4688         [ #  # ]:          0 :         if (bReverse)
    4689         [ #  # ]:          0 :             while (rIndex > 0 && rMat.IsValue(rIndex-1) &&
           [ #  #  #  # ]
                 [ #  # ]
    4690                 :          0 :                     nVal == rMat.GetDouble(rIndex-1))
    4691                 :          0 :                 --rIndex;
    4692                 :            :         else
    4693         [ #  # ]:          0 :             while (rIndex < nMatCount-1 && rMat.IsValue(rIndex+1) &&
           [ #  #  #  # ]
                 [ #  # ]
    4694                 :          0 :                     nVal == rMat.GetDouble(rIndex+1))
    4695                 :          0 :                 ++rIndex;
    4696                 :            :     }
    4697                 :            :     //! Order of IsEmptyPath, IsEmpty, IsString is significant!
    4698         [ #  # ]:          0 :     else if (rMat.IsEmptyPath(rIndex))
    4699                 :            :     {
    4700         [ #  # ]:          0 :         if (bReverse)
    4701 [ #  # ][ #  # ]:          0 :             while (rIndex > 0 && rMat.IsEmptyPath(rIndex-1))
                 [ #  # ]
    4702                 :          0 :                 --rIndex;
    4703                 :            :         else
    4704 [ #  # ][ #  # ]:          0 :             while (rIndex < nMatCount-1 && rMat.IsEmptyPath(rIndex+1))
                 [ #  # ]
    4705                 :          0 :                 ++rIndex;
    4706                 :            :     }
    4707         [ #  # ]:          0 :     else if (rMat.IsEmpty(rIndex))
    4708                 :            :     {
    4709         [ #  # ]:          0 :         if (bReverse)
    4710 [ #  # ][ #  # ]:          0 :             while (rIndex > 0 && rMat.IsEmpty(rIndex-1))
                 [ #  # ]
    4711                 :          0 :                 --rIndex;
    4712                 :            :         else
    4713 [ #  # ][ #  # ]:          0 :             while (rIndex < nMatCount-1 && rMat.IsEmpty(rIndex+1))
                 [ #  # ]
    4714                 :          0 :                 ++rIndex;
    4715                 :            :     }
    4716         [ #  # ]:          0 :     else if (rMat.IsString(rIndex))
    4717                 :            :     {
    4718         [ #  # ]:          0 :         rtl::OUString aStr( rMat.GetString(rIndex));
    4719         [ #  # ]:          0 :         if (bReverse)
    4720 [ #  # ][ #  # ]:          0 :             while (rIndex > 0 && rMat.IsString(rIndex-1) &&
           [ #  #  #  # ]
                 [ #  # ]
    4721 [ #  # ][ #  # ]:          0 :                     aStr == rMat.GetString(rIndex-1))
                 [ #  # ]
    4722                 :          0 :                 --rIndex;
    4723                 :            :         else
    4724 [ #  # ][ #  # ]:          0 :             while (rIndex < nMatCount-1 && rMat.IsString(rIndex+1) &&
           [ #  #  #  # ]
                 [ #  # ]
    4725 [ #  # ][ #  # ]:          0 :                     aStr == rMat.GetString(rIndex+1))
                 [ #  # ]
    4726                 :          0 :                 ++rIndex;
    4727                 :            :     }
    4728                 :            :     else
    4729                 :            :     {
    4730                 :            :         OSL_FAIL("lcl_GetLastMatch: unhandled matrix type");
    4731                 :            :     }
    4732                 :          0 : }
    4733                 :            : 
    4734                 :            : }
    4735                 :            : 
    4736                 :         93 : void ScInterpreter::ScMatch()
    4737                 :            : {
    4738                 :            :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScMatch" );
    4739                 :            : 
    4740                 :         93 :     sal_uInt8 nParamCount = GetByte();
    4741         [ +  - ]:         93 :     if ( MustHaveParamCount( nParamCount, 2, 3 ) )
    4742                 :            :     {
    4743                 :            :         double fTyp;
    4744         [ +  - ]:         93 :         if (nParamCount == 3)
    4745         [ +  - ]:         93 :             fTyp = GetDouble();
    4746                 :            :         else
    4747                 :          0 :             fTyp = 1.0;
    4748                 :         93 :         SCCOL nCol1 = 0;
    4749                 :         93 :         SCROW nRow1 = 0;
    4750                 :         93 :         SCTAB nTab1 = 0;
    4751                 :         93 :         SCCOL nCol2 = 0;
    4752                 :         93 :         SCROW nRow2 = 0;
    4753                 :         93 :         SCTAB nTab2 = 0;
    4754                 :         93 :         ScMatrixRef pMatSrc = NULL;
    4755                 :            : 
    4756      [ +  -  - ]:         93 :         switch (GetStackType())
                 [ +  - ]
    4757                 :            :         {
    4758                 :            :             case svDoubleRef:
    4759                 :            :             {
    4760         [ +  - ]:         93 :                 PopDoubleRef(nCol1, nRow1, nTab1, nCol2, nRow2, nTab2);
    4761 [ +  - ][ -  + ]:         93 :                 if (nTab1 != nTab2 || (nCol1 != nCol2 && nRow1 != nRow2))
                 [ #  # ]
    4762                 :            :                 {
    4763         [ #  # ]:          0 :                     PushIllegalParameter();
    4764                 :            :                     return;
    4765                 :            :                 }
    4766                 :            :             }
    4767                 :         93 :             break;
    4768                 :            :             case svMatrix:
    4769                 :            :             case svExternalDoubleRef:
    4770                 :            :             {
    4771 [ #  # ][ #  # ]:          0 :                 if (GetStackType() == svMatrix)
    4772 [ #  # ][ #  # ]:          0 :                     pMatSrc = PopMatrix();
                 [ #  # ]
    4773                 :            :                 else
    4774         [ #  # ]:          0 :                     PopExternalDoubleRef(pMatSrc);
    4775                 :            : 
    4776         [ #  # ]:          0 :                 if (!pMatSrc)
    4777                 :            :                 {
    4778         [ #  # ]:          0 :                     PushIllegalParameter();
    4779                 :            :                     return;
    4780                 :            :                 }
    4781                 :            :             }
    4782                 :          0 :             break;
    4783                 :            :             default:
    4784         [ #  # ]:          0 :                 PushIllegalParameter();
    4785                 :            :                 return;
    4786                 :            :         }
    4787                 :            : 
    4788         [ +  - ]:         93 :         if (nGlobalError == 0)
    4789                 :            :         {
    4790                 :            :             double fVal;
    4791         [ +  - ]:         93 :             String sStr;
    4792         [ +  - ]:         93 :             ScQueryParam rParam;
    4793                 :         93 :             rParam.nCol1       = nCol1;
    4794                 :         93 :             rParam.nRow1       = nRow1;
    4795                 :         93 :             rParam.nCol2       = nCol2;
    4796                 :         93 :             rParam.nTab        = nTab1;
    4797                 :            : 
    4798         [ +  - ]:         93 :             ScQueryEntry& rEntry = rParam.GetEntry(0);
    4799         [ +  - ]:         93 :             ScQueryEntry::Item& rItem = rEntry.GetQueryItem();
    4800                 :         93 :             rEntry.bDoQuery = true;
    4801         [ +  + ]:         93 :             if (fTyp < 0.0)
    4802                 :         48 :                 rEntry.eOp = SC_GREATER_EQUAL;
    4803         [ +  - ]:         45 :             else if (fTyp > 0.0)
    4804                 :         45 :                 rEntry.eOp = SC_LESS_EQUAL;
    4805 [ +  - ][ -  -  :         93 :             switch ( GetStackType() )
             +  -  -  -  
                      - ]
    4806                 :            :             {
    4807                 :            :                 case svDouble:
    4808                 :            :                 {
    4809         [ #  # ]:          0 :                     fVal = GetDouble();
    4810                 :          0 :                     rItem.mfVal = fVal;
    4811                 :          0 :                     rItem.meType = ScQueryEntry::ByValue;
    4812                 :            :                 }
    4813                 :          0 :                 break;
    4814                 :            :                 case svString:
    4815                 :            :                 {
    4816 [ #  # ][ #  # ]:          0 :                     sStr = GetString();
    4817                 :          0 :                     rItem.meType = ScQueryEntry::ByString;
    4818         [ #  # ]:          0 :                     rItem.maString = sStr;
    4819                 :            :                 }
    4820                 :          0 :                 break;
    4821                 :            :                 case svDoubleRef :
    4822                 :            :                 case svSingleRef :
    4823                 :            :                 {
    4824                 :         93 :                     ScAddress aAdr;
    4825 [ -  + ][ +  - ]:         93 :                     if ( !PopDoubleRefOrSingleRef( aAdr ) )
    4826                 :            :                     {
    4827         [ #  # ]:          0 :                         PushInt(0);
    4828                 :            :                         return ;
    4829                 :            :                     }
    4830         [ +  - ]:         93 :                     ScBaseCell* pCell = GetCell( aAdr );
    4831 [ +  - ][ +  + ]:         93 :                     if (HasCellValueData(pCell))
    4832                 :            :                     {
    4833         [ +  - ]:         72 :                         fVal = GetCellValue( aAdr, pCell );
    4834                 :         72 :                         rItem.meType = ScQueryEntry::ByValue;
    4835                 :         72 :                         rItem.mfVal = fVal;
    4836                 :            :                     }
    4837                 :            :                     else
    4838                 :            :                     {
    4839         [ +  - ]:         21 :                         GetCellString(sStr, pCell);
    4840                 :         21 :                         rItem.meType = ScQueryEntry::ByString;
    4841         [ +  - ]:         21 :                         rItem.maString = sStr;
    4842                 :            :                     }
    4843                 :            :                 }
    4844                 :         93 :                 break;
    4845                 :            :                 case svExternalSingleRef:
    4846                 :            :                 {
    4847                 :          0 :                     ScExternalRefCache::TokenRef pToken;
    4848         [ #  # ]:          0 :                     PopExternalSingleRef(pToken);
    4849         [ #  # ]:          0 :                     if (!pToken)
    4850                 :            :                     {
    4851         [ #  # ]:          0 :                         PushInt(0);
    4852                 :            :                         return;
    4853                 :            :                     }
    4854         [ #  # ]:          0 :                     if (pToken->GetType() == svDouble)
    4855                 :            :                     {
    4856                 :          0 :                         rItem.meType = ScQueryEntry::ByValue;
    4857         [ #  # ]:          0 :                         rItem.mfVal = pToken->GetDouble();
    4858                 :            :                     }
    4859                 :            :                     else
    4860                 :            :                     {
    4861                 :          0 :                         rItem.meType = ScQueryEntry::ByString;
    4862 [ #  # ][ #  # ]:          0 :                         rItem.maString = pToken->GetString();
    4863 [ #  # ][ #  # ]:          0 :                     }
    4864                 :            :                 }
    4865                 :          0 :                 break;
    4866                 :            :                 case svExternalDoubleRef:
    4867                 :            :                     // TODO: Implement this.
    4868         [ #  # ]:          0 :                     PushIllegalParameter();
    4869                 :            :                     return;
    4870                 :            :                 break;
    4871                 :            :                 case svMatrix :
    4872                 :            :                 {
    4873         [ #  # ]:          0 :                     String aStr;
    4874                 :            :                     ScMatValType nType = GetDoubleOrStringFromMatrix(
    4875         [ #  # ]:          0 :                             rItem.mfVal, aStr);
    4876         [ #  # ]:          0 :                     rItem.maString = aStr;
    4877                 :          0 :                     rItem.meType = ScMatrix::IsNonValueType(nType) ?
    4878 [ #  # ][ #  # ]:          0 :                         ScQueryEntry::ByString : ScQueryEntry::ByValue;
    4879                 :            :                 }
    4880                 :          0 :                 break;
    4881                 :            :                 default:
    4882                 :            :                 {
    4883         [ #  # ]:          0 :                     PushIllegalParameter();
    4884                 :            :                     return;
    4885                 :            :                 }
    4886                 :            :             }
    4887         [ +  + ]:         93 :             if (rItem.meType == ScQueryEntry::ByString)
    4888                 :            :             {
    4889                 :         21 :                 bool bIsVBAMode = false;
    4890         [ +  - ]:         21 :                 if ( pDok )
    4891         [ +  - ]:         21 :                     bIsVBAMode = pDok->IsInVBAMode();
    4892                 :            : 
    4893                 :            :                 // #TODO handle MSO wildcards
    4894         [ -  + ]:         21 :                 if ( bIsVBAMode )
    4895                 :          0 :                     rParam.bRegExp = false;
    4896                 :            :                 else
    4897 [ +  - ][ +  - ]:         21 :                     rParam.bRegExp = MayBeRegExp(rEntry.GetQueryItem().maString, pDok);
    4898                 :            :             }
    4899                 :            : 
    4900         [ -  + ]:         93 :             if (pMatSrc) // The source data is matrix array.
    4901                 :            :             {
    4902                 :            :                 SCSIZE nC, nR;
    4903         [ #  # ]:          0 :                 pMatSrc->GetDimensions( nC, nR);
    4904 [ #  # ][ #  # ]:          0 :                 if (nC > 1 && nR > 1)
    4905                 :            :                 {
    4906                 :            :                     // The source matrix must be a vector.
    4907         [ #  # ]:          0 :                     PushIllegalParameter();
    4908                 :            :                     return;
    4909                 :            :                 }
    4910         [ #  # ]:          0 :                 SCSIZE nMatCount = (nC == 1) ? nR : nC;
    4911                 :          0 :                 VectorMatrixAccessor aMatAcc(*pMatSrc, nC == 1);
    4912                 :            : 
    4913                 :            :                 // simple serial search for equality mode (source data doesn't
    4914                 :            :                 // need to be sorted).
    4915                 :            : 
    4916         [ #  # ]:          0 :                 if (rEntry.eOp == SC_EQUAL)
    4917                 :            :                 {
    4918         [ #  # ]:          0 :                     for (SCSIZE i = 0; i < nMatCount; ++i)
    4919                 :            :                     {
    4920 [ #  # ][ #  # ]:          0 :                         if (lcl_CompareMatrix2Query( i, aMatAcc, rEntry) == 0)
    4921                 :            :                         {
    4922         [ #  # ]:          0 :                             PushDouble(i+1); // found !
    4923                 :            :                             return;
    4924                 :            :                         }
    4925                 :            :                     }
    4926         [ #  # ]:          0 :                     PushNA(); // not found
    4927                 :            :                     return;
    4928                 :            :                 }
    4929                 :            : 
    4930                 :            :                 // binary search for non-equality mode (the source data is
    4931                 :            :                 // assumed to be sorted).
    4932                 :            : 
    4933                 :          0 :                 bool bAscOrder = (rEntry.eOp == SC_LESS_EQUAL);
    4934                 :          0 :                 SCSIZE nFirst = 0, nLast = nMatCount-1, nHitIndex = 0;
    4935         [ #  # ]:          0 :                 for (SCSIZE nLen = nLast-nFirst; nLen > 0; nLen = nLast-nFirst)
    4936                 :            :                 {
    4937                 :          0 :                     SCSIZE nMid = nFirst + nLen/2;
    4938         [ #  # ]:          0 :                     sal_Int32 nCmp = lcl_CompareMatrix2Query( nMid, aMatAcc, rEntry);
    4939         [ #  # ]:          0 :                     if (nCmp == 0)
    4940                 :            :                     {
    4941                 :            :                         // exact match.  find the last item with the same value.
    4942         [ #  # ]:          0 :                         lcl_GetLastMatch( nMid, aMatAcc, nMatCount, !bAscOrder);
    4943         [ #  # ]:          0 :                         PushDouble( nMid+1);
    4944                 :            :                         return;
    4945                 :            :                     }
    4946                 :            : 
    4947         [ #  # ]:          0 :                     if (nLen == 1) // first and last items are next to each other.
    4948                 :            :                     {
    4949         [ #  # ]:          0 :                         if (nCmp < 0)
    4950         [ #  # ]:          0 :                             nHitIndex = bAscOrder ? nLast : nFirst;
    4951                 :            :                         else
    4952         [ #  # ]:          0 :                             nHitIndex = bAscOrder ? nFirst : nLast;
    4953                 :            :                         break;
    4954                 :            :                     }
    4955                 :            : 
    4956         [ #  # ]:          0 :                     if (nCmp < 0)
    4957                 :            :                     {
    4958         [ #  # ]:          0 :                         if (bAscOrder)
    4959                 :          0 :                             nFirst = nMid;
    4960                 :            :                         else
    4961                 :          0 :                             nLast = nMid;
    4962                 :            :                     }
    4963                 :            :                     else
    4964                 :            :                     {
    4965         [ #  # ]:          0 :                         if (bAscOrder)
    4966                 :          0 :                             nLast = nMid;
    4967                 :            :                         else
    4968                 :          0 :                             nFirst = nMid;
    4969                 :            :                     }
    4970                 :            :                 }
    4971                 :            : 
    4972         [ #  # ]:          0 :                 if (nHitIndex == nMatCount-1) // last item
    4973                 :            :                 {
    4974         [ #  # ]:          0 :                     sal_Int32 nCmp = lcl_CompareMatrix2Query( nHitIndex, aMatAcc, rEntry);
    4975 [ #  # ][ #  # ]:          0 :                     if ((bAscOrder && nCmp <= 0) || (!bAscOrder && nCmp >= 0))
         [ #  # ][ #  # ]
    4976                 :            :                     {
    4977                 :            :                         // either the last item is an exact match or the real
    4978                 :            :                         // hit is beyond the last item.
    4979         [ #  # ]:          0 :                         PushDouble( nHitIndex+1);
    4980                 :            :                         return;
    4981                 :            :                     }
    4982                 :            :                 }
    4983                 :            : 
    4984         [ #  # ]:          0 :                 if (nHitIndex > 0) // valid hit must be 2nd item or higher
    4985                 :            :                 {
    4986         [ #  # ]:          0 :                     PushDouble( nHitIndex); // non-exact match
    4987                 :            :                     return;
    4988                 :            :                 }
    4989                 :            : 
    4990         [ #  # ]:          0 :                 PushNA();
    4991                 :            :                 return;
    4992                 :            :             }
    4993                 :            : 
    4994                 :         93 :             SCCOLROW nDelta = 0;
    4995         [ +  - ]:         93 :             if (nCol1 == nCol2)
    4996                 :            :             {                                           // search row in column
    4997                 :         93 :                 rParam.nRow2 = nRow2;
    4998                 :         93 :                 rEntry.nField = nCol1;
    4999                 :         93 :                 ScAddress aResultPos( nCol1, nRow1, nTab1);
    5000 [ +  + ][ +  - ]:         93 :                 if (!LookupQueryWithCache( aResultPos, rParam))
    5001                 :            :                 {
    5002         [ +  - ]:         12 :                     PushNA();
    5003                 :            :                     return;
    5004                 :            :                 }
    5005                 :         93 :                 nDelta = aResultPos.Row() - nRow1;
    5006                 :            :             }
    5007                 :            :             else
    5008                 :            :             {                                           // search column in row
    5009                 :            :                 SCCOL nC;
    5010                 :          0 :                 rParam.bByRow = false;
    5011                 :          0 :                 rParam.nRow2 = nRow1;
    5012                 :          0 :                 rEntry.nField = nCol1;
    5013         [ #  # ]:          0 :                 ScQueryCellIterator aCellIter(pDok, nTab1, rParam, false);
    5014                 :            :                 // Advance Entry.nField in Iterator if column changed
    5015                 :          0 :                 aCellIter.SetAdvanceQueryParamEntryField( true );
    5016         [ #  # ]:          0 :                 if (fTyp == 0.0)
    5017                 :            :                 {                                       // EQUAL
    5018 [ #  # ][ #  # ]:          0 :                     if ( aCellIter.GetFirst() )
    5019                 :          0 :                         nC = aCellIter.GetCol();
    5020                 :            :                     else
    5021                 :            :                     {
    5022         [ #  # ]:          0 :                         PushNA();
    5023                 :            :                         return;
    5024                 :            :                     }
    5025                 :            :                 }
    5026                 :            :                 else
    5027                 :            :                 {                                       // <= or >=
    5028                 :            :                     SCROW nR;
    5029 [ #  # ][ #  # ]:          0 :                     if ( !aCellIter.FindEqualOrSortedLastInRange( nC, nR ) )
    5030                 :            :                     {
    5031         [ #  # ]:          0 :                         PushNA();
    5032                 :            :                         return;
    5033                 :            :                     }
    5034                 :            :                 }
    5035 [ #  # ][ #  # ]:          0 :                 nDelta = nC - nCol1;
    5036                 :            :             }
    5037 [ +  - ][ +  - ]:         93 :             PushDouble((double) (nDelta + 1));
         [ +  + ][ +  - ]
                 [ +  + ]
    5038                 :            :         }
    5039                 :            :         else
    5040 [ #  # ][ +  - ]:         93 :             PushIllegalParameter();
                 [ +  + ]
    5041                 :            :     }
    5042                 :            : }
    5043                 :            : 
    5044                 :            : 
    5045                 :          3 : void ScInterpreter::ScCountEmptyCells()
    5046                 :            : {
    5047                 :            :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScCountEmptyCells" );
    5048         [ +  - ]:          3 :     if ( MustHaveParamCount( GetByte(), 1 ) )
    5049                 :            :     {
    5050                 :          3 :         sal_uLong nMaxCount = 0, nCount = 0;
    5051                 :            :         CellType eCellType;
    5052      [ -  +  - ]:          3 :         switch (GetStackType())
    5053                 :            :         {
    5054                 :            :             case svSingleRef :
    5055                 :            :             {
    5056                 :          0 :                 nMaxCount = 1;
    5057                 :          0 :                 ScAddress aAdr;
    5058         [ #  # ]:          0 :                 PopSingleRef( aAdr );
    5059         [ #  # ]:          0 :                 eCellType = GetCellType( GetCell( aAdr ) );
    5060 [ #  # ][ #  # ]:          0 :                 if (eCellType != CELLTYPE_NONE && eCellType != CELLTYPE_NOTE)
    5061                 :          0 :                     nCount = 1;
    5062                 :            :             }
    5063                 :          0 :             break;
    5064                 :            :             case svDoubleRef :
    5065                 :            :             case svRefList :
    5066                 :            :             {
    5067                 :          3 :                 ScRange aRange;
    5068                 :          3 :                 short nParam = 1;
    5069                 :          3 :                 size_t nRefInList = 0;
    5070         [ +  + ]:          6 :                 while (nParam-- > 0)
    5071                 :            :                 {
    5072         [ +  - ]:          3 :                     PopDoubleRef( aRange, nParam, nRefInList);
    5073                 :            :                     nMaxCount +=
    5074                 :          3 :                         static_cast<sal_uLong>(aRange.aEnd.Row() - aRange.aStart.Row() + 1) *
    5075                 :          3 :                         static_cast<sal_uLong>(aRange.aEnd.Col() - aRange.aStart.Col() + 1) *
    5076                 :          3 :                         static_cast<sal_uLong>(aRange.aEnd.Tab() - aRange.aStart.Tab() + 1);
    5077                 :            :                     ScBaseCell* pCell;
    5078         [ +  - ]:          3 :                     ScCellIterator aDocIter( pDok, aRange, glSubTotal);
    5079 [ +  - ][ +  - ]:          3 :                     if ( (pCell = aDocIter.GetFirst()) != NULL )
    5080                 :            :                     {
    5081 [ +  - ][ +  + ]:         93 :                         do
    5082                 :            :                         {
    5083 [ +  - ][ +  - ]:         93 :                             if ((eCellType = pCell->GetCellType()) != CELLTYPE_NONE
                 [ +  - ]
    5084                 :            :                                     && eCellType != CELLTYPE_NOTE)
    5085                 :         93 :                                 nCount++;
    5086                 :            :                         } while ( (pCell = aDocIter.GetNext()) != NULL );
    5087                 :            :                     }
    5088                 :            :                 }
    5089                 :            :             }
    5090                 :          3 :             break;
    5091                 :          0 :             default : SetError(errIllegalParameter); break;
    5092                 :            :         }
    5093                 :          3 :         PushDouble(nMaxCount - nCount);
    5094                 :            :     }
    5095                 :          3 : }
    5096                 :            : 
    5097                 :            : 
    5098                 :         69 : void ScInterpreter::ScCountIf()
    5099                 :            : {
    5100                 :            :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScCountIf" );
    5101         [ +  - ]:         69 :     if ( MustHaveParamCount( GetByte(), 2 ) )
    5102                 :            :     {
    5103         [ +  - ]:         69 :         String rString;
    5104                 :         69 :         double fVal = 0.0;
    5105                 :         69 :         bool bIsString = true;
    5106         [ +  - ]:         69 :         switch ( GetStackType() )
           [ -  -  +  + ]
    5107                 :            :         {
    5108                 :            :             case svDoubleRef :
    5109                 :            :             case svSingleRef :
    5110                 :            :             {
    5111                 :          0 :                 ScAddress aAdr;
    5112 [ #  # ][ #  # ]:          0 :                 if ( !PopDoubleRefOrSingleRef( aAdr ) )
    5113                 :            :                 {
    5114         [ #  # ]:          0 :                     PushInt(0);
    5115                 :            :                     return ;
    5116                 :            :                 }
    5117         [ #  # ]:          0 :                 ScBaseCell* pCell = GetCell( aAdr );
    5118   [ #  #  #  # ]:          0 :                 switch ( GetCellType( pCell ) )
    5119                 :            :                 {
    5120                 :            :                     case CELLTYPE_VALUE :
    5121         [ #  # ]:          0 :                         fVal = GetCellValue( aAdr, pCell );
    5122                 :          0 :                         bIsString = false;
    5123                 :          0 :                         break;
    5124                 :            :                     case CELLTYPE_FORMULA :
    5125 [ #  # ][ #  # ]:          0 :                         if( ((ScFormulaCell*)pCell)->IsValue() )
                 [ #  # ]
    5126                 :            :                         {
    5127         [ #  # ]:          0 :                             fVal = GetCellValue( aAdr, pCell );
    5128                 :          0 :                             bIsString = false;
    5129                 :            :                         }
    5130                 :            :                         else
    5131         [ #  # ]:          0 :                             GetCellString(rString, pCell);
    5132                 :          0 :                         break;
    5133                 :            :                     case CELLTYPE_STRING :
    5134                 :            :                     case CELLTYPE_EDIT :
    5135         [ #  # ]:          0 :                         GetCellString(rString, pCell);
    5136                 :          0 :                         break;
    5137                 :            :                     default:
    5138                 :          0 :                         fVal = 0.0;
    5139                 :          0 :                         bIsString = false;
    5140                 :            :                 }
    5141                 :            :             }
    5142                 :          0 :             break;
    5143                 :            :             case svMatrix:
    5144                 :            :             case svExternalSingleRef:
    5145                 :            :             case svExternalDoubleRef:
    5146                 :            :             {
    5147                 :            :                 ScMatValType nType = GetDoubleOrStringFromMatrix( fVal,
    5148         [ #  # ]:          0 :                         rString);
    5149                 :          0 :                 bIsString = ScMatrix::IsNonValueType( nType);
    5150                 :            :             }
    5151                 :          0 :             break;
    5152                 :            :             case svString:
    5153 [ +  - ][ +  - ]:         36 :                 rString = GetString();
    5154                 :         36 :             break;
    5155                 :            :             default:
    5156                 :            :             {
    5157         [ +  - ]:         33 :                 fVal = GetDouble();
    5158                 :         33 :                 bIsString = false;
    5159                 :            :             }
    5160                 :            :         }
    5161                 :         69 :         double fSum = 0.0;
    5162                 :         69 :         short nParam = 1;
    5163                 :         69 :         size_t nRefInList = 0;
    5164         [ +  + ]:        138 :         while (nParam-- > 0)
    5165                 :            :         {
    5166                 :            :             SCCOL nCol1;
    5167                 :            :             SCROW nRow1;
    5168                 :            :             SCTAB nTab1;
    5169                 :            :             SCCOL nCol2;
    5170                 :            :             SCROW nRow2;
    5171                 :            :             SCTAB nTab2;
    5172                 :         69 :             ScMatrixRef pQueryMatrix;
    5173   [ +  +  -  - ]:         69 :             switch ( GetStackType() )
                 [ +  - ]
    5174                 :            :             {
    5175                 :            :                 case svDoubleRef :
    5176                 :            :                 case svRefList :
    5177                 :            :                     {
    5178                 :         66 :                         ScRange aRange;
    5179         [ +  - ]:         66 :                         PopDoubleRef( aRange, nParam, nRefInList);
    5180                 :         66 :                         aRange.GetVars( nCol1, nRow1, nTab1, nCol2, nRow2, nTab2);
    5181                 :            :                     }
    5182                 :         66 :                     break;
    5183                 :            :                 case svSingleRef :
    5184         [ +  - ]:          3 :                     PopSingleRef( nCol1, nRow1, nTab1 );
    5185                 :          3 :                     nCol2 = nCol1;
    5186                 :          3 :                     nRow2 = nRow1;
    5187                 :          3 :                     nTab2 = nTab1;
    5188                 :          3 :                     break;
    5189                 :            :                 case svMatrix:
    5190                 :            :                 case svExternalSingleRef:
    5191                 :            :                 case svExternalDoubleRef:
    5192                 :            :                 {
    5193 [ #  # ][ #  # ]:          0 :                     pQueryMatrix = GetMatrix();
                 [ #  # ]
    5194         [ #  # ]:          0 :                     if (!pQueryMatrix)
    5195                 :            :                     {
    5196         [ #  # ]:          0 :                         PushIllegalParameter();
    5197                 :            :                         return;
    5198                 :            :                     }
    5199                 :          0 :                     nCol1 = 0;
    5200                 :          0 :                     nRow1 = 0;
    5201                 :          0 :                     nTab1 = 0;
    5202                 :            :                     SCSIZE nC, nR;
    5203         [ #  # ]:          0 :                     pQueryMatrix->GetDimensions( nC, nR);
    5204                 :          0 :                     nCol2 = static_cast<SCCOL>(nC - 1);
    5205                 :          0 :                     nRow2 = static_cast<SCROW>(nR - 1);
    5206                 :          0 :                     nTab2 = 0;
    5207                 :            :                 }
    5208                 :          0 :                 break;
    5209                 :            :                 default:
    5210         [ #  # ]:          0 :                     PushIllegalParameter();
    5211                 :            :                     return ;
    5212                 :            :             }
    5213         [ -  + ]:         69 :             if ( nTab1 != nTab2 )
    5214                 :            :             {
    5215         [ #  # ]:          0 :                 PushIllegalParameter();
    5216                 :            :                 return;
    5217                 :            :             }
    5218         [ -  + ]:         69 :             if (nCol1 > nCol2)
    5219                 :            :             {
    5220         [ #  # ]:          0 :                 PushIllegalParameter();
    5221                 :            :                 return;
    5222                 :            :             }
    5223         [ +  - ]:         69 :             if (nGlobalError == 0)
    5224                 :            :             {
    5225         [ +  - ]:         69 :                 ScQueryParam rParam;
    5226                 :         69 :                 rParam.nRow1       = nRow1;
    5227                 :         69 :                 rParam.nRow2       = nRow2;
    5228                 :            : 
    5229         [ +  - ]:         69 :                 ScQueryEntry& rEntry = rParam.GetEntry(0);
    5230         [ +  - ]:         69 :                 ScQueryEntry::Item& rItem = rEntry.GetQueryItem();
    5231                 :         69 :                 rEntry.bDoQuery = true;
    5232         [ +  + ]:         69 :                 if (!bIsString)
    5233                 :            :                 {
    5234                 :         33 :                     rItem.meType = ScQueryEntry::ByValue;
    5235                 :         33 :                     rItem.mfVal = fVal;
    5236                 :         33 :                     rEntry.eOp = SC_EQUAL;
    5237                 :            :                 }
    5238                 :            :                 else
    5239                 :            :                 {
    5240 [ +  - ][ +  - ]:         36 :                     rParam.FillInExcelSyntax(rString, 0);
    5241                 :         36 :                     sal_uInt32 nIndex = 0;
    5242                 :            :                     bool bNumber = pFormatter->IsNumberFormat(
    5243 [ +  - ][ +  - ]:         36 :                             rItem.maString, nIndex, rItem.mfVal);
                 [ +  - ]
    5244         [ +  + ]:         36 :                     rItem.meType = bNumber ? ScQueryEntry::ByValue : ScQueryEntry::ByString;
    5245         [ +  + ]:         36 :                     if (rItem.meType == ScQueryEntry::ByString)
    5246         [ +  - ]:         36 :                         rParam.bRegExp = MayBeRegExp(rItem.maString, pDok);
    5247                 :            :                 }
    5248                 :         69 :                 rParam.nCol1  = nCol1;
    5249                 :         69 :                 rParam.nCol2  = nCol2;
    5250                 :         69 :                 rEntry.nField = nCol1;
    5251         [ -  + ]:         69 :                 if (pQueryMatrix)
    5252                 :            :                 {
    5253                 :            :                     // Never case-sensitive.
    5254         [ #  # ]:          0 :                     ScCompareOptions aOptions( pDok, rEntry, rParam.bRegExp);
    5255         [ #  # ]:          0 :                     ScMatrixRef pResultMatrix = QueryMat( pQueryMatrix, aOptions);
    5256 [ #  # ][ #  # ]:          0 :                     if (nGlobalError || !pResultMatrix)
                 [ #  # ]
    5257                 :            :                     {
    5258         [ #  # ]:          0 :                         PushIllegalParameter();
    5259                 :            :                         return;
    5260                 :            :                     }
    5261                 :            : 
    5262         [ #  # ]:          0 :                     SCSIZE nSize = pResultMatrix->GetElementCount();
    5263         [ #  # ]:          0 :                     for (SCSIZE nIndex = 0; nIndex < nSize; ++nIndex)
    5264                 :            :                     {
    5265 [ #  # ][ #  # ]:          0 :                         if (pResultMatrix->IsValue( nIndex) &&
         [ #  # ][ #  # ]
    5266         [ #  # ]:          0 :                                 pResultMatrix->GetDouble( nIndex))
    5267                 :          0 :                             ++fSum;
    5268 [ #  # ][ #  # ]:          0 :                     }
         [ #  # ][ #  # ]
    5269                 :            :                 }
    5270                 :            :                 else
    5271                 :            :                 {
    5272         [ +  - ]:         69 :                     ScQueryCellIterator aCellIter(pDok, nTab1, rParam, false);
    5273                 :            :                     // Keep Entry.nField in iterator on column change
    5274                 :         69 :                     aCellIter.SetAdvanceQueryParamEntryField( true );
    5275 [ +  + ][ +  - ]:         69 :                     if ( aCellIter.GetFirst() )
    5276                 :            :                     {
    5277         [ +  + ]:        204 :                         do
    5278                 :            :                         {
    5279                 :        204 :                             fSum++;
    5280         [ +  - ]:        204 :                         } while ( aCellIter.GetNext() );
    5281         [ +  - ]:         69 :                     }
    5282 [ +  - ][ +  - ]:         69 :                 }
    5283                 :            :             }
    5284                 :            :             else
    5285                 :            :             {
    5286         [ #  # ]:          0 :                 PushIllegalParameter();
    5287                 :            :                 return;
    5288                 :            :             }
    5289 [ +  - ][ +  - ]:         69 :         }
    5290 [ +  - ][ +  - ]:         69 :         PushDouble(fSum);
                 [ +  - ]
    5291                 :            :     }
    5292                 :            : }
    5293                 :            : 
    5294                 :            : 
    5295                 :          0 : void ScInterpreter::ScSumIf()
    5296                 :            : {
    5297                 :          0 :     sal_uInt8 nParamCount = GetByte();
    5298 [ #  # ][ #  # ]:          0 :     if ( !MustHaveParamCount( nParamCount, 2, 3 ) )
    5299                 :            :         return;
    5300                 :            : 
    5301                 :          0 :     SCCOL nCol3 = 0;
    5302                 :          0 :     SCROW nRow3 = 0;
    5303                 :          0 :     SCTAB nTab3 = 0;
    5304                 :            : 
    5305                 :          0 :     ScMatrixRef pSumExtraMatrix;
    5306                 :          0 :     bool bSumExtraRange = (nParamCount == 3);
    5307         [ #  # ]:          0 :     if (bSumExtraRange)
    5308                 :            :     {
    5309                 :            :         // Save only the upperleft cell in case of cell range.  The geometry
    5310                 :            :         // of the 3rd parameter is taken from the 1st parameter.
    5311                 :            : 
    5312 [ #  # ][ #  #  :          0 :         switch ( GetStackType() )
             #  #  #  # ]
    5313                 :            :         {
    5314                 :            :             case svDoubleRef :
    5315                 :            :             {
    5316                 :          0 :                 SCCOL nColJunk = 0;
    5317                 :          0 :                 SCROW nRowJunk = 0;
    5318                 :          0 :                 SCTAB nTabJunk = 0;
    5319         [ #  # ]:          0 :                 PopDoubleRef( nCol3, nRow3, nTab3, nColJunk, nRowJunk, nTabJunk );
    5320         [ #  # ]:          0 :                 if ( nTabJunk != nTab3 )
    5321                 :            :                 {
    5322         [ #  # ]:          0 :                     PushIllegalParameter();
    5323                 :            :                     return;
    5324                 :            :                 }
    5325                 :            :             }
    5326                 :          0 :             break;
    5327                 :            :             case svSingleRef :
    5328         [ #  # ]:          0 :                 PopSingleRef( nCol3, nRow3, nTab3 );
    5329                 :          0 :             break;
    5330                 :            :             case svMatrix:
    5331 [ #  # ][ #  # ]:          0 :                 pSumExtraMatrix = PopMatrix();
                 [ #  # ]
    5332                 :            :                 //! nCol3, nRow3, nTab3 remain 0
    5333                 :          0 :             break;
    5334                 :            :             case svExternalSingleRef:
    5335                 :            :             {
    5336 [ #  # ][ #  # ]:          0 :                 pSumExtraMatrix = new ScMatrix(1, 1, 0.0);
                 [ #  # ]
    5337                 :          0 :                 ScExternalRefCache::TokenRef pToken;
    5338         [ #  # ]:          0 :                 PopExternalSingleRef(pToken);
    5339         [ #  # ]:          0 :                 if (!pToken)
    5340                 :            :                 {
    5341         [ #  # ]:          0 :                     PushIllegalParameter();
    5342                 :            :                     return;
    5343                 :            :                 }
    5344                 :            : 
    5345         [ #  # ]:          0 :                 if (pToken->GetType() == svDouble)
    5346 [ #  # ][ #  # ]:          0 :                     pSumExtraMatrix->PutDouble(pToken->GetDouble(), 0, 0);
    5347                 :            :                 else
    5348 [ #  # ][ #  # ]:          0 :                     pSumExtraMatrix->PutString(pToken->GetString(), 0, 0);
         [ #  # ][ #  # ]
                 [ #  # ]
    5349                 :            :             }
    5350                 :          0 :             break;
    5351                 :            :             case svExternalDoubleRef:
    5352         [ #  # ]:          0 :                 PopExternalDoubleRef(pSumExtraMatrix);
    5353                 :          0 :             break;
    5354                 :            :             default:
    5355         [ #  # ]:          0 :                 PushIllegalParameter();
    5356                 :            :                 return ;
    5357                 :            :         }
    5358                 :            :     }
    5359                 :            : 
    5360         [ #  # ]:          0 :     String aString;
    5361                 :          0 :     double fVal = 0.0;
    5362                 :          0 :     bool bIsString = true;
    5363 [ #  # ][ #  #  :          0 :     switch ( GetStackType() )
                #  #  # ]
    5364                 :            :     {
    5365                 :            :         case svDoubleRef :
    5366                 :            :         case svSingleRef :
    5367                 :            :         {
    5368                 :          0 :             ScAddress aAdr;
    5369 [ #  # ][ #  # ]:          0 :             if ( !PopDoubleRefOrSingleRef( aAdr ) )
    5370                 :            :             {
    5371         [ #  # ]:          0 :                 PushInt(0);
    5372                 :            :                 return ;
    5373                 :            :             }
    5374         [ #  # ]:          0 :             ScBaseCell* pCell = GetCell( aAdr );
    5375   [ #  #  #  # ]:          0 :             switch ( GetCellType( pCell ) )
    5376                 :            :             {
    5377                 :            :                 case CELLTYPE_VALUE :
    5378         [ #  # ]:          0 :                     fVal = GetCellValue( aAdr, pCell );
    5379                 :          0 :                     bIsString = false;
    5380                 :          0 :                     break;
    5381                 :            :                 case CELLTYPE_FORMULA :
    5382 [ #  # ][ #  # ]:          0 :                     if( ((ScFormulaCell*)pCell)->IsValue() )
                 [ #  # ]
    5383                 :            :                     {
    5384         [ #  # ]:          0 :                         fVal = GetCellValue( aAdr, pCell );
    5385                 :          0 :                         bIsString = false;
    5386                 :            :                     }
    5387                 :            :                     else
    5388         [ #  # ]:          0 :                         GetCellString(aString, pCell);
    5389                 :          0 :                     break;
    5390                 :            :                 case CELLTYPE_STRING :
    5391                 :            :                 case CELLTYPE_EDIT :
    5392         [ #  # ]:          0 :                     GetCellString(aString, pCell);
    5393                 :          0 :                     break;
    5394                 :            :                 default:
    5395                 :          0 :                     fVal = 0.0;
    5396                 :          0 :                     bIsString = false;
    5397                 :            :             }
    5398                 :            :         }
    5399                 :          0 :         break;
    5400                 :            :         case svString:
    5401 [ #  # ][ #  # ]:          0 :             aString = GetString();
    5402                 :          0 :         break;
    5403                 :            :         case svMatrix :
    5404                 :            :         case svExternalDoubleRef:
    5405                 :            :         {
    5406         [ #  # ]:          0 :             ScMatValType nType = GetDoubleOrStringFromMatrix(fVal, aString);
    5407                 :          0 :             bIsString = ScMatrix::IsNonValueType( nType);
    5408                 :            :         }
    5409                 :          0 :         break;
    5410                 :            :         case svExternalSingleRef:
    5411                 :            :         {
    5412                 :          0 :             ScExternalRefCache::TokenRef pToken;
    5413         [ #  # ]:          0 :             PopExternalSingleRef(pToken);
    5414         [ #  # ]:          0 :             if (pToken)
    5415                 :            :             {
    5416         [ #  # ]:          0 :                 if (pToken->GetType() == svDouble)
    5417                 :            :                 {
    5418         [ #  # ]:          0 :                     fVal = pToken->GetDouble();
    5419                 :          0 :                     bIsString = false;
    5420                 :            :                 }
    5421                 :            :                 else
    5422 [ #  # ][ #  # ]:          0 :                     aString = pToken->GetString();
    5423         [ #  # ]:          0 :             }
    5424                 :            :         }
    5425                 :          0 :         break;
    5426                 :            :         default:
    5427                 :            :         {
    5428         [ #  # ]:          0 :             fVal = GetDouble();
    5429                 :          0 :             bIsString = false;
    5430                 :            :         }
    5431                 :            :     }
    5432                 :            : 
    5433                 :          0 :     double fSum = 0.0;
    5434                 :          0 :     double fMem = 0.0;
    5435                 :          0 :     bool bNull = true;
    5436                 :          0 :     short nParam = 1;
    5437                 :          0 :     size_t nRefInList = 0;
    5438         [ #  # ]:          0 :     while (nParam-- > 0)
    5439                 :            :     {
    5440                 :            :         SCCOL nCol1;
    5441                 :            :         SCROW nRow1;
    5442                 :            :         SCTAB nTab1;
    5443                 :            :         SCCOL nCol2;
    5444                 :            :         SCROW nRow2;
    5445                 :            :         SCTAB nTab2;
    5446                 :          0 :         ScMatrixRef pQueryMatrix;
    5447   [ #  #  #  #  :          0 :         switch ( GetStackType() )
              # ][ #  # ]
    5448                 :            :         {
    5449                 :            :             case svRefList :
    5450         [ #  # ]:          0 :                 if (bSumExtraRange)
    5451                 :            :                 {
    5452         [ #  # ]:          0 :                     PushIllegalParameter();
    5453                 :            :                     return;
    5454                 :            :                 }
    5455                 :            :                 else
    5456                 :            :                 {
    5457                 :          0 :                     ScRange aRange;
    5458         [ #  # ]:          0 :                     PopDoubleRef( aRange, nParam, nRefInList);
    5459                 :          0 :                     aRange.GetVars( nCol1, nRow1, nTab1, nCol2, nRow2, nTab2);
    5460                 :            :                 }
    5461                 :          0 :                 break;
    5462                 :            :             case svDoubleRef :
    5463         [ #  # ]:          0 :                 PopDoubleRef( nCol1, nRow1, nTab1, nCol2, nRow2, nTab2 );
    5464                 :          0 :                 break;
    5465                 :            :             case svSingleRef :
    5466         [ #  # ]:          0 :                 PopSingleRef( nCol1, nRow1, nTab1 );
    5467                 :          0 :                 nCol2 = nCol1;
    5468                 :          0 :                 nRow2 = nRow1;
    5469                 :          0 :                 nTab2 = nTab1;
    5470                 :          0 :                 break;
    5471                 :            :             case svMatrix:
    5472                 :            :             case svExternalSingleRef:
    5473                 :            :             case svExternalDoubleRef:
    5474                 :            :             {
    5475 [ #  # ][ #  # ]:          0 :                 pQueryMatrix = GetMatrix();
                 [ #  # ]
    5476         [ #  # ]:          0 :                 if (!pQueryMatrix)
    5477                 :            :                 {
    5478         [ #  # ]:          0 :                     PushIllegalParameter();
    5479                 :            :                     return;
    5480                 :            :                 }
    5481                 :          0 :                 nCol1 = 0;
    5482                 :          0 :                 nRow1 = 0;
    5483                 :          0 :                 nTab1 = 0;
    5484                 :            :                 SCSIZE nC, nR;
    5485         [ #  # ]:          0 :                 pQueryMatrix->GetDimensions( nC, nR);
    5486                 :          0 :                 nCol2 = static_cast<SCCOL>(nC - 1);
    5487                 :          0 :                 nRow2 = static_cast<SCROW>(nR - 1);
    5488                 :          0 :                 nTab2 = 0;
    5489                 :            :             }
    5490                 :          0 :             break;
    5491                 :            :             default:
    5492         [ #  # ]:          0 :                 PushIllegalParameter();
    5493                 :            :                 return ;
    5494                 :            :         }
    5495         [ #  # ]:          0 :         if ( nTab1 != nTab2 )
    5496                 :            :         {
    5497         [ #  # ]:          0 :             PushIllegalArgument();
    5498                 :            :             return;
    5499                 :            :         }
    5500                 :            : 
    5501         [ #  # ]:          0 :         if (bSumExtraRange)
    5502                 :            :         {
    5503                 :            :             // Take the range geometry of the 1st parameter and apply it to
    5504                 :            :             // the 3rd. If parts of the resulting range would point outside
    5505                 :            :             // the sheet, don't complain but silently ignore and simply cut
    5506                 :            :             // them away, this is what Xcl does :-/
    5507                 :            : 
    5508                 :            :             // For the cut-away part we also don't need to determine the
    5509                 :            :             // criteria match, so shrink the source range accordingly,
    5510                 :            :             // instead of the result range.
    5511                 :          0 :             SCCOL nColDelta = nCol2 - nCol1;
    5512                 :          0 :             SCROW nRowDelta = nRow2 - nRow1;
    5513                 :            :             SCCOL nMaxCol;
    5514                 :            :             SCROW nMaxRow;
    5515         [ #  # ]:          0 :             if (pSumExtraMatrix)
    5516                 :            :             {
    5517                 :            :                 SCSIZE nC, nR;
    5518         [ #  # ]:          0 :                 pSumExtraMatrix->GetDimensions( nC, nR);
    5519                 :          0 :                 nMaxCol = static_cast<SCCOL>(nC - 1);
    5520                 :          0 :                 nMaxRow = static_cast<SCROW>(nR - 1);
    5521                 :            :             }
    5522                 :            :             else
    5523                 :            :             {
    5524                 :          0 :                 nMaxCol = MAXCOL;
    5525                 :          0 :                 nMaxRow = MAXROW;
    5526                 :            :             }
    5527         [ #  # ]:          0 :             if (nCol3 + nColDelta > nMaxCol)
    5528                 :            :             {
    5529                 :          0 :                 SCCOL nNewDelta = nMaxCol - nCol3;
    5530                 :          0 :                 nCol2 = nCol1 + nNewDelta;
    5531                 :            :             }
    5532                 :            : 
    5533         [ #  # ]:          0 :             if (nRow3 + nRowDelta > nMaxRow)
    5534                 :            :             {
    5535                 :          0 :                 SCROW nNewDelta = nMaxRow - nRow3;
    5536                 :          0 :                 nRow2 = nRow1 + nNewDelta;
    5537                 :            :             }
    5538                 :            :         }
    5539                 :            :         else
    5540                 :            :         {
    5541                 :          0 :             nCol3 = nCol1;
    5542                 :          0 :             nRow3 = nRow1;
    5543                 :          0 :             nTab3 = nTab1;
    5544                 :            :         }
    5545                 :            : 
    5546         [ #  # ]:          0 :         if (nGlobalError == 0)
    5547                 :            :         {
    5548         [ #  # ]:          0 :             ScQueryParam rParam;
    5549                 :          0 :             rParam.nRow1       = nRow1;
    5550                 :          0 :             rParam.nRow2       = nRow2;
    5551                 :            : 
    5552         [ #  # ]:          0 :             ScQueryEntry& rEntry = rParam.GetEntry(0);
    5553         [ #  # ]:          0 :             ScQueryEntry::Item& rItem = rEntry.GetQueryItem();
    5554                 :          0 :             rEntry.bDoQuery = true;
    5555         [ #  # ]:          0 :             if (!bIsString)
    5556                 :            :             {
    5557                 :          0 :                 rItem.meType = ScQueryEntry::ByValue;
    5558                 :          0 :                 rItem.mfVal = fVal;
    5559                 :          0 :                 rEntry.eOp = SC_EQUAL;
    5560                 :            :             }
    5561                 :            :             else
    5562                 :            :             {
    5563 [ #  # ][ #  # ]:          0 :                 rParam.FillInExcelSyntax(aString, 0);
    5564                 :          0 :                 sal_uInt32 nIndex = 0;
    5565                 :            :                 bool bNumber = pFormatter->IsNumberFormat(
    5566 [ #  # ][ #  # ]:          0 :                         rItem.maString, nIndex, rItem.mfVal);
                 [ #  # ]
    5567         [ #  # ]:          0 :                 rItem.meType = bNumber ? ScQueryEntry::ByValue : ScQueryEntry::ByString;
    5568         [ #  # ]:          0 :                 if (rItem.meType == ScQueryEntry::ByString)
    5569         [ #  # ]:          0 :                     rParam.bRegExp = MayBeRegExp(rItem.maString, pDok);
    5570                 :            :             }
    5571                 :          0 :             ScAddress aAdr;
    5572                 :          0 :             aAdr.SetTab( nTab3 );
    5573                 :          0 :             rParam.nCol1  = nCol1;
    5574                 :          0 :             rParam.nCol2  = nCol2;
    5575                 :          0 :             rEntry.nField = nCol1;
    5576                 :          0 :             SCsCOL nColDiff = nCol3 - nCol1;
    5577                 :          0 :             SCsROW nRowDiff = nRow3 - nRow1;
    5578         [ #  # ]:          0 :             if (pQueryMatrix)
    5579                 :            :             {
    5580                 :            :                 // Never case-sensitive.
    5581         [ #  # ]:          0 :                 ScCompareOptions aOptions( pDok, rEntry, rParam.bRegExp);
    5582         [ #  # ]:          0 :                 ScMatrixRef pResultMatrix = QueryMat( pQueryMatrix, aOptions);
    5583 [ #  # ][ #  # ]:          0 :                 if (nGlobalError || !pResultMatrix)
                 [ #  # ]
    5584                 :            :                 {
    5585         [ #  # ]:          0 :                     PushIllegalParameter();
    5586                 :            :                     return;
    5587                 :            :                 }
    5588                 :            : 
    5589         [ #  # ]:          0 :                 if (pSumExtraMatrix)
    5590                 :            :                 {
    5591         [ #  # ]:          0 :                     for (SCCOL nCol = nCol1; nCol <= nCol2; ++nCol)
    5592                 :            :                     {
    5593         [ #  # ]:          0 :                         for (SCROW nRow = nRow1; nRow <= nRow2; ++nRow)
    5594                 :            :                         {
    5595 [ #  # ][ #  # ]:          0 :                             if (pResultMatrix->IsValue( nCol, nRow) &&
         [ #  # ][ #  # ]
    5596         [ #  # ]:          0 :                                     pResultMatrix->GetDouble( nCol, nRow))
    5597                 :            :                             {
    5598                 :          0 :                                 SCSIZE nC = nCol + nColDiff;
    5599                 :          0 :                                 SCSIZE nR = nRow + nRowDiff;
    5600 [ #  # ][ #  # ]:          0 :                                 if (pSumExtraMatrix->IsValue( nC, nR))
    5601                 :            :                                 {
    5602         [ #  # ]:          0 :                                     fVal = pSumExtraMatrix->GetDouble( nC, nR);
    5603 [ #  # ][ #  # ]:          0 :                                     if ( bNull && fVal != 0.0 )
    5604                 :            :                                     {
    5605                 :          0 :                                         bNull = false;
    5606                 :          0 :                                         fMem = fVal;
    5607                 :            :                                     }
    5608                 :            :                                     else
    5609                 :          0 :                                         fSum += fVal;
    5610                 :            :                                 }
    5611                 :            :                             }
    5612                 :            :                         }
    5613                 :            :                     }
    5614                 :            :                 }
    5615                 :            :                 else
    5616                 :            :                 {
    5617         [ #  # ]:          0 :                     for (SCCOL nCol = nCol1; nCol <= nCol2; ++nCol)
    5618                 :            :                     {
    5619         [ #  # ]:          0 :                         for (SCROW nRow = nRow1; nRow <= nRow2; ++nRow)
    5620                 :            :                         {
    5621 [ #  # ][ #  # ]:          0 :                             if (pResultMatrix->GetDouble( nCol, nRow))
    5622                 :            :                             {
    5623                 :          0 :                                 aAdr.SetCol( nCol + nColDiff);
    5624                 :          0 :                                 aAdr.SetRow( nRow + nRowDiff);
    5625         [ #  # ]:          0 :                                 ScBaseCell* pCell = GetCell( aAdr );
    5626 [ #  # ][ #  # ]:          0 :                                 if ( HasCellValueData(pCell) )
    5627                 :            :                                 {
    5628         [ #  # ]:          0 :                                     fVal = GetCellValue( aAdr, pCell );
    5629 [ #  # ][ #  # ]:          0 :                                     if ( bNull && fVal != 0.0 )
    5630                 :            :                                     {
    5631                 :          0 :                                         bNull = false;
    5632                 :          0 :                                         fMem = fVal;
    5633                 :            :                                     }
    5634                 :            :                                     else
    5635                 :          0 :                                         fSum += fVal;
    5636                 :            :                                 }
    5637                 :            :                             }
    5638                 :            :                         }
    5639                 :            :                     }
    5640 [ #  # ][ #  # ]:          0 :                 }
         [ #  # ][ #  # ]
    5641                 :            :             }
    5642                 :            :             else
    5643                 :            :             {
    5644         [ #  # ]:          0 :                 ScQueryCellIterator aCellIter(pDok, nTab1, rParam, false);
    5645                 :            :                 // Increment Entry.nField in iterator when switching to next column.
    5646                 :          0 :                 aCellIter.SetAdvanceQueryParamEntryField( true );
    5647 [ #  # ][ #  # ]:          0 :                 if ( aCellIter.GetFirst() )
    5648                 :            :                 {
    5649         [ #  # ]:          0 :                     if (pSumExtraMatrix)
    5650                 :            :                     {
    5651         [ #  # ]:          0 :                         do
    5652                 :            :                         {
    5653                 :          0 :                             SCSIZE nC = aCellIter.GetCol() + nColDiff;
    5654                 :          0 :                             SCSIZE nR = aCellIter.GetRow() + nRowDiff;
    5655 [ #  # ][ #  # ]:          0 :                             if (pSumExtraMatrix->IsValue( nC, nR))
    5656                 :            :                             {
    5657         [ #  # ]:          0 :                                 fVal = pSumExtraMatrix->GetDouble( nC, nR);
    5658 [ #  # ][ #  # ]:          0 :                                 if ( bNull && fVal != 0.0 )
    5659                 :            :                                 {
    5660                 :          0 :                                     bNull = false;
    5661                 :          0 :                                     fMem = fVal;
    5662                 :            :                                 }
    5663                 :            :                                 else
    5664                 :          0 :                                     fSum += fVal;
    5665                 :            :                             }
    5666         [ #  # ]:          0 :                         } while ( aCellIter.GetNext() );
    5667                 :            :                     }
    5668                 :            :                     else
    5669                 :            :                     {
    5670         [ #  # ]:          0 :                         do
    5671                 :            :                         {
    5672                 :          0 :                             aAdr.SetCol( aCellIter.GetCol() + nColDiff);
    5673                 :          0 :                             aAdr.SetRow( aCellIter.GetRow() + nRowDiff);
    5674         [ #  # ]:          0 :                             ScBaseCell* pCell = GetCell( aAdr );
    5675 [ #  # ][ #  # ]:          0 :                             if ( HasCellValueData(pCell) )
    5676                 :            :                             {
    5677         [ #  # ]:          0 :                                 fVal = GetCellValue( aAdr, pCell );
    5678 [ #  # ][ #  # ]:          0 :                                 if ( bNull && fVal != 0.0 )
    5679                 :            :                                 {
    5680                 :          0 :                                     bNull = false;
    5681                 :          0 :                                     fMem = fVal;
    5682                 :            :                                 }
    5683                 :            :                                 else
    5684                 :          0 :                                     fSum += fVal;
    5685                 :            :                             }
    5686         [ #  # ]:          0 :                         } while ( aCellIter.GetNext() );
    5687                 :            :                     }
    5688         [ #  # ]:          0 :                 }
    5689 [ #  # ][ #  # ]:          0 :             }
    5690                 :            :         }
    5691                 :            :         else
    5692                 :            :         {
    5693         [ #  # ]:          0 :             PushIllegalParameter();
    5694                 :            :             return;
    5695                 :            :         }
    5696 [ #  # ][ #  # ]:          0 :     }
    5697 [ #  # ][ #  # ]:          0 :     PushDouble( ::rtl::math::approxAdd( fSum, fMem ) );
         [ #  # ][ #  # ]
                 [ #  # ]
    5698                 :            : }
    5699                 :            : 
    5700                 :            : 
    5701                 :          0 : void ScInterpreter::ScLookup()
    5702                 :            : {
    5703                 :            :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScLookup" );
    5704                 :          0 :     sal_uInt8 nParamCount = GetByte();
    5705 [ #  # ][ #  # ]:          0 :     if ( !MustHaveParamCount( nParamCount, 2, 3 ) )
    5706                 :            :         return ;
    5707                 :            : 
    5708                 :          0 :     ScMatrixRef pDataMat = NULL, pResMat = NULL;
    5709                 :          0 :     SCCOL nCol1 = 0, nCol2 = 0, nResCol1 = 0, nResCol2 = 0;
    5710                 :          0 :     SCROW nRow1 = 0, nRow2 = 0, nResRow1 = 0, nResRow2 = 0;
    5711                 :          0 :     SCTAB nTab1 = 0, nResTab = 0;
    5712                 :          0 :     SCSIZE nLenMajor = 0;   // length of major direction
    5713                 :          0 :     bool bVertical = true;  // whether to lookup vertically or horizontally
    5714                 :            : 
    5715                 :            :     // The third parameter, result array, for double, string and single reference.
    5716                 :          0 :     double fResVal = 0.0;
    5717         [ #  # ]:          0 :     String aResStr;
    5718                 :          0 :     ScAddress aResAdr;
    5719                 :          0 :     StackVar eResArrayType = svUnknown;
    5720                 :            : 
    5721         [ #  # ]:          0 :     if (nParamCount == 3)
    5722                 :            :     {
    5723         [ #  # ]:          0 :         eResArrayType = GetStackType();
    5724   [ #  #  #  #  :          0 :         switch (eResArrayType)
                   #  # ]
    5725                 :            :         {
    5726                 :            :             case svDoubleRef:
    5727                 :            :             {
    5728                 :            :                 SCTAB nTabJunk;
    5729                 :            :                 PopDoubleRef(nResCol1, nResRow1, nResTab,
    5730         [ #  # ]:          0 :                              nResCol2, nResRow2, nTabJunk);
    5731 [ #  # ][ #  # ]:          0 :                 if (nResTab != nTabJunk ||
                 [ #  # ]
    5732                 :            :                     ((nResRow2 - nResRow1) > 0 && (nResCol2 - nResCol1) > 0))
    5733                 :            :                 {
    5734                 :            :                     // The result array must be a vector.
    5735         [ #  # ]:          0 :                     PushIllegalParameter();
    5736                 :            :                     return;
    5737                 :            :                 }
    5738                 :            :             }
    5739                 :          0 :             break;
    5740                 :            :             case svMatrix:
    5741                 :            :             case svExternalSingleRef:
    5742                 :            :             case svExternalDoubleRef:
    5743                 :            :             {
    5744 [ #  # ][ #  # ]:          0 :                 pResMat = GetMatrix();
                 [ #  # ]
    5745         [ #  # ]:          0 :                 if (!pResMat)
    5746                 :            :                 {
    5747         [ #  # ]:          0 :                     PushIllegalParameter();
    5748                 :            :                     return;
    5749                 :            :                 }
    5750                 :            :                 SCSIZE nC, nR;
    5751         [ #  # ]:          0 :                 pResMat->GetDimensions(nC, nR);
    5752 [ #  # ][ #  # ]:          0 :                 if (nC != 1 && nR != 1)
    5753                 :            :                 {
    5754                 :            :                     // Result matrix must be a vector.
    5755         [ #  # ]:          0 :                     PushIllegalParameter();
    5756                 :            :                     return;
    5757                 :            :                 }
    5758                 :            :             }
    5759                 :          0 :             break;
    5760                 :            :             case svDouble:
    5761         [ #  # ]:          0 :                 fResVal = GetDouble();
    5762                 :          0 :             break;
    5763                 :            :             case svString:
    5764 [ #  # ][ #  # ]:          0 :                 aResStr = GetString();
    5765                 :          0 :             break;
    5766                 :            :             case svSingleRef:
    5767         [ #  # ]:          0 :                 PopSingleRef( aResAdr );
    5768                 :          0 :             break;
    5769                 :            :             default:
    5770         [ #  # ]:          0 :                 PushIllegalParameter();
    5771                 :            :                 return;
    5772                 :            :         }
    5773                 :            :     }
    5774                 :            : 
    5775                 :            :     // For double, string and single reference.
    5776                 :          0 :     double fDataVal = 0.0;
    5777         [ #  # ]:          0 :     String aDataStr;
    5778                 :          0 :     ScAddress aDataAdr;
    5779                 :          0 :     bool bValueData = false;
    5780                 :            : 
    5781                 :            :     // Get the data-result range and also determine whether this is vertical
    5782                 :            :     // lookup or horizontal lookup.
    5783                 :            : 
    5784         [ #  # ]:          0 :     StackVar eDataArrayType = GetStackType();
    5785   [ #  #  #  #  :          0 :     switch (eDataArrayType)
                   #  # ]
    5786                 :            :     {
    5787                 :            :         case svDoubleRef:
    5788                 :            :         {
    5789                 :            :             SCTAB nTabJunk;
    5790         [ #  # ]:          0 :             PopDoubleRef(nCol1, nRow1, nTab1, nCol2, nRow2, nTabJunk);
    5791         [ #  # ]:          0 :             if (nTab1 != nTabJunk)
    5792                 :            :             {
    5793         [ #  # ]:          0 :                 PushIllegalParameter();
    5794                 :            :                 return;
    5795                 :            :             }
    5796                 :          0 :             bVertical = (nRow2 - nRow1) >= (nCol2 - nCol1);
    5797         [ #  # ]:          0 :             nLenMajor = bVertical ? nRow2 - nRow1 + 1 : nCol2 - nCol1 + 1;
    5798                 :            :         }
    5799                 :          0 :         break;
    5800                 :            :         case svMatrix:
    5801                 :            :         case svExternalSingleRef:
    5802                 :            :         case svExternalDoubleRef:
    5803                 :            :         {
    5804 [ #  # ][ #  # ]:          0 :             pDataMat = GetMatrix();
                 [ #  # ]
    5805         [ #  # ]:          0 :             if (!pDataMat)
    5806                 :            :             {
    5807         [ #  # ]:          0 :                 PushIllegalParameter();
    5808                 :            :                 return;
    5809                 :            :             }
    5810                 :            : 
    5811                 :            :             SCSIZE nC, nR;
    5812         [ #  # ]:          0 :             pDataMat->GetDimensions(nC, nR);
    5813                 :          0 :             bVertical = (nR >= nC);
    5814         [ #  # ]:          0 :             nLenMajor = bVertical ? nR : nC;
    5815                 :            :         }
    5816                 :          0 :         break;
    5817                 :            :         case svDouble:
    5818                 :            :         {
    5819         [ #  # ]:          0 :             fDataVal = GetDouble();
    5820                 :          0 :             bValueData = true;
    5821                 :            :         }
    5822                 :          0 :         break;
    5823                 :            :         case svString:
    5824                 :            :         {
    5825 [ #  # ][ #  # ]:          0 :             aDataStr = GetString();
    5826                 :            :         }
    5827                 :          0 :         break;
    5828                 :            :         case svSingleRef:
    5829                 :            :         {
    5830         [ #  # ]:          0 :             PopSingleRef( aDataAdr );
    5831         [ #  # ]:          0 :             const ScBaseCell* pDataCell = GetCell( aDataAdr );
    5832 [ #  # ][ #  # ]:          0 :             if (HasCellEmptyData( pDataCell))
    5833                 :            :             {
    5834                 :            :                 // Empty cells aren't found anywhere, bail out early.
    5835                 :          0 :                 SetError( NOTAVAILABLE);
    5836                 :            :             }
    5837 [ #  # ][ #  # ]:          0 :             else if (HasCellValueData( pDataCell))
    5838                 :            :             {
    5839         [ #  # ]:          0 :                 fDataVal = GetCellValue( aDataAdr, pDataCell );
    5840                 :          0 :                 bValueData = true;
    5841                 :            :             }
    5842                 :            :             else
    5843         [ #  # ]:          0 :                 GetCellString( aDataStr, pDataCell );
    5844                 :            :         }
    5845                 :          0 :         break;
    5846                 :            :         default:
    5847                 :          0 :             SetError( errIllegalParameter);
    5848                 :            :     }
    5849                 :            : 
    5850                 :            : 
    5851         [ #  # ]:          0 :     if (nGlobalError)
    5852                 :            :     {
    5853         [ #  # ]:          0 :         PushError( nGlobalError);
    5854                 :            :         return;
    5855                 :            :     }
    5856                 :            : 
    5857                 :            :     // Get the lookup value.
    5858                 :            : 
    5859         [ #  # ]:          0 :     ScQueryParam aParam;
    5860         [ #  # ]:          0 :     ScQueryEntry& rEntry = aParam.GetEntry(0);
    5861 [ #  # ][ #  # ]:          0 :     if ( !FillEntry(rEntry) )
    5862                 :            :         return;
    5863                 :            : 
    5864 [ #  # ][ #  # ]:          0 :     if ( eDataArrayType == svDouble || eDataArrayType == svString ||
                 [ #  # ]
    5865                 :            :             eDataArrayType == svSingleRef )
    5866                 :            :     {
    5867                 :            :         // Delta position for a single value is always 0.
    5868                 :            : 
    5869                 :            :         // Found if data <= query, but not if query is string and found data is
    5870                 :            :         // numeric or vice versa. This is how Excel does it but doesn't
    5871                 :            :         // document it.
    5872                 :            : 
    5873                 :          0 :         bool bFound = false;
    5874         [ #  # ]:          0 :         ScQueryEntry::Item& rItem = rEntry.GetQueryItem();
    5875                 :            : 
    5876         [ #  # ]:          0 :         if ( bValueData )
    5877                 :            :         {
    5878         [ #  # ]:          0 :             if (rItem.meType == ScQueryEntry::ByString)
    5879                 :          0 :                 bFound = false;
    5880                 :            :             else
    5881                 :          0 :                 bFound = (fDataVal <= rItem.mfVal);
    5882                 :            :         }
    5883                 :            :         else
    5884                 :            :         {
    5885         [ #  # ]:          0 :             if (rItem.meType != ScQueryEntry::ByString)
    5886                 :          0 :                 bFound = false;
    5887                 :            :             else
    5888 [ #  # ][ #  # ]:          0 :                 bFound = (ScGlobal::GetCollator()->compareString(aDataStr, rItem.maString) <= 0);
                 [ #  # ]
    5889                 :            :         }
    5890                 :            : 
    5891         [ #  # ]:          0 :         if (!bFound)
    5892                 :            :         {
    5893         [ #  # ]:          0 :             PushNA();
    5894                 :            :             return;
    5895                 :            :         }
    5896                 :            : 
    5897         [ #  # ]:          0 :         if (pResMat)
    5898                 :            :         {
    5899 [ #  # ][ #  # ]:          0 :             if (pResMat->IsValue( 0, 0 ))
    5900 [ #  # ][ #  # ]:          0 :                 PushDouble(pResMat->GetDouble( 0, 0 ));
    5901                 :            :             else
    5902 [ #  # ][ #  # ]:          0 :                 PushString(pResMat->GetString( 0, 0 ));
         [ #  # ][ #  # ]
    5903                 :            :         }
    5904         [ #  # ]:          0 :         else if (nParamCount == 3)
    5905                 :            :         {
    5906   [ #  #  #  #  :          0 :             switch (eResArrayType)
                      # ]
    5907                 :            :             {
    5908                 :            :                 case svDouble:
    5909         [ #  # ]:          0 :                     PushDouble( fResVal );
    5910                 :          0 :                     break;
    5911                 :            :                 case svString:
    5912         [ #  # ]:          0 :                     PushString( aResStr );
    5913                 :          0 :                     break;
    5914                 :            :                 case svDoubleRef:
    5915                 :          0 :                     aResAdr.Set( nResCol1, nResRow1, nResTab);
    5916                 :            :                     // fallthru
    5917                 :            :                 case svSingleRef:
    5918         [ #  # ]:          0 :                     PushCellResultToken( true, aResAdr, NULL, NULL);
    5919                 :          0 :                     break;
    5920                 :            :                 default:
    5921                 :            :                     OSL_FAIL( "ScInterpreter::ScLookup: unhandled eResArrayType, single value data");
    5922                 :            :             }
    5923                 :            :         }
    5924                 :            :         else
    5925                 :            :         {
    5926   [ #  #  #  # ]:          0 :             switch (eDataArrayType)
    5927                 :            :             {
    5928                 :            :                 case svDouble:
    5929         [ #  # ]:          0 :                     PushDouble( fDataVal );
    5930                 :          0 :                     break;
    5931                 :            :                 case svString:
    5932         [ #  # ]:          0 :                     PushString( aDataStr );
    5933                 :          0 :                     break;
    5934                 :            :                 case svSingleRef:
    5935         [ #  # ]:          0 :                     PushCellResultToken( true, aDataAdr, NULL, NULL);
    5936                 :          0 :                     break;
    5937                 :            :                 default:
    5938                 :            :                     OSL_FAIL( "ScInterpreter::ScLookup: unhandled eDataArrayType, single value data");
    5939                 :            :             }
    5940                 :            :         }
    5941                 :            :         return;
    5942                 :            :     }
    5943                 :            : 
    5944                 :            :     // Now, perform the search to compute the delta position (nDelta).
    5945                 :            : 
    5946         [ #  # ]:          0 :     if (pDataMat)
    5947                 :            :     {
    5948                 :            :         // Data array is given as a matrix.
    5949                 :          0 :         rEntry.bDoQuery = true;
    5950                 :          0 :         rEntry.eOp = SC_LESS_EQUAL;
    5951                 :          0 :         bool bFound = false;
    5952                 :            : 
    5953                 :            :         SCSIZE nC, nR;
    5954         [ #  # ]:          0 :         pDataMat->GetDimensions(nC, nR);
    5955                 :            : 
    5956                 :            :         // In case of non-vector matrix, only search the first row or column.
    5957                 :          0 :         ScMatrixRef pDataMat2;
    5958         [ #  # ]:          0 :         if (bVertical)
    5959                 :            :         {
    5960 [ #  # ][ #  # ]:          0 :             ScMatrixRef pTempMat(new ScMatrix(1, nR, 0.0));
    5961         [ #  # ]:          0 :             for (SCSIZE i = 0; i < nR; ++i)
    5962 [ #  # ][ #  # ]:          0 :                 if (pDataMat->IsValue(0, i))
    5963 [ #  # ][ #  # ]:          0 :                     pTempMat->PutDouble(pDataMat->GetDouble(0, i), 0, i);
    5964                 :            :                 else
    5965 [ #  # ][ #  # ]:          0 :                     pTempMat->PutString(pDataMat->GetString(0, i), 0, i);
    5966 [ #  # ][ #  # ]:          0 :             pDataMat2 = pTempMat;
    5967                 :            :         }
    5968                 :            :         else
    5969                 :            :         {
    5970 [ #  # ][ #  # ]:          0 :             ScMatrixRef pTempMat(new ScMatrix(nC, 1, 0.0));
    5971         [ #  # ]:          0 :             for (SCSIZE i = 0; i < nC; ++i)
    5972 [ #  # ][ #  # ]:          0 :                 if (pDataMat->IsValue(i, 0))
    5973 [ #  # ][ #  # ]:          0 :                     pTempMat->PutDouble(pDataMat->GetDouble(i, 0), i, 0);
    5974                 :            :                 else
    5975 [ #  # ][ #  # ]:          0 :                     pTempMat->PutString(pDataMat->GetString(i, 0), i, 0);
    5976 [ #  # ][ #  # ]:          0 :             pDataMat2 = pTempMat;
    5977                 :            :         }
    5978                 :            : 
    5979                 :          0 :         VectorMatrixAccessor aMatAcc2(*pDataMat2, bVertical);
    5980                 :            : 
    5981                 :            :         // binary search for non-equality mode (the source data is
    5982                 :            :         // assumed to be sorted in ascending order).
    5983                 :            : 
    5984                 :          0 :         SCCOLROW nDelta = -1;
    5985                 :            : 
    5986                 :          0 :         SCSIZE nFirst = 0, nLast = nLenMajor-1; //, nHitIndex = 0;
    5987         [ #  # ]:          0 :         for (SCSIZE nLen = nLast-nFirst; nLen > 0; nLen = nLast-nFirst)
    5988                 :            :         {
    5989                 :          0 :             SCSIZE nMid = nFirst + nLen/2;
    5990         [ #  # ]:          0 :             sal_Int32 nCmp = lcl_CompareMatrix2Query( nMid, aMatAcc2, rEntry);
    5991         [ #  # ]:          0 :             if (nCmp == 0)
    5992                 :            :             {
    5993                 :            :                 // exact match.  find the last item with the same value.
    5994         [ #  # ]:          0 :                 lcl_GetLastMatch( nMid, aMatAcc2, nLenMajor, false);
    5995                 :          0 :                 nDelta = nMid;
    5996                 :          0 :                 bFound = true;
    5997                 :            :                 break;
    5998                 :            :             }
    5999                 :            : 
    6000         [ #  # ]:          0 :             if (nLen == 1) // first and last items are next to each other.
    6001                 :            :             {
    6002         [ #  # ]:          0 :                 nDelta = nCmp < 0 ? nLast - 1 : nFirst - 1;
    6003                 :            :                 // If already the 1st item is greater there's nothing found.
    6004                 :          0 :                 bFound = (nDelta >= 0);
    6005                 :            :                 break;
    6006                 :            :             }
    6007                 :            : 
    6008         [ #  # ]:          0 :             if (nCmp < 0)
    6009                 :          0 :                 nFirst = nMid;
    6010                 :            :             else
    6011                 :          0 :                 nLast = nMid;
    6012                 :            :         }
    6013                 :            : 
    6014         [ #  # ]:          0 :         if (nDelta == static_cast<SCCOLROW>(nLenMajor-2)) // last item
    6015                 :            :         {
    6016         [ #  # ]:          0 :             sal_Int32 nCmp = lcl_CompareMatrix2Query(nDelta+1, aMatAcc2, rEntry);
    6017         [ #  # ]:          0 :             if (nCmp <= 0)
    6018                 :            :             {
    6019                 :            :                 // either the last item is an exact match or the real
    6020                 :            :                 // hit is beyond the last item.
    6021                 :          0 :                 nDelta += 1;
    6022                 :          0 :                 bFound = true;
    6023                 :            :             }
    6024                 :            :         }
    6025         [ #  # ]:          0 :         else if (nDelta > 0) // valid hit must be 2nd item or higher
    6026                 :            :         {
    6027                 :            :             // non-exact match
    6028                 :          0 :             bFound = true;
    6029                 :            :         }
    6030                 :            : 
    6031                 :            :         // With 0-9 < A-Z, if query is numeric and data found is string, or
    6032                 :            :         // vice versa, the (yet another undocumented) Excel behavior is to
    6033                 :            :         // return #N/A instead.
    6034                 :            : 
    6035         [ #  # ]:          0 :         if (bFound)
    6036                 :            :         {
    6037                 :          0 :             VectorMatrixAccessor aMatAcc(*pDataMat, bVertical);
    6038                 :          0 :             SCCOLROW i = nDelta;
    6039         [ #  # ]:          0 :             SCSIZE n = aMatAcc.GetElementCount();
    6040         [ #  # ]:          0 :             if (static_cast<SCSIZE>(i) >= n)
    6041                 :          0 :                 i = static_cast<SCCOLROW>(n);
    6042         [ #  # ]:          0 :             bool bByString = rEntry.GetQueryItem().meType == ScQueryEntry::ByString;
    6043 [ #  # ][ #  # ]:          0 :             if (bByString == aMatAcc.IsValue(i))
    6044                 :          0 :                 bFound = false;
    6045                 :            :         }
    6046                 :            : 
    6047         [ #  # ]:          0 :         if (!bFound)
    6048                 :            :         {
    6049         [ #  # ]:          0 :             PushNA();
    6050                 :            :             return;
    6051                 :            :         }
    6052                 :            : 
    6053                 :            :         // Now that we've found the delta, push the result back to the cell.
    6054                 :            : 
    6055         [ #  # ]:          0 :         if (pResMat)
    6056                 :            :         {
    6057                 :          0 :             VectorMatrixAccessor aResMatAcc(*pResMat, bVertical);
    6058                 :            :             // result array is matrix.
    6059 [ #  # ][ #  # ]:          0 :             if (static_cast<SCSIZE>(nDelta) >= aResMatAcc.GetElementCount())
    6060                 :            :             {
    6061         [ #  # ]:          0 :                 PushNA();
    6062                 :            :                 return;
    6063                 :            :             }
    6064 [ #  # ][ #  # ]:          0 :             if (aResMatAcc.IsValue(nDelta))
    6065 [ #  # ][ #  # ]:          0 :                 PushDouble(aResMatAcc.GetDouble(nDelta));
    6066                 :            :             else
    6067 [ #  # ][ #  # ]:          0 :                 PushString(aResMatAcc.GetString(nDelta));
         [ #  # ][ #  # ]
    6068                 :            :         }
    6069         [ #  # ]:          0 :         else if (nParamCount == 3)
    6070                 :            :         {
    6071                 :            :             // result array is cell range.
    6072                 :          0 :             ScAddress aAdr;
    6073                 :          0 :             aAdr.SetTab(nResTab);
    6074                 :          0 :             bool bResVertical = (nResRow2 - nResRow1) > 0;
    6075         [ #  # ]:          0 :             if (bResVertical)
    6076                 :            :             {
    6077                 :          0 :                 SCROW nTempRow = static_cast<SCROW>(nResRow1 + nDelta);
    6078         [ #  # ]:          0 :                 if (nTempRow > MAXROW)
    6079                 :            :                 {
    6080         [ #  # ]:          0 :                     PushDouble(0);
    6081                 :            :                     return;
    6082                 :            :                 }
    6083                 :          0 :                 aAdr.SetCol(nResCol1);
    6084                 :          0 :                 aAdr.SetRow(nTempRow);
    6085                 :            :             }
    6086                 :            :             else
    6087                 :            :             {
    6088                 :          0 :                 SCCOL nTempCol = static_cast<SCCOL>(nResCol1 + nDelta);
    6089         [ #  # ]:          0 :                 if (nTempCol > MAXCOL)
    6090                 :            :                 {
    6091         [ #  # ]:          0 :                     PushDouble(0);
    6092                 :            :                     return;
    6093                 :            :                 }
    6094                 :          0 :                 aAdr.SetCol(nTempCol);
    6095                 :          0 :                 aAdr.SetRow(nResRow1);
    6096                 :            :             }
    6097         [ #  # ]:          0 :             PushCellResultToken(true, aAdr, NULL, NULL);
    6098                 :            :         }
    6099                 :            :         else
    6100                 :            :         {
    6101                 :            :             // no result array.  Use the data array to get the final value from.
    6102         [ #  # ]:          0 :             if (bVertical)
    6103                 :            :             {
    6104 [ #  # ][ #  # ]:          0 :                 if (pDataMat->IsValue(nC-1, nDelta))
    6105 [ #  # ][ #  # ]:          0 :                     PushDouble(pDataMat->GetDouble(nC-1, nDelta));
    6106                 :            :                 else
    6107 [ #  # ][ #  # ]:          0 :                     PushString(pDataMat->GetString(nC-1, nDelta));
         [ #  # ][ #  # ]
    6108                 :            :             }
    6109                 :            :             else
    6110                 :            :             {
    6111 [ #  # ][ #  # ]:          0 :                 if (pDataMat->IsValue(nDelta, nR-1))
    6112 [ #  # ][ #  # ]:          0 :                     PushDouble(pDataMat->GetDouble(nDelta, nR-1));
    6113                 :            :                 else
    6114 [ #  # ][ #  # ]:          0 :                     PushString(pDataMat->GetString(nDelta, nR-1));
         [ #  # ][ #  # ]
    6115                 :            :             }
    6116                 :            :         }
    6117                 :            : 
    6118         [ #  # ]:          0 :         return;
    6119                 :            :     }
    6120                 :            : 
    6121                 :            :     // Perform cell range search.
    6122                 :            : 
    6123                 :          0 :     aParam.nCol1            = nCol1;
    6124                 :          0 :     aParam.nRow1            = nRow1;
    6125         [ #  # ]:          0 :     aParam.nCol2            = bVertical ? nCol1 : nCol2;
    6126         [ #  # ]:          0 :     aParam.nRow2            = bVertical ? nRow2 : nRow1;
    6127                 :          0 :     aParam.bByRow           = bVertical;
    6128                 :            : 
    6129                 :          0 :     rEntry.bDoQuery = true;
    6130                 :          0 :     rEntry.eOp = SC_LESS_EQUAL;
    6131                 :          0 :     rEntry.nField = nCol1;
    6132         [ #  # ]:          0 :     ScQueryEntry::Item& rItem = rEntry.GetQueryItem();
    6133         [ #  # ]:          0 :     if (rItem.meType == ScQueryEntry::ByString)
    6134         [ #  # ]:          0 :         aParam.bRegExp = MayBeRegExp(rItem.maString, pDok);
    6135                 :            : 
    6136         [ #  # ]:          0 :     ScQueryCellIterator aCellIter(pDok, nTab1, aParam, false);
    6137                 :            :     SCCOL nC;
    6138                 :            :     SCROW nR;
    6139                 :            :     // Advance Entry.nField in iterator upon switching columns if
    6140                 :            :     // lookup in row.
    6141                 :          0 :     aCellIter.SetAdvanceQueryParamEntryField(!bVertical);
    6142 [ #  # ][ #  # ]:          0 :     if ( !aCellIter.FindEqualOrSortedLastInRange(nC, nR) )
    6143                 :            :     {
    6144         [ #  # ]:          0 :         PushNA();
    6145                 :            :         return;
    6146                 :            :     }
    6147                 :            : 
    6148         [ #  # ]:          0 :     SCCOLROW nDelta = bVertical ? static_cast<SCSIZE>(nR-nRow1) : static_cast<SCSIZE>(nC-nCol1);
    6149                 :            : 
    6150         [ #  # ]:          0 :     if (pResMat)
    6151                 :            :     {
    6152                 :          0 :         VectorMatrixAccessor aResMatAcc(*pResMat, bVertical);
    6153                 :            :         // Use the matrix result array.
    6154 [ #  # ][ #  # ]:          0 :         if (aResMatAcc.IsValue(nDelta))
    6155 [ #  # ][ #  # ]:          0 :             PushDouble(aResMatAcc.GetDouble(nDelta));
    6156                 :            :         else
    6157 [ #  # ][ #  # ]:          0 :             PushString(aResMatAcc.GetString(nDelta));
         [ #  # ][ #  # ]
    6158                 :            :     }
    6159         [ #  # ]:          0 :     else if (nParamCount == 3)
    6160                 :            :     {
    6161      [ #  #  # ]:          0 :         switch (eResArrayType)
    6162                 :            :         {
    6163                 :            :             case svDoubleRef:
    6164                 :            :             {
    6165                 :            :                 // Use the result array vector.  Note that the result array is assumed
    6166                 :            :                 // to be a vector (i.e. 1-dimensinoal array).
    6167                 :            : 
    6168                 :          0 :                 ScAddress aAdr;
    6169                 :          0 :                 aAdr.SetTab(nResTab);
    6170                 :          0 :                 bool bResVertical = (nResRow2 - nResRow1) > 0;
    6171         [ #  # ]:          0 :                 if (bResVertical)
    6172                 :            :                 {
    6173                 :          0 :                     SCROW nTempRow = static_cast<SCROW>(nResRow1 + nDelta);
    6174         [ #  # ]:          0 :                     if (nTempRow > MAXROW)
    6175                 :            :                     {
    6176         [ #  # ]:          0 :                         PushDouble(0);
    6177                 :            :                         return;
    6178                 :            :                     }
    6179                 :          0 :                     aAdr.SetCol(nResCol1);
    6180                 :          0 :                     aAdr.SetRow(nTempRow);
    6181                 :            :                 }
    6182                 :            :                 else
    6183                 :            :                 {
    6184                 :          0 :                     SCCOL nTempCol = static_cast<SCCOL>(nResCol1 + nDelta);
    6185         [ #  # ]:          0 :                     if (nTempCol > MAXCOL)
    6186                 :            :                     {
    6187         [ #  # ]:          0 :                         PushDouble(0);
    6188                 :            :                         return;
    6189                 :            :                     }
    6190                 :          0 :                     aAdr.SetCol(nTempCol);
    6191                 :          0 :                     aAdr.SetRow(nResRow1);
    6192                 :            :                 }
    6193         [ #  # ]:          0 :                 PushCellResultToken( true, aAdr, NULL, NULL);
    6194                 :            :             }
    6195                 :          0 :             break;
    6196                 :            :             case svDouble:
    6197                 :            :             case svString:
    6198                 :            :             case svSingleRef:
    6199                 :            :             {
    6200         [ #  # ]:          0 :                 if (nDelta != 0)
    6201         [ #  # ]:          0 :                     PushNA();
    6202                 :            :                 else
    6203                 :            :                 {
    6204   [ #  #  #  # ]:          0 :                     switch (eResArrayType)
    6205                 :            :                     {
    6206                 :            :                         case svDouble:
    6207         [ #  # ]:          0 :                             PushDouble( fResVal );
    6208                 :          0 :                             break;
    6209                 :            :                         case svString:
    6210         [ #  # ]:          0 :                             PushString( aResStr );
    6211                 :          0 :                             break;
    6212                 :            :                         case svSingleRef:
    6213         [ #  # ]:          0 :                             PushCellResultToken( true, aResAdr, NULL, NULL);
    6214                 :          0 :                             break;
    6215                 :            :                         default:
    6216                 :            :                             ;   // nothing
    6217                 :            :                     }
    6218                 :            :                 }
    6219                 :            :             }
    6220                 :          0 :             break;
    6221                 :            :             default:
    6222                 :            :                 OSL_FAIL( "ScInterpreter::ScLookup: unhandled eResArrayType, range search");
    6223                 :            :         }
    6224                 :            :     }
    6225                 :            :     else
    6226                 :            :     {
    6227                 :            :         // Regardless of whether or not the result array exists, the last
    6228                 :            :         // array is always used as the "result" array.
    6229                 :            : 
    6230                 :          0 :         ScAddress aAdr;
    6231                 :          0 :         aAdr.SetTab(nTab1);
    6232         [ #  # ]:          0 :         if (bVertical)
    6233                 :            :         {
    6234                 :          0 :             SCROW nTempRow = static_cast<SCROW>(nRow1 + nDelta);
    6235         [ #  # ]:          0 :             if (nTempRow > MAXROW)
    6236                 :            :             {
    6237         [ #  # ]:          0 :                 PushDouble(0);
    6238                 :            :                 return;
    6239                 :            :             }
    6240                 :          0 :             aAdr.SetCol(nCol2);
    6241                 :          0 :             aAdr.SetRow(nTempRow);
    6242                 :            :         }
    6243                 :            :         else
    6244                 :            :         {
    6245                 :          0 :             SCCOL nTempCol = static_cast<SCCOL>(nCol1 + nDelta);
    6246         [ #  # ]:          0 :             if (nTempCol > MAXCOL)
    6247                 :            :             {
    6248         [ #  # ]:          0 :                 PushDouble(0);
    6249                 :            :                 return;
    6250                 :            :             }
    6251                 :          0 :             aAdr.SetCol(nTempCol);
    6252                 :          0 :             aAdr.SetRow(nRow2);
    6253                 :            :         }
    6254         [ #  # ]:          0 :         PushCellResultToken(true, aAdr, NULL, NULL);
    6255 [ #  # ][ #  # ]:          0 :     }
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
    6256                 :            : }
    6257                 :            : 
    6258                 :            : 
    6259                 :          0 : void ScInterpreter::ScHLookup()
    6260                 :            : {
    6261                 :            :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScHLookup" );
    6262                 :          0 :     CalculateLookup(true);
    6263                 :          0 : }
    6264                 :         51 : void ScInterpreter::CalculateLookup(bool HLookup)
    6265                 :            : {
    6266                 :            :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::CalculateLookup" );
    6267                 :         51 :     sal_uInt8 nParamCount = GetByte();
    6268         [ +  - ]:         51 :     if ( MustHaveParamCount( nParamCount, 3, 4 ) )
    6269                 :            :     {
    6270                 :            :         bool bSorted;
    6271         [ +  - ]:         51 :         if (nParamCount == 4)
    6272         [ +  - ]:         51 :             bSorted = GetBool();
    6273                 :            :         else
    6274                 :          0 :             bSorted = true;
    6275         [ +  - ]:         51 :         double fIndex = ::rtl::math::approxFloor( GetDouble() ) - 1.0;
    6276                 :         51 :         ScMatrixRef pMat = NULL;
    6277                 :         51 :         SCSIZE nC = 0, nR = 0;
    6278                 :         51 :         SCCOL nCol1 = 0;
    6279                 :         51 :         SCROW nRow1 = 0;
    6280                 :         51 :         SCTAB nTab1 = 0;
    6281                 :         51 :         SCCOL nCol2 = 0;
    6282                 :         51 :         SCROW nRow2 = 0;
    6283                 :            :         SCTAB nTab2;
    6284         [ +  - ]:         51 :         StackVar eType = GetStackType();
    6285         [ +  - ]:         51 :         if (eType == svDoubleRef)
    6286                 :            :         {
    6287         [ +  - ]:         51 :             PopDoubleRef(nCol1, nRow1, nTab1, nCol2, nRow2, nTab2);
    6288         [ -  + ]:         51 :             if (nTab1 != nTab2)
    6289                 :            :             {
    6290         [ #  # ]:          0 :                 PushIllegalParameter();
    6291                 :            :                 return;
    6292                 :            :             }
    6293                 :            :         }
    6294         [ #  # ]:          0 :         else if (eType == svSingleRef)
    6295                 :            :         {
    6296         [ #  # ]:          0 :             PopSingleRef(nCol1, nRow1, nTab1);
    6297                 :          0 :             nCol2 = nCol1;
    6298                 :          0 :             nRow2 = nRow1;
    6299                 :            :         }
    6300 [ #  # ][ #  # ]:          0 :         else if (eType == svMatrix || eType == svExternalDoubleRef || eType == svExternalSingleRef)
                 [ #  # ]
    6301                 :            :         {
    6302 [ #  # ][ #  # ]:          0 :             pMat = GetMatrix();
                 [ #  # ]
    6303                 :            : 
    6304         [ #  # ]:          0 :             if (pMat)
    6305         [ #  # ]:          0 :                 pMat->GetDimensions(nC, nR);
    6306                 :            :             else
    6307                 :            :             {
    6308         [ #  # ]:          0 :                 PushIllegalParameter();
    6309                 :            :                 return;
    6310                 :            :             }
    6311                 :            :         }
    6312                 :            :         else
    6313                 :            :         {
    6314         [ #  # ]:          0 :             PushIllegalParameter();
    6315                 :            :             return;
    6316                 :            :         }
    6317 [ +  - ][ -  + ]:         51 :         if ( fIndex < 0.0 || (HLookup ? (pMat ? (fIndex >= nR) : (fIndex+nRow1 > nRow2)) : (pMat ? (fIndex >= nC) : (fIndex+nCol1 > nCol2)) ) )
         [ #  # ][ #  # ]
         [ #  # ][ -  + ]
         [ #  # ][ -  + ]
                 [ -  + ]
    6318                 :            :         {
    6319         [ #  # ]:          0 :             PushIllegalArgument();
    6320                 :            :             return;
    6321                 :            :         }
    6322                 :         51 :         SCROW nZIndex = static_cast<SCROW>(fIndex);
    6323                 :         51 :         SCCOL nSpIndex = static_cast<SCCOL>(fIndex);
    6324                 :            : 
    6325         [ +  - ]:         51 :         if (!pMat)
    6326                 :            :         {
    6327                 :         51 :             nZIndex += nRow1;                       // Wertzeile
    6328                 :         51 :             nSpIndex = sal::static_int_cast<SCCOL>( nSpIndex + nCol1 );     // value column
    6329                 :            :         }
    6330                 :            : 
    6331         [ +  - ]:         51 :         if (nGlobalError == 0)
    6332                 :            :         {
    6333         [ +  - ]:         51 :             ScQueryParam rParam;
    6334                 :         51 :             rParam.nCol1       = nCol1;
    6335                 :         51 :             rParam.nRow1       = nRow1;
    6336         [ -  + ]:         51 :             if ( HLookup )
    6337                 :            :             {
    6338                 :          0 :                 rParam.nCol2       = nCol2;
    6339                 :          0 :                 rParam.nRow2       = nRow1;     // nur in der ersten Zeile suchen
    6340                 :          0 :                 rParam.bByRow      = false;
    6341                 :            :             } // if ( HLookup )
    6342                 :            :             else
    6343                 :            :             {
    6344                 :         51 :                 rParam.nCol2       = nCol1;     // nur in der ersten Spalte suchen
    6345                 :         51 :                 rParam.nRow2       = nRow2;
    6346                 :         51 :                 rParam.nTab        = nTab1;
    6347                 :            :             }
    6348                 :            : 
    6349         [ +  - ]:         51 :             ScQueryEntry& rEntry = rParam.GetEntry(0);
    6350                 :         51 :             rEntry.bDoQuery = true;
    6351         [ +  - ]:         51 :             if ( bSorted )
    6352                 :         51 :                 rEntry.eOp = SC_LESS_EQUAL;
    6353 [ +  - ][ -  + ]:         51 :             if ( !FillEntry(rEntry) )
    6354                 :            :                 return;
    6355                 :            : 
    6356         [ +  - ]:         51 :             ScQueryEntry::Item& rItem = rEntry.GetQueryItem();
    6357         [ +  + ]:         51 :             if (rItem.meType == ScQueryEntry::ByString)
    6358         [ +  - ]:         24 :                 rParam.bRegExp = MayBeRegExp(rItem.maString, pDok);
    6359         [ -  + ]:         51 :             if (pMat)
    6360                 :            :             {
    6361         [ #  # ]:          0 :                 SCSIZE nMatCount = HLookup ? nC : nR;
    6362                 :          0 :                 SCSIZE nDelta = SCSIZE_MAX;
    6363         [ #  # ]:          0 :                 if (rItem.meType == ScQueryEntry::ByString)
    6364                 :            :                 {
    6365                 :            :         //!!!!!!!
    6366                 :            :         //! TODO: enable regex on matrix strings
    6367                 :            :         //!!!!!!!
    6368                 :          0 :                     const rtl::OUString& rParamStr = rItem.maString;
    6369         [ #  # ]:          0 :                     if ( bSorted )
    6370                 :            :                     {
    6371 [ #  # ][ #  # ]:          0 :                         static CollatorWrapper* pCollator = ScGlobal::GetCollator();
         [ #  # ][ #  # ]
    6372         [ #  # ]:          0 :                         for (SCSIZE i = 0; i < nMatCount; i++)
    6373                 :            :                         {
    6374 [ #  # ][ #  # ]:          0 :                             if (HLookup ? pMat->IsString(i, 0) : pMat->IsString(0, i))
         [ #  # ][ #  # ]
    6375                 :            :                             {
    6376                 :            :                                 sal_Int32 nRes =
    6377 [ #  # ][ #  # ]:          0 :                                     pCollator->compareString( HLookup ? pMat->GetString(i,0) : pMat->GetString(0,i), rParamStr);
         [ #  # ][ #  # ]
    6378         [ #  # ]:          0 :                                 if (nRes <= 0)
    6379                 :          0 :                                     nDelta = i;
    6380         [ #  # ]:          0 :                                 else if (i>0)   // #i2168# ignore first mismatch
    6381                 :          0 :                                     i = nMatCount+1;
    6382                 :            :                             }
    6383                 :            :                             else
    6384                 :          0 :                                 nDelta = i;
    6385                 :            :                         }
    6386                 :            :                     }
    6387                 :            :                     else
    6388                 :            :                     {
    6389         [ #  # ]:          0 :                         for (SCSIZE i = 0; i < nMatCount; i++)
    6390                 :            :                         {
    6391 [ #  # ][ #  # ]:          0 :                             if (HLookup ? pMat->IsString(i, 0) : pMat->IsString(0, i))
         [ #  # ][ #  # ]
    6392                 :            :                             {
    6393         [ #  # ]:          0 :                                 if ( ScGlobal::GetpTransliteration()->isEqual(
    6394 [ #  # ][ #  # ]:          0 :                                     HLookup ? pMat->GetString(i,0) : pMat->GetString(0,i), rParamStr))
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
    6395                 :            :                                 {
    6396                 :          0 :                                     nDelta = i;
    6397                 :          0 :                                     i = nMatCount + 1;
    6398                 :            :                                 }
    6399                 :            :                             }
    6400                 :            :                         }
    6401                 :            :                     }
    6402                 :            :                 }
    6403                 :            :                 else
    6404                 :            :                 {
    6405         [ #  # ]:          0 :                     if ( bSorted )
    6406                 :            :                     {
    6407                 :            :                         // #i2168# ignore strings
    6408         [ #  # ]:          0 :                         for (SCSIZE i = 0; i < nMatCount; i++)
    6409                 :            :                         {
    6410 [ #  # ][ #  # ]:          0 :                             if (!(HLookup ? pMat->IsString(i, 0) : pMat->IsString(0, i)))
         [ #  # ][ #  # ]
    6411                 :            :                             {
    6412 [ #  # ][ #  # ]:          0 :                                 if ((HLookup ? pMat->GetDouble(i,0) : pMat->GetDouble(0,i)) <= rItem.mfVal)
         [ #  # ][ #  # ]
    6413                 :          0 :                                     nDelta = i;
    6414                 :            :                                 else
    6415                 :          0 :                                     i = nMatCount+1;
    6416                 :            :                             }
    6417                 :            :                         }
    6418                 :            :                     }
    6419                 :            :                     else
    6420                 :            :                     {
    6421         [ #  # ]:          0 :                         for (SCSIZE i = 0; i < nMatCount; i++)
    6422                 :            :                         {
    6423 [ #  # ][ #  # ]:          0 :                             if (!(HLookup ? pMat->IsString(i, 0) : pMat->IsString(0, i)))
         [ #  # ][ #  # ]
    6424                 :            :                             {
    6425 [ #  # ][ #  # ]:          0 :                                 if ((HLookup ? pMat->GetDouble(i,0) : pMat->GetDouble(0,i)) == rItem.mfVal)
         [ #  # ][ #  # ]
    6426                 :            :                                 {
    6427                 :          0 :                                     nDelta = i;
    6428                 :          0 :                                     i = nMatCount + 1;
    6429                 :            :                                 }
    6430                 :            :                             }
    6431                 :            :                         }
    6432                 :            :                     }
    6433                 :            :                 }
    6434         [ #  # ]:          0 :                 if ( nDelta != SCSIZE_MAX )
    6435                 :            :                 {
    6436                 :          0 :                     SCSIZE nX = static_cast<SCSIZE>(nSpIndex);
    6437                 :          0 :                     SCSIZE nY = nDelta;
    6438         [ #  # ]:          0 :                     if ( HLookup )
    6439                 :            :                     {
    6440                 :          0 :                         nX = nDelta;
    6441                 :          0 :                         nY = static_cast<SCSIZE>(nZIndex);
    6442                 :            :                     }
    6443 [ #  # ][ #  # ]:          0 :                     if ( pMat->IsString( nX, nY) )
    6444 [ #  # ][ #  # ]:          0 :                         PushString(pMat->GetString( nX,nY));
         [ #  # ][ #  # ]
    6445                 :            :                     else
    6446 [ #  # ][ #  # ]:          0 :                         PushDouble(pMat->GetDouble( nX,nY));
    6447                 :            :                 }
    6448                 :            :                 else
    6449         [ #  # ]:          0 :                     PushNA();
    6450                 :            :             }
    6451                 :            :             else
    6452                 :            :             {
    6453                 :         51 :                 rEntry.nField = nCol1;
    6454                 :         51 :                 bool bFound = false;
    6455                 :         51 :                 SCCOL nCol = 0;
    6456                 :         51 :                 SCROW nRow = 0;
    6457         [ +  - ]:         51 :                 if ( bSorted )
    6458                 :         51 :                     rEntry.eOp = SC_LESS_EQUAL;
    6459         [ -  + ]:         51 :                 if ( HLookup )
    6460                 :            :                 {
    6461         [ #  # ]:          0 :                     ScQueryCellIterator aCellIter(pDok, nTab1, rParam, false);
    6462                 :            :                     // advance Entry.nField in Iterator upon switching columns
    6463                 :          0 :                     aCellIter.SetAdvanceQueryParamEntryField( true );
    6464         [ #  # ]:          0 :                     if ( bSorted )
    6465                 :            :                     {
    6466                 :            :                         SCROW nRow1_temp;
    6467         [ #  # ]:          0 :                         bFound = aCellIter.FindEqualOrSortedLastInRange( nCol, nRow1_temp );
    6468                 :            :                     }
    6469 [ #  # ][ #  # ]:          0 :                     else if ( aCellIter.GetFirst() )
    6470                 :            :                     {
    6471                 :          0 :                         bFound = true;
    6472                 :          0 :                         nCol = aCellIter.GetCol();
    6473                 :            :                     }
    6474         [ #  # ]:          0 :                     nRow = nZIndex;
    6475                 :            :                 } // if ( HLookup )
    6476                 :            :                 else
    6477                 :            :                 {
    6478                 :         51 :                     ScAddress aResultPos( nCol1, nRow1, nTab1);
    6479         [ +  - ]:         51 :                     bFound = LookupQueryWithCache( aResultPos, rParam);
    6480                 :         51 :                     nRow = aResultPos.Row();
    6481                 :         51 :                     nCol = nSpIndex;
    6482                 :            :                 }
    6483         [ +  + ]:         51 :                 if ( bFound )
    6484                 :            :                 {
    6485                 :         48 :                     ScAddress aAdr( nCol, nRow, nTab1 );
    6486         [ +  - ]:         48 :                     PushCellResultToken( true, aAdr, NULL, NULL);
    6487                 :            :                 }
    6488                 :            :                 else
    6489         [ +  - ]:         51 :                     PushNA();
    6490 [ +  - ][ +  - ]:         51 :             }
    6491                 :            :         }
    6492                 :            :         else
    6493 [ #  # ][ +  - ]:         51 :             PushIllegalParameter();
                 [ +  - ]
    6494                 :            :     }
    6495                 :            : }
    6496                 :            : 
    6497                 :         51 : bool ScInterpreter::FillEntry(ScQueryEntry& rEntry)
    6498                 :            : {
    6499                 :            :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::FillEntry" );
    6500                 :         51 :     ScQueryEntry::Item& rItem = rEntry.GetQueryItem();
    6501   [ -  -  +  -  :         51 :     switch ( GetStackType() )
                      - ]
    6502                 :            :     {
    6503                 :            :         case svDouble:
    6504                 :            :         {
    6505                 :          0 :             rItem.meType = ScQueryEntry::ByValue;
    6506                 :          0 :             rItem.mfVal = GetDouble();
    6507                 :            :         }
    6508                 :          0 :         break;
    6509                 :            :         case svString:
    6510                 :            :         {
    6511                 :          0 :             const String& sStr = GetString();
    6512                 :          0 :             rItem.meType = ScQueryEntry::ByString;
    6513                 :          0 :             rItem.maString = sStr;
    6514                 :            :         }
    6515                 :          0 :         break;
    6516                 :            :         case svDoubleRef :
    6517                 :            :         case svSingleRef :
    6518                 :            :         {
    6519                 :         51 :             ScAddress aAdr;
    6520 [ -  + ][ +  - ]:         51 :             if ( !PopDoubleRefOrSingleRef( aAdr ) )
    6521                 :            :             {
    6522         [ #  # ]:          0 :                 PushInt(0);
    6523                 :          0 :                 return false;
    6524                 :            :             }
    6525         [ +  - ]:         51 :             ScBaseCell* pCell = GetCell( aAdr );
    6526 [ +  - ][ +  + ]:         51 :             if (HasCellValueData(pCell))
    6527                 :            :             {
    6528                 :         27 :                 rItem.meType = ScQueryEntry::ByValue;
    6529         [ +  - ]:         27 :                 rItem.mfVal = GetCellValue(aAdr, pCell);
    6530                 :            :             }
    6531                 :            :             else
    6532                 :            :             {
    6533         [ -  + ]:         24 :                 if ( GetCellType( pCell ) == CELLTYPE_NOTE )
    6534                 :            :                 {
    6535                 :          0 :                     rItem.meType = ScQueryEntry::ByValue;
    6536                 :          0 :                     rItem.mfVal = 0.0;
    6537                 :            :                 }
    6538                 :            :                 else
    6539                 :            :                 {
    6540         [ +  - ]:         24 :                     String sStr;
    6541         [ +  - ]:         24 :                     GetCellString(sStr, pCell);
    6542                 :         24 :                     rItem.meType = ScQueryEntry::ByString;
    6543 [ +  - ][ +  - ]:         24 :                     rItem.maString = sStr;
    6544                 :            :                 }
    6545                 :            :             }
    6546                 :            :         }
    6547                 :         51 :         break;
    6548                 :            :         case svMatrix :
    6549                 :            :         {
    6550         [ #  # ]:          0 :             String aStr;
    6551         [ #  # ]:          0 :             const ScMatValType nType = GetDoubleOrStringFromMatrix(rItem.mfVal, aStr);
    6552         [ #  # ]:          0 :             rItem.maString = aStr;
    6553                 :          0 :             rItem.meType = ScMatrix::IsNonValueType(nType) ?
    6554 [ #  # ][ #  # ]:          0 :                 ScQueryEntry::ByString : ScQueryEntry::ByValue;
    6555                 :            :         }
    6556                 :          0 :         break;
    6557                 :            :         default:
    6558                 :            :         {
    6559                 :          0 :             PushIllegalParameter();
    6560                 :          0 :             return false;
    6561                 :            :         }
    6562                 :            :     } // switch ( GetStackType() )
    6563                 :         51 :     return true;
    6564                 :            : }
    6565                 :         51 : void ScInterpreter::ScVLookup()
    6566                 :            : {
    6567                 :            :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScVLookup" );
    6568                 :         51 :     CalculateLookup(false);
    6569                 :         51 : }
    6570                 :            : 
    6571                 :          7 : void ScInterpreter::ScSubTotal()
    6572                 :            : {
    6573                 :            :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScSubTotal" );
    6574                 :          7 :     sal_uInt8 nParamCount = GetByte();
    6575         [ +  - ]:          7 :     if ( MustHaveParamCountMin( nParamCount, 2 ) )
    6576                 :            :     {
    6577                 :            :         // We must fish the 1st parameter deep from the stack! And push it on top.
    6578                 :          7 :         const FormulaToken* p = pStack[ sp - nParamCount ];
    6579                 :          7 :         PushTempToken( *p );
    6580                 :          7 :         int nFunc = (int) ::rtl::math::approxFloor( GetDouble() );
    6581 [ -  + ][ +  - ]:          7 :         if( nFunc < 1 || nFunc > 11 )
    6582                 :          0 :             PushIllegalArgument();  // simulate return on stack, not SetError(...)
    6583                 :            :         else
    6584                 :            :         {
    6585                 :          7 :             cPar = nParamCount - 1;
    6586                 :          7 :             glSubTotal = true;
    6587   [ -  -  -  -  :          7 :             switch( nFunc )
          -  -  -  -  +  
                -  -  - ]
    6588                 :            :             {
    6589                 :          0 :                 case SUBTOTAL_FUNC_AVE  : ScAverage(); break;
    6590                 :          0 :                 case SUBTOTAL_FUNC_CNT  : ScCount();   break;
    6591                 :          0 :                 case SUBTOTAL_FUNC_CNT2 : ScCount2();  break;
    6592                 :          0 :                 case SUBTOTAL_FUNC_MAX  : ScMax();     break;
    6593                 :          0 :                 case SUBTOTAL_FUNC_MIN  : ScMin();     break;
    6594                 :          0 :                 case SUBTOTAL_FUNC_PROD : ScProduct(); break;
    6595                 :          0 :                 case SUBTOTAL_FUNC_STD  : ScStDev();   break;
    6596                 :          0 :                 case SUBTOTAL_FUNC_STDP : ScStDevP();  break;
    6597                 :          7 :                 case SUBTOTAL_FUNC_SUM  : ScSum();     break;
    6598                 :          0 :                 case SUBTOTAL_FUNC_VAR  : ScVar();     break;
    6599                 :          0 :                 case SUBTOTAL_FUNC_VARP : ScVarP();    break;
    6600                 :          0 :                 default : PushIllegalArgument();       break;
    6601                 :            :             }
    6602                 :          7 :             glSubTotal = false;
    6603                 :            :         }
    6604                 :            :         // Get rid of the 1st (fished) parameter.
    6605                 :          7 :         double nVal = GetDouble();
    6606                 :          7 :         Pop();
    6607                 :          7 :         PushDouble( nVal );
    6608                 :            :     }
    6609                 :          7 : }
    6610                 :            : 
    6611                 :         24 : ScDBQueryParamBase* ScInterpreter::GetDBParams( bool& rMissingField )
    6612                 :            : {
    6613                 :            :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::GetDBParams" );
    6614                 :         24 :     bool bAllowMissingField = false;
    6615         [ +  - ]:         24 :     if ( rMissingField )
    6616                 :            :     {
    6617                 :         24 :         bAllowMissingField = true;
    6618                 :         24 :         rMissingField = false;
    6619                 :            :     }
    6620         [ +  - ]:         24 :     if ( GetByte() == 3 )
    6621                 :            :     {
    6622                 :            :         // First, get the query criteria range.
    6623                 :            :         SAL_WNODEPRECATED_DECLARATIONS_PUSH
    6624         [ +  - ]:         24 :         ::std::auto_ptr<ScDBRangeBase> pQueryRef( PopDBDoubleRef() );
    6625                 :            :         SAL_WNODEPRECATED_DECLARATIONS_POP
    6626         [ -  + ]:         24 :         if (!pQueryRef.get())
    6627                 :          0 :             return NULL;
    6628                 :            : 
    6629                 :         24 :         bool    bByVal = true;
    6630                 :         24 :         double  nVal = 0.0;
    6631         [ +  - ]:         24 :         String  aStr;
    6632                 :         24 :         ScRange aMissingRange;
    6633                 :         24 :         bool bRangeFake = false;
    6634   [ +  -  -  -  :         24 :         switch (GetStackType())
           -  - ][ +  - ]
    6635                 :            :         {
    6636                 :            :             case svDouble :
    6637         [ +  - ]:         24 :                 nVal = ::rtl::math::approxFloor( GetDouble() );
    6638 [ +  + ][ +  - ]:         24 :                 if ( bAllowMissingField && nVal == 0.0 )
    6639                 :         12 :                     rMissingField = true;   // fake missing parameter
    6640                 :         24 :                 break;
    6641                 :            :             case svString :
    6642                 :          0 :                 bByVal = false;
    6643 [ #  # ][ #  # ]:          0 :                 aStr = GetString();
    6644                 :          0 :                 break;
    6645                 :            :             case svSingleRef :
    6646                 :            :                 {
    6647                 :          0 :                     ScAddress aAdr;
    6648         [ #  # ]:          0 :                     PopSingleRef( aAdr );
    6649         [ #  # ]:          0 :                     ScBaseCell* pCell = GetCell( aAdr );
    6650 [ #  # ][ #  # ]:          0 :                     if (HasCellValueData(pCell))
    6651         [ #  # ]:          0 :                         nVal = GetCellValue( aAdr, pCell );
    6652                 :            :                     else
    6653                 :            :                     {
    6654                 :          0 :                         bByVal = false;
    6655         [ #  # ]:          0 :                         GetCellString(aStr, pCell);
    6656                 :            :                     }
    6657                 :            :                 }
    6658                 :          0 :                 break;
    6659                 :            :             case svDoubleRef :
    6660         [ #  # ]:          0 :                 if ( bAllowMissingField )
    6661                 :            :                 {   // fake missing parameter for old SO compatibility
    6662                 :          0 :                     bRangeFake = true;
    6663         [ #  # ]:          0 :                     PopDoubleRef( aMissingRange );
    6664                 :            :                 }
    6665                 :            :                 else
    6666                 :            :                 {
    6667         [ #  # ]:          0 :                     PopError();
    6668                 :          0 :                     SetError( errIllegalParameter );
    6669                 :            :                 }
    6670                 :          0 :                 break;
    6671                 :            :             case svMissing :
    6672         [ #  # ]:          0 :                 PopError();
    6673         [ #  # ]:          0 :                 if ( bAllowMissingField )
    6674                 :          0 :                     rMissingField = true;
    6675                 :            :                 else
    6676                 :          0 :                     SetError( errIllegalParameter );
    6677                 :          0 :                 break;
    6678                 :            :             default:
    6679         [ #  # ]:          0 :                 PopError();
    6680                 :          0 :                 SetError( errIllegalParameter );
    6681                 :            :         }
    6682                 :            : 
    6683         [ -  + ]:         24 :         if (nGlobalError)
    6684                 :          0 :             return NULL;
    6685                 :            : 
    6686                 :            :         SAL_WNODEPRECATED_DECLARATIONS_PUSH
    6687         [ +  - ]:         24 :         auto_ptr<ScDBRangeBase> pDBRef( PopDBDoubleRef() );
    6688                 :            :         SAL_WNODEPRECATED_DECLARATIONS_POP
    6689                 :            : 
    6690 [ -  + ][ -  + ]:         24 :         if (nGlobalError || !pDBRef.get())
                 [ +  - ]
    6691                 :          0 :             return NULL;
    6692                 :            : 
    6693         [ -  + ]:         24 :         if ( bRangeFake )
    6694                 :            :         {
    6695                 :            :             // range parameter must match entire database range
    6696 [ #  # ][ #  # ]:          0 :             if (pDBRef->isRangeEqual(aMissingRange))
    6697                 :          0 :                 rMissingField = true;
    6698                 :            :             else
    6699                 :          0 :                 SetError( errIllegalParameter );
    6700                 :            :         }
    6701                 :            : 
    6702         [ -  + ]:         24 :         if (nGlobalError)
    6703                 :          0 :             return NULL;
    6704                 :            : 
    6705         [ +  - ]:         24 :         SCCOL nField = pDBRef->getFirstFieldColumn();
    6706         [ +  + ]:         24 :         if (rMissingField)
    6707                 :            :             ; // special case
    6708         [ +  - ]:         12 :         else if (bByVal)
    6709         [ +  - ]:         12 :             nField = pDBRef->findFieldColumn(static_cast<SCCOL>(nVal));
    6710                 :            :         else
    6711                 :            :         {
    6712                 :          0 :             sal_uInt16 nErr = 0;
    6713 [ #  # ][ #  # ]:          0 :             nField = pDBRef->findFieldColumn(aStr, &nErr);
    6714                 :          0 :             SetError(nErr);
    6715                 :            :         }
    6716                 :            : 
    6717         [ -  + ]:         24 :         if (!ValidCol(nField))
    6718                 :          0 :             return NULL;
    6719                 :            : 
    6720                 :            :         SAL_WNODEPRECATED_DECLARATIONS_PUSH
    6721         [ +  - ]:         24 :         auto_ptr<ScDBQueryParamBase> pParam( pDBRef->createQueryParam(pQueryRef.get()) );
    6722                 :            :         SAL_WNODEPRECATED_DECLARATIONS_POP
    6723                 :            : 
    6724         [ +  - ]:         24 :         if (pParam.get())
    6725                 :            :         {
    6726                 :            :             // An allowed missing field parameter sets the result field
    6727                 :            :             // to any of the query fields, just to be able to return
    6728                 :            :             // some cell from the iterator.
    6729         [ +  + ]:         24 :             if ( rMissingField )
    6730         [ +  - ]:         12 :                 nField = static_cast<SCCOL>(pParam->GetEntry(0).nField);
    6731                 :         24 :             pParam->mnField = nField;
    6732                 :            : 
    6733         [ +  - ]:         24 :             SCSIZE nCount = pParam->GetEntryCount();
    6734         [ +  - ]:         84 :             for ( SCSIZE i=0; i < nCount; i++ )
    6735                 :            :             {
    6736         [ +  - ]:         60 :                 ScQueryEntry& rEntry = pParam->GetEntry(i);
    6737         [ +  + ]:         60 :                 if (!rEntry.bDoQuery)
    6738                 :            :                     break;
    6739                 :            : 
    6740         [ +  - ]:         36 :                 ScQueryEntry::Item& rItem = rEntry.GetQueryItem();
    6741                 :         36 :                 sal_uInt32 nIndex = 0;
    6742                 :         36 :                 const rtl::OUString& rQueryStr = rItem.maString;
    6743                 :            :                 bool bNumber = pFormatter->IsNumberFormat(
    6744 [ +  - ][ +  - ]:         36 :                     rQueryStr, nIndex, rItem.mfVal);
                 [ +  - ]
    6745         [ +  - ]:         36 :                 rItem.meType = bNumber ? ScQueryEntry::ByValue : ScQueryEntry::ByString;
    6746                 :            : 
    6747 [ -  + ][ #  # ]:         36 :                 if (!bNumber && !pParam->bRegExp)
                 [ -  + ]
    6748         [ #  # ]:          0 :                     pParam->bRegExp = MayBeRegExp(rQueryStr, pDok);
    6749                 :            :             }
    6750                 :         24 :             return pParam.release();
    6751 [ +  - ][ +  - ]:         24 :         }
         [ +  - ][ -  + ]
         [ +  - ][ +  - ]
         [ +  - ][ -  + ]
    6752                 :            :     }
    6753                 :         24 :     return NULL;
    6754                 :            : }
    6755                 :            : 
    6756                 :            : 
    6757                 :          0 : void ScInterpreter::DBIterator( ScIterFunc eFunc )
    6758                 :            : {
    6759                 :            :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::DBIterator" );
    6760                 :          0 :     double nErg = 0.0;
    6761                 :          0 :     double fMem = 0.0;
    6762                 :          0 :     bool bNull = true;
    6763                 :          0 :     sal_uLong nCount = 0;
    6764                 :          0 :     bool bMissingField = false;
    6765                 :            :     SAL_WNODEPRECATED_DECLARATIONS_PUSH
    6766         [ #  # ]:          0 :     auto_ptr<ScDBQueryParamBase> pQueryParam( GetDBParams(bMissingField) );
    6767                 :            :     SAL_WNODEPRECATED_DECLARATIONS_POP
    6768         [ #  # ]:          0 :     if (pQueryParam.get())
    6769                 :            :     {
    6770 [ #  # ][ #  # ]:          0 :         if (!pQueryParam->IsValidFieldIndex())
    6771                 :            :         {
    6772                 :          0 :             SetError(errNoValue);
    6773                 :          0 :             return;
    6774                 :            :         }
    6775         [ #  # ]:          0 :         ScDBQueryDataIterator aValIter(pDok, pQueryParam.release());
    6776         [ #  # ]:          0 :         ScDBQueryDataIterator::Value aValue;
    6777 [ #  # ][ #  # ]:          0 :         if ( aValIter.GetFirst(aValue) && !aValue.mnError )
         [ #  # ][ #  # ]
    6778                 :            :         {
    6779   [ #  #  #  # ]:          0 :             switch( eFunc )
    6780                 :            :             {
    6781                 :          0 :                 case ifPRODUCT: nErg = 1; break;
    6782                 :          0 :                 case ifMAX:     nErg = -MAXDOUBLE; break;
    6783                 :          0 :                 case ifMIN:     nErg = MAXDOUBLE; break;
    6784                 :            :                 default: ; // nothing
    6785                 :            :             }
    6786 [ #  # ][ #  # ]:          0 :             do
                 [ #  # ]
    6787                 :            :             {
    6788                 :          0 :                 nCount++;
    6789   [ #  #  #  #  :          0 :                 switch( eFunc )
                   #  # ]
    6790                 :            :                 {
    6791                 :            :                     case ifAVERAGE:
    6792                 :            :                     case ifSUM:
    6793 [ #  # ][ #  # ]:          0 :                         if ( bNull && aValue.mfValue != 0.0 )
    6794                 :            :                         {
    6795                 :          0 :                             bNull = false;
    6796                 :          0 :                             fMem = aValue.mfValue;
    6797                 :            :                         }
    6798                 :            :                         else
    6799                 :          0 :                             nErg += aValue.mfValue;
    6800                 :          0 :                         break;
    6801                 :          0 :                     case ifSUMSQ:   nErg += aValue.mfValue * aValue.mfValue; break;
    6802                 :          0 :                     case ifPRODUCT: nErg *= aValue.mfValue; break;
    6803         [ #  # ]:          0 :                     case ifMAX:     if( aValue.mfValue > nErg ) nErg = aValue.mfValue; break;
    6804         [ #  # ]:          0 :                     case ifMIN:     if( aValue.mfValue < nErg ) nErg = aValue.mfValue; break;
    6805                 :            :                     default: ; // nothing
    6806                 :            :                 }
    6807                 :            :             }
    6808         [ #  # ]:          0 :             while ( aValIter.GetNext(aValue) && !aValue.mnError );
    6809                 :            :         }
    6810         [ #  # ]:          0 :         SetError(aValue.mnError);
    6811                 :            :     }
    6812                 :            :     else
    6813                 :          0 :         SetError( errIllegalParameter);
    6814   [ #  #  #  # ]:          0 :     switch( eFunc )
    6815                 :            :     {
    6816                 :          0 :         case ifCOUNT:   nErg = nCount; break;
    6817                 :          0 :         case ifSUM:     nErg = ::rtl::math::approxAdd( nErg, fMem ); break;
    6818                 :          0 :         case ifAVERAGE: nErg = ::rtl::math::approxAdd( nErg, fMem ) / nCount; break;
    6819                 :            :         default: ; // nothing
    6820                 :            :     }
    6821 [ #  # ][ #  # ]:          0 :     PushDouble( nErg );
                 [ #  # ]
    6822                 :            : }
    6823                 :            : 
    6824                 :            : 
    6825                 :          0 : void ScInterpreter::ScDBSum()
    6826                 :            : {
    6827                 :            :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScDBSum" );
    6828                 :          0 :     DBIterator( ifSUM );
    6829                 :          0 : }
    6830                 :            : 
    6831                 :            : 
    6832                 :         24 : void ScInterpreter::ScDBCount()
    6833                 :            : {
    6834                 :            :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScDBCount" );
    6835                 :         24 :     bool bMissingField = true;
    6836                 :            :     SAL_WNODEPRECATED_DECLARATIONS_PUSH
    6837         [ +  - ]:         24 :     auto_ptr<ScDBQueryParamBase> pQueryParam( GetDBParams(bMissingField) );
    6838                 :            :     SAL_WNODEPRECATED_DECLARATIONS_POP
    6839         [ +  - ]:         24 :     if (pQueryParam.get())
    6840                 :            :     {
    6841                 :         24 :         sal_uLong nCount = 0;
    6842 [ +  + ][ +  - ]:         24 :         if ( bMissingField && pQueryParam->GetType() == ScDBQueryParamBase::INTERNAL )
         [ +  - ][ +  + ]
    6843                 :            :         {   // count all matching records
    6844                 :            :             // TODO: currently the QueryIterators only return cell pointers of
    6845                 :            :             // existing cells, so if a query matches an empty cell there's
    6846                 :            :             // nothing returned, and therefor not counted!
    6847                 :            :             // Since this has ever been the case and this code here only came
    6848                 :            :             // into existance to fix #i6899 and it never worked before we'll
    6849                 :            :             // have to live with it until we reimplement the iterators to also
    6850                 :            :             // return empty cells, which would mean to adapt all callers of
    6851                 :            :             // iterators.
    6852                 :         12 :             ScDBQueryParamInternal* p = static_cast<ScDBQueryParamInternal*>(pQueryParam.get());
    6853                 :         12 :             p->nCol2 = p->nCol1; // Don't forget to select only one column.
    6854                 :         12 :             SCTAB nTab = p->nTab;
    6855                 :            :             // ScQueryCellIterator doesn't make use of ScDBQueryParamBase::mnField,
    6856                 :            :             // so the source range has to be restricted, like before the introduction
    6857                 :            :             // of ScDBQueryParamBase.
    6858                 :         12 :             p->nCol1 = p->nCol2 = p->mnField;
    6859 [ +  - ][ +  - ]:         12 :             ScQueryCellIterator aCellIter( pDok, nTab, *p);
                 [ +  - ]
    6860 [ +  - ][ +  - ]:         12 :             if ( aCellIter.GetFirst() )
    6861                 :            :             {
    6862         [ +  + ]:         24 :                 do
    6863                 :            :                 {
    6864                 :         24 :                     nCount++;
    6865         [ +  - ]:         24 :                 } while ( aCellIter.GetNext() );
    6866         [ +  - ]:         12 :             }
    6867                 :            :         }
    6868                 :            :         else
    6869                 :            :         {   // count only matching records with a value in the "result" field
    6870 [ +  - ][ -  + ]:         12 :             if (!pQueryParam->IsValidFieldIndex())
    6871                 :            :             {
    6872                 :          0 :                 SetError(errNoValue);
    6873                 :         24 :                 return;
    6874                 :            :             }
    6875         [ +  - ]:         12 :             ScDBQueryDataIterator aValIter( pDok, pQueryParam.release());
    6876         [ +  - ]:         12 :             ScDBQueryDataIterator::Value aValue;
    6877 [ +  - ][ +  - ]:         12 :             if ( aValIter.GetFirst(aValue) && !aValue.mnError )
         [ +  - ][ +  - ]
    6878                 :            :             {
    6879 [ +  + ][ +  - ]:         48 :                 do
                 [ +  + ]
    6880                 :            :                 {
    6881                 :         48 :                     nCount++;
    6882                 :            :                 }
    6883         [ +  - ]:         48 :                 while ( aValIter.GetNext(aValue) && !aValue.mnError );
    6884                 :            :             }
    6885         [ +  - ]:         12 :             SetError(aValue.mnError);
    6886                 :            :         }
    6887         [ +  - ]:         24 :         PushDouble( nCount );
    6888                 :            :     }
    6889                 :            :     else
    6890 [ #  # ][ +  - ]:         24 :         PushIllegalParameter();
                 [ +  - ]
    6891                 :            : }
    6892                 :            : 
    6893                 :            : 
    6894                 :          0 : void ScInterpreter::ScDBCount2()
    6895                 :            : {
    6896                 :            :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScDBCount2" );
    6897                 :          0 :     bool bMissingField = true;
    6898                 :            :     SAL_WNODEPRECATED_DECLARATIONS_PUSH
    6899         [ #  # ]:          0 :     auto_ptr<ScDBQueryParamBase> pQueryParam( GetDBParams(bMissingField) );
    6900                 :            :     SAL_WNODEPRECATED_DECLARATIONS_POP
    6901         [ #  # ]:          0 :     if (pQueryParam.get())
    6902                 :            :     {
    6903 [ #  # ][ #  # ]:          0 :         if (!pQueryParam->IsValidFieldIndex())
    6904                 :            :         {
    6905                 :          0 :             SetError(errNoValue);
    6906                 :          0 :             return;
    6907                 :            :         }
    6908                 :          0 :         sal_uLong nCount = 0;
    6909                 :          0 :         pQueryParam->mbSkipString = false;
    6910         [ #  # ]:          0 :         ScDBQueryDataIterator aValIter( pDok, pQueryParam.release());
    6911         [ #  # ]:          0 :         ScDBQueryDataIterator::Value aValue;
    6912 [ #  # ][ #  # ]:          0 :         if ( aValIter.GetFirst(aValue) && !aValue.mnError )
         [ #  # ][ #  # ]
    6913                 :            :         {
    6914 [ #  # ][ #  # ]:          0 :             do
                 [ #  # ]
    6915                 :            :             {
    6916                 :          0 :                 nCount++;
    6917                 :            :             }
    6918         [ #  # ]:          0 :             while ( aValIter.GetNext(aValue) && !aValue.mnError );
    6919                 :            :         }
    6920                 :          0 :         SetError(aValue.mnError);
    6921 [ #  # ][ #  # ]:          0 :         PushDouble( nCount );
    6922                 :            :     }
    6923                 :            :     else
    6924 [ #  # ][ #  # ]:          0 :         PushIllegalParameter();
                 [ #  # ]
    6925                 :            : }
    6926                 :            : 
    6927                 :            : 
    6928                 :          0 : void ScInterpreter::ScDBAverage()
    6929                 :            : {
    6930                 :            :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScDBAverage" );
    6931                 :          0 :     DBIterator( ifAVERAGE );
    6932                 :          0 : }
    6933                 :            : 
    6934                 :            : 
    6935                 :          0 : void ScInterpreter::ScDBMax()
    6936                 :            : {
    6937                 :            :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScDBMax" );
    6938                 :          0 :     DBIterator( ifMAX );
    6939                 :          0 : }
    6940                 :            : 
    6941                 :            : 
    6942                 :          0 : void ScInterpreter::ScDBMin()
    6943                 :            : {
    6944                 :            :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScDBMin" );
    6945                 :          0 :     DBIterator( ifMIN );
    6946                 :          0 : }
    6947                 :            : 
    6948                 :            : 
    6949                 :          0 : void ScInterpreter::ScDBProduct()
    6950                 :            : {
    6951                 :            :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScDBProduct" );
    6952                 :          0 :     DBIterator( ifPRODUCT );
    6953                 :          0 : }
    6954                 :            : 
    6955                 :            : 
    6956                 :          0 : void ScInterpreter::GetDBStVarParams( double& rVal, double& rValCount )
    6957                 :            : {
    6958                 :            :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::GetDBStVarParams" );
    6959         [ #  # ]:          0 :     std::vector<double> values;
    6960                 :          0 :     double vSum    = 0.0;
    6961                 :          0 :     double vMean    = 0.0;
    6962                 :            : 
    6963                 :          0 :     rValCount = 0.0;
    6964                 :          0 :     double fSum    = 0.0;
    6965                 :          0 :     bool bMissingField = false;
    6966                 :            :     SAL_WNODEPRECATED_DECLARATIONS_PUSH
    6967         [ #  # ]:          0 :     auto_ptr<ScDBQueryParamBase> pQueryParam( GetDBParams(bMissingField) );
    6968                 :            :     SAL_WNODEPRECATED_DECLARATIONS_POP
    6969         [ #  # ]:          0 :     if (pQueryParam.get())
    6970                 :            :     {
    6971 [ #  # ][ #  # ]:          0 :         if (!pQueryParam->IsValidFieldIndex())
    6972                 :            :         {
    6973                 :          0 :             SetError(errNoValue);
    6974                 :          0 :             return;
    6975                 :            :         }
    6976         [ #  # ]:          0 :         ScDBQueryDataIterator aValIter(pDok, pQueryParam.release());
    6977         [ #  # ]:          0 :         ScDBQueryDataIterator::Value aValue;
    6978 [ #  # ][ #  # ]:          0 :         if (aValIter.GetFirst(aValue) && !aValue.mnError)
         [ #  # ][ #  # ]
    6979                 :            :         {
    6980 [ #  # ][ #  # ]:          0 :             do
                 [ #  # ]
    6981                 :            :             {
    6982                 :          0 :                 rValCount++;
    6983         [ #  # ]:          0 :                 values.push_back(aValue.mfValue);
    6984                 :          0 :                 fSum += aValue.mfValue;
    6985                 :            :             }
    6986         [ #  # ]:          0 :             while ((aValue.mnError == 0) && aValIter.GetNext(aValue));
    6987                 :            :         }
    6988         [ #  # ]:          0 :         SetError(aValue.mnError);
    6989                 :            :     }
    6990                 :            :     else
    6991                 :          0 :         SetError( errIllegalParameter);
    6992                 :            : 
    6993                 :          0 :     vMean = fSum / values.size();
    6994                 :            : 
    6995         [ #  # ]:          0 :     for (size_t i = 0; i < values.size(); i++)
    6996 [ #  # ][ #  # ]:          0 :         vSum += (values[i] - vMean) * (values[i] - vMean);
    6997                 :            : 
    6998 [ #  # ][ #  # ]:          0 :     rVal = vSum;
                 [ #  # ]
    6999                 :            : }
    7000                 :            : 
    7001                 :            : 
    7002                 :          0 : void ScInterpreter::ScDBStdDev()
    7003                 :            : {
    7004                 :            :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScDBStdDev" );
    7005                 :            :     double fVal, fCount;
    7006         [ #  # ]:          0 :     GetDBStVarParams( fVal, fCount );
    7007         [ #  # ]:          0 :     PushDouble( sqrt(fVal/(fCount-1)));
    7008                 :          0 : }
    7009                 :            : 
    7010                 :            : 
    7011                 :          0 : void ScInterpreter::ScDBStdDevP()
    7012                 :            : {
    7013                 :            :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScDBStdDevP" );
    7014                 :            :     double fVal, fCount;
    7015         [ #  # ]:          0 :     GetDBStVarParams( fVal, fCount );
    7016         [ #  # ]:          0 :     PushDouble( sqrt(fVal/fCount));
    7017                 :          0 : }
    7018                 :            : 
    7019                 :            : 
    7020                 :          0 : void ScInterpreter::ScDBVar()
    7021                 :            : {
    7022                 :            :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScDBVar" );
    7023                 :            :     double fVal, fCount;
    7024         [ #  # ]:          0 :     GetDBStVarParams( fVal, fCount );
    7025         [ #  # ]:          0 :     PushDouble(fVal/(fCount-1));
    7026                 :          0 : }
    7027                 :            : 
    7028                 :            : 
    7029                 :          0 : void ScInterpreter::ScDBVarP()
    7030                 :            : {
    7031                 :            :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScDBVarP" );
    7032                 :            :     double fVal, fCount;
    7033         [ #  # ]:          0 :     GetDBStVarParams( fVal, fCount );
    7034         [ #  # ]:          0 :     PushDouble(fVal/fCount);
    7035                 :          0 : }
    7036                 :            : 
    7037                 :        102 : void ScInterpreter::ScIndirect()
    7038                 :            : {
    7039                 :            :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScIndirect" );
    7040                 :        102 :     sal_uInt8 nParamCount = GetByte();
    7041         [ +  - ]:        102 :     if ( MustHaveParamCount( nParamCount, 1, 2 )  )
    7042                 :            :     {
    7043                 :            :         // Reference address syntax for INDIRECT is configurable.
    7044         [ +  - ]:        102 :         FormulaGrammar::AddressConvention eConv = GetGlobalConfig().meStringRefAddressSyntax;
    7045         [ +  + ]:        102 :         if (eConv == FormulaGrammar::CONV_UNSPECIFIED)
    7046                 :            :             // Use the current address syntax if unspecified.
    7047         [ +  - ]:         66 :             eConv = pDok->GetAddressConvention();
    7048                 :            : 
    7049 [ +  + ][ +  - ]:        102 :         if (nParamCount == 2 && 0.0 == ::rtl::math::approxFloor( GetDouble()))
         [ +  - ][ +  + ]
    7050                 :            :         {
    7051                 :            :             // Overwrite the config and try Excel R1C1.
    7052                 :         30 :             eConv = FormulaGrammar::CONV_XL_R1C1;
    7053                 :            :         }
    7054         [ +  - ]:        102 :         const ScAddress::Details aDetails( eConv, aPos );
    7055                 :        102 :         SCTAB nTab = aPos.Tab();
    7056 [ +  - ][ +  - ]:        102 :         String sRefStr( GetString() );
    7057                 :        102 :         ScRefAddress aRefAd, aRefAd2;
    7058                 :        102 :         ScAddress::ExternalInfo aExtInfo;
    7059 [ -  + ][ +  - ]:        102 :         if (ConvertDoubleRef(pDok, sRefStr, nTab, aRefAd, aRefAd2, aDetails, &aExtInfo))
    7060                 :            :         {
    7061         [ #  # ]:          0 :             if (aExtInfo.mbExternal)
    7062                 :            :             {
    7063                 :            :                 PushExternalDoubleRef(
    7064                 :            :                     aExtInfo.mnFileId, aExtInfo.maTabName,
    7065                 :          0 :                     aRefAd.Col(), aRefAd.Row(), aRefAd.Tab(),
    7066 [ #  # ][ #  # ]:          0 :                     aRefAd2.Col(), aRefAd2.Row(), aRefAd2.Tab());
                 [ #  # ]
    7067                 :            :             }
    7068                 :            :             else
    7069                 :          0 :                 PushDoubleRef( aRefAd.Col(), aRefAd.Row(), aRefAd.Tab(),
    7070         [ #  # ]:          0 :                         aRefAd2.Col(), aRefAd2.Row(), aRefAd2.Tab() );
    7071                 :            :         }
    7072 [ +  - ][ +  + ]:        102 :         else if (ConvertSingleRef(pDok, sRefStr, nTab, aRefAd, aDetails, &aExtInfo))
    7073                 :            :         {
    7074         [ -  + ]:         78 :             if (aExtInfo.mbExternal)
    7075                 :            :             {
    7076                 :            :                 PushExternalSingleRef(
    7077 [ #  # ][ #  # ]:          0 :                     aExtInfo.mnFileId, aExtInfo.maTabName, aRefAd.Col(), aRefAd.Row(), aRefAd.Tab());
                 [ #  # ]
    7078                 :            :             }
    7079                 :            :             else
    7080         [ +  - ]:         78 :                 PushSingleRef( aRefAd.Col(), aRefAd.Row(), aRefAd.Tab() );
    7081                 :            :         }
    7082                 :            :         else
    7083                 :            :         {
    7084                 :            :             do
    7085                 :            :             {
    7086 [ +  - ][ +  - ]:         24 :                 ScRangeData* pData = ScRangeStringConverter::GetRangeDataFromString(sRefStr, nTab, pDok);
    7087         [ -  + ]:         24 :                 if (!pData)
    7088                 :            :                     break;
    7089                 :            : 
    7090                 :            :                 // We need this in order to obtain a good range.
    7091         [ #  # ]:          0 :                 pData->ValidateTabRefs();
    7092                 :            : 
    7093                 :          0 :                 ScRange aRange;
    7094                 :            : 
    7095                 :            :                 // This is the usual way to treat named ranges containing
    7096                 :            :                 // relative references.
    7097 [ #  # ][ #  # ]:          0 :                 if (!pData->IsReference( aRange, aPos))
    7098                 :            :                     break;
    7099                 :            : 
    7100         [ #  # ]:          0 :                 if (aRange.aStart == aRange.aEnd)
    7101                 :          0 :                     PushSingleRef( aRange.aStart.Col(), aRange.aStart.Row(),
    7102         [ #  # ]:          0 :                             aRange.aStart.Tab());
    7103                 :            :                 else
    7104                 :          0 :                     PushDoubleRef( aRange.aStart.Col(), aRange.aStart.Row(),
    7105                 :          0 :                             aRange.aStart.Tab(), aRange.aEnd.Col(),
    7106         [ #  # ]:          0 :                             aRange.aEnd.Row(), aRange.aEnd.Tab());
    7107                 :            : 
    7108                 :            :                 // success!
    7109                 :        102 :                 return;
    7110                 :            :             }
    7111                 :            :             while (false);
    7112                 :            : 
    7113         [ +  - ]:        102 :             PushError( errNoRef);
    7114 [ -  + ][ +  - ]:        102 :         }
                 [ +  - ]
    7115                 :            :     }
    7116                 :            : }
    7117                 :            : 
    7118                 :            : 
    7119                 :         12 : void ScInterpreter::ScAddressFunc()
    7120                 :            : {
    7121                 :            :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScAddressFunc" );
    7122         [ +  - ]:         12 :     String  sTabStr;
    7123                 :            : 
    7124                 :         12 :     sal_uInt8    nParamCount = GetByte();
    7125 [ -  + ][ +  - ]:         12 :     if( !MustHaveParamCount( nParamCount, 2, 5 ) )
    7126                 :            :         return;
    7127                 :            : 
    7128         [ +  + ]:         12 :     if( nParamCount >= 5 )
    7129 [ +  - ][ +  - ]:          6 :         sTabStr = GetString();
    7130                 :            : 
    7131                 :         12 :     FormulaGrammar::AddressConvention eConv = FormulaGrammar::CONV_OOO;      // default
    7132 [ +  + ][ +  - ]:         12 :     if( nParamCount >= 4 && 0.0 == ::rtl::math::approxFloor( GetDoubleWithDefault( 1.0)))
         [ +  + ][ +  + ]
    7133                 :          3 :         eConv = FormulaGrammar::CONV_XL_R1C1;
    7134                 :            : 
    7135                 :         12 :     sal_uInt16  nFlags = SCA_COL_ABSOLUTE | SCA_ROW_ABSOLUTE;   // default
    7136         [ +  + ]:         12 :     if( nParamCount >= 3 )
    7137                 :            :     {
    7138         [ +  - ]:          6 :         sal_uInt16 n = (sal_uInt16) ::rtl::math::approxFloor( GetDoubleWithDefault( 1.0));
    7139   [ -  +  +  -  :          6 :         switch ( n )
                      - ]
    7140                 :            :         {
    7141                 :            :             default :
    7142         [ #  # ]:          0 :                 PushNoValue();
    7143                 :            :                 return;
    7144                 :            : 
    7145                 :            :             case 5:
    7146                 :          3 :             case 1 : break; // default
    7147                 :            :             case 6:
    7148                 :          3 :             case 2 : nFlags = SCA_ROW_ABSOLUTE; break;
    7149                 :            :             case 7:
    7150                 :          0 :             case 3 : nFlags = SCA_COL_ABSOLUTE; break;
    7151                 :            :             case 8:
    7152                 :          6 :             case 4 : nFlags = 0; break; // both relative
    7153                 :            :         }
    7154                 :            :     }
    7155                 :         12 :     nFlags |= SCA_VALID | SCA_VALID_ROW | SCA_VALID_COL;
    7156                 :            : 
    7157         [ +  - ]:         12 :     SCCOL nCol = (SCCOL) ::rtl::math::approxFloor(GetDouble());
    7158         [ +  - ]:         12 :     SCROW nRow = (SCROW) ::rtl::math::approxFloor(GetDouble());
    7159         [ +  + ]:         12 :     if( eConv == FormulaGrammar::CONV_XL_R1C1 )
    7160                 :            :     {
    7161                 :            :         // YUCK!  The XL interface actually treats rel R1C1 refs differently
    7162                 :            :         // than A1
    7163         [ -  + ]:          3 :         if( !(nFlags & SCA_COL_ABSOLUTE) )
    7164                 :          0 :             nCol += aPos.Col() + 1;
    7165         [ -  + ]:          3 :         if( !(nFlags & SCA_ROW_ABSOLUTE) )
    7166                 :          0 :             nRow += aPos.Row() + 1;
    7167                 :            :     }
    7168                 :            : 
    7169                 :         12 :     --nCol;
    7170                 :         12 :     --nRow;
    7171 [ +  - ][ -  + ]:         12 :     if(!ValidCol( nCol) || !ValidRow( nRow))
                 [ -  + ]
    7172                 :            :     {
    7173         [ #  # ]:          0 :         PushIllegalArgument();
    7174                 :            :         return;
    7175                 :            :     }
    7176                 :            : 
    7177         [ +  - ]:         12 :     String aRefStr;
    7178         [ +  - ]:         12 :     const ScAddress::Details aDetails( eConv, aPos );
    7179                 :         12 :     const ScAddress aAdr( nCol, nRow, 0);
    7180         [ +  - ]:         12 :     aAdr.Format( aRefStr, nFlags, pDok, aDetails );
    7181                 :            : 
    7182         [ +  + ]:         12 :     if( nParamCount >= 5 )
    7183                 :            :     {
    7184         [ +  - ]:          6 :         ScCompiler::CheckTabQuotes( sTabStr, eConv);
    7185 [ +  + ][ +  - ]:          6 :         sTabStr += static_cast<sal_Unicode>(eConv == FormulaGrammar::CONV_XL_R1C1 ? '!' : '.');
    7186         [ +  - ]:          6 :         sTabStr += aRefStr;
    7187         [ +  - ]:          6 :         PushString( sTabStr );
    7188                 :            :     }
    7189                 :            :     else
    7190 [ +  - ][ +  - ]:         12 :         PushString( aRefStr );
         [ +  - ][ +  - ]
    7191                 :            : }
    7192                 :            : 
    7193                 :            : 
    7194                 :          0 : void ScInterpreter::ScOffset()
    7195                 :            : {
    7196                 :            :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScOffset" );
    7197                 :          0 :     sal_uInt8 nParamCount = GetByte();
    7198         [ #  # ]:          0 :     if ( MustHaveParamCount( nParamCount, 3, 5 ) )
    7199                 :            :     {
    7200                 :          0 :         long nColNew = -1, nRowNew = -1, nColPlus, nRowPlus;
    7201         [ #  # ]:          0 :         if (nParamCount == 5)
    7202         [ #  # ]:          0 :             nColNew = (long) ::rtl::math::approxFloor(GetDouble());
    7203         [ #  # ]:          0 :         if (nParamCount >= 4)
    7204         [ #  # ]:          0 :             nRowNew = (long) ::rtl::math::approxFloor(GetDoubleWithDefault( -1.0 ));
    7205         [ #  # ]:          0 :         nColPlus = (long) ::rtl::math::approxFloor(GetDouble());
    7206         [ #  # ]:          0 :         nRowPlus = (long) ::rtl::math::approxFloor(GetDouble());
    7207                 :          0 :         SCCOL nCol1(0);
    7208                 :          0 :         SCROW nRow1(0);
    7209                 :          0 :         SCTAB nTab1(0);
    7210                 :          0 :         SCCOL nCol2(0);
    7211                 :          0 :         SCROW nRow2(0);
    7212                 :          0 :         SCTAB nTab2(0);
    7213 [ #  # ][ #  # ]:          0 :         if (nColNew == 0 || nRowNew == 0)
    7214                 :            :         {
    7215         [ #  # ]:          0 :             PushIllegalArgument();
    7216                 :          0 :             return;
    7217                 :            :         }
    7218 [ #  # ][ #  # ]:          0 :         if (GetStackType() == svSingleRef)
    7219                 :            :         {
    7220         [ #  # ]:          0 :             PopSingleRef(nCol1, nRow1, nTab1);
    7221 [ #  # ][ #  # ]:          0 :             if (nParamCount == 3 || (nColNew < 0 && nRowNew < 0))
                 [ #  # ]
    7222                 :            :             {
    7223                 :          0 :                 nCol1 = (SCCOL)((long) nCol1 + nColPlus);
    7224                 :          0 :                 nRow1 = (SCROW)((long) nRow1 + nRowPlus);
    7225 [ #  # ][ #  # ]:          0 :                 if (!ValidCol(nCol1) || !ValidRow(nRow1))
                 [ #  # ]
    7226         [ #  # ]:          0 :                     PushIllegalArgument();
    7227                 :            :                 else
    7228         [ #  # ]:          0 :                     PushSingleRef(nCol1, nRow1, nTab1);
    7229                 :            :             }
    7230                 :            :             else
    7231                 :            :             {
    7232         [ #  # ]:          0 :                 if (nColNew < 0)
    7233                 :          0 :                     nColNew = 1;
    7234         [ #  # ]:          0 :                 if (nRowNew < 0)
    7235                 :          0 :                     nRowNew = 1;
    7236                 :          0 :                 nCol1 = (SCCOL)((long)nCol1+nColPlus);      // ! nCol1 wird veraendert!
    7237                 :          0 :                 nRow1 = (SCROW)((long)nRow1+nRowPlus);
    7238                 :          0 :                 nCol2 = (SCCOL)((long)nCol1+nColNew-1);
    7239                 :          0 :                 nRow2 = (SCROW)((long)nRow1+nRowNew-1);
    7240 [ #  # ][ #  #  :          0 :                 if (!ValidCol(nCol1) || !ValidRow(nRow1) ||
             #  #  #  # ]
                 [ #  # ]
    7241                 :          0 :                     !ValidCol(nCol2) || !ValidRow(nRow2))
    7242         [ #  # ]:          0 :                     PushIllegalArgument();
    7243                 :            :                 else
    7244         [ #  # ]:          0 :                     PushDoubleRef(nCol1, nRow1, nTab1, nCol2, nRow2, nTab1);
    7245                 :            :             }
    7246                 :            :         }
    7247 [ #  # ][ #  # ]:          0 :         else if (GetStackType() == svExternalSingleRef)
    7248                 :            :         {
    7249                 :            :             sal_uInt16 nFileId;
    7250         [ #  # ]:          0 :             String aTabName;
    7251                 :            :             ScSingleRefData aRef;
    7252         [ #  # ]:          0 :             PopExternalSingleRef(nFileId, aTabName, aRef);
    7253         [ #  # ]:          0 :             aRef.CalcAbsIfRel(aPos);
    7254                 :          0 :             nCol1 = aRef.nCol;
    7255                 :          0 :             nRow1 = aRef.nRow;
    7256                 :          0 :             nTab1 = aRef.nTab;
    7257                 :            : 
    7258 [ #  # ][ #  # ]:          0 :             if (nParamCount == 3 || (nColNew < 0 && nRowNew < 0))
                 [ #  # ]
    7259                 :            :             {
    7260                 :          0 :                 nCol1 = (SCCOL)((long) nCol1 + nColPlus);
    7261                 :          0 :                 nRow1 = (SCROW)((long) nRow1 + nRowPlus);
    7262 [ #  # ][ #  # ]:          0 :                 if (!ValidCol(nCol1) || !ValidRow(nRow1))
                 [ #  # ]
    7263         [ #  # ]:          0 :                     PushIllegalArgument();
    7264                 :            :                 else
    7265         [ #  # ]:          0 :                     PushExternalSingleRef(nFileId, aTabName, nCol1, nRow1, nTab1);
    7266                 :            :             }
    7267                 :            :             else
    7268                 :            :             {
    7269         [ #  # ]:          0 :                 if (nColNew < 0)
    7270                 :          0 :                     nColNew = 1;
    7271         [ #  # ]:          0 :                 if (nRowNew < 0)
    7272                 :          0 :                     nRowNew = 1;
    7273                 :          0 :                 nCol1 = (SCCOL)((long)nCol1+nColPlus);      // ! nCol1 wird veraendert!
    7274                 :          0 :                 nRow1 = (SCROW)((long)nRow1+nRowPlus);
    7275                 :          0 :                 nCol2 = (SCCOL)((long)nCol1+nColNew-1);
    7276                 :          0 :                 nTab2 = nTab1;
    7277 [ #  # ][ #  #  :          0 :                 if (!ValidCol(nCol1) || !ValidRow(nRow1) ||
             #  #  #  # ]
                 [ #  # ]
    7278                 :          0 :                     !ValidCol(nCol2) || !ValidRow(nRow2))
    7279         [ #  # ]:          0 :                     PushIllegalArgument();
    7280                 :            :                 else
    7281         [ #  # ]:          0 :                     PushExternalDoubleRef(nFileId, aTabName, nCol1, nRow1, nTab1, nCol2, nRow2, nTab2);
    7282         [ #  # ]:          0 :             }
    7283                 :            :         }
    7284 [ #  # ][ #  # ]:          0 :         else if (GetStackType() == svDoubleRef)
    7285                 :            :         {
    7286         [ #  # ]:          0 :             PopDoubleRef(nCol1, nRow1, nTab1, nCol2, nRow2, nTab2);
    7287         [ #  # ]:          0 :             if (nColNew < 0)
    7288                 :          0 :                 nColNew = nCol2 - nCol1 + 1;
    7289         [ #  # ]:          0 :             if (nRowNew < 0)
    7290                 :          0 :                 nRowNew = nRow2 - nRow1 + 1;
    7291                 :          0 :             nCol1 = (SCCOL)((long)nCol1+nColPlus);
    7292                 :          0 :             nRow1 = (SCROW)((long)nRow1+nRowPlus);
    7293                 :          0 :             nCol2 = (SCCOL)((long)nCol1+nColNew-1);
    7294                 :          0 :             nRow2 = (SCROW)((long)nRow1+nRowNew-1);
    7295 [ #  # ][ #  #  :          0 :             if (!ValidCol(nCol1) || !ValidRow(nRow1) ||
             #  #  #  # ]
         [ #  # ][ #  # ]
    7296                 :          0 :                 !ValidCol(nCol2) || !ValidRow(nRow2) || nTab1 != nTab2)
    7297         [ #  # ]:          0 :                 PushIllegalArgument();
    7298                 :            :             else
    7299         [ #  # ]:          0 :                 PushDoubleRef(nCol1, nRow1, nTab1, nCol2, nRow2, nTab1);
    7300                 :            :         }
    7301 [ #  # ][ #  # ]:          0 :         else if (GetStackType() == svExternalDoubleRef)
    7302                 :            :         {
    7303                 :            :             sal_uInt16 nFileId;
    7304         [ #  # ]:          0 :             String aTabName;
    7305                 :            :             ScComplexRefData aRef;
    7306         [ #  # ]:          0 :             PopExternalDoubleRef(nFileId, aTabName, aRef);
    7307         [ #  # ]:          0 :             aRef.CalcAbsIfRel(aPos);
    7308                 :          0 :             nCol1 = aRef.Ref1.nCol;
    7309                 :          0 :             nRow1 = aRef.Ref1.nRow;
    7310                 :          0 :             nTab1 = aRef.Ref1.nTab;
    7311                 :          0 :             nCol2 = aRef.Ref2.nCol;
    7312                 :          0 :             nRow2 = aRef.Ref2.nRow;
    7313                 :          0 :             nTab2 = aRef.Ref2.nTab;
    7314         [ #  # ]:          0 :             if (nColNew < 0)
    7315                 :          0 :                 nColNew = nCol2 - nCol1 + 1;
    7316         [ #  # ]:          0 :             if (nRowNew < 0)
    7317                 :          0 :                 nRowNew = nRow2 - nRow1 + 1;
    7318                 :          0 :             nCol1 = (SCCOL)((long)nCol1+nColPlus);
    7319                 :          0 :             nRow1 = (SCROW)((long)nRow1+nRowPlus);
    7320                 :          0 :             nCol2 = (SCCOL)((long)nCol1+nColNew-1);
    7321                 :          0 :             nRow2 = (SCROW)((long)nRow1+nRowNew-1);
    7322 [ #  # ][ #  #  :          0 :             if (!ValidCol(nCol1) || !ValidRow(nRow1) ||
             #  #  #  # ]
         [ #  # ][ #  # ]
    7323                 :          0 :                 !ValidCol(nCol2) || !ValidRow(nRow2) || nTab1 != nTab2)
    7324         [ #  # ]:          0 :                 PushIllegalArgument();
    7325                 :            :             else
    7326 [ #  # ][ #  # ]:          0 :                 PushExternalDoubleRef(nFileId, aTabName, nCol1, nRow1, nTab1, nCol2, nRow2, nTab2);
    7327                 :            :         }
    7328                 :            :         else
    7329         [ #  # ]:          0 :             PushIllegalParameter();
    7330                 :            :     }
    7331                 :            : }
    7332                 :            : 
    7333                 :            : 
    7334                 :          0 : void ScInterpreter::ScIndex()
    7335                 :            : {
    7336                 :            :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScIndex" );
    7337                 :          0 :     sal_uInt8 nParamCount = GetByte();
    7338         [ #  # ]:          0 :     if ( MustHaveParamCount( nParamCount, 1, 4 ) )
    7339                 :            :     {
    7340                 :            :         long nArea;
    7341                 :            :         size_t nAreaCount;
    7342                 :            :         SCCOL nCol;
    7343                 :            :         SCROW nRow;
    7344         [ #  # ]:          0 :         if (nParamCount == 4)
    7345                 :          0 :             nArea = (long) ::rtl::math::approxFloor(GetDouble());
    7346                 :            :         else
    7347                 :          0 :             nArea = 1;
    7348         [ #  # ]:          0 :         if (nParamCount >= 3)
    7349                 :          0 :             nCol = (SCCOL) ::rtl::math::approxFloor(GetDouble());
    7350                 :            :         else
    7351                 :          0 :             nCol = 0;
    7352         [ #  # ]:          0 :         if (nParamCount >= 2)
    7353                 :          0 :             nRow = (SCROW) ::rtl::math::approxFloor(GetDouble());
    7354                 :            :         else
    7355                 :          0 :             nRow = 0;
    7356         [ #  # ]:          0 :         if (GetStackType() == svRefList)
    7357         [ #  # ]:          0 :             nAreaCount = (sp ? static_cast<ScToken*>(pStack[sp-1])->GetRefList()->size() : 0);
    7358                 :            :         else
    7359                 :          0 :             nAreaCount = 1;     // one reference or array or whatever
    7360 [ #  # ][ #  # ]:          0 :         if (nAreaCount == 0 || (size_t)nArea > nAreaCount)
    7361                 :            :         {
    7362                 :          0 :             PushError( errNoRef);
    7363                 :          0 :             return;
    7364                 :            :         }
    7365 [ #  # ][ #  # ]:          0 :         else if (nArea < 1 || nCol < 0 || nRow < 0)
                 [ #  # ]
    7366                 :            :         {
    7367                 :          0 :             PushIllegalArgument();
    7368                 :          0 :             return;
    7369                 :            :         }
    7370   [ #  #  #  # ]:          0 :         switch (GetStackType())
    7371                 :            :         {
    7372                 :            :             case svMatrix:
    7373                 :            :             case svExternalSingleRef:
    7374                 :            :             case svExternalDoubleRef:
    7375                 :            :                 {
    7376         [ #  # ]:          0 :                     if (nArea != 1)
    7377                 :          0 :                         SetError(errIllegalArgument);
    7378                 :          0 :                     sal_uInt16 nOldSp = sp;
    7379         [ #  # ]:          0 :                     ScMatrixRef pMat = GetMatrix();
    7380         [ #  # ]:          0 :                     if (pMat)
    7381                 :            :                     {
    7382                 :            :                         SCSIZE nC, nR;
    7383         [ #  # ]:          0 :                         pMat->GetDimensions(nC, nR);
    7384                 :            :                         // Access one element of a vector independent of col/row
    7385                 :            :                         // orientation?
    7386 [ #  # ][ #  # ]:          0 :                         bool bVector = ((nCol == 0 || nRow == 0) && (nC == 1 || nR == 1));
         [ #  # ][ #  # ]
    7387                 :            :                         SCSIZE nElement = ::std::max( static_cast<SCSIZE>(nCol),
    7388         [ #  # ]:          0 :                                 static_cast<SCSIZE>(nRow));
    7389 [ #  # ][ #  # ]:          0 :                         if (nC == 0 || nR == 0 ||
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
    7390                 :          0 :                                 (!bVector && (static_cast<SCSIZE>(nCol) > nC ||
    7391                 :            :                                               static_cast<SCSIZE>(nRow) > nR)) ||
    7392                 :            :                                 (bVector && nElement > nC * nR))
    7393         [ #  # ]:          0 :                             PushIllegalArgument();
    7394 [ #  # ][ #  # ]:          0 :                         else if (nCol == 0 && nRow == 0)
    7395                 :          0 :                             sp = nOldSp;
    7396         [ #  # ]:          0 :                         else if (bVector)
    7397                 :            :                         {
    7398                 :          0 :                             --nElement;
    7399 [ #  # ][ #  # ]:          0 :                             if (pMat->IsString( nElement))
    7400 [ #  # ][ #  # ]:          0 :                                 PushString( pMat->GetString( nElement));
         [ #  # ][ #  # ]
    7401                 :            :                             else
    7402 [ #  # ][ #  # ]:          0 :                                 PushDouble( pMat->GetDouble( nElement));
    7403                 :            :                         }
    7404         [ #  # ]:          0 :                         else if (nCol == 0)
    7405                 :            :                         {
    7406         [ #  # ]:          0 :                             ScMatrixRef pResMat = GetNewMat(nC, 1);
    7407         [ #  # ]:          0 :                             if (pResMat)
    7408                 :            :                             {
    7409                 :          0 :                                 SCSIZE nRowMinus1 = static_cast<SCSIZE>(nRow - 1);
    7410         [ #  # ]:          0 :                                 for (SCSIZE i = 0; i < nC; i++)
    7411 [ #  # ][ #  # ]:          0 :                                     if (!pMat->IsString(i, nRowMinus1))
    7412                 :            :                                         pResMat->PutDouble(pMat->GetDouble(i,
    7413 [ #  # ][ #  # ]:          0 :                                                     nRowMinus1), i, 0);
    7414                 :            :                                     else
    7415                 :            :                                         pResMat->PutString(pMat->GetString(i,
    7416 [ #  # ][ #  # ]:          0 :                                                     nRowMinus1), i, 0);
    7417         [ #  # ]:          0 :                                 PushMatrix(pResMat);
    7418                 :            :                             }
    7419                 :            :                             else
    7420 [ #  # ][ #  # ]:          0 :                                 PushIllegalArgument();
    7421                 :            :                         }
    7422         [ #  # ]:          0 :                         else if (nRow == 0)
    7423                 :            :                         {
    7424         [ #  # ]:          0 :                             ScMatrixRef pResMat = GetNewMat(1, nR);
    7425         [ #  # ]:          0 :                             if (pResMat)
    7426                 :            :                             {
    7427                 :          0 :                                 SCSIZE nColMinus1 = static_cast<SCSIZE>(nCol - 1);
    7428         [ #  # ]:          0 :                                 for (SCSIZE i = 0; i < nR; i++)
    7429 [ #  # ][ #  # ]:          0 :                                     if (!pMat->IsString(nColMinus1, i))
    7430                 :            :                                         pResMat->PutDouble(pMat->GetDouble(nColMinus1,
    7431 [ #  # ][ #  # ]:          0 :                                                     i), i);
    7432                 :            :                                     else
    7433                 :            :                                         pResMat->PutString(pMat->GetString(nColMinus1,
    7434 [ #  # ][ #  # ]:          0 :                                                     i), i);
    7435         [ #  # ]:          0 :                                 PushMatrix(pResMat);
    7436                 :            :                             }
    7437                 :            :                             else
    7438 [ #  # ][ #  # ]:          0 :                                 PushIllegalArgument();
    7439                 :            :                         }
    7440                 :            :                         else
    7441                 :            :                         {
    7442         [ #  # ]:          0 :                             if (!pMat->IsString( static_cast<SCSIZE>(nCol-1),
    7443         [ #  # ]:          0 :                                         static_cast<SCSIZE>(nRow-1)))
    7444                 :            :                                 PushDouble( pMat->GetDouble(
    7445                 :            :                                             static_cast<SCSIZE>(nCol-1),
    7446 [ #  # ][ #  # ]:          0 :                                             static_cast<SCSIZE>(nRow-1)));
    7447                 :            :                             else
    7448                 :            :                                 PushString( pMat->GetString(
    7449                 :            :                                             static_cast<SCSIZE>(nCol-1),
    7450 [ #  # ][ #  # ]:          0 :                                             static_cast<SCSIZE>(nRow-1)));
         [ #  # ][ #  # ]
    7451                 :            :                         }
    7452         [ #  # ]:          0 :                     }
    7453                 :            :                 }
    7454                 :          0 :                 break;
    7455                 :            :             case svSingleRef:
    7456                 :            :                 {
    7457                 :          0 :                     SCCOL nCol1 = 0;
    7458                 :          0 :                     SCROW nRow1 = 0;
    7459                 :          0 :                     SCTAB nTab1 = 0;
    7460         [ #  # ]:          0 :                     PopSingleRef( nCol1, nRow1, nTab1);
    7461 [ #  # ][ #  # ]:          0 :                     if (nCol > 1 || nRow > 1)
    7462         [ #  # ]:          0 :                         PushIllegalArgument();
    7463                 :            :                     else
    7464         [ #  # ]:          0 :                         PushSingleRef( nCol1, nRow1, nTab1);
    7465                 :            :                 }
    7466                 :          0 :                 break;
    7467                 :            :             case svDoubleRef:
    7468                 :            :             case svRefList:
    7469                 :            :                 {
    7470                 :          0 :                     SCCOL nCol1 = 0;
    7471                 :          0 :                     SCROW nRow1 = 0;
    7472                 :          0 :                     SCTAB nTab1 = 0;
    7473                 :          0 :                     SCCOL nCol2 = 0;
    7474                 :          0 :                     SCROW nRow2 = 0;
    7475                 :          0 :                     SCTAB nTab2 = 0;
    7476                 :          0 :                     bool bRowArray = false;
    7477 [ #  # ][ #  # ]:          0 :                     if (GetStackType() == svRefList)
    7478                 :            :                     {
    7479         [ #  # ]:          0 :                         FormulaTokenRef xRef = PopToken();
    7480 [ #  # ][ #  # ]:          0 :                         if (nGlobalError || !xRef)
                 [ #  # ]
    7481                 :            :                         {
    7482         [ #  # ]:          0 :                             PushIllegalParameter();
    7483                 :            :                             return;
    7484                 :            :                         }
    7485                 :          0 :                         ScRange aRange( ScAddress::UNINITIALIZED);
    7486 [ #  # ][ #  # ]:          0 :                         DoubleRefToRange( (*(static_cast<ScToken*>(xRef.get())->GetRefList()))[nArea-1], aRange);
    7487                 :          0 :                         aRange.GetVars( nCol1, nRow1, nTab1, nCol2, nRow2, nTab2);
    7488 [ #  # ][ #  # ]:          0 :                         if ( nParamCount == 2 && nRow1 == nRow2 )
    7489 [ #  # ][ #  # ]:          0 :                             bRowArray = true;
    7490                 :            :                     }
    7491                 :            :                     else
    7492                 :            :                     {
    7493         [ #  # ]:          0 :                         PopDoubleRef( nCol1, nRow1, nTab1, nCol2, nRow2, nTab2);
    7494 [ #  # ][ #  # ]:          0 :                         if ( nParamCount == 2 && nRow1 == nRow2 )
    7495                 :          0 :                             bRowArray = true;
    7496                 :            :                     }
    7497 [ #  # ][ #  # ]:          0 :                     if ( nTab1 != nTab2 ||
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
    7498                 :            :                             (nCol > 0 && nCol1+nCol-1 > nCol2) ||
    7499                 :          0 :                             (nRow > 0 && nRow1+nRow-1 > nRow2 && !bRowArray ) ||
    7500                 :            :                             ( nRow > nCol2 - nCol1 + 1 && bRowArray ))
    7501         [ #  # ]:          0 :                         PushIllegalArgument();
    7502 [ #  # ][ #  # ]:          0 :                     else if (nCol == 0 && nRow == 0)
    7503                 :            :                     {
    7504 [ #  # ][ #  # ]:          0 :                         if ( nCol1 == nCol2 && nRow1 == nRow2 )
    7505         [ #  # ]:          0 :                             PushSingleRef( nCol1, nRow1, nTab1 );
    7506                 :            :                         else
    7507         [ #  # ]:          0 :                             PushDoubleRef( nCol1, nRow1, nTab1, nCol2, nRow2, nTab1 );
    7508                 :            :                     }
    7509         [ #  # ]:          0 :                     else if (nRow == 0)
    7510                 :            :                     {
    7511         [ #  # ]:          0 :                         if ( nRow1 == nRow2 )
    7512         [ #  # ]:          0 :                             PushSingleRef( nCol1+nCol-1, nRow1, nTab1 );
    7513                 :            :                         else
    7514                 :            :                             PushDoubleRef( nCol1+nCol-1, nRow1, nTab1,
    7515         [ #  # ]:          0 :                                     nCol1+nCol-1, nRow2, nTab1 );
    7516                 :            :                     }
    7517         [ #  # ]:          0 :                     else if (nCol == 0)
    7518                 :            :                     {
    7519         [ #  # ]:          0 :                         if ( nCol1 == nCol2 )
    7520         [ #  # ]:          0 :                             PushSingleRef( nCol1, nRow1+nRow-1, nTab1 );
    7521         [ #  # ]:          0 :                         else if ( bRowArray )
    7522                 :            :                         {
    7523                 :          0 :                             nCol =(SCCOL) nRow;
    7524                 :          0 :                             nRow = 1;
    7525         [ #  # ]:          0 :                             PushSingleRef( nCol1+nCol-1, nRow1+nRow-1, nTab1);
    7526                 :            :                         }
    7527                 :            :                         else
    7528                 :            :                             PushDoubleRef( nCol1, nRow1+nRow-1, nTab1,
    7529         [ #  # ]:          0 :                                     nCol2, nRow1+nRow-1, nTab1);
    7530                 :            :                     }
    7531                 :            :                     else
    7532         [ #  # ]:          0 :                         PushSingleRef( nCol1+nCol-1, nRow1+nRow-1, nTab1);
    7533                 :            :                 }
    7534                 :          0 :                 break;
    7535                 :            :             default:
    7536                 :          0 :                 PushIllegalParameter();
    7537                 :            :         }
    7538                 :            :     }
    7539                 :            : }
    7540                 :            : 
    7541                 :            : 
    7542                 :          0 : void ScInterpreter::ScMultiArea()
    7543                 :            : {
    7544                 :            :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScMultiArea" );
    7545                 :            :     // Legacy support, convert to RefList
    7546                 :          0 :     sal_uInt8 nParamCount = GetByte();
    7547         [ #  # ]:          0 :     if (MustHaveParamCountMin( nParamCount, 1))
    7548                 :            :     {
    7549 [ #  # ][ #  # ]:          0 :         while (!nGlobalError && nParamCount-- > 1)
                 [ #  # ]
    7550                 :            :         {
    7551                 :          0 :             ScUnionFunc();
    7552                 :            :         }
    7553                 :            :     }
    7554                 :          0 : }
    7555                 :            : 
    7556                 :            : 
    7557                 :          0 : void ScInterpreter::ScAreas()
    7558                 :            : {
    7559                 :            :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScAreas" );
    7560                 :          0 :     sal_uInt8 nParamCount = GetByte();
    7561         [ #  # ]:          0 :     if (MustHaveParamCount( nParamCount, 1))
    7562                 :            :     {
    7563                 :          0 :         size_t nCount = 0;
    7564   [ #  #  #  # ]:          0 :         switch (GetStackType())
    7565                 :            :         {
    7566                 :            :             case svSingleRef:
    7567                 :            :                 {
    7568         [ #  # ]:          0 :                     FormulaTokenRef xT = PopToken();
    7569 [ #  # ][ #  # ]:          0 :                     ValidateRef( static_cast<ScToken*>(xT.get())->GetSingleRef());
    7570         [ #  # ]:          0 :                     ++nCount;
    7571                 :            :                 }
    7572                 :          0 :                 break;
    7573                 :            :             case svDoubleRef:
    7574                 :            :                 {
    7575         [ #  # ]:          0 :                     FormulaTokenRef xT = PopToken();
    7576 [ #  # ][ #  # ]:          0 :                     ValidateRef( static_cast<ScToken*>(xT.get())->GetDoubleRef());
    7577         [ #  # ]:          0 :                     ++nCount;
    7578                 :            :                 }
    7579                 :          0 :                 break;
    7580                 :            :             case svRefList:
    7581                 :            :                 {
    7582         [ #  # ]:          0 :                     FormulaTokenRef xT = PopToken();
    7583 [ #  # ][ #  # ]:          0 :                     ValidateRef( *(static_cast<ScToken*>(xT.get())->GetRefList()));
    7584 [ #  # ][ #  # ]:          0 :                     nCount += static_cast<ScToken*>(xT.get())->GetRefList()->size();
    7585                 :            :                 }
    7586                 :          0 :                 break;
    7587                 :            :             default:
    7588                 :          0 :                 SetError( errIllegalParameter);
    7589                 :            :         }
    7590                 :          0 :         PushDouble( double(nCount));
    7591                 :            :     }
    7592                 :          0 : }
    7593                 :            : 
    7594                 :            : 
    7595                 :          0 : void ScInterpreter::ScCurrency()
    7596                 :            : {
    7597                 :            :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScCurrency" );
    7598                 :          0 :     sal_uInt8 nParamCount = GetByte();
    7599         [ #  # ]:          0 :     if ( MustHaveParamCount( nParamCount, 1, 2 ) )
    7600                 :            :     {
    7601         [ #  # ]:          0 :         String aStr;
    7602                 :            :         double fDec;
    7603         [ #  # ]:          0 :         if (nParamCount == 2)
    7604                 :            :         {
    7605         [ #  # ]:          0 :             fDec = ::rtl::math::approxFloor(GetDouble());
    7606 [ #  # ][ #  # ]:          0 :             if (fDec < -15.0 || fDec > 15.0)
    7607                 :            :             {
    7608         [ #  # ]:          0 :                 PushIllegalArgument();
    7609                 :          0 :                 return;
    7610                 :            :             }
    7611                 :            :         }
    7612                 :            :         else
    7613                 :          0 :             fDec = 2.0;
    7614         [ #  # ]:          0 :         double fVal = GetDouble();
    7615                 :            :         double fFac;
    7616         [ #  # ]:          0 :         if ( fDec != 0.0 )
    7617                 :          0 :             fFac = pow( (double)10, fDec );
    7618                 :            :         else
    7619                 :          0 :             fFac = 1.0;
    7620         [ #  # ]:          0 :         if (fVal < 0.0)
    7621                 :          0 :             fVal = ceil(fVal*fFac-0.5)/fFac;
    7622                 :            :         else
    7623                 :          0 :             fVal = floor(fVal*fFac+0.5)/fFac;
    7624                 :          0 :         Color* pColor = NULL;
    7625         [ #  # ]:          0 :         if ( fDec < 0.0 )
    7626                 :          0 :             fDec = 0.0;
    7627                 :            :         sal_uLong nIndex = pFormatter->GetStandardFormat(
    7628                 :            :                                         NUMBERFORMAT_CURRENCY,
    7629         [ #  # ]:          0 :                                         ScGlobal::eLnge);
    7630 [ #  # ][ #  # ]:          0 :         if ( (sal_uInt16) fDec != pFormatter->GetFormatPrecision( nIndex ) )
    7631                 :            :         {
    7632         [ #  # ]:          0 :             String sFormatString;
    7633                 :            :             pFormatter->GenerateFormat(sFormatString,
    7634                 :            :                                                    nIndex,
    7635                 :            :                                                    ScGlobal::eLnge,
    7636                 :            :                                                    true,        // mit Tausenderpunkt
    7637                 :            :                                                    false,       // nicht rot
    7638                 :            :                                                   (sal_uInt16) fDec,// Nachkommastellen
    7639         [ #  # ]:          0 :                                                    1);          // 1 Vorkommanull
    7640         [ #  # ]:          0 :             if (!pFormatter->GetPreviewString(sFormatString,
    7641                 :            :                                                   fVal,
    7642                 :            :                                                   aStr,
    7643                 :            :                                                   &pColor,
    7644         [ #  # ]:          0 :                                                   ScGlobal::eLnge))
    7645         [ #  # ]:          0 :                 SetError(errIllegalArgument);
    7646                 :            :         }
    7647                 :            :         else
    7648                 :            :         {
    7649         [ #  # ]:          0 :             pFormatter->GetOutputString(fVal, nIndex, aStr, &pColor);
    7650                 :            :         }
    7651 [ #  # ][ #  # ]:          0 :         PushString(aStr);
                 [ #  # ]
    7652                 :            :     }
    7653                 :            : }
    7654                 :            : 
    7655                 :            : 
    7656                 :          0 : void ScInterpreter::ScReplace()
    7657                 :            : {
    7658                 :            :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScReplace" );
    7659         [ #  # ]:          0 :     if ( MustHaveParamCount( GetByte(), 4 ) )
    7660                 :            :     {
    7661 [ #  # ][ #  # ]:          0 :         String aNewStr( GetString() );
    7662         [ #  # ]:          0 :         double fCount = ::rtl::math::approxFloor( GetDouble());
    7663         [ #  # ]:          0 :         double fPos   = ::rtl::math::approxFloor( GetDouble());
    7664 [ #  # ][ #  # ]:          0 :         String aOldStr( GetString() );
    7665 [ #  # ][ #  # ]:          0 :         if (fPos < 1.0 || fPos > static_cast<double>(STRING_MAXLEN)
         [ #  # ][ #  # ]
    7666                 :            :                 || fCount < 0.0 || fCount > static_cast<double>(STRING_MAXLEN))
    7667         [ #  # ]:          0 :             PushIllegalArgument();
    7668                 :            :         else
    7669                 :            :         {
    7670                 :          0 :             xub_StrLen nCount = static_cast<xub_StrLen>(fCount);
    7671                 :          0 :             xub_StrLen nPos   = static_cast<xub_StrLen>(fPos);
    7672                 :          0 :             xub_StrLen nLen   = aOldStr.Len();
    7673         [ #  # ]:          0 :             if (nPos > nLen + 1)
    7674                 :          0 :                 nPos = nLen + 1;
    7675         [ #  # ]:          0 :             if (nCount > nLen - nPos + 1)
    7676                 :          0 :                 nCount = nLen - nPos + 1;
    7677         [ #  # ]:          0 :             aOldStr.Erase( nPos-1, nCount );
    7678 [ #  # ][ #  # ]:          0 :             if ( CheckStringResultLen( aOldStr, aNewStr ) )
    7679         [ #  # ]:          0 :                 aOldStr.Insert( aNewStr, nPos-1 );
    7680         [ #  # ]:          0 :             PushString( aOldStr );
    7681 [ #  # ][ #  # ]:          0 :         }
    7682                 :            :     }
    7683                 :          0 : }
    7684                 :            : 
    7685                 :            : 
    7686                 :          0 : void ScInterpreter::ScFixed()
    7687                 :            : {
    7688                 :            :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScFixed" );
    7689                 :          0 :     sal_uInt8 nParamCount = GetByte();
    7690         [ #  # ]:          0 :     if ( MustHaveParamCount( nParamCount, 1, 3 ) )
    7691                 :            :     {
    7692         [ #  # ]:          0 :         String aStr;
    7693                 :            :         double fDec;
    7694                 :            :         bool bThousand;
    7695         [ #  # ]:          0 :         if (nParamCount == 3)
    7696         [ #  # ]:          0 :             bThousand = !GetBool();     // Param TRUE: keine Tausenderpunkte
    7697                 :            :         else
    7698                 :          0 :             bThousand = true;
    7699         [ #  # ]:          0 :         if (nParamCount >= 2)
    7700                 :            :         {
    7701         [ #  # ]:          0 :             fDec = ::rtl::math::approxFloor(GetDoubleWithDefault( 2.0 ));
    7702 [ #  # ][ #  # ]:          0 :             if (fDec < -15.0 || fDec > 15.0)
    7703                 :            :             {
    7704         [ #  # ]:          0 :                 PushIllegalArgument();
    7705                 :          0 :                 return;
    7706                 :            :             }
    7707                 :            :         }
    7708                 :            :         else
    7709                 :          0 :             fDec = 2.0;
    7710         [ #  # ]:          0 :         double fVal = GetDouble();
    7711                 :            :         double fFac;
    7712         [ #  # ]:          0 :         if ( fDec != 0.0 )
    7713                 :          0 :             fFac = pow( (double)10, fDec );
    7714                 :            :         else
    7715                 :          0 :             fFac = 1.0;
    7716         [ #  # ]:          0 :         if (fVal < 0.0)
    7717                 :          0 :             fVal = ceil(fVal*fFac-0.5)/fFac;
    7718                 :            :         else
    7719                 :          0 :             fVal = floor(fVal*fFac+0.5)/fFac;
    7720                 :          0 :         Color* pColor = NULL;
    7721         [ #  # ]:          0 :         String sFormatString;
    7722         [ #  # ]:          0 :         if (fDec < 0.0)
    7723                 :          0 :             fDec = 0.0;
    7724                 :            :         sal_uLong nIndex = pFormatter->GetStandardFormat(
    7725                 :            :                                             NUMBERFORMAT_NUMBER,
    7726         [ #  # ]:          0 :                                             ScGlobal::eLnge);
    7727                 :            :         pFormatter->GenerateFormat(sFormatString,
    7728                 :            :                                                nIndex,
    7729                 :            :                                                ScGlobal::eLnge,
    7730                 :            :                                                bThousand,   // mit Tausenderpunkt
    7731                 :            :                                                false,       // nicht rot
    7732                 :            :                                                (sal_uInt16) fDec,// Nachkommastellen
    7733         [ #  # ]:          0 :                                                1);          // 1 Vorkommanull
    7734         [ #  # ]:          0 :         if (!pFormatter->GetPreviewString(sFormatString,
    7735                 :            :                                                   fVal,
    7736                 :            :                                                   aStr,
    7737                 :            :                                                   &pColor,
    7738         [ #  # ]:          0 :                                                   ScGlobal::eLnge))
    7739         [ #  # ]:          0 :             PushIllegalArgument();
    7740                 :            :         else
    7741 [ #  # ][ #  # ]:          0 :             PushString(aStr);
         [ #  # ][ #  # ]
    7742                 :            :     }
    7743                 :            : }
    7744                 :            : 
    7745                 :            : 
    7746                 :          0 : void ScInterpreter::ScFind()
    7747                 :            : {
    7748                 :            :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScFind" );
    7749                 :          0 :     sal_uInt8 nParamCount = GetByte();
    7750         [ #  # ]:          0 :     if ( MustHaveParamCount( nParamCount, 2, 3 ) )
    7751                 :            :     {
    7752                 :            :         double fAnz;
    7753         [ #  # ]:          0 :         if (nParamCount == 3)
    7754         [ #  # ]:          0 :             fAnz = GetDouble();
    7755                 :            :         else
    7756                 :          0 :             fAnz = 1.0;
    7757 [ #  # ][ #  # ]:          0 :         String sStr = GetString();
    7758 [ #  # ][ #  # ]:          0 :         if( fAnz < 1.0 || fAnz > (double) sStr.Len() )
                 [ #  # ]
    7759         [ #  # ]:          0 :             PushNoValue();
    7760                 :            :         else
    7761                 :            :         {
    7762 [ #  # ][ #  # ]:          0 :             xub_StrLen nPos = sStr.Search( GetString(), (xub_StrLen) fAnz - 1 );
    7763         [ #  # ]:          0 :             if (nPos == STRING_NOTFOUND)
    7764         [ #  # ]:          0 :                 PushNoValue();
    7765                 :            :             else
    7766         [ #  # ]:          0 :                 PushDouble((double)(nPos + 1));
    7767         [ #  # ]:          0 :         }
    7768                 :            :     }
    7769                 :          0 : }
    7770                 :            : 
    7771                 :            : 
    7772                 :          0 : void ScInterpreter::ScExact()
    7773                 :            : {
    7774                 :            :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScExact" );
    7775                 :          0 :     nFuncFmtType = NUMBERFORMAT_LOGICAL;
    7776         [ #  # ]:          0 :     if ( MustHaveParamCount( GetByte(), 2 ) )
    7777                 :            :     {
    7778 [ #  # ][ #  # ]:          0 :         String s1( GetString() );
    7779 [ #  # ][ #  # ]:          0 :         String s2( GetString() );
    7780 [ #  # ][ #  # ]:          0 :         PushInt( s1 == s2 );
         [ #  # ][ #  # ]
    7781                 :            :     }
    7782                 :          0 : }
    7783                 :            : 
    7784                 :            : 
    7785                 :          0 : void ScInterpreter::ScLeft()
    7786                 :            : {
    7787                 :            :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScLeft" );
    7788                 :          0 :     sal_uInt8 nParamCount = GetByte();
    7789         [ #  # ]:          0 :     if ( MustHaveParamCount( nParamCount, 1, 2 ) )
    7790                 :            :     {
    7791                 :            :         xub_StrLen n;
    7792         [ #  # ]:          0 :         if (nParamCount == 2)
    7793                 :            :         {
    7794         [ #  # ]:          0 :             double nVal = ::rtl::math::approxFloor(GetDouble());
    7795 [ #  # ][ #  # ]:          0 :             if ( nVal < 0.0 || nVal > STRING_MAXLEN )
    7796                 :            :             {
    7797         [ #  # ]:          0 :                 PushIllegalArgument();
    7798                 :          0 :                 return ;
    7799                 :            :             }
    7800                 :            :             else
    7801                 :          0 :                 n = (xub_StrLen) nVal;
    7802                 :            :         }
    7803                 :            :         else
    7804                 :          0 :             n = 1;
    7805 [ #  # ][ #  # ]:          0 :         String aStr( GetString() );
    7806         [ #  # ]:          0 :         aStr.Erase( n );
    7807 [ #  # ][ #  # ]:          0 :         PushString( aStr );
    7808                 :            :     }
    7809                 :            : }
    7810                 :            : 
    7811                 :            : 
    7812                 :          0 : void ScInterpreter::ScRight()
    7813                 :            : {
    7814                 :            :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScRight" );
    7815                 :          0 :     sal_uInt8 nParamCount = GetByte();
    7816         [ #  # ]:          0 :     if ( MustHaveParamCount( nParamCount, 1, 2 ) )
    7817                 :            :     {
    7818                 :            :         xub_StrLen n;
    7819         [ #  # ]:          0 :         if (nParamCount == 2)
    7820                 :            :         {
    7821         [ #  # ]:          0 :             double nVal = ::rtl::math::approxFloor(GetDouble());
    7822 [ #  # ][ #  # ]:          0 :             if ( nVal < 0.0 || nVal > STRING_MAXLEN )
    7823                 :            :             {
    7824         [ #  # ]:          0 :                 PushIllegalArgument();
    7825                 :          0 :                 return ;
    7826                 :            :             }
    7827                 :            :             else
    7828                 :          0 :                 n = (xub_StrLen) nVal;
    7829                 :            :         }
    7830                 :            :         else
    7831                 :          0 :             n = 1;
    7832 [ #  # ][ #  # ]:          0 :         String aStr( GetString() );
    7833         [ #  # ]:          0 :         if( n < aStr.Len() )
    7834         [ #  # ]:          0 :             aStr.Erase( 0, aStr.Len() - n );
    7835 [ #  # ][ #  # ]:          0 :         PushString( aStr );
    7836                 :            :     }
    7837                 :            : }
    7838                 :            : 
    7839                 :            : 
    7840                 :          0 : void ScInterpreter::ScSearch()
    7841                 :            : {
    7842                 :            :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScSearch" );
    7843                 :          0 :     sal_uInt8 nParamCount = GetByte();
    7844         [ #  # ]:          0 :     if ( MustHaveParamCount( nParamCount, 2, 3 ) )
    7845                 :            :     {
    7846                 :            :         double fAnz;
    7847         [ #  # ]:          0 :         if (nParamCount == 3)
    7848                 :            :         {
    7849         [ #  # ]:          0 :             fAnz = ::rtl::math::approxFloor(GetDouble());
    7850         [ #  # ]:          0 :             if (fAnz > double(STRING_MAXLEN))
    7851                 :            :             {
    7852         [ #  # ]:          0 :                 PushIllegalArgument();
    7853                 :          0 :                 return;
    7854                 :            :             }
    7855                 :            :         }
    7856                 :            :         else
    7857                 :          0 :             fAnz = 1.0;
    7858 [ #  # ][ #  # ]:          0 :         String sStr = GetString();
    7859 [ #  # ][ #  # ]:          0 :         OUString SearchStr = GetString();
    7860                 :          0 :         xub_StrLen nPos = (xub_StrLen) fAnz - 1;
    7861                 :          0 :         xub_StrLen nEndPos = sStr.Len();
    7862         [ #  # ]:          0 :         if( nPos >= nEndPos )
    7863         [ #  # ]:          0 :             PushNoValue();
    7864                 :            :         else
    7865                 :            :         {
    7866                 :            :             utl::SearchParam::SearchType eSearchType =
    7867         [ #  # ]:          0 :                 (MayBeRegExp( SearchStr, pDok ) ?
    7868         [ #  # ]:          0 :                 utl::SearchParam::SRCH_REGEXP : utl::SearchParam::SRCH_NORMAL);
    7869         [ #  # ]:          0 :             utl::SearchParam sPar(SearchStr, eSearchType, false, false, false);
    7870         [ #  # ]:          0 :             utl::TextSearch sT( sPar, *ScGlobal::pCharClass );
    7871         [ #  # ]:          0 :             int nBool = sT.SearchFrwrd(sStr, &nPos, &nEndPos);
    7872         [ #  # ]:          0 :             if (!nBool)
    7873         [ #  # ]:          0 :                 PushNoValue();
    7874                 :            :             else
    7875 [ #  # ][ #  # ]:          0 :                 PushDouble((double)(nPos) + 1);
                 [ #  # ]
    7876         [ #  # ]:          0 :         }
    7877                 :            :     }
    7878                 :            : }
    7879                 :            : 
    7880                 :            : 
    7881                 :          0 : void ScInterpreter::ScMid()
    7882                 :            : {
    7883                 :            :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScMid" );
    7884         [ #  # ]:          0 :     if ( MustHaveParamCount( GetByte(), 3 ) )
    7885                 :            :     {
    7886                 :          0 :         double fAnz    = ::rtl::math::approxFloor(GetDouble());
    7887                 :          0 :         double fAnfang = ::rtl::math::approxFloor(GetDouble());
    7888                 :          0 :         const String& rStr = GetString();
    7889 [ #  # ][ #  # ]:          0 :         if (fAnfang < 1.0 || fAnz < 0.0 || fAnfang > double(STRING_MAXLEN) || fAnz > double(STRING_MAXLEN))
         [ #  # ][ #  # ]
    7890                 :          0 :             PushIllegalArgument();
    7891                 :            :         else
    7892         [ #  # ]:          0 :             PushString(rStr.Copy( (xub_StrLen) fAnfang - 1, (xub_StrLen) fAnz ));
    7893                 :            :     }
    7894                 :          0 : }
    7895                 :            : 
    7896                 :            : 
    7897                 :          0 : void ScInterpreter::ScText()
    7898                 :            : {
    7899                 :            :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScText" );
    7900         [ #  # ]:          0 :     if ( MustHaveParamCount( GetByte(), 2 ) )
    7901                 :            :     {
    7902 [ #  # ][ #  # ]:          0 :         String sFormatString = GetString();
    7903         [ #  # ]:          0 :         String aStr;
    7904                 :          0 :         bool bString = false;
    7905                 :          0 :         double fVal = 0.0;
    7906         [ #  # ]:          0 :         switch (GetStackType())
              [ #  #  # ]
    7907                 :            :         {
    7908                 :            :             case svError:
    7909         [ #  # ]:          0 :                 PopError();
    7910                 :          0 :                 break;
    7911                 :            :             case svDouble:
    7912         [ #  # ]:          0 :                 fVal = PopDouble();
    7913                 :          0 :                 break;
    7914                 :            :             default:
    7915                 :            :                 {
    7916         [ #  # ]:          0 :                     FormulaTokenRef xTok( PopToken());
    7917         [ #  # ]:          0 :                     if (!nGlobalError)
    7918                 :            :                     {
    7919         [ #  # ]:          0 :                         PushTempToken( xTok.get());
    7920                 :            :                         // Temporarily override the ConvertStringToValue()
    7921                 :            :                         // error for GetCellValue() / GetCellValueOrZero()
    7922                 :          0 :                         sal_uInt16 nSErr = mnStringNoValueError;
    7923                 :          0 :                         mnStringNoValueError = errNotNumericString;
    7924         [ #  # ]:          0 :                         fVal = GetDouble();
    7925                 :          0 :                         mnStringNoValueError = nSErr;
    7926         [ #  # ]:          0 :                         if (nGlobalError == errNotNumericString)
    7927                 :            :                         {
    7928                 :            :                             // Not numeric.
    7929                 :          0 :                             nGlobalError = 0;
    7930         [ #  # ]:          0 :                             PushTempToken( xTok.get());
    7931 [ #  # ][ #  # ]:          0 :                             aStr = GetString();
    7932                 :          0 :                             bString = true;
    7933                 :            :                         }
    7934         [ #  # ]:          0 :                     }
    7935                 :            :                 }
    7936                 :            :         }
    7937         [ #  # ]:          0 :         if (nGlobalError)
    7938         [ #  # ]:          0 :             PushError( nGlobalError);
    7939                 :            :         else
    7940                 :            :         {
    7941         [ #  # ]:          0 :             String aResult;
    7942                 :          0 :             Color* pColor = NULL;
    7943                 :            :             LanguageType eCellLang;
    7944                 :            :             const ScPatternAttr* pPattern = pDok->GetPattern(
    7945         [ #  # ]:          0 :                     aPos.Col(), aPos.Row(), aPos.Tab() );
    7946         [ #  # ]:          0 :             if ( pPattern )
    7947                 :            :                 eCellLang = ((const SvxLanguageItem&)
    7948         [ #  # ]:          0 :                         pPattern->GetItem( ATTR_LANGUAGE_FORMAT )).GetValue();
    7949                 :            :             else
    7950                 :          0 :                 eCellLang = ScGlobal::eLnge;
    7951         [ #  # ]:          0 :             if (bString)
    7952                 :            :             {
    7953         [ #  # ]:          0 :                 if (!pFormatter->GetPreviewString( sFormatString, aStr,
    7954         [ #  # ]:          0 :                             aResult, &pColor, eCellLang))
    7955         [ #  # ]:          0 :                     PushIllegalArgument();
    7956                 :            :                 else
    7957         [ #  # ]:          0 :                     PushString( aResult);
    7958                 :            :             }
    7959                 :            :             else
    7960                 :            :             {
    7961         [ #  # ]:          0 :                 if (!pFormatter->GetPreviewStringGuess( sFormatString, fVal,
    7962         [ #  # ]:          0 :                             aResult, &pColor, eCellLang))
    7963         [ #  # ]:          0 :                     PushIllegalArgument();
    7964                 :            :                 else
    7965         [ #  # ]:          0 :                     PushString( aResult);
    7966         [ #  # ]:          0 :             }
    7967 [ #  # ][ #  # ]:          0 :         }
    7968                 :            :     }
    7969                 :          0 : }
    7970                 :            : 
    7971                 :            : 
    7972                 :          0 : void ScInterpreter::ScSubstitute()
    7973                 :            : {
    7974                 :            :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScSubstitute" );
    7975                 :          0 :     sal_uInt8 nParamCount = GetByte();
    7976         [ #  # ]:          0 :     if ( MustHaveParamCount( nParamCount, 3, 4 ) )
    7977                 :            :     {
    7978                 :            :         xub_StrLen nAnz;
    7979         [ #  # ]:          0 :         if (nParamCount == 4)
    7980                 :            :         {
    7981         [ #  # ]:          0 :             double fAnz = ::rtl::math::approxFloor(GetDouble());
    7982 [ #  # ][ #  # ]:          0 :             if( fAnz < 1 || fAnz > STRING_MAXLEN )
    7983                 :            :             {
    7984         [ #  # ]:          0 :                 PushIllegalArgument();
    7985                 :          0 :                 return;
    7986                 :            :             }
    7987                 :            :             else
    7988                 :          0 :                 nAnz = (xub_StrLen) fAnz;
    7989                 :            :         }
    7990                 :            :         else
    7991                 :          0 :             nAnz = 0;
    7992 [ #  # ][ #  # ]:          0 :         String sNewStr = GetString();
    7993 [ #  # ][ #  # ]:          0 :         String sOldStr = GetString();
    7994 [ #  # ][ #  # ]:          0 :         String sStr    = GetString();
    7995                 :          0 :         xub_StrLen nPos = 0;
    7996                 :          0 :         xub_StrLen nCount = 0;
    7997                 :          0 :         xub_StrLen nNewLen = sNewStr.Len();
    7998                 :          0 :         xub_StrLen nOldLen = sOldStr.Len();
    7999                 :          0 :         while( true )
    8000                 :            :         {
    8001         [ #  # ]:          0 :             nPos = sStr.Search( sOldStr, nPos );
    8002         [ #  # ]:          0 :             if (nPos != STRING_NOTFOUND)
    8003                 :            :             {
    8004                 :          0 :                 nCount++;
    8005 [ #  # ][ #  # ]:          0 :                 if( !nAnz || nCount == nAnz )
    8006                 :            :                 {
    8007         [ #  # ]:          0 :                     sStr.Erase(nPos,nOldLen);
    8008 [ #  # ][ #  # ]:          0 :                     if ( CheckStringResultLen( sStr, sNewStr ) )
    8009                 :            :                     {
    8010         [ #  # ]:          0 :                         sStr.Insert(sNewStr,nPos);
    8011                 :          0 :                         nPos = sal::static_int_cast<xub_StrLen>( nPos + nNewLen );
    8012                 :            :                     }
    8013                 :            :                     else
    8014                 :          0 :                         break;
    8015                 :            :                 }
    8016                 :            :                 else
    8017                 :          0 :                     nPos++;
    8018                 :            :             }
    8019                 :            :             else
    8020                 :          0 :                 break;
    8021                 :            :         }
    8022 [ #  # ][ #  # ]:          0 :         PushString( sStr );
         [ #  # ][ #  # ]
    8023                 :            :     }
    8024                 :            : }
    8025                 :            : 
    8026                 :            : 
    8027                 :          0 : void ScInterpreter::ScRept()
    8028                 :            : {
    8029                 :            :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScRept" );
    8030         [ #  # ]:          0 :     if ( MustHaveParamCount( GetByte(), 2 ) )
    8031                 :            :     {
    8032         [ #  # ]:          0 :         double fAnz = ::rtl::math::approxFloor(GetDouble());
    8033 [ #  # ][ #  # ]:          0 :         String aStr( GetString() );
    8034         [ #  # ]:          0 :         if ( fAnz < 0.0 )
    8035         [ #  # ]:          0 :             PushIllegalArgument();
    8036         [ #  # ]:          0 :         else if ( fAnz * aStr.Len() > STRING_MAXLEN )
    8037                 :            :         {
    8038         [ #  # ]:          0 :             PushError( errStringOverflow );
    8039                 :            :         }
    8040         [ #  # ]:          0 :         else if ( fAnz == 0.0 )
    8041 [ #  # ][ #  # ]:          0 :             PushString( EMPTY_STRING );
    8042                 :            :         else
    8043                 :            :         {
    8044                 :          0 :             const xub_StrLen nLen = aStr.Len();
    8045                 :          0 :             xub_StrLen n = (xub_StrLen) fAnz;
    8046                 :          0 :             rtl::OUStringBuffer aRes(n*nLen);
    8047         [ #  # ]:          0 :             while( n-- )
    8048 [ #  # ][ #  # ]:          0 :                 aRes.append(aStr);
    8049 [ #  # ][ #  # ]:          0 :             PushString( aRes.makeStringAndClear() );
         [ #  # ][ #  # ]
    8050         [ #  # ]:          0 :         }
    8051                 :            :     }
    8052                 :          0 : }
    8053                 :            : 
    8054                 :            : 
    8055                 :          0 : void ScInterpreter::ScConcat()
    8056                 :            : {
    8057                 :            :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScConcat" );
    8058                 :          0 :     sal_uInt8 nParamCount = GetByte();
    8059         [ #  # ]:          0 :     String aRes;
    8060         [ #  # ]:          0 :     while( nParamCount-- > 0)
    8061                 :            :     {
    8062         [ #  # ]:          0 :         const String& rStr = GetString();
    8063         [ #  # ]:          0 :         aRes.Insert( rStr, 0 );
    8064                 :            :     }
    8065 [ #  # ][ #  # ]:          0 :     PushString( aRes );
    8066                 :          0 : }
    8067                 :            : 
    8068                 :            : 
    8069                 :          0 : void ScInterpreter::ScErrorType()
    8070                 :            : {
    8071                 :            :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScErrorType" );
    8072                 :            :     sal_uInt16 nErr;
    8073                 :          0 :     sal_uInt16 nOldError = nGlobalError;
    8074                 :          0 :     nGlobalError = 0;
    8075   [ #  #  #  # ]:          0 :     switch ( GetStackType() )
    8076                 :            :     {
    8077                 :            :         case svRefList :
    8078                 :            :         {
    8079         [ #  # ]:          0 :             FormulaTokenRef x = PopToken();
    8080         [ #  # ]:          0 :             if (nGlobalError)
    8081                 :          0 :                 nErr = nGlobalError;
    8082                 :            :             else
    8083                 :            :             {
    8084         [ #  # ]:          0 :                 const ScRefList* pRefList = static_cast<ScToken*>(x.get())->GetRefList();
    8085                 :          0 :                 size_t n = pRefList->size();
    8086         [ #  # ]:          0 :                 if (!n)
    8087                 :          0 :                     nErr = errNoRef;
    8088         [ #  # ]:          0 :                 else if (n > 1)
    8089                 :          0 :                     nErr = errNoValue;
    8090                 :            :                 else
    8091                 :            :                 {
    8092                 :          0 :                     ScRange aRange;
    8093         [ #  # ]:          0 :                     DoubleRefToRange( (*pRefList)[0], aRange);
    8094         [ #  # ]:          0 :                     if (nGlobalError)
    8095                 :          0 :                         nErr = nGlobalError;
    8096                 :            :                     else
    8097                 :            :                     {
    8098                 :          0 :                         ScAddress aAdr;
    8099 [ #  # ][ #  # ]:          0 :                         if ( DoubleRefToPosSingleRef( aRange, aAdr ) )
    8100         [ #  # ]:          0 :                             nErr = pDok->GetErrCode( aAdr );
    8101                 :            :                         else
    8102                 :          0 :                             nErr = nGlobalError;
    8103                 :            :                     }
    8104                 :            :                 }
    8105         [ #  # ]:          0 :             }
    8106                 :            :         }
    8107                 :          0 :         break;
    8108                 :            :         case svDoubleRef :
    8109                 :            :         {
    8110                 :          0 :             ScRange aRange;
    8111         [ #  # ]:          0 :             PopDoubleRef( aRange );
    8112         [ #  # ]:          0 :             if ( nGlobalError )
    8113                 :          0 :                 nErr = nGlobalError;
    8114                 :            :             else
    8115                 :            :             {
    8116                 :          0 :                 ScAddress aAdr;
    8117 [ #  # ][ #  # ]:          0 :                 if ( DoubleRefToPosSingleRef( aRange, aAdr ) )
    8118         [ #  # ]:          0 :                     nErr = pDok->GetErrCode( aAdr );
    8119                 :            :                 else
    8120                 :          0 :                     nErr = nGlobalError;
    8121                 :            :             }
    8122                 :            :         }
    8123                 :          0 :         break;
    8124                 :            :         case svSingleRef :
    8125                 :            :         {
    8126                 :          0 :             ScAddress aAdr;
    8127         [ #  # ]:          0 :             PopSingleRef( aAdr );
    8128         [ #  # ]:          0 :             if ( nGlobalError )
    8129                 :          0 :                 nErr = nGlobalError;
    8130                 :            :             else
    8131         [ #  # ]:          0 :                 nErr = pDok->GetErrCode( aAdr );
    8132                 :            :         }
    8133                 :          0 :         break;
    8134                 :            :         default:
    8135                 :          0 :             PopError();
    8136                 :          0 :             nErr = nGlobalError;
    8137                 :            :     }
    8138         [ #  # ]:          0 :     if ( nErr )
    8139                 :            :     {
    8140                 :          0 :         nGlobalError = 0;
    8141                 :          0 :         PushDouble( nErr );
    8142                 :            :     }
    8143                 :            :     else
    8144                 :            :     {
    8145                 :          0 :         nGlobalError = nOldError;
    8146                 :          0 :         PushNA();
    8147                 :            :     }
    8148                 :          0 : }
    8149                 :            : 
    8150                 :            : 
    8151                 :         51 : bool ScInterpreter::MayBeRegExp( const OUString& rStr, const ScDocument* pDoc  )
    8152                 :            : {
    8153                 :            :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::MayBeRegExp" );
    8154 [ +  - ][ -  + ]:         51 :     if ( pDoc && !pDoc->GetDocOptions().IsFormulaRegexEnabled() )
                 [ -  + ]
    8155                 :          0 :         return false;
    8156 [ +  - ][ +  + ]:         51 :     if ( rStr.isEmpty() || (rStr.getLength() == 1 && rStr[0] != '.') )
         [ +  - ][ +  + ]
    8157                 :          6 :         return false;   // single meta characters can not be a regexp
    8158                 :            :     static const sal_Unicode cre[] = { '.','*','+','?','[',']','^','$','\\','<','>','(',')','|', 0 };
    8159                 :         45 :     const sal_Unicode* p1 = rStr.getStr();
    8160                 :            :     sal_Unicode c1;
    8161         [ +  + ]:        279 :     while ( ( c1 = *p1++ ) != 0 )
    8162                 :            :     {
    8163                 :        234 :         const sal_Unicode* p2 = cre;
    8164         [ +  + ]:       3510 :         while ( *p2 )
    8165                 :            :         {
    8166         [ -  + ]:       3276 :             if ( c1 == *p2++ )
    8167                 :          0 :                 return true;
    8168                 :            :         }
    8169                 :            :     }
    8170                 :         51 :     return false;
    8171                 :            : }
    8172                 :            : 
    8173                 :        144 : static bool lcl_LookupQuery( ScAddress & o_rResultPos, ScDocument * pDoc,
    8174                 :            :         const ScQueryParam & rParam, const ScQueryEntry & rEntry )
    8175                 :            : {
    8176                 :        144 :     bool bFound = false;
    8177         [ +  - ]:        144 :     ScQueryCellIterator aCellIter( pDoc, rParam.nTab, rParam, false);
    8178         [ +  - ]:        144 :     if (rEntry.eOp != SC_EQUAL)
    8179                 :            :     {
    8180                 :            :         // range lookup <= or >=
    8181                 :            :         SCCOL nCol;
    8182                 :            :         SCROW nRow;
    8183         [ +  - ]:        144 :         bFound = aCellIter.FindEqualOrSortedLastInRange( nCol, nRow);
    8184         [ +  + ]:        144 :         if (bFound)
    8185                 :            :         {
    8186                 :        129 :             o_rResultPos.SetCol( nCol);
    8187                 :        144 :             o_rResultPos.SetRow( nRow);
    8188                 :            :         }
    8189                 :            :     }
    8190 [ #  # ][ #  # ]:          0 :     else if (aCellIter.GetFirst())
    8191                 :            :     {
    8192                 :            :         // EQUAL
    8193                 :          0 :         bFound = true;
    8194                 :          0 :         o_rResultPos.SetCol( aCellIter.GetCol());
    8195                 :          0 :         o_rResultPos.SetRow( aCellIter.GetRow());
    8196                 :            :     }
    8197         [ +  - ]:        144 :     return bFound;
    8198                 :            : }
    8199                 :            : 
    8200                 :        144 : bool ScInterpreter::LookupQueryWithCache( ScAddress & o_rResultPos,
    8201                 :            :         const ScQueryParam & rParam ) const
    8202                 :            : {
    8203                 :            :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::LookupQueryWithCache" );
    8204                 :        144 :     bool bFound = false;
    8205                 :        144 :     const ScQueryEntry& rEntry = rParam.GetEntry(0);
    8206                 :        144 :     bool bColumnsMatch = (rParam.nCol1 == rEntry.nField);
    8207                 :            :     OSL_ENSURE( bColumnsMatch, "ScInterpreter::LookupQueryWithCache: columns don't match");
    8208         [ -  + ]:        144 :     if (!bColumnsMatch)
    8209                 :          0 :         bFound = lcl_LookupQuery( o_rResultPos, pDok, rParam, rEntry);
    8210                 :            :     else
    8211                 :            :     {
    8212                 :            :         ScRange aLookupRange( rParam.nCol1, rParam.nRow1, rParam.nTab,
    8213                 :        144 :                 rParam.nCol2, rParam.nRow2, rParam.nTab);
    8214         [ +  - ]:        144 :         ScLookupCache& rCache = pDok->GetLookupCache( aLookupRange);
    8215         [ +  - ]:        144 :         ScLookupCache::QueryCriteria aCriteria( rEntry);
    8216                 :            :         ScLookupCache::Result eCacheResult = rCache.lookup( o_rResultPos,
    8217         [ +  - ]:        144 :                 aCriteria, aPos);
    8218   [ +  -  -  - ]:        144 :         switch (eCacheResult)
    8219                 :            :         {
    8220                 :            :             case ScLookupCache::NOT_CACHED :
    8221                 :            :             case ScLookupCache::CRITERIA_DIFFERENT :
    8222         [ +  - ]:        144 :                 bFound = lcl_LookupQuery( o_rResultPos, pDok, rParam, rEntry);
    8223         [ +  - ]:        144 :                 if (eCacheResult == ScLookupCache::NOT_CACHED)
    8224         [ +  - ]:        144 :                     rCache.insert( o_rResultPos, aCriteria, aPos, bFound);
    8225                 :        144 :                 break;
    8226                 :            :             case ScLookupCache::FOUND :
    8227                 :          0 :                 bFound = true;
    8228                 :          0 :                 break;
    8229                 :            :             case ScLookupCache::NOT_AVAILABLE :
    8230                 :            :                 ;   // nothing, bFound remains FALSE
    8231                 :          0 :                 break;
    8232         [ +  - ]:        144 :         }
    8233                 :            :     }
    8234                 :        144 :     return bFound;
    8235 [ +  - ][ +  - ]:        153 : }
    8236                 :            : 
    8237                 :            : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10