1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: token.cxx,v $
10 * $Revision: 1.33.32.3 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sc.hxx"
36 // INCLUDE ---------------------------------------------------------------
38 #if STLPORT_VERSION<321
46 #include <tools/mempool.hxx>
47 #include <tools/debug.hxx>
50 #include "tokenarray.hxx"
51 #include "compiler.hxx"
52 #include <formula/compiler.hrc>
53 #include "rechead.hxx"
54 #include "parclass.hxx"
55 #include "jumpmatrix.hxx"
56 #include "rangeseq.hxx"
57 #include "externalrefmgr.hxx"
58 #include "document.hxx"
62 #include <com/sun/star/sheet/ComplexReference.hpp>
63 #include <com/sun/star/sheet/ExternalReference.hpp>
64 #include <com/sun/star/sheet/ReferenceFlags.hpp>
66 using namespace formula
;
67 using namespace com::sun::star
;
71 void lcl_SingleRefToCalc( ScSingleRefData
& rRef
, const sheet::SingleReference
& rAPI
)
75 rRef
.nCol
= static_cast<SCsCOL
>(rAPI
.Column
);
76 rRef
.nRow
= static_cast<SCsROW
>(rAPI
.Row
);
77 rRef
.nTab
= static_cast<SCsTAB
>(rAPI
.Sheet
);
78 rRef
.nRelCol
= static_cast<SCsCOL
>(rAPI
.RelativeColumn
);
79 rRef
.nRelRow
= static_cast<SCsROW
>(rAPI
.RelativeRow
);
80 rRef
.nRelTab
= static_cast<SCsTAB
>(rAPI
.RelativeSheet
);
82 rRef
.SetColRel( ( rAPI
.Flags
& sheet::ReferenceFlags::COLUMN_RELATIVE
) != 0 );
83 rRef
.SetRowRel( ( rAPI
.Flags
& sheet::ReferenceFlags::ROW_RELATIVE
) != 0 );
84 rRef
.SetTabRel( ( rAPI
.Flags
& sheet::ReferenceFlags::SHEET_RELATIVE
) != 0 );
85 rRef
.SetColDeleted( ( rAPI
.Flags
& sheet::ReferenceFlags::COLUMN_DELETED
) != 0 );
86 rRef
.SetRowDeleted( ( rAPI
.Flags
& sheet::ReferenceFlags::ROW_DELETED
) != 0 );
87 rRef
.SetTabDeleted( ( rAPI
.Flags
& sheet::ReferenceFlags::SHEET_DELETED
) != 0 );
88 rRef
.SetFlag3D( ( rAPI
.Flags
& sheet::ReferenceFlags::SHEET_3D
) != 0 );
89 rRef
.SetRelName( ( rAPI
.Flags
& sheet::ReferenceFlags::RELATIVE_NAME
) != 0 );
92 void lcl_ExternalRefToCalc( ScSingleRefData
& rRef
, const sheet::SingleReference
& rAPI
)
96 rRef
.nCol
= static_cast<SCsCOL
>(rAPI
.Column
);
97 rRef
.nRow
= static_cast<SCsROW
>(rAPI
.Row
);
99 rRef
.nRelCol
= static_cast<SCsCOL
>(rAPI
.RelativeColumn
);
100 rRef
.nRelRow
= static_cast<SCsROW
>(rAPI
.RelativeRow
);
103 rRef
.SetColRel( ( rAPI
.Flags
& sheet::ReferenceFlags::COLUMN_RELATIVE
) != 0 );
104 rRef
.SetRowRel( ( rAPI
.Flags
& sheet::ReferenceFlags::ROW_RELATIVE
) != 0 );
105 rRef
.SetTabRel( false ); // sheet index must be absolute for external refs
106 rRef
.SetColDeleted( ( rAPI
.Flags
& sheet::ReferenceFlags::COLUMN_DELETED
) != 0 );
107 rRef
.SetRowDeleted( ( rAPI
.Flags
& sheet::ReferenceFlags::ROW_DELETED
) != 0 );
108 rRef
.SetTabDeleted( false ); // sheet must not be deleted for external refs
109 rRef
.SetFlag3D( ( rAPI
.Flags
& sheet::ReferenceFlags::SHEET_3D
) != 0 );
110 rRef
.SetRelName( false );
115 // ImpTokenIterator wird je Interpreter angelegt, mehrfache auch durch
116 // SubCode via FormulaTokenIterator Push/Pop moeglich
117 IMPL_FIXEDMEMPOOL_NEWDEL( ImpTokenIterator
, 32, 16 )
119 // Align MemPools on 4k boundaries - 64 bytes (4k is a MUST for OS/2)
121 // Since RawTokens are temporary for the compiler, don't align on 4k and waste memory.
122 // ScRawToken size is FixMembers + MAXSTRLEN + ~4 ~= 1036
123 IMPL_FIXEDMEMPOOL_NEWDEL( ScRawToken
, 8, 4 )
124 // Some ScDoubleRawToken, FixMembers + sizeof(double) ~= 16
125 const USHORT nMemPoolDoubleRawToken
= 0x0400 / sizeof(ScDoubleRawToken
);
126 IMPL_FIXEDMEMPOOL_NEWDEL( ScDoubleRawToken
, nMemPoolDoubleRawToken
, nMemPoolDoubleRawToken
)
128 // Need a whole bunch of ScSingleRefToken
129 const USHORT nMemPoolSingleRefToken
= (0x4000 - 64) / sizeof(ScSingleRefToken
);
130 IMPL_FIXEDMEMPOOL_NEWDEL( ScSingleRefToken
, nMemPoolSingleRefToken
, nMemPoolSingleRefToken
)
131 // Need quite a lot of ScDoubleRefToken
132 const USHORT nMemPoolDoubleRefToken
= (0x2000 - 64) / sizeof(ScDoubleRefToken
);
133 IMPL_FIXEDMEMPOOL_NEWDEL( ScDoubleRefToken
, nMemPoolDoubleRefToken
, nMemPoolDoubleRefToken
)
135 // --- helpers --------------------------------------------------------------
137 inline BOOL
lcl_IsReference( OpCode eOp
, StackVar eType
)
140 (eOp
== ocPush
&& (eType
== svSingleRef
|| eType
== svDoubleRef
))
141 || (eOp
== ocColRowNameAuto
&& eType
== svDoubleRef
)
142 || (eOp
== ocColRowName
&& eType
== svSingleRef
)
143 || (eOp
== ocMatRef
&& eType
== svSingleRef
)
148 // --- class ScRawToken -----------------------------------------------------
150 xub_StrLen
ScRawToken::GetStrLen( const sal_Unicode
* pStr
)
154 register const sal_Unicode
* p
= pStr
;
157 return sal::static_int_cast
<xub_StrLen
>( p
- pStr
);
161 void ScRawToken::SetOpCode( OpCode e
)
168 nJump
[ 0 ] = 3; // If, Else, Behind
172 nJump
[ 0 ] = MAXJUMPCOUNT
+1;
189 sbyte
.bHasForceArray
= ScParameterClassification::HasForceArray( eOp
);
194 void ScRawToken::SetString( const sal_Unicode
* pStr
)
200 xub_StrLen nLen
= GetStrLen( pStr
) + 1;
201 if( nLen
> MAXSTRLEN
)
203 memcpy( cStr
, pStr
, GetStrLenBytes( nLen
) );
211 void ScRawToken::SetSingleReference( const ScSingleRefData
& rRef
)
220 void ScRawToken::SetDoubleReference( const ScComplexRefData
& rRef
)
228 void ScRawToken::SetDouble(double rVal
)
236 void ScRawToken::SetName( USHORT n
)
244 void ScRawToken::SetExternalSingleRef( sal_uInt16 nFileId
, const String
& rTabName
, const ScSingleRefData
& rRef
)
247 eType
= svExternalSingleRef
;
250 extref
.nFileId
= nFileId
;
252 extref
.aRef
.Ref2
= rRef
;
254 xub_StrLen n
= rTabName
.Len();
255 memcpy(extref
.cTabName
, rTabName
.GetBuffer(), n
*sizeof(sal_Unicode
));
256 extref
.cTabName
[n
] = 0;
259 void ScRawToken::SetExternalDoubleRef( sal_uInt16 nFileId
, const String
& rTabName
, const ScComplexRefData
& rRef
)
262 eType
= svExternalDoubleRef
;
265 extref
.nFileId
= nFileId
;
268 xub_StrLen n
= rTabName
.Len();
269 memcpy(extref
.cTabName
, rTabName
.GetBuffer(), n
*sizeof(sal_Unicode
));
270 extref
.cTabName
[n
] = 0;
273 void ScRawToken::SetExternalName( sal_uInt16 nFileId
, const String
& rName
)
276 eType
= svExternalName
;
279 extname
.nFileId
= nFileId
;
281 xub_StrLen n
= rName
.Len();
282 memcpy(extname
.cName
, rName
.GetBuffer(), n
*sizeof(sal_Unicode
));
283 extname
.cName
[n
] = 0;
286 //UNUSED2008-05 void ScRawToken::SetInt(int rVal)
288 //UNUSED2008-05 eOp = ocPush;
289 //UNUSED2008-05 eType = svDouble;
290 //UNUSED2008-05 nValue = (double)rVal;
291 //UNUSED2008-05 nRefCnt = 0;
294 //UNUSED2008-05 void ScRawToken::SetMatrix( ScMatrix* p )
296 //UNUSED2008-05 eOp = ocPush;
297 //UNUSED2008-05 eType = svMatrix;
298 //UNUSED2008-05 pMat = p;
299 //UNUSED2008-05 nRefCnt = 0;
302 //UNUSED2008-05 ScComplexRefData& ScRawToken::GetReference()
304 //UNUSED2008-05 DBG_ASSERT( lcl_IsReference( eOp, GetType() ), "GetReference: no Ref" );
305 //UNUSED2008-05 return aRef;
308 //UNUSED2008-05 void ScRawToken::SetReference( ScComplexRefData& rRef )
310 //UNUSED2008-05 DBG_ASSERT( lcl_IsReference( eOp, GetType() ), "SetReference: no Ref" );
311 //UNUSED2008-05 aRef = rRef;
312 //UNUSED2008-05 if( GetType() == svSingleRef )
313 //UNUSED2008-05 aRef.Ref2 = aRef.Ref1;
316 void ScRawToken::SetExternal( const sal_Unicode
* pStr
)
320 xub_StrLen nLen
= GetStrLen( pStr
) + 1;
321 if( nLen
>= MAXSTRLEN
)
323 // Platz fuer Byte-Parameter lassen!
324 memcpy( cStr
+1, pStr
, GetStrLenBytes( nLen
) );
329 USHORT
lcl_ScRawTokenOffset()
331 // offset of sbyte in ScRawToken
332 // offsetof(ScRawToken, sbyte) gives a warning with gcc, because ScRawToken is no POD
335 return static_cast<USHORT
>( reinterpret_cast<char*>(&aToken
.sbyte
) - reinterpret_cast<char*>(&aToken
) );
338 ScRawToken
* ScRawToken::Clone() const
341 if ( eType
== svDouble
)
343 p
= (ScRawToken
*) new ScDoubleRawToken
;
350 static USHORT nOffset
= lcl_ScRawTokenOffset(); // offset of sbyte
353 if (eOp
== ocExternalRef
)
357 case svExternalSingleRef
:
358 case svExternalDoubleRef
: n
+= sizeof(extref
); break;
359 case svExternalName
: n
+= sizeof(extname
); break;
362 DBG_ERROR1( "unknown ScRawToken::Clone() external type %d", int(eType
));
371 case svByte
: n
+= sizeof(ScRawToken::sbyte
); break;
372 case svDouble
: n
+= sizeof(double); break;
373 case svString
: n
= sal::static_int_cast
<USHORT
>( n
+ GetStrLenBytes( cStr
) + GetStrLenBytes( 1 ) ); break;
375 case svDoubleRef
: n
+= sizeof(aRef
); break;
376 case svMatrix
: n
+= sizeof(ScMatrix
*); break;
377 case svIndex
: n
+= sizeof(USHORT
); break;
378 case svJump
: n
+= nJump
[ 0 ] * 2 + 2; break;
379 case svExternal
: n
= sal::static_int_cast
<USHORT
>( n
+ GetStrLenBytes( cStr
+1 ) + GetStrLenBytes( 2 ) ); break;
382 DBG_ERROR1( "unknown ScRawToken::Clone() type %d", int(eType
));
386 p
= (ScRawToken
*) new BYTE
[ n
];
387 memcpy( p
, this, n
* sizeof(BYTE
) );
395 FormulaToken
* ScRawToken::CreateToken() const
398 #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))
400 #define IF_NOT_OPCODE_ERROR(o,c)
405 return new FormulaByteToken( eOp
, sbyte
.cByte
, sbyte
.bHasForceArray
);
407 IF_NOT_OPCODE_ERROR( ocPush
, FormulaDoubleToken
);
408 return new FormulaDoubleToken( nValue
);
411 return new FormulaStringToken( String( cStr
) );
413 return new FormulaStringOpToken( eOp
, String( cStr
) );
416 return new ScSingleRefToken( aRef
.Ref1
);
418 return new ScSingleRefToken( aRef
.Ref1
, eOp
);
421 return new ScDoubleRefToken( aRef
);
423 return new ScDoubleRefToken( aRef
, eOp
);
425 IF_NOT_OPCODE_ERROR( ocPush
, ScMatrixToken
);
426 return new ScMatrixToken( pMat
);
428 return new FormulaIndexToken( eOp
, nIndex
);
429 case svExternalSingleRef
:
431 String
aTabName(extref
.cTabName
);
432 return new ScExternalSingleRefToken(extref
.nFileId
, aTabName
, extref
.aRef
.Ref1
);
434 case svExternalDoubleRef
:
436 String
aTabName(extref
.cTabName
);
437 return new ScExternalDoubleRefToken(extref
.nFileId
, aTabName
, extref
.aRef
);
441 String
aName(extname
.cName
);
442 return new ScExternalNameToken( extname
.nFileId
, aName
);
445 return new FormulaJumpToken( eOp
, (short*) nJump
);
447 return new FormulaExternalToken( eOp
, sbyte
.cByte
, String( cStr
+1 ) );
449 return new FormulaFAPToken( eOp
, sbyte
.cByte
, NULL
);
451 IF_NOT_OPCODE_ERROR( ocMissing
, FormulaMissingToken
);
452 return new FormulaMissingToken
;
454 return new FormulaToken( svSep
,eOp
);
456 return new FormulaUnknownToken( eOp
);
459 DBG_ERROR1( "unknown ScRawToken::CreateToken() type %d", int(GetType()));
460 return new FormulaUnknownToken( ocBad
);
463 #undef IF_NOT_OPCODE_ERROR
467 void ScRawToken::Delete()
470 delete this; // FixedMemPool ScRawToken
472 { // created per Clone
476 delete (ScDoubleRawToken
*) this; // FixedMemPool ScDoubleRawToken
479 delete [] (BYTE
*) this;
485 // --- class ScToken --------------------------------------------------------
487 ScSingleRefData
lcl_ScToken_InitSingleRef()
489 ScSingleRefData aRef
;
490 aRef
.InitAddress( ScAddress() );
494 ScComplexRefData
lcl_ScToken_InitDoubleRef()
496 ScComplexRefData aRef
;
497 aRef
.Ref1
= lcl_ScToken_InitSingleRef();
498 aRef
.Ref2
= aRef
.Ref1
;
506 // TextEqual: if same formula entered (for optimization in sort)
507 BOOL
ScToken::TextEqual( const FormulaToken
& _rToken
) const
509 if ( eType
== svSingleRef
|| eType
== svDoubleRef
)
511 // in relative Refs only compare relative parts
513 if ( eType
!= _rToken
.GetType() || GetOpCode() != _rToken
.GetOpCode() )
516 const ScToken
& rToken
= static_cast<const ScToken
&>(_rToken
);
517 ScComplexRefData aTemp1
;
518 if ( eType
== svSingleRef
)
520 aTemp1
.Ref1
= GetSingleRef();
521 aTemp1
.Ref2
= aTemp1
.Ref1
;
524 aTemp1
= GetDoubleRef();
526 ScComplexRefData aTemp2
;
527 if ( rToken
.eType
== svSingleRef
)
529 aTemp2
.Ref1
= rToken
.GetSingleRef();
530 aTemp2
.Ref2
= aTemp2
.Ref1
;
533 aTemp2
= rToken
.GetDoubleRef();
536 aTemp1
.SmartRelAbs(aPos
);
537 aTemp2
.SmartRelAbs(aPos
);
539 // memcmp doesn't work because of the alignment byte after bFlags.
540 // After SmartRelAbs only absolute parts have to be compared.
541 return aTemp1
.Ref1
.nCol
== aTemp2
.Ref1
.nCol
&&
542 aTemp1
.Ref1
.nRow
== aTemp2
.Ref1
.nRow
&&
543 aTemp1
.Ref1
.nTab
== aTemp2
.Ref1
.nTab
&&
544 aTemp1
.Ref1
.bFlags
== aTemp2
.Ref1
.bFlags
&&
545 aTemp1
.Ref2
.nCol
== aTemp2
.Ref2
.nCol
&&
546 aTemp1
.Ref2
.nRow
== aTemp2
.Ref2
.nRow
&&
547 aTemp1
.Ref2
.nTab
== aTemp2
.Ref2
.nTab
&&
548 aTemp1
.Ref2
.bFlags
== aTemp2
.Ref2
.bFlags
;
551 return *this == _rToken
; // else normal operator==
555 BOOL
ScToken::Is3DRef() const
560 if ( GetSingleRef2().IsFlag3D() )
564 if ( GetSingleRef().IsFlag3D() )
569 // added to avoid warnings
576 FormulaTokenRef
ScToken::ExtendRangeReference( FormulaToken
& rTok1
, FormulaToken
& rTok2
,
577 const ScAddress
& rPos
, bool bReuseDoubleRef
)
581 // Doing a RangeOp with RefList is probably utter nonsense, but Xcl
582 // supports it, so do we.
583 if (((sv1
= rTok1
.GetType()) != svSingleRef
&& sv1
!= svDoubleRef
&& sv1
!= svRefList
&&
584 sv1
!= svExternalSingleRef
&& sv1
!= svExternalDoubleRef
) ||
585 ((sv2
= rTok2
.GetType()) != svSingleRef
&& sv2
!= svDoubleRef
&& sv2
!= svRefList
))
588 ScToken
*p1
= static_cast<ScToken
*>(&rTok1
);
589 ScToken
*p2
= static_cast<ScToken
*>(&rTok2
);
592 bool bExternal
= (sv1
== svExternalSingleRef
);
593 if ((sv1
== svSingleRef
|| bExternal
) && sv2
== svSingleRef
)
595 // Range references like Sheet1.A1:A2 are generalized and built by
596 // first creating a DoubleRef from the first SingleRef, effectively
597 // generating Sheet1.A1:A1, and then extending that with A2 as if
598 // Sheet1.A1:A1:A2 was encountered, so the mechanisms to adjust the
599 // references apply as well.
601 /* Given the current structure of external references an external
602 * reference can only be extended if the second reference does not
603 * point to a different sheet. 'file'#Sheet1.A1:A2 is ok,
604 * 'file'#Sheet1.A1:Sheet2.A2 is not. Since we can't determine from a
605 * svSingleRef whether the sheet would be different from the one given
606 * in the external reference, we have to bail out if there is any sheet
607 * specified. NOTE: Xcl does handle external 3D references as in
608 * '[file]Sheet1:Sheet2'!A1:A2
610 * FIXME: For OOo syntax be smart and remember an external singleref
611 * encountered and if followed by ocRange and singleref, create an
612 * external singleref for the second singleref. Both could then be
613 * merged here. For Xcl syntax already parse an external range
614 * reference entirely, cumbersome. */
616 const ScSingleRefData
& rRef2
= p2
->GetSingleRef();
617 if (bExternal
&& rRef2
.IsFlag3D())
620 ScComplexRefData aRef
;
621 aRef
.Ref1
= aRef
.Ref2
= p1
->GetSingleRef();
622 aRef
.Ref2
.SetFlag3D( false);
623 aRef
.Extend( rRef2
, rPos
);
625 xRes
= new ScExternalDoubleRefToken( p1
->GetIndex(), p1
->GetString(), aRef
);
627 xRes
= new ScDoubleRefToken( aRef
);
631 bExternal
|= (sv1
== svExternalDoubleRef
);
632 const ScRefList
* pRefList
= NULL
;
633 if (sv1
== svDoubleRef
)
635 xRes
= (bReuseDoubleRef
&& p1
->GetRef() == 1 ? p1
: static_cast<ScToken
*>(p1
->Clone()));
636 sv1
= svUnknown
; // mark as handled
638 else if (sv2
== svDoubleRef
)
640 xRes
= (bReuseDoubleRef
&& p2
->GetRef() == 1 ? p2
: static_cast<ScToken
*>(p2
->Clone()));
641 sv2
= svUnknown
; // mark as handled
643 else if (sv1
== svRefList
)
644 pRefList
= p1
->GetRefList();
645 else if (sv2
== svRefList
)
646 pRefList
= p2
->GetRefList();
649 if (!pRefList
->size())
652 return NULL
; // external reference list not possible
653 xRes
= new ScDoubleRefToken( (*pRefList
)[0] );
656 return NULL
; // shouldn't happen..
657 StackVar sv
[2] = { sv1
, sv2
};
658 ScToken
* pt
[2] = { p1
, p2
};
659 ScComplexRefData
& rRef
= xRes
->GetDoubleRef();
660 for (size_t i
=0; i
<2; ++i
)
665 rRef
.Extend( pt
[i
]->GetSingleRef(), rPos
);
668 rRef
.Extend( pt
[i
]->GetDoubleRef(), rPos
);
672 const ScRefList
* p
= pt
[i
]->GetRefList();
675 ScRefList::const_iterator
it( p
->begin());
676 ScRefList::const_iterator
end( p
->end());
677 for ( ; it
!= end
; ++it
)
679 rRef
.Extend( *it
, rPos
);
683 case svExternalSingleRef
:
684 if (rRef
.Ref1
.IsFlag3D() || rRef
.Ref2
.IsFlag3D())
685 return NULL
; // no other sheets with external refs
687 rRef
.Extend( pt
[i
]->GetSingleRef(), rPos
);
689 case svExternalDoubleRef
:
690 if (rRef
.Ref1
.IsFlag3D() || rRef
.Ref2
.IsFlag3D())
691 return NULL
; // no other sheets with external refs
693 rRef
.Extend( pt
[i
]->GetDoubleRef(), rPos
);
696 ; // nothing, prevent compiler warning
700 return FormulaTokenRef(xRes
.get());
703 const ScSingleRefData
& ScToken::GetSingleRef() const
705 DBG_ERRORFILE( "ScToken::GetSingleRef: virtual dummy called" );
706 static ScSingleRefData aDummySingleRef
= lcl_ScToken_InitSingleRef();
707 return aDummySingleRef
;
710 ScSingleRefData
& ScToken::GetSingleRef()
712 DBG_ERRORFILE( "ScToken::GetSingleRef: virtual dummy called" );
713 static ScSingleRefData aDummySingleRef
= lcl_ScToken_InitSingleRef();
714 return aDummySingleRef
;
717 const ScComplexRefData
& ScToken::GetDoubleRef() const
719 DBG_ERRORFILE( "ScToken::GetDoubleRef: virtual dummy called" );
720 static ScComplexRefData aDummyDoubleRef
= lcl_ScToken_InitDoubleRef();
721 return aDummyDoubleRef
;
724 ScComplexRefData
& ScToken::GetDoubleRef()
726 DBG_ERRORFILE( "ScToken::GetDoubleRef: virtual dummy called" );
727 static ScComplexRefData aDummyDoubleRef
= lcl_ScToken_InitDoubleRef();
728 return aDummyDoubleRef
;
731 const ScSingleRefData
& ScToken::GetSingleRef2() const
733 DBG_ERRORFILE( "ScToken::GetSingleRef2: virtual dummy called" );
734 static ScSingleRefData aDummySingleRef
= lcl_ScToken_InitSingleRef();
735 return aDummySingleRef
;
738 ScSingleRefData
& ScToken::GetSingleRef2()
740 DBG_ERRORFILE( "ScToken::GetSingleRef2: virtual dummy called" );
741 static ScSingleRefData aDummySingleRef
= lcl_ScToken_InitSingleRef();
742 return aDummySingleRef
;
745 void ScToken::CalcAbsIfRel( const ScAddress
& /* rPos */ )
747 DBG_ERRORFILE( "ScToken::CalcAbsIfRel: virtual dummy called" );
750 void ScToken::CalcRelFromAbs( const ScAddress
& /* rPos */ )
752 DBG_ERRORFILE( "ScToken::CalcRelFromAbs: virtual dummy called" );
755 const ScMatrix
* ScToken::GetMatrix() const
757 DBG_ERRORFILE( "ScToken::GetMatrix: virtual dummy called" );
761 ScMatrix
* ScToken::GetMatrix()
763 DBG_ERRORFILE( "ScToken::GetMatrix: virtual dummy called" );
768 ScJumpMatrix
* ScToken::GetJumpMatrix() const
770 DBG_ERRORFILE( "ScToken::GetJumpMatrix: virtual dummy called" );
773 const ScRefList
* ScToken::GetRefList() const
775 DBG_ERRORFILE( "ScToken::GetRefList: virtual dummy called" );
779 ScRefList
* ScToken::GetRefList()
781 DBG_ERRORFILE( "ScToken::GetRefList: virtual dummy called" );
784 // ==========================================================================
785 // real implementations of virtual functions
786 // --------------------------------------------------------------------------
791 const ScSingleRefData
& ScSingleRefToken::GetSingleRef() const { return aSingleRef
; }
792 ScSingleRefData
& ScSingleRefToken::GetSingleRef() { return aSingleRef
; }
793 void ScSingleRefToken::CalcAbsIfRel( const ScAddress
& rPos
)
794 { aSingleRef
.CalcAbsIfRel( rPos
); }
795 void ScSingleRefToken::CalcRelFromAbs( const ScAddress
& rPos
)
796 { aSingleRef
.CalcRelFromAbs( rPos
); }
797 BOOL
ScSingleRefToken::operator==( const FormulaToken
& r
) const
799 return FormulaToken::operator==( r
) && aSingleRef
== static_cast<const ScToken
&>(r
).GetSingleRef();
803 const ScSingleRefData
& ScDoubleRefToken::GetSingleRef() const { return aDoubleRef
.Ref1
; }
804 ScSingleRefData
& ScDoubleRefToken::GetSingleRef() { return aDoubleRef
.Ref1
; }
805 const ScComplexRefData
& ScDoubleRefToken::GetDoubleRef() const { return aDoubleRef
; }
806 ScComplexRefData
& ScDoubleRefToken::GetDoubleRef() { return aDoubleRef
; }
807 const ScSingleRefData
& ScDoubleRefToken::GetSingleRef2() const { return aDoubleRef
.Ref2
; }
808 ScSingleRefData
& ScDoubleRefToken::GetSingleRef2() { return aDoubleRef
.Ref2
; }
809 void ScDoubleRefToken::CalcAbsIfRel( const ScAddress
& rPos
)
810 { aDoubleRef
.CalcAbsIfRel( rPos
); }
811 void ScDoubleRefToken::CalcRelFromAbs( const ScAddress
& rPos
)
812 { aDoubleRef
.CalcRelFromAbs( rPos
); }
813 BOOL
ScDoubleRefToken::operator==( const FormulaToken
& r
) const
815 return FormulaToken::operator==( r
) && aDoubleRef
== static_cast<const ScToken
&>(r
).GetDoubleRef();
819 const ScRefList
* ScRefListToken::GetRefList() const { return &aRefList
; }
820 ScRefList
* ScRefListToken::GetRefList() { return &aRefList
; }
821 void ScRefListToken::CalcAbsIfRel( const ScAddress
& rPos
)
823 for (ScRefList::iterator
it( aRefList
.begin()); it
!= aRefList
.end(); ++it
)
824 (*it
).CalcAbsIfRel( rPos
);
826 void ScRefListToken::CalcRelFromAbs( const ScAddress
& rPos
)
828 for (ScRefList::iterator
it( aRefList
.begin()); it
!= aRefList
.end(); ++it
)
829 (*it
).CalcRelFromAbs( rPos
);
831 BOOL
ScRefListToken::operator==( const FormulaToken
& r
) const
833 return FormulaToken::operator==( r
) && &aRefList
== static_cast<const ScToken
&>(r
).GetRefList();
837 const ScMatrix
* ScMatrixToken::GetMatrix() const { return pMatrix
; }
838 ScMatrix
* ScMatrixToken::GetMatrix() { return pMatrix
; }
839 BOOL
ScMatrixToken::operator==( const FormulaToken
& r
) const
841 return FormulaToken::operator==( r
) && pMatrix
== static_cast<const ScToken
&>(r
).GetMatrix();
844 // ============================================================================
846 ScExternalSingleRefToken::ScExternalSingleRefToken( sal_uInt16 nFileId
, const String
& rTabName
, const ScSingleRefData
& r
) :
847 ScToken( svExternalSingleRef
, ocExternalRef
),
854 ScExternalSingleRefToken::ScExternalSingleRefToken( const ScExternalSingleRefToken
& r
) :
856 mnFileId(r
.mnFileId
),
857 maTabName(r
.maTabName
),
858 maSingleRef(r
.maSingleRef
)
862 ScExternalSingleRefToken::~ScExternalSingleRefToken()
866 USHORT
ScExternalSingleRefToken::GetIndex() const
871 const String
& ScExternalSingleRefToken::GetString() const
876 const ScSingleRefData
& ScExternalSingleRefToken::GetSingleRef() const
881 ScSingleRefData
& ScExternalSingleRefToken::GetSingleRef()
886 void ScExternalSingleRefToken::CalcAbsIfRel( const ScAddress
& rPos
)
888 maSingleRef
.CalcAbsIfRel( rPos
);
891 void ScExternalSingleRefToken::CalcRelFromAbs( const ScAddress
& rPos
)
893 maSingleRef
.CalcRelFromAbs( rPos
);
896 BOOL
ScExternalSingleRefToken::operator ==( const FormulaToken
& r
) const
898 if (!FormulaToken::operator==(r
))
901 if (mnFileId
!= r
.GetIndex())
904 if (maTabName
!= r
.GetString())
907 return maSingleRef
== static_cast<const ScToken
&>(r
).GetSingleRef();
910 // ============================================================================
912 ScExternalDoubleRefToken::ScExternalDoubleRefToken( sal_uInt16 nFileId
, const String
& rTabName
, const ScComplexRefData
& r
) :
913 ScToken( svExternalDoubleRef
, ocExternalRef
),
920 ScExternalDoubleRefToken::ScExternalDoubleRefToken( const ScExternalDoubleRefToken
& r
) :
922 mnFileId(r
.mnFileId
),
923 maTabName(r
.maTabName
),
924 maDoubleRef(r
.maDoubleRef
)
928 ScExternalDoubleRefToken::~ScExternalDoubleRefToken()
932 USHORT
ScExternalDoubleRefToken::GetIndex() const
937 const String
& ScExternalDoubleRefToken::GetString() const
942 const ScSingleRefData
& ScExternalDoubleRefToken::GetSingleRef() const
944 return maDoubleRef
.Ref1
;
947 ScSingleRefData
& ScExternalDoubleRefToken::GetSingleRef()
949 return maDoubleRef
.Ref1
;
952 const ScSingleRefData
& ScExternalDoubleRefToken::GetSingleRef2() const
954 return maDoubleRef
.Ref2
;
957 ScSingleRefData
& ScExternalDoubleRefToken::GetSingleRef2()
959 return maDoubleRef
.Ref2
;
962 const ScComplexRefData
& ScExternalDoubleRefToken::GetDoubleRef() const
967 ScComplexRefData
& ScExternalDoubleRefToken::GetDoubleRef()
972 void ScExternalDoubleRefToken::CalcAbsIfRel( const ScAddress
& rPos
)
974 maDoubleRef
.CalcAbsIfRel( rPos
);
977 void ScExternalDoubleRefToken::CalcRelFromAbs( const ScAddress
& rPos
)
979 maDoubleRef
.CalcRelFromAbs( rPos
);
982 BOOL
ScExternalDoubleRefToken::operator ==( const FormulaToken
& r
) const
984 if (!ScToken::operator==(r
))
987 if (mnFileId
!= r
.GetIndex())
990 if (maTabName
!= r
.GetString())
993 return maDoubleRef
== static_cast<const ScToken
&>(r
).GetDoubleRef();
996 // ============================================================================
998 ScExternalNameToken::ScExternalNameToken( sal_uInt16 nFileId
, const String
& rName
) :
999 ScToken( svExternalName
, ocExternalRef
),
1005 ScExternalNameToken::ScExternalNameToken( const ScExternalNameToken
& r
) :
1007 mnFileId(r
.mnFileId
),
1012 ScExternalNameToken::~ScExternalNameToken() {}
1014 USHORT
ScExternalNameToken::GetIndex() const
1019 const String
& ScExternalNameToken::GetString() const
1024 BOOL
ScExternalNameToken::operator==( const FormulaToken
& r
) const
1026 if ( !FormulaToken::operator==(r
) )
1029 if (mnFileId
!= r
.GetIndex())
1032 xub_StrLen nLen
= maName
.Len();
1033 const String
& rName
= r
.GetString();
1034 if (nLen
!= rName
.Len())
1037 const sal_Unicode
* p1
= maName
.GetBuffer();
1038 const sal_Unicode
* p2
= rName
.GetBuffer();
1039 for (xub_StrLen j
= 0; j
< nLen
; ++j
)
1047 // ============================================================================
1049 ScJumpMatrix
* ScJumpMatrixToken::GetJumpMatrix() const { return pJumpMatrix
; }
1050 BOOL
ScJumpMatrixToken::operator==( const FormulaToken
& r
) const
1052 return FormulaToken::operator==( r
) && pJumpMatrix
== static_cast<const ScToken
&>(r
).GetJumpMatrix();
1054 ScJumpMatrixToken::~ScJumpMatrixToken()
1059 double ScEmptyCellToken::GetDouble() const { return 0.0; }
1060 const String
& ScEmptyCellToken::GetString() const
1062 static String aDummyString
;
1063 return aDummyString
;
1065 BOOL
ScEmptyCellToken::operator==( const FormulaToken
& r
) const
1067 return FormulaToken::operator==( r
) &&
1068 bInherited
== static_cast< const ScEmptyCellToken
& >(r
).IsInherited() &&
1069 bDisplayedAsString
== static_cast< const ScEmptyCellToken
& >(r
).IsDisplayedAsString();
1073 double ScMatrixCellResultToken::GetDouble() const { return xUpperLeft
->GetDouble(); }
1074 const String
& ScMatrixCellResultToken::GetString() const { return xUpperLeft
->GetString(); }
1075 const ScMatrix
* ScMatrixCellResultToken::GetMatrix() const { return xMatrix
; }
1076 // Non-const GetMatrix() is private and unused but must be implemented to
1077 // satisfy vtable linkage.
1078 ScMatrix
* ScMatrixCellResultToken::GetMatrix()
1080 return const_cast<ScMatrix
*>(xMatrix
.operator->());
1082 BOOL
ScMatrixCellResultToken::operator==( const FormulaToken
& r
) const
1084 return FormulaToken::operator==( r
) &&
1085 xUpperLeft
== static_cast<const ScMatrixCellResultToken
&>(r
).xUpperLeft
&&
1086 xMatrix
== static_cast<const ScMatrixCellResultToken
&>(r
).xMatrix
;
1090 BOOL
ScMatrixFormulaCellToken::operator==( const FormulaToken
& r
) const
1092 const ScMatrixFormulaCellToken
* p
= dynamic_cast<const ScMatrixFormulaCellToken
*>(&r
);
1093 return p
&& ScMatrixCellResultToken::operator==( r
) &&
1094 nCols
== p
->nCols
&& nRows
== p
->nRows
;
1096 void ScMatrixFormulaCellToken::Assign( const formula::FormulaToken
& r
)
1100 const ScMatrixCellResultToken
* p
= dynamic_cast<const ScMatrixCellResultToken
*>(&r
);
1102 ScMatrixCellResultToken::Assign( *p
);
1105 DBG_ASSERT( r
.GetType() != svMatrix
, "ScMatrixFormulaCellToken::operator=: assigning ScMatrixToken to ScMatrixFormulaCellToken is not proper, use ScMatrixCellResultToken instead");
1106 if (r
.GetType() == svMatrix
)
1109 xMatrix
= static_cast<const ScToken
&>(r
).GetMatrix();
1118 void ScMatrixFormulaCellToken::SetUpperLeftDouble( double f
)
1120 switch (GetUpperLeftType())
1123 const_cast<FormulaToken
*>(xUpperLeft
.get())->GetDoubleAsReference() = f
;
1128 xUpperLeft
= new FormulaDoubleToken( f
);
1134 DBG_ERRORFILE("ScMatrixFormulaCellToken::SetUpperLeftDouble: not modifying unhandled token type");
1140 double ScHybridCellToken::GetDouble() const { return fDouble
; }
1141 const String
& ScHybridCellToken::GetString() const { return aString
; }
1142 BOOL
ScHybridCellToken::operator==( const FormulaToken
& r
) const
1144 return FormulaToken::operator==( r
) &&
1145 fDouble
== r
.GetDouble() && aString
== r
.GetString() &&
1146 aFormula
== static_cast<const ScHybridCellToken
&>(r
).GetFormula();
1152 //////////////////////////////////////////////////////////////////////////
1154 bool ScTokenArray::AddFormulaToken(const com::sun::star::sheet::FormulaToken
& _aToken
,formula::ExternalReferenceHelper
* _pRef
)
1156 bool bError
= FormulaTokenArray::AddFormulaToken(_aToken
,_pRef
);
1160 const OpCode eOpCode
= static_cast<OpCode
>(_aToken
.OpCode
); //! assuming equal values for the moment
1162 const uno::TypeClass eClass
= _aToken
.Data
.getValueTypeClass();
1165 case uno::TypeClass_STRUCT
:
1167 uno::Type aType
= _aToken
.Data
.getValueType();
1168 if ( aType
.equals( cppu::UnoType
<sheet::SingleReference
>::get() ) )
1170 ScSingleRefData aSingleRef
;
1171 sheet::SingleReference aApiRef
;
1172 _aToken
.Data
>>= aApiRef
;
1173 lcl_SingleRefToCalc( aSingleRef
, aApiRef
);
1174 if ( eOpCode
== ocPush
)
1175 AddSingleReference( aSingleRef
);
1176 else if ( eOpCode
== ocColRowName
)
1177 AddColRowName( aSingleRef
);
1181 else if ( aType
.equals( cppu::UnoType
<sheet::ComplexReference
>::get() ) )
1183 ScComplexRefData aComplRef
;
1184 sheet::ComplexReference aApiRef
;
1185 _aToken
.Data
>>= aApiRef
;
1186 lcl_SingleRefToCalc( aComplRef
.Ref1
, aApiRef
.Reference1
);
1187 lcl_SingleRefToCalc( aComplRef
.Ref2
, aApiRef
.Reference2
);
1189 if ( eOpCode
== ocPush
)
1190 AddDoubleReference( aComplRef
);
1194 else if ( aType
.equals( cppu::UnoType
<sheet::ExternalReference
>::get() ) )
1196 sheet::ExternalReference aApiExtRef
;
1197 if( (eOpCode
== ocPush
) && (_aToken
.Data
>>= aApiExtRef
) && (0 <= aApiExtRef
.Index
) && (aApiExtRef
.Index
<= SAL_MAX_UINT16
) )
1199 sal_uInt16 nFileId
= static_cast< sal_uInt16
>( aApiExtRef
.Index
);
1200 sheet::SingleReference aApiSRef
;
1201 sheet::ComplexReference aApiCRef
;
1202 ::rtl::OUString aName
;
1203 if( aApiExtRef
.Reference
>>= aApiSRef
)
1205 // try to resolve cache index to sheet name
1206 size_t nCacheId
= static_cast< size_t >( aApiSRef
.Sheet
);
1207 String aTabName
= _pRef
->getCacheTableName( nFileId
, nCacheId
);
1208 if( aTabName
.Len() > 0 )
1210 ScSingleRefData aSingleRef
;
1211 // convert column/row settings, set sheet index to absolute
1212 lcl_ExternalRefToCalc( aSingleRef
, aApiSRef
);
1213 AddExternalSingleReference( nFileId
, aTabName
, aSingleRef
);
1218 else if( aApiExtRef
.Reference
>>= aApiCRef
)
1220 // try to resolve cache index to sheet name.
1221 size_t nCacheId
= static_cast< size_t >( aApiCRef
.Reference1
.Sheet
);
1222 String aTabName
= _pRef
->getCacheTableName( nFileId
, nCacheId
);
1223 if( aTabName
.Len() > 0 )
1225 ScComplexRefData aComplRef
;
1226 // convert column/row settings, set sheet index to absolute
1227 lcl_ExternalRefToCalc( aComplRef
.Ref1
, aApiCRef
.Reference1
);
1228 lcl_ExternalRefToCalc( aComplRef
.Ref2
, aApiCRef
.Reference2
);
1229 // NOTE: This assumes that cached sheets are in consecutive order!
1230 aComplRef
.Ref2
.nTab
= aComplRef
.Ref1
.nTab
+ static_cast<SCsTAB
>(aApiCRef
.Reference2
.Sheet
- aApiCRef
.Reference1
.Sheet
);
1231 AddExternalDoubleReference( nFileId
, aTabName
, aComplRef
);
1236 else if( aApiExtRef
.Reference
>>= aName
)
1238 if( aName
.getLength() > 0 )
1239 AddExternalName( nFileId
, aName
);
1250 bError
= true; // unknown struct
1253 case uno::TypeClass_SEQUENCE
:
1255 if ( eOpCode
!= ocPush
)
1256 bError
= true; // not an inline array
1257 else if (!_aToken
.Data
.getValueType().equals( getCppuType(
1258 (uno::Sequence
< uno::Sequence
< uno::Any
> > *)0)))
1259 bError
= true; // unexpected sequence type
1262 ScMatrixRef xMat
= ScSequenceToMatrix::CreateMixedMatrix( _aToken
.Data
);
1276 BOOL
ScTokenArray::ImplGetReference( ScRange
& rRange
, BOOL bValidOnly
) const
1279 if ( pCode
&& nLen
== 1 )
1281 const FormulaToken
* pToken
= pCode
[0];
1284 if ( pToken
->GetType() == svSingleRef
)
1286 const ScSingleRefData
& rRef
= ((const ScSingleRefToken
*)pToken
)->GetSingleRef();
1287 rRange
.aStart
= rRange
.aEnd
= ScAddress( rRef
.nCol
, rRef
.nRow
, rRef
.nTab
);
1288 bIs
= !bValidOnly
|| !rRef
.IsDeleted();
1290 else if ( pToken
->GetType() == svDoubleRef
)
1292 const ScComplexRefData
& rCompl
= ((const ScDoubleRefToken
*)pToken
)->GetDoubleRef();
1293 const ScSingleRefData
& rRef1
= rCompl
.Ref1
;
1294 const ScSingleRefData
& rRef2
= rCompl
.Ref2
;
1295 rRange
.aStart
= ScAddress( rRef1
.nCol
, rRef1
.nRow
, rRef1
.nTab
);
1296 rRange
.aEnd
= ScAddress( rRef2
.nCol
, rRef2
.nRow
, rRef2
.nTab
);
1297 bIs
= !bValidOnly
|| (!rRef1
.IsDeleted() && !rRef2
.IsDeleted());
1304 BOOL
ScTokenArray::IsReference( ScRange
& rRange
) const
1306 return ImplGetReference( rRange
, FALSE
);
1309 BOOL
ScTokenArray::IsValidReference( ScRange
& rRange
) const
1311 return ImplGetReference( rRange
, TRUE
);
1314 ////////////////////////////////////////////////////////////////////////////
1316 ScTokenArray::ScTokenArray()
1320 ScTokenArray::ScTokenArray( const ScTokenArray
& rArr
) : FormulaTokenArray(rArr
)
1324 ScTokenArray::~ScTokenArray()
1330 ScTokenArray
& ScTokenArray::operator=( const ScTokenArray
& rArr
)
1337 ScTokenArray
* ScTokenArray::Clone() const
1339 ScTokenArray
* p
= new ScTokenArray();
1345 p
->bHyperLink
= bHyperLink
;
1349 pp
= p
->pCode
= new FormulaToken
*[ nLen
];
1350 memcpy( pp
, pCode
, nLen
* sizeof( ScToken
* ) );
1351 for( USHORT i
= 0; i
< nLen
; i
++, pp
++ )
1353 *pp
= (*pp
)->Clone();
1359 pp
= p
->pRPN
= new FormulaToken
*[ nRPN
];
1360 memcpy( pp
, pRPN
, nRPN
* sizeof( ScToken
* ) );
1361 for( USHORT i
= 0; i
< nRPN
; i
++, pp
++ )
1363 FormulaToken
* t
= *pp
;
1364 if( t
->GetRef() > 1 )
1366 FormulaToken
** p2
= pCode
;
1367 USHORT nIdx
= 0xFFFF;
1368 for( USHORT j
= 0; j
< nLen
; j
++, p2
++ )
1375 if( nIdx
== 0xFFFF )
1378 *pp
= p
->pCode
[ nIdx
];
1388 FormulaToken
* ScTokenArray::AddRawToken( const ScRawToken
& r
)
1390 return Add( r
.CreateToken() );
1393 // Utility function to ensure that there is strict alternation of values and
1396 checkArraySep( bool & bPrevWasSep
, bool bNewVal
)
1398 bool bResult
= (bPrevWasSep
== bNewVal
);
1399 bPrevWasSep
= bNewVal
;
1403 FormulaToken
* ScTokenArray::MergeArray( )
1405 int nCol
= -1, nRow
= 0;
1406 int i
, nPrevRowSep
= -1, nStart
= 0;
1407 bool bPrevWasSep
= false; // top of stack is ocArrayClose
1409 bool bNumeric
= false; // numeric value encountered in current element
1411 // (1) Iterate from the end to the start to find matrix dims
1412 // and do basic validation.
1413 for ( i
= nLen
; i
-- > nStart
; )
1416 switch ( t
->GetOpCode() )
1419 if( checkArraySep( bPrevWasSep
, false ) )
1424 // no references or nested arrays
1425 if ( t
->GetType() != svDouble
&& t
->GetType() != svString
)
1429 bNumeric
= (t
->GetType() == svDouble
);
1435 if( checkArraySep( bPrevWasSep
, false ) )
1442 case ocArrayColSep
:
1444 if( checkArraySep( bPrevWasSep
, true ) )
1452 // not possible with the , but check just in case
1453 // something changes in the future
1459 if( checkArraySep( bPrevWasSep
, true ) )
1469 nStart
= i
; // stop iteration
1470 // fall through to ArrayRowSep
1472 case ocArrayRowSep
:
1473 if( checkArraySep( bPrevWasSep
, true ) )
1478 if( nPrevRowSep
< 0 || // missing ocArrayClose
1479 ((nPrevRowSep
- i
) % 2) == 1) // no complex elements
1486 nCol
= (nPrevRowSep
- i
) / 2;
1488 else if( (nPrevRowSep
- i
)/2 != nCol
) // irregular array
1500 // negation or unary plus must precede numeric value
1505 --nPrevRowSep
; // shorten this row by 1
1506 bNumeric
= false; // one level only, no --42
1511 --nPrevRowSep
; // shorten this row by 1
1515 // no functions or operators
1519 if( nCol
<= 0 || nRow
<= 0 )
1522 // fprintf (stderr, "Array (cols = %d, rows = %d)\n", nCol, nRow );
1525 ScMatrix
* pArray
= new ScMatrix( nCol
, nRow
);
1526 for ( i
= nStart
, nCol
= 0, nRow
= 0 ; i
< nLen
; i
++ )
1530 switch ( t
->GetOpCode() )
1533 if ( t
->GetType() == svDouble
)
1535 pArray
->PutDouble( t
->GetDouble() * nSign
, nCol
, nRow
);
1538 else if ( t
->GetType() == svString
)
1540 pArray
->PutString( t
->GetString(), nCol
, nRow
);
1545 pArray
->PutEmpty( nCol
, nRow
);
1549 pArray
->PutBoolean( true, nCol
, nRow
);
1553 pArray
->PutBoolean( false, nCol
, nRow
);
1556 case ocArrayColSep
:
1561 case ocArrayRowSep
:
1575 nLen
= USHORT( nStart
);
1576 return AddMatrix( pArray
);
1580 FormulaToken
* ScTokenArray::MergeRangeReference( const ScAddress
& rPos
)
1582 if (!pCode
|| !nLen
)
1585 FormulaToken
*p1
, *p2
, *p3
; // ref, ocRange, ref
1586 // The actual types are checked in ExtendRangeReference().
1587 if (((p3
= PeekPrev(nIdx
)) != 0) &&
1588 (((p2
= PeekPrev(nIdx
)) != 0) && p2
->GetOpCode() == ocRange
) &&
1589 ((p1
= PeekPrev(nIdx
)) != 0))
1591 FormulaTokenRef p
= ScToken::ExtendRangeReference( *p1
, *p3
, rPos
, true);
1599 pCode
[ nLen
-1 ] = p
;
1603 return pCode
[ nLen
-1 ];
1606 FormulaToken
* ScTokenArray::AddOpCode( OpCode e
)
1610 return AddRawToken( t
);
1613 FormulaToken
* ScTokenArray::AddSingleReference( const ScSingleRefData
& rRef
)
1615 return Add( new ScSingleRefToken( rRef
) );
1618 FormulaToken
* ScTokenArray::AddMatrixSingleReference( const ScSingleRefData
& rRef
)
1620 return Add( new ScSingleRefToken( rRef
, ocMatRef
) );
1623 FormulaToken
* ScTokenArray::AddDoubleReference( const ScComplexRefData
& rRef
)
1625 return Add( new ScDoubleRefToken( rRef
) );
1628 FormulaToken
* ScTokenArray::AddMatrix( ScMatrix
* p
)
1630 return Add( new ScMatrixToken( p
) );
1633 FormulaToken
* ScTokenArray::AddExternalName( sal_uInt16 nFileId
, const String
& rName
)
1635 return Add( new ScExternalNameToken(nFileId
, rName
) );
1638 FormulaToken
* ScTokenArray::AddExternalSingleReference( sal_uInt16 nFileId
, const String
& rTabName
, const ScSingleRefData
& rRef
)
1640 return Add( new ScExternalSingleRefToken(nFileId
, rTabName
, rRef
) );
1643 FormulaToken
* ScTokenArray::AddExternalDoubleReference( sal_uInt16 nFileId
, const String
& rTabName
, const ScComplexRefData
& rRef
)
1645 return Add( new ScExternalDoubleRefToken(nFileId
, rTabName
, rRef
) );
1648 FormulaToken
* ScTokenArray::AddColRowName( const ScSingleRefData
& rRef
)
1650 return Add( new ScSingleRefToken( rRef
, ocColRowName
) );
1653 BOOL
ScTokenArray::GetAdjacentExtendOfOuterFuncRefs( SCCOLROW
& nExtend
,
1654 const ScAddress
& rPos
, ScDirection eDir
)
1661 if ( rPos
.Row() < MAXROW
)
1662 nRow
= (nExtend
= rPos
.Row()) + 1;
1667 if ( rPos
.Col() < MAXCOL
)
1668 nCol
= static_cast<SCCOL
>(nExtend
= rPos
.Col()) + 1;
1673 if ( rPos
.Row() > 0 )
1674 nRow
= (nExtend
= rPos
.Row()) - 1;
1679 if ( rPos
.Col() > 0 )
1680 nCol
= static_cast<SCCOL
>(nExtend
= rPos
.Col()) - 1;
1685 DBG_ERRORFILE( "unknown Direction" );
1690 FormulaToken
* t
= pRPN
[nRPN
-1];
1691 if ( t
->GetType() == svByte
)
1693 BYTE nParamCount
= t
->GetByte();
1694 if ( nParamCount
&& nRPN
> nParamCount
)
1697 USHORT nParam
= nRPN
- nParamCount
- 1;
1698 for ( ; nParam
< nRPN
-1; nParam
++ )
1700 FormulaToken
* p
= pRPN
[nParam
];
1701 switch ( p
->GetType() )
1705 ScSingleRefData
& rRef
= static_cast<ScToken
*>(p
)->GetSingleRef();
1706 rRef
.CalcAbsIfRel( rPos
);
1710 if ( rRef
.nRow
== nRow
1711 && rRef
.nRow
> nExtend
)
1713 nExtend
= rRef
.nRow
;
1718 if ( rRef
.nCol
== nCol
1719 && static_cast<SCCOLROW
>(rRef
.nCol
)
1722 nExtend
= rRef
.nCol
;
1727 if ( rRef
.nRow
== nRow
1728 && rRef
.nRow
< nExtend
)
1730 nExtend
= rRef
.nRow
;
1735 if ( rRef
.nCol
== nCol
1736 && static_cast<SCCOLROW
>(rRef
.nCol
)
1739 nExtend
= rRef
.nCol
;
1748 ScComplexRefData
& rRef
= static_cast<ScToken
*>(p
)->GetDoubleRef();
1749 rRef
.CalcAbsIfRel( rPos
);
1753 if ( rRef
.Ref1
.nRow
== nRow
1754 && rRef
.Ref2
.nRow
> nExtend
)
1756 nExtend
= rRef
.Ref2
.nRow
;
1761 if ( rRef
.Ref1
.nCol
== nCol
&&
1762 static_cast<SCCOLROW
>(rRef
.Ref2
.nCol
)
1765 nExtend
= rRef
.Ref2
.nCol
;
1770 if ( rRef
.Ref2
.nRow
== nRow
1771 && rRef
.Ref1
.nRow
< nExtend
)
1773 nExtend
= rRef
.Ref1
.nRow
;
1778 if ( rRef
.Ref2
.nCol
== nCol
&&
1779 static_cast<SCCOLROW
>(rRef
.Ref1
.nCol
)
1782 nExtend
= rRef
.Ref1
.nCol
;
1791 // added to avoid warnings
1803 void ScTokenArray::ReadjustRelative3DReferences( const ScAddress
& rOldPos
,
1804 const ScAddress
& rNewPos
)
1806 for ( USHORT j
=0; j
<nLen
; ++j
)
1808 switch ( pCode
[j
]->GetType() )
1812 ScSingleRefData
& rRef2
= static_cast<ScToken
*>(pCode
[j
])->GetSingleRef2();
1813 // Also adjust if the reference is of the form Sheet1.A2:A3
1814 if ( rRef2
.IsFlag3D() || static_cast<ScToken
*>(pCode
[j
])->GetSingleRef().IsFlag3D() )
1816 rRef2
.CalcAbsIfRel( rOldPos
);
1817 rRef2
.CalcRelFromAbs( rNewPos
);
1823 ScSingleRefData
& rRef1
= static_cast<ScToken
*>(pCode
[j
])->GetSingleRef();
1824 if ( rRef1
.IsFlag3D() )
1826 rRef1
.CalcAbsIfRel( rOldPos
);
1827 rRef1
.CalcRelFromAbs( rNewPos
);
1833 // added to avoid warnings