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