LCOV - code coverage report
Current view: top level - libreoffice/sc/source/core/tool - token.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 422 968 43.6 %
Date: 2012-12-27 Functions: 70 147 47.6 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : #include <cstddef>
      21             : #include <cstdio>
      22             : 
      23             : #include <string.h>
      24             : #include <tools/mempool.hxx>
      25             : #include <osl/diagnose.h>
      26             : #include <sfx2/docfile.hxx>
      27             : 
      28             : #include "token.hxx"
      29             : #include "tokenarray.hxx"
      30             : #include "reftokenhelper.hxx"
      31             : #include "clipparam.hxx"
      32             : #include "compiler.hxx"
      33             : #include <formula/compiler.hrc>
      34             : #include "rechead.hxx"
      35             : #include "parclass.hxx"
      36             : #include "jumpmatrix.hxx"
      37             : #include "rangeseq.hxx"
      38             : #include "externalrefmgr.hxx"
      39             : #include "document.hxx"
      40             : 
      41             : using ::std::vector;
      42             : 
      43             : #include <com/sun/star/sheet/ComplexReference.hpp>
      44             : #include <com/sun/star/sheet/ExternalReference.hpp>
      45             : #include <com/sun/star/sheet/ReferenceFlags.hpp>
      46             : #include <com/sun/star/sheet/NameToken.hpp>
      47             : 
      48             : using namespace formula;
      49             : using namespace com::sun::star;
      50             : 
      51             : namespace
      52             : {
      53          38 :     void lcl_SingleRefToCalc( ScSingleRefData& rRef, const sheet::SingleReference& rAPI )
      54             :     {
      55          38 :         rRef.InitFlags();
      56             : 
      57          38 :         rRef.nCol    = static_cast<SCsCOL>(rAPI.Column);
      58          38 :         rRef.nRow    = static_cast<SCsROW>(rAPI.Row);
      59          38 :         rRef.nTab    = static_cast<SCsTAB>(rAPI.Sheet);
      60          38 :         rRef.nRelCol = static_cast<SCsCOL>(rAPI.RelativeColumn);
      61          38 :         rRef.nRelRow = static_cast<SCsROW>(rAPI.RelativeRow);
      62          38 :         rRef.nRelTab = static_cast<SCsTAB>(rAPI.RelativeSheet);
      63             : 
      64          38 :         rRef.SetColRel(     ( rAPI.Flags & sheet::ReferenceFlags::COLUMN_RELATIVE ) != 0 );
      65          38 :         rRef.SetRowRel(     ( rAPI.Flags & sheet::ReferenceFlags::ROW_RELATIVE    ) != 0 );
      66          38 :         rRef.SetTabRel(     ( rAPI.Flags & sheet::ReferenceFlags::SHEET_RELATIVE  ) != 0 );
      67          38 :         rRef.SetColDeleted( ( rAPI.Flags & sheet::ReferenceFlags::COLUMN_DELETED  ) != 0 );
      68          38 :         rRef.SetRowDeleted( ( rAPI.Flags & sheet::ReferenceFlags::ROW_DELETED     ) != 0 );
      69          38 :         rRef.SetTabDeleted( ( rAPI.Flags & sheet::ReferenceFlags::SHEET_DELETED   ) != 0 );
      70          38 :         rRef.SetFlag3D(     ( rAPI.Flags & sheet::ReferenceFlags::SHEET_3D        ) != 0 );
      71          38 :         rRef.SetRelName(    ( rAPI.Flags & sheet::ReferenceFlags::RELATIVE_NAME   ) != 0 );
      72          38 :     }
      73             : 
      74           0 :     void lcl_ExternalRefToCalc( ScSingleRefData& rRef, const sheet::SingleReference& rAPI )
      75             :     {
      76           0 :         rRef.InitFlags();
      77             : 
      78           0 :         rRef.nCol    = static_cast<SCsCOL>(rAPI.Column);
      79           0 :         rRef.nRow    = static_cast<SCsROW>(rAPI.Row);
      80           0 :         rRef.nTab    = 0;
      81           0 :         rRef.nRelCol = static_cast<SCsCOL>(rAPI.RelativeColumn);
      82           0 :         rRef.nRelRow = static_cast<SCsROW>(rAPI.RelativeRow);
      83           0 :         rRef.nRelTab = 0;
      84             : 
      85           0 :         rRef.SetColRel(     ( rAPI.Flags & sheet::ReferenceFlags::COLUMN_RELATIVE ) != 0 );
      86           0 :         rRef.SetRowRel(     ( rAPI.Flags & sheet::ReferenceFlags::ROW_RELATIVE    ) != 0 );
      87           0 :         rRef.SetTabRel(     false );    // sheet index must be absolute for external refs
      88           0 :         rRef.SetColDeleted( ( rAPI.Flags & sheet::ReferenceFlags::COLUMN_DELETED  ) != 0 );
      89           0 :         rRef.SetRowDeleted( ( rAPI.Flags & sheet::ReferenceFlags::ROW_DELETED     ) != 0 );
      90           0 :         rRef.SetTabDeleted( false );    // sheet must not be deleted for external refs
      91           0 :         rRef.SetFlag3D(     ( rAPI.Flags & sheet::ReferenceFlags::SHEET_3D        ) != 0 );
      92           0 :         rRef.SetRelName(    false );
      93           0 :     }
      94             : //
      95             : } // namespace
      96             : 
      97             : // Align MemPools on 4k boundaries - 64 bytes (4k is a MUST for OS/2)
      98             : 
      99             : // Since RawTokens are temporary for the compiler, don't align on 4k and waste memory.
     100             : // ScRawToken size is FixMembers + MAXSTRLEN + ~4 ~= 1036
     101           5 : IMPL_FIXEDMEMPOOL_NEWDEL( ScRawToken )
     102             : // Some ScDoubleRawToken, FixMembers + sizeof(double) ~= 16
     103           5 : IMPL_FIXEDMEMPOOL_NEWDEL( ScDoubleRawToken )
     104             : 
     105             : // Need a whole bunch of ScSingleRefToken
     106           5 : IMPL_FIXEDMEMPOOL_NEWDEL( ScSingleRefToken )
     107             : // Need quite a lot of ScDoubleRefToken
     108           5 : IMPL_FIXEDMEMPOOL_NEWDEL( ScDoubleRefToken )
     109             : 
     110             : // --- class ScRawToken -----------------------------------------------------
     111             : 
     112         216 : xub_StrLen ScRawToken::GetStrLen( const sal_Unicode* pStr )
     113             : {
     114         216 :     if ( !pStr )
     115           0 :         return 0;
     116         216 :     register const sal_Unicode* p = pStr;
     117        1344 :     while ( *p )
     118         912 :         p++;
     119         216 :     return sal::static_int_cast<xub_StrLen>( p - pStr );
     120             : }
     121             : 
     122             : 
     123       21169 : void ScRawToken::SetOpCode( OpCode e )
     124             : {
     125       21169 :     eOp   = e;
     126       21169 :     switch (eOp)
     127             :     {
     128             :         case ocIf:
     129          20 :             eType = svJump;
     130          20 :             nJump[ 0 ] = 3; // If, Else, Behind
     131          20 :             break;
     132             :         case ocChose:
     133           0 :             eType = svJump;
     134           0 :             nJump[ 0 ] = MAXJUMPCOUNT+1;
     135           0 :             break;
     136             :         case ocMissing:
     137           0 :             eType = svMissing;
     138           0 :             break;
     139             :         case ocSep:
     140             :         case ocOpen:
     141             :         case ocClose:
     142             :         case ocArrayRowSep:
     143             :         case ocArrayColSep:
     144             :         case ocArrayOpen:
     145             :         case ocArrayClose:
     146       12332 :             eType = svSep;
     147       12332 :             break;
     148             :         default:
     149        8817 :             eType = svByte;
     150        8817 :             sbyte.cByte = 0;
     151        8817 :             sbyte.bHasForceArray = ScParameterClassification::HasForceArray( eOp);
     152             :     }
     153       21169 :     nRefCnt = 0;
     154       21169 : }
     155             : 
     156         108 : void ScRawToken::SetString( const sal_Unicode* pStr )
     157             : {
     158         108 :     eOp   = ocPush;
     159         108 :     eType = svString;
     160         108 :     if ( pStr )
     161             :     {
     162         108 :         xub_StrLen nLen = GetStrLen( pStr ) + 1;
     163         108 :         if( nLen > MAXSTRLEN )
     164           0 :             nLen = MAXSTRLEN;
     165         108 :         memcpy( cStr, pStr, GetStrLenBytes( nLen ) );
     166         108 :         cStr[ nLen-1 ] = 0;
     167             :     }
     168             :     else
     169           0 :         cStr[0] = 0;
     170         108 :     nRefCnt = 0;
     171         108 : }
     172             : 
     173         377 : void ScRawToken::SetSingleReference( const ScSingleRefData& rRef )
     174             : {
     175         377 :     eOp       = ocPush;
     176         377 :     eType     = svSingleRef;
     177             :     aRef.Ref1 =
     178         377 :     aRef.Ref2 = rRef;
     179         377 :     nRefCnt   = 0;
     180         377 : }
     181             : 
     182         181 : void ScRawToken::SetDoubleReference( const ScComplexRefData& rRef )
     183             : {
     184         181 :     eOp   = ocPush;
     185         181 :     eType = svDoubleRef;
     186         181 :     aRef  = rRef;
     187         181 :     nRefCnt = 0;
     188         181 : }
     189             : 
     190         435 : void ScRawToken::SetDouble(double rVal)
     191             : {
     192         435 :     eOp   = ocPush;
     193         435 :     eType = svDouble;
     194         435 :     nValue = rVal;
     195         435 :     nRefCnt = 0;
     196         435 : }
     197             : 
     198           0 : void ScRawToken::SetErrorConstant( sal_uInt16 nErr )
     199             : {
     200           0 :     eOp   = ocPush;
     201           0 :     eType = svError;
     202           0 :     nError = nErr;
     203           0 :     nRefCnt = 0;
     204           0 : }
     205             : 
     206          39 : void ScRawToken::SetName(bool bGlobal, sal_uInt16 nIndex)
     207             : {
     208          39 :     eOp = ocName;
     209          39 :     eType = svIndex;
     210          39 :     nRefCnt = 0;
     211             : 
     212          39 :     name.bGlobal = bGlobal;
     213          39 :     name.nIndex = nIndex;
     214          39 : }
     215             : 
     216          23 : void ScRawToken::SetExternalSingleRef( sal_uInt16 nFileId, const String& rTabName, const ScSingleRefData& rRef )
     217             : {
     218          23 :     eOp = ocPush;
     219          23 :     eType = svExternalSingleRef;
     220          23 :     nRefCnt = 0;
     221             : 
     222          23 :     extref.nFileId = nFileId;
     223             :     extref.aRef.Ref1 =
     224          23 :     extref.aRef.Ref2 = rRef;
     225             : 
     226          23 :     xub_StrLen n = rTabName.Len();
     227          23 :     memcpy(extref.cTabName, rTabName.GetBuffer(), n*sizeof(sal_Unicode));
     228          23 :     extref.cTabName[n] = 0;
     229          23 : }
     230             : 
     231           6 : void ScRawToken::SetExternalDoubleRef( sal_uInt16 nFileId, const String& rTabName, const ScComplexRefData& rRef )
     232             : {
     233           6 :     eOp = ocPush;
     234           6 :     eType = svExternalDoubleRef;
     235           6 :     nRefCnt = 0;
     236             : 
     237           6 :     extref.nFileId = nFileId;
     238           6 :     extref.aRef = rRef;
     239             : 
     240           6 :     xub_StrLen n = rTabName.Len();
     241           6 :     memcpy(extref.cTabName, rTabName.GetBuffer(), n*sizeof(sal_Unicode));
     242           6 :     extref.cTabName[n] = 0;
     243           6 : }
     244             : 
     245           0 : void ScRawToken::SetExternalName( sal_uInt16 nFileId, const String& rName )
     246             : {
     247           0 :     eOp = ocPush;
     248           0 :     eType = svExternalName;
     249           0 :     nRefCnt = 0;
     250             : 
     251           0 :     extname.nFileId = nFileId;
     252             : 
     253           0 :     xub_StrLen n = rName.Len();
     254           0 :     memcpy(extname.cName, rName.GetBuffer(), n*sizeof(sal_Unicode));
     255           0 :     extname.cName[n] = 0;
     256           0 : }
     257             : 
     258             : 
     259             : 
     260           0 : void ScRawToken::SetExternal( const sal_Unicode* pStr )
     261             : {
     262           0 :     eOp   = ocExternal;
     263           0 :     eType = svExternal;
     264           0 :     xub_StrLen nLen = GetStrLen( pStr ) + 1;
     265           0 :     if( nLen >= MAXSTRLEN )
     266           0 :         nLen = MAXSTRLEN-1;
     267             :     // Platz fuer Byte-Parameter lassen!
     268           0 :     memcpy( cStr+1, pStr, GetStrLenBytes( nLen ) );
     269           0 :     cStr[ nLen+1 ] = 0;
     270           0 :     nRefCnt = 0;
     271           0 : }
     272             : 
     273             : 
     274         446 : bool ScRawToken::IsValidReference() const
     275             : {
     276         446 :     switch (eType)
     277             :     {
     278             :         case svSingleRef:
     279         284 :             return aRef.Ref1.Valid();
     280             :         case svDoubleRef:
     281         133 :             return aRef.Valid();
     282             :         case svExternalSingleRef:
     283             :         case svExternalDoubleRef:
     284          29 :             return true;
     285             :         default:
     286             :             ;   // nothing
     287             :     }
     288           0 :     return false;
     289             : }
     290             : 
     291             : 
     292           3 : sal_uInt16 ScRawToken::sbyteOffset()
     293             : {
     294             :     // offset of sbyte in ScRawToken
     295             :     // offsetof(ScRawToken, sbyte) gives a warning with gcc, because ScRawToken is no POD
     296             : 
     297           3 :     ScRawToken aToken;
     298           3 :     return static_cast<sal_uInt16>( reinterpret_cast<char*>(&aToken.sbyte) - reinterpret_cast<char*>(&aToken) );
     299             : }
     300             : 
     301        3291 : ScRawToken* ScRawToken::Clone() const
     302             : {
     303             :     ScRawToken* p;
     304        3291 :     if ( eType == svDouble )
     305             :     {
     306         435 :         p = (ScRawToken*) new ScDoubleRawToken;
     307         435 :         p->eOp = eOp;
     308         435 :         p->eType = eType;
     309         435 :         p->nValue = nValue;
     310             :     }
     311             :     else
     312             :     {
     313        2856 :         static sal_uInt16 nOffset = sbyteOffset();     // offset of sbyte
     314        2856 :         sal_uInt16 n = nOffset;
     315             : 
     316        2856 :         switch( eType )
     317             :         {
     318        1433 :             case svSep:         break;
     319         670 :             case svByte:        n += sizeof(ScRawToken::sbyte); break;
     320           0 :             case svDouble:      n += sizeof(double); break;
     321           0 :             case svError:       n += sizeof(nError); break;
     322         108 :             case svString:      n = sal::static_int_cast<sal_uInt16>( n + GetStrLenBytes( cStr ) + GetStrLenBytes( 1 ) ); break;
     323             :             case svSingleRef:
     324         558 :             case svDoubleRef:   n += sizeof(aRef); break;
     325           0 :             case svMatrix:      n += sizeof(ScMatrix*); break;
     326          39 :             case svIndex:       n += sizeof(name); break;
     327          19 :             case svJump:        n += nJump[ 0 ] * 2 + 2; break;
     328           0 :             case svExternal:    n = sal::static_int_cast<sal_uInt16>( n + GetStrLenBytes( cStr+1 ) + GetStrLenBytes( 2 ) ); break;
     329             : 
     330             :             // external references
     331             :             case svExternalSingleRef:
     332          29 :             case svExternalDoubleRef: n += sizeof(extref); break;
     333           0 :             case svExternalName:      n += sizeof(extname); break;
     334             :             default:
     335             :             {
     336             :                 OSL_TRACE( "unknown ScRawToken::Clone() type %d", int(eType));
     337             :             }
     338             :         }
     339        2856 :         p = (ScRawToken*) new sal_uInt8[ n ];
     340        2856 :         memcpy( p, this, n * sizeof(sal_uInt8) );
     341             :     }
     342        3291 :     p->nRefCnt = 0;
     343        3291 :     p->bRaw = false;
     344        3291 :     return p;
     345             : }
     346             : 
     347             : 
     348       22338 : FormulaToken* ScRawToken::CreateToken() const
     349             : {
     350             : #if OSL_DEBUG_LEVEL > 1
     351             : #define IF_NOT_OPCODE_ERROR(o,c) if (eOp!=o) OSL_TRACE( #c "::ctor: OpCode %d lost, converted to " #o "; maybe inherit from FormulaToken instead!", int(eOp))
     352             : #else
     353             : #define IF_NOT_OPCODE_ERROR(o,c)
     354             : #endif
     355       22338 :     switch ( GetType() )
     356             :     {
     357             :         case svByte :
     358        8817 :             return new FormulaByteToken( eOp, sbyte.cByte, sbyte.bHasForceArray );
     359             :         case svDouble :
     360             :             IF_NOT_OPCODE_ERROR( ocPush, FormulaDoubleToken);
     361         435 :             return new FormulaDoubleToken( nValue );
     362             :         case svString :
     363         108 :             if (eOp == ocPush)
     364         101 :                 return new FormulaStringToken( rtl::OUString( cStr ) );
     365             :             else
     366           7 :                 return new FormulaStringOpToken( eOp, rtl::OUString( cStr ) );
     367             :         case svSingleRef :
     368         377 :             if (eOp == ocPush)
     369         377 :                 return new ScSingleRefToken( aRef.Ref1 );
     370             :             else
     371           0 :                 return new ScSingleRefToken( aRef.Ref1, eOp );
     372             :         case svDoubleRef :
     373         181 :             if (eOp == ocPush)
     374         181 :                 return new ScDoubleRefToken( aRef );
     375             :             else
     376           0 :                 return new ScDoubleRefToken( aRef, eOp );
     377             :         case svMatrix :
     378             :             IF_NOT_OPCODE_ERROR( ocPush, ScMatrixToken);
     379           0 :             return new ScMatrixToken( pMat );
     380             :         case svIndex :
     381          39 :             return new FormulaIndexToken( eOp, name.nIndex, name.bGlobal);
     382             :         case svExternalSingleRef:
     383             :             {
     384          23 :                 rtl::OUString aTabName(extref.cTabName);
     385          23 :                 return new ScExternalSingleRefToken(extref.nFileId, aTabName, extref.aRef.Ref1);
     386             :             }
     387             :         case svExternalDoubleRef:
     388             :             {
     389           6 :                 rtl::OUString aTabName(extref.cTabName);
     390           6 :                 return new ScExternalDoubleRefToken(extref.nFileId, aTabName, extref.aRef);
     391             :             }
     392             :         case svExternalName:
     393             :             {
     394           0 :                 rtl::OUString aName(extname.cName);
     395           0 :                 return new ScExternalNameToken( extname.nFileId, aName );
     396             :             }
     397             :         case svJump :
     398          20 :             return new FormulaJumpToken( eOp, (short*) nJump );
     399             :         case svExternal :
     400           0 :             return new FormulaExternalToken( eOp, sbyte.cByte, rtl::OUString( cStr+1 ) );
     401             :         case svFAP :
     402           0 :             return new FormulaFAPToken( eOp, sbyte.cByte, NULL );
     403             :         case svMissing :
     404             :             IF_NOT_OPCODE_ERROR( ocMissing, FormulaMissingToken);
     405           0 :             return new FormulaMissingToken;
     406             :         case svSep :
     407       12332 :             return new FormulaToken( svSep,eOp );
     408             :         case svError :
     409           0 :             return new FormulaErrorToken( nError );
     410             :         case svUnknown :
     411           0 :             return new FormulaUnknownToken( eOp );
     412             :         default:
     413             :             {
     414             :                 OSL_TRACE( "unknown ScRawToken::CreateToken() type %d", int(GetType()));
     415           0 :                 return new FormulaUnknownToken( ocBad );
     416             :             }
     417             :     }
     418             : #undef IF_NOT_OPCODE_ERROR
     419             : }
     420             : 
     421             : 
     422        3291 : void ScRawToken::Delete()
     423             : {
     424        3291 :     if ( bRaw )
     425           0 :         delete this;                            // FixedMemPool ScRawToken
     426             :     else
     427             :     {   // created per Clone
     428        3291 :         switch ( eType )
     429             :         {
     430             :             case svDouble :
     431         435 :                 delete (ScDoubleRawToken*) this;    // FixedMemPool ScDoubleRawToken
     432         435 :             break;
     433             :             default:
     434        2856 :                 delete [] (sal_uInt8*) this;
     435             :         }
     436             :     }
     437        3291 : }
     438             : 
     439             : 
     440             : // --- class ScToken --------------------------------------------------------
     441             : 
     442           0 : static ScSingleRefData lcl_ScToken_InitSingleRef()
     443             : {
     444             :     ScSingleRefData aRef;
     445           0 :     aRef.InitAddress( ScAddress() );
     446           0 :     return aRef;
     447             : }
     448             : 
     449           0 : static ScComplexRefData lcl_ScToken_InitDoubleRef()
     450             : {
     451             :     ScComplexRefData aRef;
     452           0 :     aRef.Ref1 = lcl_ScToken_InitSingleRef();
     453           0 :     aRef.Ref2 = aRef.Ref1;
     454           0 :     return aRef;
     455             : }
     456             : 
     457        7820 : ScToken::~ScToken()
     458             : {
     459        7820 : }
     460             : 
     461             : //  TextEqual: if same formula entered (for optimization in sort)
     462           0 : bool ScToken::TextEqual( const FormulaToken& _rToken ) const
     463             : {
     464           0 :     if ( eType == svSingleRef || eType == svDoubleRef )
     465             :     {
     466             :         //  in relative Refs only compare relative parts
     467             : 
     468           0 :         if ( eType != _rToken.GetType() || GetOpCode() != _rToken.GetOpCode() )
     469           0 :             return false;
     470             : 
     471           0 :         const ScToken& rToken = static_cast<const ScToken&>(_rToken);
     472             :         ScComplexRefData aTemp1;
     473           0 :         if ( eType == svSingleRef )
     474             :         {
     475           0 :             aTemp1.Ref1 = GetSingleRef();
     476           0 :             aTemp1.Ref2 = aTemp1.Ref1;
     477             :         }
     478             :         else
     479           0 :             aTemp1 = GetDoubleRef();
     480             : 
     481             :         ScComplexRefData aTemp2;
     482           0 :         if ( rToken.eType == svSingleRef )
     483             :         {
     484           0 :             aTemp2.Ref1 = rToken.GetSingleRef();
     485           0 :             aTemp2.Ref2 = aTemp2.Ref1;
     486             :         }
     487             :         else
     488           0 :             aTemp2 = rToken.GetDoubleRef();
     489             : 
     490           0 :         ScAddress aPos;
     491           0 :         aTemp1.SmartRelAbs(aPos);
     492           0 :         aTemp2.SmartRelAbs(aPos);
     493             : 
     494             :         //  memcmp doesn't work because of the alignment byte after bFlags.
     495             :         //  After SmartRelAbs only absolute parts have to be compared.
     496             :         return aTemp1.Ref1.nCol   == aTemp2.Ref1.nCol   &&
     497             :                aTemp1.Ref1.nRow   == aTemp2.Ref1.nRow   &&
     498             :                aTemp1.Ref1.nTab   == aTemp2.Ref1.nTab   &&
     499             :                aTemp1.Ref1.bFlags == aTemp2.Ref1.bFlags &&
     500             :                aTemp1.Ref2.nCol   == aTemp2.Ref2.nCol   &&
     501             :                aTemp1.Ref2.nRow   == aTemp2.Ref2.nRow   &&
     502             :                aTemp1.Ref2.nTab   == aTemp2.Ref2.nTab   &&
     503           0 :                aTemp1.Ref2.bFlags == aTemp2.Ref2.bFlags;
     504             :     }
     505             :     else
     506           0 :         return *this == _rToken;     // else normal operator==
     507             : }
     508             : 
     509             : 
     510           0 : bool ScToken::Is3DRef() const
     511             : {
     512           0 :     switch ( eType )
     513             :     {
     514             :         case svDoubleRef :
     515           0 :             if ( GetSingleRef2().IsFlag3D() )
     516           0 :                 return true;
     517             :         //! fallthru
     518             :         case svSingleRef :
     519           0 :             if ( GetSingleRef().IsFlag3D() )
     520           0 :                 return true;
     521           0 :             break;
     522             :         default:
     523             :         {
     524             :             // added to avoid warnings
     525             :         }
     526             :     }
     527           0 :     return false;
     528             : }
     529             : 
     530           0 : FormulaTokenRef ScToken::ExtendRangeReference( FormulaToken & rTok1, FormulaToken & rTok2,
     531             :         const ScAddress & rPos, bool bReuseDoubleRef )
     532             : {
     533             : 
     534             :     StackVar sv1, sv2;
     535             :     // Doing a RangeOp with RefList is probably utter nonsense, but Xcl
     536             :     // supports it, so do we.
     537           0 :     if (((sv1 = rTok1.GetType()) != svSingleRef && sv1 != svDoubleRef && sv1 != svRefList &&
     538             :             sv1 != svExternalSingleRef && sv1 != svExternalDoubleRef ) ||
     539             :         ((sv2 = rTok2.GetType()) != svSingleRef && sv2 != svDoubleRef && sv2 != svRefList))
     540           0 :         return NULL;
     541             : 
     542           0 :     ScToken *p1 = static_cast<ScToken*>(&rTok1);
     543           0 :     ScToken *p2 = static_cast<ScToken*>(&rTok2);
     544             : 
     545           0 :     ScTokenRef xRes;
     546           0 :     bool bExternal = (sv1 == svExternalSingleRef);
     547           0 :     if ((sv1 == svSingleRef || bExternal) && sv2 == svSingleRef)
     548             :     {
     549             :         // Range references like Sheet1.A1:A2 are generalized and built by
     550             :         // first creating a DoubleRef from the first SingleRef, effectively
     551             :         // generating Sheet1.A1:A1, and then extending that with A2 as if
     552             :         // Sheet1.A1:A1:A2 was encountered, so the mechanisms to adjust the
     553             :         // references apply as well.
     554             : 
     555             :         /* Given the current structure of external references an external
     556             :          * reference can only be extended if the second reference does not
     557             :          * point to a different sheet. 'file'#Sheet1.A1:A2 is ok,
     558             :          * 'file'#Sheet1.A1:Sheet2.A2 is not. Since we can't determine from a
     559             :          * svSingleRef whether the sheet would be different from the one given
     560             :          * in the external reference, we have to bail out if there is any sheet
     561             :          * specified. NOTE: Xcl does handle external 3D references as in
     562             :          * '[file]Sheet1:Sheet2'!A1:A2
     563             :          *
     564             :          * FIXME: For OOo syntax be smart and remember an external singleref
     565             :          * encountered and if followed by ocRange and singleref, create an
     566             :          * external singleref for the second singleref. Both could then be
     567             :          * merged here. For Xcl syntax already parse an external range
     568             :          * reference entirely, cumbersome. */
     569             : 
     570           0 :         const ScSingleRefData& rRef2 = p2->GetSingleRef();
     571           0 :         if (bExternal && rRef2.IsFlag3D())
     572           0 :             return NULL;
     573             : 
     574             :         ScComplexRefData aRef;
     575           0 :         aRef.Ref1 = aRef.Ref2 = p1->GetSingleRef();
     576           0 :         aRef.Ref2.SetFlag3D( false);
     577           0 :         aRef.Extend( rRef2, rPos);
     578           0 :         if (bExternal)
     579           0 :             xRes = new ScExternalDoubleRefToken( p1->GetIndex(), p1->GetString(), aRef);
     580             :         else
     581           0 :             xRes = new ScDoubleRefToken( aRef);
     582             :     }
     583             :     else
     584             :     {
     585           0 :         bExternal |= (sv1 == svExternalDoubleRef);
     586           0 :         const ScRefList* pRefList = NULL;
     587           0 :         if (sv1 == svDoubleRef)
     588             :         {
     589           0 :             xRes = (bReuseDoubleRef && p1->GetRef() == 1 ? p1 : static_cast<ScToken*>(p1->Clone()));
     590           0 :             sv1 = svUnknown;    // mark as handled
     591             :         }
     592           0 :         else if (sv2 == svDoubleRef)
     593             :         {
     594           0 :             xRes = (bReuseDoubleRef && p2->GetRef() == 1 ? p2 : static_cast<ScToken*>(p2->Clone()));
     595           0 :             sv2 = svUnknown;    // mark as handled
     596             :         }
     597           0 :         else if (sv1 == svRefList)
     598           0 :             pRefList = p1->GetRefList();
     599           0 :         else if (sv2 == svRefList)
     600           0 :             pRefList = p2->GetRefList();
     601           0 :         if (pRefList)
     602             :         {
     603           0 :             if (!pRefList->size())
     604           0 :                 return NULL;
     605           0 :             if (bExternal)
     606           0 :                 return NULL;    // external reference list not possible
     607           0 :             xRes = new ScDoubleRefToken( (*pRefList)[0] );
     608             :         }
     609           0 :         if (!xRes)
     610           0 :             return NULL;    // shouldn't happen..
     611           0 :         StackVar sv[2] = { sv1, sv2 };
     612           0 :         ScToken* pt[2] = { p1, p2 };
     613           0 :         ScComplexRefData& rRef = xRes->GetDoubleRef();
     614           0 :         for (size_t i=0; i<2; ++i)
     615             :         {
     616           0 :             switch (sv[i])
     617             :             {
     618             :                 case svSingleRef:
     619           0 :                     rRef.Extend( pt[i]->GetSingleRef(), rPos);
     620           0 :                     break;
     621             :                 case svDoubleRef:
     622           0 :                     rRef.Extend( pt[i]->GetDoubleRef(), rPos);
     623           0 :                     break;
     624             :                 case svRefList:
     625             :                     {
     626           0 :                         const ScRefList* p = pt[i]->GetRefList();
     627           0 :                         if (!p->size())
     628           0 :                             return NULL;
     629           0 :                         ScRefList::const_iterator it( p->begin());
     630           0 :                         ScRefList::const_iterator end( p->end());
     631           0 :                         for ( ; it != end; ++it)
     632             :                         {
     633           0 :                             rRef.Extend( *it, rPos);
     634             :                         }
     635             :                     }
     636           0 :                     break;
     637             :                 case svExternalSingleRef:
     638           0 :                     if (rRef.Ref1.IsFlag3D() || rRef.Ref2.IsFlag3D())
     639           0 :                         return NULL;    // no other sheets with external refs
     640             :                     else
     641           0 :                         rRef.Extend( pt[i]->GetSingleRef(), rPos);
     642           0 :                     break;
     643             :                 case svExternalDoubleRef:
     644           0 :                     if (rRef.Ref1.IsFlag3D() || rRef.Ref2.IsFlag3D())
     645           0 :                         return NULL;    // no other sheets with external refs
     646             :                     else
     647           0 :                         rRef.Extend( pt[i]->GetDoubleRef(), rPos);
     648           0 :                     break;
     649             :                 default:
     650             :                     ;   // nothing, prevent compiler warning
     651             :             }
     652             :         }
     653             :     }
     654           0 :     return FormulaTokenRef(xRes.get());
     655             : }
     656             : 
     657           0 : const ScSingleRefData& ScToken::GetSingleRef() const
     658             : {
     659             :     OSL_FAIL( "ScToken::GetSingleRef: virtual dummy called" );
     660           0 :     static ScSingleRefData aDummySingleRef = lcl_ScToken_InitSingleRef();
     661           0 :     return aDummySingleRef;
     662             : }
     663             : 
     664           0 : ScSingleRefData& ScToken::GetSingleRef()
     665             : {
     666             :     OSL_FAIL( "ScToken::GetSingleRef: virtual dummy called" );
     667           0 :     static ScSingleRefData aDummySingleRef = lcl_ScToken_InitSingleRef();
     668           0 :     return aDummySingleRef;
     669             : }
     670             : 
     671           0 : const ScComplexRefData& ScToken::GetDoubleRef() const
     672             : {
     673             :     OSL_FAIL( "ScToken::GetDoubleRef: virtual dummy called" );
     674           0 :     static ScComplexRefData aDummyDoubleRef = lcl_ScToken_InitDoubleRef();
     675           0 :     return aDummyDoubleRef;
     676             : }
     677             : 
     678           0 : ScComplexRefData& ScToken::GetDoubleRef()
     679             : {
     680             :     OSL_FAIL( "ScToken::GetDoubleRef: virtual dummy called" );
     681           0 :     static ScComplexRefData aDummyDoubleRef = lcl_ScToken_InitDoubleRef();
     682           0 :     return aDummyDoubleRef;
     683             : }
     684             : 
     685           0 : const ScSingleRefData& ScToken::GetSingleRef2() const
     686             : {
     687             :     OSL_FAIL( "ScToken::GetSingleRef2: virtual dummy called" );
     688           0 :     static ScSingleRefData aDummySingleRef = lcl_ScToken_InitSingleRef();
     689           0 :     return aDummySingleRef;
     690             : }
     691             : 
     692           0 : ScSingleRefData& ScToken::GetSingleRef2()
     693             : {
     694             :     OSL_FAIL( "ScToken::GetSingleRef2: virtual dummy called" );
     695           0 :     static ScSingleRefData aDummySingleRef = lcl_ScToken_InitSingleRef();
     696           0 :     return aDummySingleRef;
     697             : }
     698             : 
     699           0 : void ScToken::CalcAbsIfRel( const ScAddress& /* rPos */ )
     700             : {
     701             :     OSL_FAIL( "ScToken::CalcAbsIfRel: virtual dummy called" );
     702           0 : }
     703             : 
     704           0 : void ScToken::CalcRelFromAbs( const ScAddress& /* rPos */ )
     705             : {
     706             :     OSL_FAIL( "ScToken::CalcRelFromAbs: virtual dummy called" );
     707           0 : }
     708             : 
     709           0 : const ScMatrix* ScToken::GetMatrix() const
     710             : {
     711             :     OSL_FAIL( "ScToken::GetMatrix: virtual dummy called" );
     712           0 :     return NULL;
     713             : }
     714             : 
     715           0 : ScMatrix* ScToken::GetMatrix()
     716             : {
     717             :     OSL_FAIL( "ScToken::GetMatrix: virtual dummy called" );
     718           0 :     return NULL;
     719             : }
     720             : 
     721             : 
     722           0 : ScJumpMatrix* ScToken::GetJumpMatrix() const
     723             : {
     724             :     OSL_FAIL( "ScToken::GetJumpMatrix: virtual dummy called" );
     725           0 :     return NULL;
     726             : }
     727           0 : const ScRefList* ScToken::GetRefList() const
     728             : {
     729             :     OSL_FAIL( "ScToken::GetRefList: virtual dummy called" );
     730           0 :     return NULL;
     731             : }
     732             : 
     733           0 : ScRefList* ScToken::GetRefList()
     734             : {
     735             :     OSL_FAIL( "ScToken::GetRefList: virtual dummy called" );
     736           0 :     return NULL;
     737             : }
     738             : // ==========================================================================
     739             : // real implementations of virtual functions
     740             : // --------------------------------------------------------------------------
     741             : 
     742             : 
     743             : 
     744             : 
     745          70 : const ScSingleRefData&    ScSingleRefToken::GetSingleRef() const  { return aSingleRef; }
     746       11748 : ScSingleRefData&          ScSingleRefToken::GetSingleRef()        { return aSingleRef; }
     747          37 : void                    ScSingleRefToken::CalcAbsIfRel( const ScAddress& rPos )
     748          37 :                             { aSingleRef.CalcAbsIfRel( rPos ); }
     749          62 : void                    ScSingleRefToken::CalcRelFromAbs( const ScAddress& rPos )
     750          62 :                             { aSingleRef.CalcRelFromAbs( rPos ); }
     751           2 : bool ScSingleRefToken::operator==( const FormulaToken& r ) const
     752             : {
     753           2 :     return FormulaToken::operator==( r ) && aSingleRef == static_cast<const ScToken&>(r).GetSingleRef();
     754             : }
     755             : 
     756             : 
     757          14 : const ScSingleRefData&    ScDoubleRefToken::GetSingleRef() const  { return aDoubleRef.Ref1; }
     758        2319 : ScSingleRefData&          ScDoubleRefToken::GetSingleRef()        { return aDoubleRef.Ref1; }
     759         201 : const ScComplexRefData&     ScDoubleRefToken::GetDoubleRef() const  { return aDoubleRef; }
     760        3431 : ScComplexRefData&           ScDoubleRefToken::GetDoubleRef()        { return aDoubleRef; }
     761          14 : const ScSingleRefData&    ScDoubleRefToken::GetSingleRef2() const { return aDoubleRef.Ref2; }
     762           0 : ScSingleRefData&          ScDoubleRefToken::GetSingleRef2()       { return aDoubleRef.Ref2; }
     763        2279 : void                    ScDoubleRefToken::CalcAbsIfRel( const ScAddress& rPos )
     764        2279 :                             { aDoubleRef.CalcAbsIfRel( rPos ); }
     765           0 : void                    ScDoubleRefToken::CalcRelFromAbs( const ScAddress& rPos )
     766           0 :                             { aDoubleRef.CalcRelFromAbs( rPos ); }
     767           0 : bool ScDoubleRefToken::operator==( const FormulaToken& r ) const
     768             : {
     769           0 :     return FormulaToken::operator==( r ) && aDoubleRef == static_cast<const ScToken&>(r).GetDoubleRef();
     770             : }
     771             : 
     772             : 
     773           0 : const ScRefList*        ScRefListToken::GetRefList() const  { return &aRefList; }
     774           0 :       ScRefList*        ScRefListToken::GetRefList()        { return &aRefList; }
     775           0 : void                    ScRefListToken::CalcAbsIfRel( const ScAddress& rPos )
     776             : {
     777           0 :     for (ScRefList::iterator it( aRefList.begin()); it != aRefList.end(); ++it)
     778           0 :         (*it).CalcAbsIfRel( rPos);
     779           0 : }
     780           0 : void                    ScRefListToken::CalcRelFromAbs( const ScAddress& rPos )
     781             : {
     782           0 :     for (ScRefList::iterator it( aRefList.begin()); it != aRefList.end(); ++it)
     783           0 :         (*it).CalcRelFromAbs( rPos);
     784           0 : }
     785           0 : bool ScRefListToken::operator==( const FormulaToken& r ) const
     786             : {
     787           0 :     return FormulaToken::operator==( r ) && &aRefList == static_cast<const ScToken&>(r).GetRefList();
     788             : }
     789             : 
     790             : 
     791           2 : const ScMatrix* ScMatrixToken::GetMatrix() const        { return pMatrix.get(); }
     792          44 : ScMatrix*       ScMatrixToken::GetMatrix()              { return pMatrix.get(); }
     793           0 : bool ScMatrixToken::operator==( const FormulaToken& r ) const
     794             : {
     795           0 :     return FormulaToken::operator==( r ) && pMatrix == static_cast<const ScToken&>(r).GetMatrix();
     796             : }
     797             : 
     798             : // ============================================================================
     799             : 
     800          26 : ScExternalSingleRefToken::ScExternalSingleRefToken( sal_uInt16 nFileId, const String& rTabName, const ScSingleRefData& r ) :
     801             :     ScToken( svExternalSingleRef, ocPush),
     802             :     mnFileId(nFileId),
     803             :     maTabName(rTabName),
     804          26 :     maSingleRef(r)
     805             : {
     806          26 : }
     807             : 
     808           0 : ScExternalSingleRefToken::ScExternalSingleRefToken( const ScExternalSingleRefToken& r ) :
     809             :     ScToken(r),
     810             :     mnFileId(r.mnFileId),
     811             :     maTabName(r.maTabName),
     812           0 :     maSingleRef(r.maSingleRef)
     813             : {
     814           0 : }
     815             : 
     816           0 : ScExternalSingleRefToken::~ScExternalSingleRefToken()
     817             : {
     818           0 : }
     819             : 
     820          26 : sal_uInt16 ScExternalSingleRefToken::GetIndex() const
     821             : {
     822          26 :     return mnFileId;
     823             : }
     824             : 
     825          26 : const String& ScExternalSingleRefToken::GetString() const
     826             : {
     827          26 :     return maTabName;
     828             : }
     829             : 
     830           0 : const ScSingleRefData& ScExternalSingleRefToken::GetSingleRef() const
     831             : {
     832           0 :     return maSingleRef;
     833             : }
     834             : 
     835          55 : ScSingleRefData& ScExternalSingleRefToken::GetSingleRef()
     836             : {
     837          55 :     return maSingleRef;
     838             : }
     839             : 
     840           0 : void ScExternalSingleRefToken::CalcAbsIfRel( const ScAddress& rPos )
     841             : {
     842           0 :     maSingleRef.CalcAbsIfRel( rPos );
     843           0 : }
     844             : 
     845           0 : void ScExternalSingleRefToken::CalcRelFromAbs( const ScAddress& rPos )
     846             : {
     847           0 :     maSingleRef.CalcRelFromAbs( rPos );
     848           0 : }
     849             : 
     850           0 : bool ScExternalSingleRefToken::operator ==( const FormulaToken& r ) const
     851             : {
     852           0 :     if (!FormulaToken::operator==(r))
     853           0 :         return false;
     854             : 
     855           0 :     if (mnFileId != r.GetIndex())
     856           0 :         return false;
     857             : 
     858           0 :     if (maTabName != r.GetString())
     859           0 :         return false;
     860             : 
     861           0 :     return maSingleRef == static_cast<const ScToken&>(r).GetSingleRef();
     862             : }
     863             : 
     864             : // ============================================================================
     865             : 
     866           6 : ScExternalDoubleRefToken::ScExternalDoubleRefToken( sal_uInt16 nFileId, const String& rTabName, const ScComplexRefData& r ) :
     867             :     ScToken( svExternalDoubleRef, ocPush),
     868             :     mnFileId(nFileId),
     869             :     maTabName(rTabName),
     870           6 :     maDoubleRef(r)
     871             : {
     872           6 : }
     873             : 
     874           0 : ScExternalDoubleRefToken::ScExternalDoubleRefToken( const ScExternalDoubleRefToken& r ) :
     875             :     ScToken(r),
     876             :     mnFileId(r.mnFileId),
     877             :     maTabName(r.maTabName),
     878           0 :     maDoubleRef(r.maDoubleRef)
     879             : {
     880           0 : }
     881             : 
     882          12 : ScExternalDoubleRefToken::~ScExternalDoubleRefToken()
     883             : {
     884          12 : }
     885             : 
     886           6 : sal_uInt16 ScExternalDoubleRefToken::GetIndex() const
     887             : {
     888           6 :     return mnFileId;
     889             : }
     890             : 
     891           6 : const String& ScExternalDoubleRefToken::GetString() const
     892             : {
     893           6 :     return maTabName;
     894             : }
     895             : 
     896           0 : const ScSingleRefData& ScExternalDoubleRefToken::GetSingleRef() const
     897             : {
     898           0 :     return maDoubleRef.Ref1;
     899             : }
     900             : 
     901          12 : ScSingleRefData& ScExternalDoubleRefToken::GetSingleRef()
     902             : {
     903          12 :     return maDoubleRef.Ref1;
     904             : }
     905             : 
     906           0 : const ScSingleRefData& ScExternalDoubleRefToken::GetSingleRef2() const
     907             : {
     908           0 :     return maDoubleRef.Ref2;
     909             : }
     910             : 
     911           0 : ScSingleRefData& ScExternalDoubleRefToken::GetSingleRef2()
     912             : {
     913           0 :     return maDoubleRef.Ref2;
     914             : }
     915             : 
     916           0 : const ScComplexRefData& ScExternalDoubleRefToken::GetDoubleRef() const
     917             : {
     918           0 :     return maDoubleRef;
     919             : }
     920             : 
     921           6 : ScComplexRefData& ScExternalDoubleRefToken::GetDoubleRef()
     922             : {
     923           6 :     return maDoubleRef;
     924             : }
     925             : 
     926           0 : void ScExternalDoubleRefToken::CalcAbsIfRel( const ScAddress& rPos )
     927             : {
     928           0 :     maDoubleRef.CalcAbsIfRel( rPos );
     929           0 : }
     930             : 
     931           0 : void ScExternalDoubleRefToken::CalcRelFromAbs( const ScAddress& rPos )
     932             : {
     933           0 :     maDoubleRef.CalcRelFromAbs( rPos );
     934           0 : }
     935             : 
     936           0 : bool ScExternalDoubleRefToken::operator ==( const FormulaToken& r ) const
     937             : {
     938           0 :     if (!ScToken::operator==(r))
     939           0 :         return false;
     940             : 
     941           0 :     if (mnFileId != r.GetIndex())
     942           0 :         return false;
     943             : 
     944           0 :     if (maTabName != r.GetString())
     945           0 :         return false;
     946             : 
     947           0 :     return maDoubleRef == static_cast<const ScToken&>(r).GetDoubleRef();
     948             : }
     949             : 
     950             : // ============================================================================
     951             : 
     952           0 : ScExternalNameToken::ScExternalNameToken( sal_uInt16 nFileId, const String& rName ) :
     953             :     ScToken( svExternalName, ocPush),
     954             :     mnFileId(nFileId),
     955           0 :     maName(rName)
     956             : {
     957           0 : }
     958             : 
     959           0 : ScExternalNameToken::ScExternalNameToken( const ScExternalNameToken& r ) :
     960             :     ScToken(r),
     961             :     mnFileId(r.mnFileId),
     962           0 :     maName(r.maName)
     963             : {
     964           0 : }
     965             : 
     966           0 : ScExternalNameToken::~ScExternalNameToken() {}
     967             : 
     968           0 : sal_uInt16 ScExternalNameToken::GetIndex() const
     969             : {
     970           0 :     return mnFileId;
     971             : }
     972             : 
     973           0 : const String& ScExternalNameToken::GetString() const
     974             : {
     975           0 :     return maName;
     976             : }
     977             : 
     978           0 : bool ScExternalNameToken::operator==( const FormulaToken& r ) const
     979             : {
     980           0 :     if ( !FormulaToken::operator==(r) )
     981           0 :         return false;
     982             : 
     983           0 :     if (mnFileId != r.GetIndex())
     984           0 :         return false;
     985             : 
     986           0 :     xub_StrLen nLen = maName.Len();
     987           0 :     const String& rName = r.GetString();
     988           0 :     if (nLen != rName.Len())
     989           0 :         return false;
     990             : 
     991           0 :     const sal_Unicode* p1 = maName.GetBuffer();
     992           0 :     const sal_Unicode* p2 = rName.GetBuffer();
     993           0 :     for (xub_StrLen j = 0; j < nLen; ++j)
     994             :     {
     995           0 :         if (p1[j] != p2[j])
     996           0 :             return false;
     997             :     }
     998           0 :     return true;
     999             : }
    1000             : 
    1001             : // ============================================================================
    1002             : 
    1003           0 : ScJumpMatrix* ScJumpMatrixToken::GetJumpMatrix() const  { return pJumpMatrix; }
    1004           0 : bool ScJumpMatrixToken::operator==( const FormulaToken& r ) const
    1005             : {
    1006           0 :     return FormulaToken::operator==( r ) && pJumpMatrix == static_cast<const ScToken&>(r).GetJumpMatrix();
    1007             : }
    1008           0 : ScJumpMatrixToken::~ScJumpMatrixToken()
    1009             : {
    1010           0 :     delete pJumpMatrix;
    1011           0 : }
    1012             : 
    1013           0 : double          ScEmptyCellToken::GetDouble() const     { return 0.0; }
    1014           0 : const String &  ScEmptyCellToken::GetString() const
    1015             : {
    1016           0 :     static  String              aDummyString;
    1017           0 :     return aDummyString;
    1018             : }
    1019           0 : bool ScEmptyCellToken::operator==( const FormulaToken& r ) const
    1020             : {
    1021           0 :     return FormulaToken::operator==( r ) &&
    1022           0 :         bInherited == static_cast< const ScEmptyCellToken & >(r).IsInherited() &&
    1023           0 :         bDisplayedAsString == static_cast< const ScEmptyCellToken & >(r).IsDisplayedAsString();
    1024             : }
    1025             : 
    1026             : 
    1027           0 : double          ScMatrixCellResultToken::GetDouble() const  { return xUpperLeft->GetDouble(); }
    1028           0 : const String &  ScMatrixCellResultToken::GetString() const  { return xUpperLeft->GetString(); }
    1029          90 : const ScMatrix* ScMatrixCellResultToken::GetMatrix() const  { return xMatrix.get(); }
    1030             : // Non-const GetMatrix() is private and unused but must be implemented to
    1031             : // satisfy vtable linkage.
    1032           0 : ScMatrix* ScMatrixCellResultToken::GetMatrix()
    1033             : {
    1034           0 :     return const_cast<ScMatrix*>(xMatrix.get());
    1035             : }
    1036           0 : bool ScMatrixCellResultToken::operator==( const FormulaToken& r ) const
    1037             : {
    1038           0 :     return FormulaToken::operator==( r ) &&
    1039           0 :         xUpperLeft == static_cast<const ScMatrixCellResultToken &>(r).xUpperLeft &&
    1040           0 :         xMatrix == static_cast<const ScMatrixCellResultToken &>(r).xMatrix;
    1041             : }
    1042             : 
    1043             : 
    1044           0 : bool ScMatrixFormulaCellToken::operator==( const FormulaToken& r ) const
    1045             : {
    1046           0 :     const ScMatrixFormulaCellToken* p = dynamic_cast<const ScMatrixFormulaCellToken*>(&r);
    1047           0 :     return p && ScMatrixCellResultToken::operator==( r ) &&
    1048           0 :         nCols == p->nCols && nRows == p->nRows;
    1049             : }
    1050           2 : void ScMatrixFormulaCellToken::Assign( const formula::FormulaToken& r )
    1051             : {
    1052           2 :     if (this == &r)
    1053           2 :         return;
    1054           2 :     const ScMatrixCellResultToken* p = dynamic_cast<const ScMatrixCellResultToken*>(&r);
    1055           2 :     if (p)
    1056           0 :         ScMatrixCellResultToken::Assign( *p);
    1057             :     else
    1058             :     {
    1059             :         OSL_ENSURE( r.GetType() != svMatrix, "ScMatrixFormulaCellToken::operator=: assigning ScMatrixToken to ScMatrixFormulaCellToken is not proper, use ScMatrixCellResultToken instead");
    1060           2 :         if (r.GetType() == svMatrix)
    1061             :         {
    1062           0 :             xUpperLeft = NULL;
    1063           0 :             xMatrix = static_cast<const ScToken&>(r).GetMatrix();
    1064             :         }
    1065             :         else
    1066             :         {
    1067           2 :             xUpperLeft = &r;
    1068           2 :             xMatrix = NULL;
    1069             :         }
    1070             :     }
    1071             : }
    1072          17 : void ScMatrixFormulaCellToken::SetUpperLeftDouble( double f )
    1073             : {
    1074          17 :     switch (GetUpperLeftType())
    1075             :     {
    1076             :         case svDouble:
    1077           0 :             const_cast<FormulaToken*>(xUpperLeft.get())->GetDoubleAsReference() = f;
    1078           0 :             break;
    1079             :         case svUnknown:
    1080          17 :             if (!xUpperLeft)
    1081             :             {
    1082          17 :                 xUpperLeft = new FormulaDoubleToken( f);
    1083          17 :                 break;
    1084             :             }
    1085             :             // fall thru
    1086             :         default:
    1087             :             {
    1088             :                 OSL_FAIL("ScMatrixFormulaCellToken::SetUpperLeftDouble: not modifying unhandled token type");
    1089             :             }
    1090             :     }
    1091          17 : }
    1092             : 
    1093             : 
    1094           0 : double          ScHybridCellToken::GetDouble() const    { return fDouble; }
    1095          52 : const String &  ScHybridCellToken::GetString() const    { return aString; }
    1096           0 : bool ScHybridCellToken::operator==( const FormulaToken& r ) const
    1097             : {
    1098           0 :     return FormulaToken::operator==( r ) &&
    1099           0 :         fDouble == r.GetDouble() && aString == r.GetString() &&
    1100           0 :         aFormula == static_cast<const ScHybridCellToken &>(r).GetFormula();
    1101             : }
    1102             : 
    1103             : 
    1104             : 
    1105             : 
    1106             : //////////////////////////////////////////////////////////////////////////
    1107             : 
    1108         125 : bool ScTokenArray::AddFormulaToken(const com::sun::star::sheet::FormulaToken& _aToken,formula::ExternalReferenceHelper* _pRef)
    1109             : {
    1110         125 :     bool bError = FormulaTokenArray::AddFormulaToken(_aToken,_pRef);
    1111         125 :     if ( bError )
    1112             :     {
    1113          45 :         bError = false;
    1114          45 :         const OpCode eOpCode = static_cast<OpCode>(_aToken.OpCode);      //! assuming equal values for the moment
    1115             : 
    1116          45 :         const uno::TypeClass eClass = _aToken.Data.getValueTypeClass();
    1117          45 :         switch ( eClass )
    1118             :         {
    1119             :             case uno::TypeClass_STRUCT:
    1120             :                 {
    1121          44 :                     uno::Type aType = _aToken.Data.getValueType();
    1122          44 :                     if ( aType.equals( cppu::UnoType<sheet::SingleReference>::get() ) )
    1123             :                     {
    1124             :                         ScSingleRefData aSingleRef;
    1125          16 :                         sheet::SingleReference aApiRef;
    1126          16 :                         _aToken.Data >>= aApiRef;
    1127          16 :                         lcl_SingleRefToCalc( aSingleRef, aApiRef );
    1128          16 :                         if ( eOpCode == ocPush )
    1129          16 :                             AddSingleReference( aSingleRef );
    1130           0 :                         else if ( eOpCode == ocColRowName )
    1131           0 :                             AddColRowName( aSingleRef );
    1132             :                         else
    1133           0 :                             bError = true;
    1134             :                     }
    1135          28 :                     else if ( aType.equals( cppu::UnoType<sheet::ComplexReference>::get() ) )
    1136             :                     {
    1137             :                         ScComplexRefData aComplRef;
    1138          11 :                         sheet::ComplexReference aApiRef;
    1139          11 :                         _aToken.Data >>= aApiRef;
    1140          11 :                         lcl_SingleRefToCalc( aComplRef.Ref1, aApiRef.Reference1 );
    1141          11 :                         lcl_SingleRefToCalc( aComplRef.Ref2, aApiRef.Reference2 );
    1142             : 
    1143          11 :                         if ( eOpCode == ocPush )
    1144          11 :                             AddDoubleReference( aComplRef );
    1145             :                         else
    1146           0 :                             bError = true;
    1147             :                     }
    1148          17 :                     else if ( aType.equals( cppu::UnoType<sheet::NameToken>::get() ) )
    1149             :                     {
    1150          17 :                         sheet::NameToken aTokenData;
    1151          17 :                         _aToken.Data >>= aTokenData;
    1152          17 :                         if ( eOpCode == ocName )
    1153          17 :                             AddRangeName(aTokenData.Index, aTokenData.Global);
    1154           0 :                         else if (eOpCode == ocDBArea)
    1155           0 :                             AddDBRange(aTokenData.Index);
    1156             :                         else
    1157           0 :                             bError = true;
    1158             :                     }
    1159           0 :                     else if ( aType.equals( cppu::UnoType<sheet::ExternalReference>::get() ) )
    1160             :                     {
    1161           0 :                         sheet::ExternalReference aApiExtRef;
    1162           0 :                         if( (eOpCode == ocPush) && (_aToken.Data >>= aApiExtRef) && (0 <= aApiExtRef.Index) && (aApiExtRef.Index <= SAL_MAX_UINT16) )
    1163             :                         {
    1164           0 :                             sal_uInt16 nFileId = static_cast< sal_uInt16 >( aApiExtRef.Index );
    1165           0 :                             sheet::SingleReference aApiSRef;
    1166           0 :                             sheet::ComplexReference aApiCRef;
    1167           0 :                             ::rtl::OUString aName;
    1168           0 :                             if( aApiExtRef.Reference >>= aApiSRef )
    1169             :                             {
    1170             :                                 // try to resolve cache index to sheet name
    1171           0 :                                 size_t nCacheId = static_cast< size_t >( aApiSRef.Sheet );
    1172           0 :                                 String aTabName = _pRef->getCacheTableName( nFileId, nCacheId );
    1173           0 :                                 if( aTabName.Len() > 0 )
    1174             :                                 {
    1175             :                                     ScSingleRefData aSingleRef;
    1176             :                                     // convert column/row settings, set sheet index to absolute
    1177           0 :                                     lcl_ExternalRefToCalc( aSingleRef, aApiSRef );
    1178           0 :                                     AddExternalSingleReference( nFileId, aTabName, aSingleRef );
    1179             :                                 }
    1180             :                                 else
    1181           0 :                                     bError = true;
    1182             :                             }
    1183           0 :                             else if( aApiExtRef.Reference >>= aApiCRef )
    1184             :                             {
    1185             :                                 // try to resolve cache index to sheet name.
    1186           0 :                                 size_t nCacheId = static_cast< size_t >( aApiCRef.Reference1.Sheet );
    1187           0 :                                 String aTabName = _pRef->getCacheTableName( nFileId, nCacheId );
    1188           0 :                                 if( aTabName.Len() > 0 )
    1189             :                                 {
    1190             :                                     ScComplexRefData aComplRef;
    1191             :                                     // convert column/row settings, set sheet index to absolute
    1192           0 :                                     lcl_ExternalRefToCalc( aComplRef.Ref1, aApiCRef.Reference1 );
    1193           0 :                                     lcl_ExternalRefToCalc( aComplRef.Ref2, aApiCRef.Reference2 );
    1194             :                                     // NOTE: This assumes that cached sheets are in consecutive order!
    1195           0 :                                     aComplRef.Ref2.nTab = aComplRef.Ref1.nTab + static_cast<SCsTAB>(aApiCRef.Reference2.Sheet - aApiCRef.Reference1.Sheet);
    1196           0 :                                     AddExternalDoubleReference( nFileId, aTabName, aComplRef );
    1197             :                                 }
    1198             :                                 else
    1199           0 :                                     bError = true;
    1200             :                             }
    1201           0 :                             else if( aApiExtRef.Reference >>= aName )
    1202             :                             {
    1203           0 :                                 if( !aName.isEmpty() )
    1204           0 :                                     AddExternalName( nFileId, aName );
    1205             :                                 else
    1206           0 :                                     bError = true;
    1207             :                             }
    1208             :                             else
    1209           0 :                                 bError = true;
    1210             :                         }
    1211             :                         else
    1212           0 :                             bError = true;
    1213             :                     }
    1214             :                     else
    1215           0 :                         bError = true;      // unknown struct
    1216             :                 }
    1217          44 :                 break;
    1218             :             case uno::TypeClass_SEQUENCE:
    1219             :                 {
    1220           1 :                     if ( eOpCode != ocPush )
    1221           0 :                         bError = true;      // not an inline array
    1222           2 :                     else if (!_aToken.Data.getValueType().equals( getCppuType(
    1223           2 :                                     (uno::Sequence< uno::Sequence< uno::Any > > *)0)))
    1224           0 :                         bError = true;      // unexpected sequence type
    1225             :                     else
    1226             :                     {
    1227           1 :                         ScMatrixRef xMat = ScSequenceToMatrix::CreateMixedMatrix( _aToken.Data);
    1228           1 :                         if (xMat)
    1229           1 :                             AddMatrix( xMat);
    1230             :                         else
    1231           0 :                             bError = true;
    1232             :                     }
    1233             :                 }
    1234           1 :                 break;
    1235             :             default:
    1236           0 :                 bError = true;
    1237             :         }
    1238             :     }
    1239         125 :     return bError;
    1240             : }
    1241          55 : bool ScTokenArray::ImplGetReference( ScRange& rRange, bool bValidOnly ) const
    1242             : {
    1243          55 :     bool bIs = false;
    1244          55 :     if ( pCode && nLen == 1 )
    1245             :     {
    1246          55 :         const FormulaToken* pToken = pCode[0];
    1247          55 :         if ( pToken )
    1248             :         {
    1249          55 :             if ( pToken->GetType() == svSingleRef )
    1250             :             {
    1251           5 :                 const ScSingleRefData& rRef = ((const ScSingleRefToken*)pToken)->GetSingleRef();
    1252           5 :                 rRange.aStart = rRange.aEnd = ScAddress( rRef.nCol, rRef.nRow, rRef.nTab );
    1253           5 :                 bIs = !bValidOnly || !rRef.IsDeleted();
    1254             :             }
    1255          50 :             else if ( pToken->GetType() == svDoubleRef )
    1256             :             {
    1257          50 :                 const ScComplexRefData& rCompl = ((const ScDoubleRefToken*)pToken)->GetDoubleRef();
    1258          50 :                 const ScSingleRefData& rRef1 = rCompl.Ref1;
    1259          50 :                 const ScSingleRefData& rRef2 = rCompl.Ref2;
    1260          50 :                 rRange.aStart = ScAddress( rRef1.nCol, rRef1.nRow, rRef1.nTab );
    1261          50 :                 rRange.aEnd   = ScAddress( rRef2.nCol, rRef2.nRow, rRef2.nTab );
    1262          50 :                 bIs = !bValidOnly || (!rRef1.IsDeleted() && !rRef2.IsDeleted());
    1263             :             }
    1264             :         }
    1265             :     }
    1266          55 :     return bIs;
    1267             : }
    1268             : 
    1269          27 : bool ScTokenArray::IsReference( ScRange& rRange ) const
    1270             : {
    1271          27 :     return ImplGetReference( rRange, false );
    1272             : }
    1273             : 
    1274          28 : bool ScTokenArray::IsValidReference( ScRange& rRange ) const
    1275             : {
    1276          28 :     return ImplGetReference( rRange, true );
    1277             : }
    1278             : 
    1279             : ////////////////////////////////////////////////////////////////////////////
    1280             : 
    1281        1742 : ScTokenArray::ScTokenArray()
    1282             : {
    1283        1742 : }
    1284             : 
    1285        3797 : ScTokenArray::ScTokenArray( const ScTokenArray& rArr ) : FormulaTokenArray(rArr)
    1286             : {
    1287        3797 : }
    1288             : 
    1289        9726 : ScTokenArray::~ScTokenArray()
    1290             : {
    1291        9726 : }
    1292             : 
    1293             : 
    1294             : 
    1295           0 : ScTokenArray& ScTokenArray::operator=( const ScTokenArray& rArr )
    1296             : {
    1297           0 :     Clear();
    1298           0 :     Assign( rArr );
    1299           0 :     return *this;
    1300             : }
    1301             : 
    1302         348 : ScTokenArray* ScTokenArray::Clone() const
    1303             : {
    1304         348 :     ScTokenArray* p = new ScTokenArray();
    1305         348 :     p->nLen = nLen;
    1306         348 :     p->nRPN = nRPN;
    1307         348 :     p->nRefs = nRefs;
    1308         348 :     p->nMode = nMode;
    1309         348 :     p->nError = nError;
    1310         348 :     p->bHyperLink = bHyperLink;
    1311             :     FormulaToken** pp;
    1312         348 :     if( nLen )
    1313             :     {
    1314         348 :         pp = p->pCode = new FormulaToken*[ nLen ];
    1315         348 :         memcpy( pp, pCode, nLen * sizeof( ScToken* ) );
    1316        1198 :         for( sal_uInt16 i = 0; i < nLen; i++, pp++ )
    1317             :         {
    1318         850 :             *pp = (*pp)->Clone();
    1319         850 :             (*pp)->IncRef();
    1320             :         }
    1321             :     }
    1322         348 :     if( nRPN )
    1323             :     {
    1324          42 :         pp = p->pRPN = new FormulaToken*[ nRPN ];
    1325          42 :         memcpy( pp, pRPN, nRPN * sizeof( ScToken* ) );
    1326         116 :         for( sal_uInt16 i = 0; i < nRPN; i++, pp++ )
    1327             :         {
    1328          74 :             FormulaToken* t = *pp;
    1329          74 :             if( t->GetRef() > 1 )
    1330             :             {
    1331          66 :                 FormulaToken** p2 = pCode;
    1332          66 :                 sal_uInt16 nIdx = 0xFFFF;
    1333         142 :                 for( sal_uInt16 j = 0; j < nLen; j++, p2++ )
    1334             :                 {
    1335         142 :                     if( *p2 == t )
    1336             :                     {
    1337          66 :                         nIdx = j; break;
    1338             :                     }
    1339             :                 }
    1340          66 :                 if( nIdx == 0xFFFF )
    1341           0 :                     *pp = t->Clone();
    1342             :                 else
    1343          66 :                     *pp = p->pCode[ nIdx ];
    1344             :             }
    1345             :             else
    1346           8 :                 *pp = t->Clone();
    1347          74 :             (*pp)->IncRef();
    1348             :         }
    1349             :     }
    1350         348 :     return p;
    1351             : }
    1352             : 
    1353       19047 : FormulaToken* ScTokenArray::AddRawToken( const ScRawToken& r )
    1354             : {
    1355       19047 :     return Add( r.CreateToken() );
    1356             : }
    1357             : 
    1358             : // Utility function to ensure that there is strict alternation of values and
    1359             : // seperators.
    1360             : static bool
    1361          43 : checkArraySep( bool & bPrevWasSep, bool bNewVal )
    1362             : {
    1363          43 :     bool bResult = (bPrevWasSep == bNewVal);
    1364          43 :     bPrevWasSep = bNewVal;
    1365          43 :     return bResult;
    1366             : }
    1367             : 
    1368           5 : FormulaToken* ScTokenArray::MergeArray( )
    1369             : {
    1370           5 :     int nCol = -1, nRow = 0;
    1371           5 :     int i, nPrevRowSep = -1, nStart = 0;
    1372           5 :     bool bPrevWasSep = false; // top of stack is ocArrayClose
    1373             :     FormulaToken* t;
    1374           5 :     bool bNumeric = false;  // numeric value encountered in current element
    1375             : 
    1376             :     // (1) Iterate from the end to the start to find matrix dims
    1377             :     // and do basic validation.
    1378          53 :     for ( i = nLen ; i-- > nStart ; )
    1379             :     {
    1380          43 :         t = pCode[i];
    1381          43 :         switch ( t->GetOpCode() )
    1382             :         {
    1383             :             case ocPush :
    1384          19 :                 if( checkArraySep( bPrevWasSep, false ) )
    1385             :                 {
    1386           0 :                     return NULL;
    1387             :                 }
    1388             : 
    1389             :                 // no references or nested arrays
    1390          19 :                 if ( t->GetType() != svDouble  && t->GetType() != svString )
    1391             :                 {
    1392           0 :                     return NULL;
    1393             :                 }
    1394          19 :                 bNumeric = (t->GetType() == svDouble);
    1395          19 :             break;
    1396             : 
    1397             :             case ocMissing :
    1398             :             case ocTrue :
    1399             :             case ocFalse :
    1400           0 :                 if( checkArraySep( bPrevWasSep, false ) )
    1401             :                 {
    1402           0 :                     return NULL;
    1403             :                 }
    1404           0 :                 bNumeric = false;
    1405           0 :             break;
    1406             : 
    1407             :             case ocArrayColSep :
    1408             :             case ocSep :
    1409          12 :                 if( checkArraySep( bPrevWasSep, true ) )
    1410             :                 {
    1411           0 :                     return NULL;
    1412             :                 }
    1413          12 :                 bNumeric = false;
    1414          12 :             break;
    1415             : 
    1416             :             case ocArrayClose :
    1417             :                 // not possible with the , but check just in case
    1418             :                 // something changes in the future
    1419           5 :                 if( i != (nLen-1))
    1420             :                 {
    1421           0 :                     return NULL;
    1422             :                 }
    1423             : 
    1424           5 :                 if( checkArraySep( bPrevWasSep, true ) )
    1425             :                 {
    1426           0 :                     return NULL;
    1427             :                 }
    1428             : 
    1429           5 :                 nPrevRowSep = i;
    1430           5 :                 bNumeric = false;
    1431           5 :             break;
    1432             : 
    1433             :             case ocArrayOpen :
    1434           5 :                 nStart = i; // stop iteration
    1435             :                 // fall through to ArrayRowSep
    1436             : 
    1437             :             case ocArrayRowSep :
    1438           7 :                 if( checkArraySep( bPrevWasSep, true ) )
    1439             :                 {
    1440           0 :                     return NULL;
    1441             :                 }
    1442             : 
    1443           7 :                 if( nPrevRowSep < 0 ||              // missing ocArrayClose
    1444             :                     ((nPrevRowSep - i) % 2) == 1)   // no complex elements
    1445             :                 {
    1446           0 :                     return NULL;
    1447             :                 }
    1448             : 
    1449           7 :                 if( nCol < 0 )
    1450             :                 {
    1451           5 :                     nCol = (nPrevRowSep - i) / 2;
    1452             :                 }
    1453           2 :                 else if( (nPrevRowSep - i)/2 != nCol)   // irregular array
    1454             :                 {
    1455           0 :                     return NULL;
    1456             :                 }
    1457             : 
    1458           7 :                 nPrevRowSep = i;
    1459           7 :                 nRow++;
    1460           7 :                 bNumeric = false;
    1461           7 :             break;
    1462             : 
    1463             :             case ocNegSub :
    1464             :             case ocAdd :
    1465             :                 // negation or unary plus must precede numeric value
    1466           0 :                 if( !bNumeric )
    1467             :                 {
    1468           0 :                     return NULL;
    1469             :                 }
    1470           0 :                 --nPrevRowSep;      // shorten this row by 1
    1471           0 :                 bNumeric = false;   // one level only, no --42
    1472           0 :             break;
    1473             : 
    1474             :             case ocSpaces :
    1475             :                 // ignore spaces
    1476           0 :                 --nPrevRowSep;      // shorten this row by 1
    1477           0 :             break;
    1478             : 
    1479             :             default :
    1480             :                 // no functions or operators
    1481           0 :                 return NULL;
    1482             :         }
    1483             :     }
    1484           5 :     if( nCol <= 0 || nRow <= 0 )
    1485           0 :         return NULL;
    1486             : 
    1487           5 :     int nSign = 1;
    1488           5 :     ScMatrix* pArray = new ScMatrix(nCol, nRow, 0.0);
    1489          48 :     for ( i = nStart, nCol = 0, nRow = 0 ; i < nLen ; i++ )
    1490             :     {
    1491          43 :         t = pCode[i];
    1492             : 
    1493          43 :         switch ( t->GetOpCode() )
    1494             :         {
    1495             :             case ocPush :
    1496          19 :                 if ( t->GetType() == svDouble )
    1497             :                 {
    1498          19 :                     pArray->PutDouble( t->GetDouble() * nSign, nCol, nRow );
    1499          19 :                     nSign = 1;
    1500             :                 }
    1501           0 :                 else if ( t->GetType() == svString )
    1502             :                 {
    1503           0 :                     pArray->PutString( t->GetString(), nCol, nRow );
    1504             :                 }
    1505          19 :             break;
    1506             : 
    1507             :             case ocMissing :
    1508           0 :                 pArray->PutEmpty( nCol, nRow );
    1509           0 :             break;
    1510             : 
    1511             :             case ocTrue :
    1512           0 :                 pArray->PutBoolean( true, nCol, nRow );
    1513           0 :             break;
    1514             : 
    1515             :             case ocFalse :
    1516           0 :                 pArray->PutBoolean( false, nCol, nRow );
    1517           0 :             break;
    1518             : 
    1519             :             case ocArrayColSep :
    1520             :             case ocSep :
    1521          12 :                 nCol++;
    1522          12 :             break;
    1523             : 
    1524             :             case ocArrayRowSep :
    1525           2 :                 nRow++; nCol = 0;
    1526           2 :             break;
    1527             : 
    1528             :             case ocNegSub :
    1529           0 :                 nSign = -nSign;
    1530           0 :             break;
    1531             : 
    1532             :             default :
    1533          10 :                 break;
    1534             :         }
    1535          43 :         pCode[i] = NULL;
    1536          43 :         t->DecRef();
    1537             :     }
    1538           5 :     nLen = sal_uInt16( nStart );
    1539           5 :     return AddMatrix( pArray );
    1540             : }
    1541             : 
    1542             : 
    1543           0 : FormulaToken* ScTokenArray::MergeRangeReference( const ScAddress & rPos )
    1544             : {
    1545           0 :     if (!pCode || !nLen)
    1546           0 :         return NULL;
    1547           0 :     sal_uInt16 nIdx = nLen;
    1548             :     FormulaToken *p1, *p2, *p3;      // ref, ocRange, ref
    1549             :     // The actual types are checked in ExtendRangeReference().
    1550           0 :     if (((p3 = PeekPrev(nIdx)) != 0) &&
    1551           0 :             (((p2 = PeekPrev(nIdx)) != 0) && p2->GetOpCode() == ocRange) &&
    1552           0 :             ((p1 = PeekPrev(nIdx)) != 0))
    1553             :     {
    1554           0 :         FormulaTokenRef p = ScToken::ExtendRangeReference( *p1, *p3, rPos, true);
    1555           0 :         if (p)
    1556             :         {
    1557           0 :             p->IncRef();
    1558           0 :             p1->DecRef();
    1559           0 :             p2->DecRef();
    1560           0 :             p3->DecRef();
    1561           0 :             nLen -= 2;
    1562           0 :             pCode[ nLen-1 ] = p.get();
    1563           0 :             nRefs--;
    1564           0 :         }
    1565             :     }
    1566           0 :     return pCode[ nLen-1 ];
    1567             : }
    1568             : 
    1569       19013 : FormulaToken* ScTokenArray::AddOpCode( OpCode e )
    1570             : {
    1571       19013 :     ScRawToken t;
    1572       19013 :     t.SetOpCode( e );
    1573       19013 :     return AddRawToken( t );
    1574             : }
    1575             : 
    1576        4439 : FormulaToken* ScTokenArray::AddSingleReference( const ScSingleRefData& rRef )
    1577             : {
    1578        4439 :     return Add( new ScSingleRefToken( rRef ) );
    1579             : }
    1580             : 
    1581          28 : FormulaToken* ScTokenArray::AddMatrixSingleReference( const ScSingleRefData& rRef )
    1582             : {
    1583          28 :     return Add( new ScSingleRefToken( rRef, ocMatRef ) );
    1584             : }
    1585             : 
    1586        2151 : FormulaToken* ScTokenArray::AddDoubleReference( const ScComplexRefData& rRef )
    1587             : {
    1588        2151 :     return Add( new ScDoubleRefToken( rRef ) );
    1589             : }
    1590             : 
    1591           7 : FormulaToken* ScTokenArray::AddMatrix( const ScMatrixRef& p )
    1592             : {
    1593           7 :     return Add( new ScMatrixToken( p ) );
    1594             : }
    1595             : 
    1596         111 : FormulaToken* ScTokenArray::AddRangeName( sal_uInt16 n, bool bGlobal )
    1597             : {
    1598         111 :     return Add( new FormulaIndexToken( ocName, n, bGlobal));
    1599             : }
    1600             : 
    1601           0 : FormulaToken* ScTokenArray::AddDBRange( sal_uInt16 n )
    1602             : {
    1603           0 :     return Add( new FormulaIndexToken( ocDBArea, n));
    1604             : }
    1605             : 
    1606           0 : FormulaToken* ScTokenArray::AddExternalName( sal_uInt16 nFileId, const String& rName )
    1607             : {
    1608           0 :     return Add( new ScExternalNameToken(nFileId, rName) );
    1609             : }
    1610             : 
    1611           0 : FormulaToken* ScTokenArray::AddExternalSingleReference( sal_uInt16 nFileId, const String& rTabName, const ScSingleRefData& rRef )
    1612             : {
    1613           0 :     return Add( new ScExternalSingleRefToken(nFileId, rTabName, rRef) );
    1614             : }
    1615             : 
    1616           0 : FormulaToken* ScTokenArray::AddExternalDoubleReference( sal_uInt16 nFileId, const String& rTabName, const ScComplexRefData& rRef )
    1617             : {
    1618           0 :     return Add( new ScExternalDoubleRefToken(nFileId, rTabName, rRef) );
    1619             : }
    1620             : 
    1621           0 : FormulaToken* ScTokenArray::AddColRowName( const ScSingleRefData& rRef )
    1622             : {
    1623           0 :     return Add( new ScSingleRefToken( rRef, ocColRowName ) );
    1624             : }
    1625             : 
    1626           0 : bool ScTokenArray::GetAdjacentExtendOfOuterFuncRefs( SCCOLROW& nExtend,
    1627             :         const ScAddress& rPos, ScDirection eDir )
    1628             : {
    1629           0 :     SCCOL nCol = 0;
    1630           0 :     SCROW nRow = 0;
    1631           0 :     switch ( eDir )
    1632             :     {
    1633             :         case DIR_BOTTOM :
    1634           0 :             if ( rPos.Row() < MAXROW )
    1635           0 :                 nRow = (nExtend = rPos.Row()) + 1;
    1636             :             else
    1637           0 :                 return false;
    1638           0 :         break;
    1639             :         case DIR_RIGHT :
    1640           0 :             if ( rPos.Col() < MAXCOL )
    1641           0 :                 nCol = static_cast<SCCOL>(nExtend = rPos.Col()) + 1;
    1642             :             else
    1643           0 :                 return false;
    1644           0 :         break;
    1645             :         case DIR_TOP :
    1646           0 :             if ( rPos.Row() > 0 )
    1647           0 :                 nRow = (nExtend = rPos.Row()) - 1;
    1648             :             else
    1649           0 :                 return false;
    1650           0 :         break;
    1651             :         case DIR_LEFT :
    1652           0 :             if ( rPos.Col() > 0 )
    1653           0 :                 nCol = static_cast<SCCOL>(nExtend = rPos.Col()) - 1;
    1654             :             else
    1655           0 :                 return false;
    1656           0 :         break;
    1657             :         default:
    1658             :             OSL_FAIL( "unknown Direction" );
    1659           0 :             return false;
    1660             :     }
    1661           0 :     if ( pRPN && nRPN )
    1662             :     {
    1663           0 :         FormulaToken* t = pRPN[nRPN-1];
    1664           0 :         if ( t->GetType() == svByte )
    1665             :         {
    1666           0 :             sal_uInt8 nParamCount = t->GetByte();
    1667           0 :             if ( nParamCount && nRPN > nParamCount )
    1668             :             {
    1669           0 :                 bool bRet = false;
    1670           0 :                 sal_uInt16 nParam = nRPN - nParamCount - 1;
    1671           0 :                 for ( ; nParam < nRPN-1; nParam++ )
    1672             :                 {
    1673           0 :                     FormulaToken* p = pRPN[nParam];
    1674           0 :                     switch ( p->GetType() )
    1675             :                     {
    1676             :                         case svSingleRef :
    1677             :                         {
    1678           0 :                             ScSingleRefData& rRef = static_cast<ScToken*>(p)->GetSingleRef();
    1679           0 :                             rRef.CalcAbsIfRel( rPos );
    1680           0 :                             switch ( eDir )
    1681             :                             {
    1682             :                                 case DIR_BOTTOM :
    1683           0 :                                     if ( rRef.nRow == nRow
    1684             :                                             && rRef.nRow > nExtend )
    1685             :                                     {
    1686           0 :                                         nExtend = rRef.nRow;
    1687           0 :                                         bRet = true;
    1688             :                                     }
    1689           0 :                                 break;
    1690             :                                 case DIR_RIGHT :
    1691           0 :                                     if ( rRef.nCol == nCol
    1692             :                                             && static_cast<SCCOLROW>(rRef.nCol)
    1693             :                                             > nExtend )
    1694             :                                     {
    1695           0 :                                         nExtend = rRef.nCol;
    1696           0 :                                         bRet = true;
    1697             :                                     }
    1698           0 :                                 break;
    1699             :                                 case DIR_TOP :
    1700           0 :                                     if ( rRef.nRow == nRow
    1701             :                                             && rRef.nRow < nExtend )
    1702             :                                     {
    1703           0 :                                         nExtend = rRef.nRow;
    1704           0 :                                         bRet = true;
    1705             :                                     }
    1706           0 :                                 break;
    1707             :                                 case DIR_LEFT :
    1708           0 :                                     if ( rRef.nCol == nCol
    1709             :                                             && static_cast<SCCOLROW>(rRef.nCol)
    1710             :                                             < nExtend )
    1711             :                                     {
    1712           0 :                                         nExtend = rRef.nCol;
    1713           0 :                                         bRet = true;
    1714             :                                     }
    1715           0 :                                 break;
    1716             :                             }
    1717             :                         }
    1718           0 :                         break;
    1719             :                         case svDoubleRef :
    1720             :                         {
    1721           0 :                             ScComplexRefData& rRef = static_cast<ScToken*>(p)->GetDoubleRef();
    1722           0 :                             rRef.CalcAbsIfRel( rPos );
    1723           0 :                             switch ( eDir )
    1724             :                             {
    1725             :                                 case DIR_BOTTOM :
    1726           0 :                                     if ( rRef.Ref1.nRow == nRow
    1727             :                                             && rRef.Ref2.nRow > nExtend )
    1728             :                                     {
    1729           0 :                                         nExtend = rRef.Ref2.nRow;
    1730           0 :                                         bRet = true;
    1731             :                                     }
    1732           0 :                                 break;
    1733             :                                 case DIR_RIGHT :
    1734           0 :                                     if ( rRef.Ref1.nCol == nCol &&
    1735             :                                             static_cast<SCCOLROW>(rRef.Ref2.nCol)
    1736             :                                             > nExtend )
    1737             :                                     {
    1738           0 :                                         nExtend = rRef.Ref2.nCol;
    1739           0 :                                         bRet = true;
    1740             :                                     }
    1741           0 :                                 break;
    1742             :                                 case DIR_TOP :
    1743           0 :                                     if ( rRef.Ref2.nRow == nRow
    1744             :                                             && rRef.Ref1.nRow < nExtend )
    1745             :                                     {
    1746           0 :                                         nExtend = rRef.Ref1.nRow;
    1747           0 :                                         bRet = true;
    1748             :                                     }
    1749           0 :                                 break;
    1750             :                                 case DIR_LEFT :
    1751           0 :                                     if ( rRef.Ref2.nCol == nCol &&
    1752             :                                             static_cast<SCCOLROW>(rRef.Ref1.nCol)
    1753             :                                             < nExtend )
    1754             :                                     {
    1755           0 :                                         nExtend = rRef.Ref1.nCol;
    1756           0 :                                         bRet = true;
    1757             :                                     }
    1758           0 :                                 break;
    1759             :                             }
    1760             :                         }
    1761           0 :                         break;
    1762             :                         default:
    1763             :                         {
    1764             :                             // added to avoid warnings
    1765             :                         }
    1766             :                     } // switch
    1767             :                 } // for
    1768           0 :                 return bRet;
    1769             :             }
    1770             :         }
    1771             :     }
    1772           0 :     return false;
    1773             : }
    1774             : 
    1775             : 
    1776           0 : void ScTokenArray::ReadjustRelative3DReferences( const ScAddress& rOldPos,
    1777             :         const ScAddress& rNewPos )
    1778             : {
    1779           0 :     for ( sal_uInt16 j=0; j<nLen; ++j )
    1780             :     {
    1781           0 :         switch ( pCode[j]->GetType() )
    1782             :         {
    1783             :             case svDoubleRef :
    1784             :             {
    1785           0 :                 ScSingleRefData& rRef2 = static_cast<ScToken*>(pCode[j])->GetSingleRef2();
    1786             :                 // Also adjust if the reference is of the form Sheet1.A2:A3
    1787           0 :                 if ( rRef2.IsFlag3D() || static_cast<ScToken*>(pCode[j])->GetSingleRef().IsFlag3D() )
    1788             :                 {
    1789           0 :                     rRef2.CalcAbsIfRel( rOldPos );
    1790           0 :                     rRef2.CalcRelFromAbs( rNewPos );
    1791             :                 }
    1792             :             }
    1793             :             //! fallthru
    1794             :             case svSingleRef :
    1795             :             {
    1796           0 :                 ScSingleRefData& rRef1 = static_cast<ScToken*>(pCode[j])->GetSingleRef();
    1797           0 :                 if ( rRef1.IsFlag3D() )
    1798             :                 {
    1799           0 :                     rRef1.CalcAbsIfRel( rOldPos );
    1800           0 :                     rRef1.CalcRelFromAbs( rNewPos );
    1801             :                 }
    1802             :             }
    1803           0 :             break;
    1804             :             default:
    1805             :             {
    1806             :                 // added to avoid warnings
    1807             :             }
    1808             :         }
    1809             :     }
    1810           0 : }
    1811             : 
    1812             : namespace {
    1813             : 
    1814           3 : void GetExternalTableData(const ScDocument* pOldDoc, const ScDocument* pNewDoc, const SCTAB nTab, rtl::OUString& rTabName, sal_uInt16& rFileId)
    1815             : {
    1816           3 :     rtl::OUString aFileName = pOldDoc->GetFileURL();;
    1817           3 :     rFileId = pNewDoc->GetExternalRefManager()->getExternalFileId(aFileName);
    1818           3 :     rTabName = pOldDoc->GetCopyTabName(nTab);
    1819           3 :     if (rTabName.isEmpty())
    1820           0 :         pOldDoc->GetName(nTab, rTabName);
    1821           3 : }
    1822             : 
    1823          11 : bool IsInCopyRange( const ScRange& rRange, const ScDocument* pClipDoc )
    1824             : {
    1825          11 :     ScClipParam& rClipParam = const_cast<ScDocument*>(pClipDoc)->GetClipParam();
    1826          11 :     return rClipParam.maRanges.In(rRange);
    1827             : }
    1828             : 
    1829          20 : bool SkipReference(ScToken* pToken, const ScAddress& rPos, const ScDocument* pOldDoc, bool bRangeName, bool bCheckCopyArea)
    1830             : {
    1831          20 :     ScRange aRange;
    1832             : 
    1833          20 :     pToken->CalcAbsIfRel(rPos);
    1834          20 :     if (!ScRefTokenHelper::getRangeFromToken(aRange, pToken))
    1835           0 :         return true;
    1836             : 
    1837          20 :     if (bRangeName && aRange.aStart.Tab() == rPos.Tab())
    1838             :     {
    1839           0 :         switch (pToken->GetType())
    1840             :         {
    1841             :             case svDoubleRef:
    1842             :                 {
    1843           0 :                     ScSingleRefData& rRef = pToken->GetSingleRef2();
    1844           0 :                     if (rRef.IsColRel() || rRef.IsRowRel())
    1845           0 :                         return true;
    1846             :                 } // fall through
    1847             :             case svSingleRef:
    1848             :                 {
    1849           0 :                     ScSingleRefData& rRef = pToken->GetSingleRef();
    1850           0 :                     if (rRef.IsColRel() || rRef.IsRowRel())
    1851           0 :                         return true;
    1852             :                 }
    1853           0 :                 break;
    1854             :             default:
    1855           0 :                 break;
    1856             :         }
    1857             :     }
    1858             : 
    1859          20 :     if (bCheckCopyArea && IsInCopyRange(aRange, pOldDoc))
    1860           6 :         return true;
    1861             : 
    1862          14 :     return false;
    1863             : }
    1864             : 
    1865           3 : void AdjustSingleRefData( ScSingleRefData& rRef, const ScAddress& rOldPos, const ScAddress& rNewPos)
    1866             : {
    1867           3 :     SCsCOL nCols = rNewPos.Col() - rOldPos.Col();
    1868           3 :     SCsROW nRows = rNewPos.Row() - rOldPos.Row();
    1869           3 :     SCsTAB nTabs = rNewPos.Tab() - rOldPos.Tab();
    1870             : 
    1871           3 :     if (!rRef.IsColRel())
    1872           3 :         rRef.nCol += nCols;
    1873             : 
    1874           3 :     if (!rRef.IsRowRel())
    1875           3 :         rRef.nRow += nRows;
    1876             : 
    1877           3 :     if (!rRef.IsTabRel())
    1878           1 :         rRef.nTab += nTabs;
    1879           3 : }
    1880             : 
    1881             : }
    1882             : 
    1883           6 : void ScTokenArray::ReadjustAbsolute3DReferences( const ScDocument* pOldDoc, const ScDocument* pNewDoc, const ScAddress& rPos, bool bRangeName )
    1884             : {
    1885          17 :     for ( sal_uInt16 j=0; j<nLen; ++j )
    1886             :     {
    1887          11 :         switch ( pCode[j]->GetType() )
    1888             :         {
    1889             :             case svDoubleRef :
    1890             :             {
    1891           0 :                 if (SkipReference(static_cast<ScToken*>(pCode[j]), rPos, pOldDoc, bRangeName, true))
    1892           0 :                     continue;
    1893             : 
    1894           0 :                 ScComplexRefData& rRef = static_cast<ScToken*>(pCode[j])->GetDoubleRef();
    1895           0 :                 ScSingleRefData& rRef2 = rRef.Ref2;
    1896           0 :                 ScSingleRefData& rRef1 = rRef.Ref1;
    1897             : 
    1898           0 :                 if ( (rRef2.IsFlag3D() && !rRef2.IsTabRel()) || (rRef1.IsFlag3D() && !rRef1.IsTabRel()) )
    1899             :                 {
    1900           0 :                     rtl::OUString aTabName;
    1901             :                     sal_uInt16 nFileId;
    1902           0 :                     GetExternalTableData(pOldDoc, pNewDoc, rRef1.nTab, aTabName, nFileId);
    1903           0 :                     pCode[j]->DecRef();
    1904           0 :                     ScExternalDoubleRefToken* pToken = new ScExternalDoubleRefToken(nFileId, aTabName, rRef);
    1905           0 :                     pToken->IncRef();
    1906           0 :                     pCode[j] = pToken;
    1907             :                 }
    1908             :             }
    1909           0 :             break;
    1910             :             case svSingleRef :
    1911             :             {
    1912           7 :                 if (SkipReference(static_cast<ScToken*>(pCode[j]), rPos, pOldDoc, bRangeName, true))
    1913           3 :                     continue;
    1914             : 
    1915           4 :                 ScSingleRefData& rRef = static_cast<ScToken*>(pCode[j])->GetSingleRef();
    1916             : 
    1917           4 :                 if ( rRef.IsFlag3D() && !rRef.IsTabRel() )
    1918             :                 {
    1919           3 :                     rtl::OUString aTabName;
    1920             :                     sal_uInt16 nFileId;
    1921           3 :                     GetExternalTableData(pOldDoc, pNewDoc, rRef.nTab, aTabName, nFileId);
    1922             :                     //replace with ScExternalSingleRefToken and adjust references
    1923           3 :                     pCode[j]->DecRef();
    1924           3 :                     ScExternalSingleRefToken* pToken = new ScExternalSingleRefToken(nFileId, aTabName, rRef);
    1925           3 :                     pToken->IncRef();
    1926           3 :                     pCode[j] = pToken;
    1927             :                 }
    1928             :             }
    1929           4 :             break;
    1930             :             default:
    1931             :             {
    1932             :                 // added to avoid warnings
    1933             :             }
    1934             :         }
    1935             :     }
    1936           6 : }
    1937             : 
    1938          14 : void ScTokenArray::AdjustAbsoluteRefs( const ScDocument* pOldDoc, const ScAddress& rOldPos, const ScAddress& rNewPos, bool bRangeName, bool bCheckCopyRange)
    1939             : {
    1940          59 :     for ( sal_uInt16 j=0; j<nLen; ++j )
    1941             :     {
    1942          45 :         switch ( pCode[j]->GetType() )
    1943             :         {
    1944             :             case svDoubleRef :
    1945             :             {
    1946           3 :                 if (!SkipReference(static_cast<ScToken*>(pCode[j]), rOldPos, pOldDoc, false, bCheckCopyRange))
    1947           3 :                     continue;
    1948             : 
    1949           0 :                 ScComplexRefData& rRef = static_cast<ScToken*>(pCode[j])->GetDoubleRef();
    1950           0 :                 ScSingleRefData& rRef2 = rRef.Ref2;
    1951           0 :                 ScSingleRefData& rRef1 = rRef.Ref1;
    1952             : 
    1953             :                 // for range names only adjust if all parts are absolute
    1954           0 :                 if (!bRangeName || !(rRef1.IsColRel() || rRef1.IsRowRel() || rRef1.IsTabRel()))
    1955           0 :                     AdjustSingleRefData( rRef1, rOldPos, rNewPos );
    1956           0 :                 if (!bRangeName || !(rRef2.IsColRel() || rRef2.IsRowRel() || rRef2.IsTabRel()))
    1957           0 :                     AdjustSingleRefData( rRef2, rOldPos, rNewPos );
    1958             : 
    1959             :             }
    1960           0 :             break;
    1961             :             case svSingleRef :
    1962             :             {
    1963          10 :                 if (!SkipReference(static_cast<ScToken*>(pCode[j]), rOldPos, pOldDoc, false, bCheckCopyRange))
    1964           7 :                     continue;
    1965             : 
    1966           3 :                 ScSingleRefData& rRef = static_cast<ScToken*>(pCode[j])->GetSingleRef();
    1967             : 
    1968             :                 // for range names only adjust if all parts are absolute
    1969           3 :                 if (!bRangeName || !(rRef.IsColRel() || rRef.IsRowRel() || rRef.IsTabRel()))
    1970           3 :                     AdjustSingleRefData( rRef, rOldPos, rNewPos );
    1971             : 
    1972             : 
    1973             :             }
    1974           3 :             break;
    1975             :             default:
    1976             :             {
    1977             :                 // added to avoid warnings
    1978             :             }
    1979             :         }
    1980             :     }
    1981          29 : }
    1982             : 
    1983             : 
    1984             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10