fix baseline build (old cairo) - 'cairo_rectangle_int_t' does not name a type
[LibreOffice.git] / formula / source / core / api / token.cxx
blob9f16f4ce90d05040360089aa73badd638456afb8
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 #include <cstddef>
22 #include <cstdio>
24 #include <string.h>
25 #include <limits.h>
26 #include <tools/debug.hxx>
27 #include <osl/diagnose.h>
29 #include "formula/token.hxx"
30 #include "formula/tokenarray.hxx"
31 #include "formula/FormulaCompiler.hxx"
32 #include <formula/compiler.hrc>
33 #include <svl/sharedstringpool.hxx>
34 #include <boost/scoped_array.hpp>
36 namespace formula
38 using namespace com::sun::star;
40 // Align MemPools on 4k boundaries - 64 bytes (4k is a MUST for OS/2)
42 // Need a lot of FormulaDoubleToken
43 IMPL_FIXEDMEMPOOL_NEWDEL_DLL( FormulaDoubleToken )
44 // Need a lot of FormulaByteToken
45 IMPL_FIXEDMEMPOOL_NEWDEL_DLL( FormulaByteToken )
46 // Need several FormulaStringToken
47 IMPL_FIXEDMEMPOOL_NEWDEL_DLL( FormulaStringToken )
50 // --- helpers --------------------------------------------------------------
52 inline bool lcl_IsReference( OpCode eOp, StackVar eType )
54 return
55 (eOp == ocPush && (eType == svSingleRef || eType == svDoubleRef))
56 || (eOp == ocColRowNameAuto && eType == svDoubleRef)
57 || (eOp == ocColRowName && eType == svSingleRef)
58 || (eOp == ocMatRef && eType == svSingleRef)
62 // --- class FormulaToken --------------------------------------------------------
64 FormulaToken::FormulaToken( StackVar eTypeP, OpCode e ) :
65 eOp(e), eType( eTypeP ), mnRefCnt(0)
69 FormulaToken::FormulaToken( const FormulaToken& r ) :
70 IFormulaToken(), eOp(r.eOp), eType( r.eType ), mnRefCnt(0)
74 FormulaToken::~FormulaToken()
78 bool FormulaToken::IsFunction() const
80 return (eOp != ocPush && eOp != ocBad && eOp != ocColRowName &&
81 eOp != ocColRowNameAuto && eOp != ocName && eOp != ocDBArea &&
82 eOp != ocTableRef &&
83 (GetByte() != 0 // x parameters
84 || (SC_OPCODE_START_NO_PAR <= eOp && eOp < SC_OPCODE_STOP_NO_PAR) // no parameter
85 || (ocIf == eOp || ocIfError == eOp || ocIfNA == eOp || ocChoose == eOp ) // @ jump commands
86 || (SC_OPCODE_START_1_PAR <= eOp && eOp < SC_OPCODE_STOP_1_PAR) // one parameter
87 || (SC_OPCODE_START_2_PAR <= eOp && eOp < SC_OPCODE_STOP_2_PAR) // x parameters (cByte==0 in
88 // FuncAutoPilot)
89 || eOp == ocMacro || eOp == ocExternal // macros, AddIns
90 || eOp == ocAnd || eOp == ocOr // former binary, now x parameters
91 || eOp == ocNot || eOp == ocNeg // unary but function
92 || (eOp >= ocInternalBegin && eOp <= ocInternalEnd) // internal
93 ));
97 sal_uInt8 FormulaToken::GetParamCount() const
99 if ( eOp < SC_OPCODE_STOP_DIV && eOp != ocExternal && eOp != ocMacro &&
100 eOp != ocIf && eOp != ocIfError && eOp != ocIfNA && eOp != ocChoose &&
101 eOp != ocPercentSign )
102 return 0; // parameters and specials
103 // ocIf, ocIfError, ocIfNA and ocChoose not for FAP, have cByte then
104 //2do: bool parameter whether FAP or not?
105 else if ( GetByte() )
106 return GetByte(); // all functions, also ocExternal and ocMacro
107 else if (SC_OPCODE_START_BIN_OP <= eOp && eOp < SC_OPCODE_STOP_BIN_OP)
108 return 2; // binary
109 else if ((SC_OPCODE_START_UN_OP <= eOp && eOp < SC_OPCODE_STOP_UN_OP)
110 || eOp == ocPercentSign)
111 return 1; // unary
112 else if (SC_OPCODE_START_NO_PAR <= eOp && eOp < SC_OPCODE_STOP_NO_PAR)
113 return 0; // no parameter
114 else if (SC_OPCODE_START_1_PAR <= eOp && eOp < SC_OPCODE_STOP_1_PAR)
115 return 1; // one parameter
116 else if ( eOp == ocIf || eOp == ocIfError || eOp == ocIfNA || eOp == ocChoose )
117 return 1; // only the condition counts as parameter
118 else
119 return 0; // all the rest, no Parameter, or
120 // if so then it should be in cByte
123 bool FormulaToken::IsExternalRef() const
125 bool bRet = false;
126 switch (eType)
128 case svExternalSingleRef:
129 case svExternalDoubleRef:
130 case svExternalName:
131 bRet = true;
132 break;
133 default:
134 bRet = false;
135 break;
137 return bRet;
140 bool FormulaToken::IsRef() const
142 switch (eType)
144 case svSingleRef:
145 case svDoubleRef:
146 case svExternalSingleRef:
147 case svExternalDoubleRef:
148 return true;
149 default:
150 if (eOp == ocTableRef)
151 return true;
154 return false;
157 bool FormulaToken::operator==( const FormulaToken& rToken ) const
159 // don't compare reference count!
160 return eType == rToken.eType && GetOpCode() == rToken.GetOpCode();
164 // --- virtual dummy methods -------------------------------------------------
166 sal_uInt8 FormulaToken::GetByte() const
168 // ok to be called for any derived class
169 return 0;
172 void FormulaToken::SetByte( sal_uInt8 )
174 SAL_WARN( "formula.core", "FormulaToken::SetByte: virtual dummy called" );
177 bool FormulaToken::HasForceArray() const
179 // ok to be called for any derived class
180 return false;
183 void FormulaToken::SetForceArray( bool )
185 SAL_WARN( "formula.core", "FormulaToken::SetForceArray: virtual dummy called" );
188 double FormulaToken::GetDouble() const
190 SAL_WARN( "formula.core", "FormulaToken::GetDouble: virtual dummy called" );
191 return 0.0;
194 double & FormulaToken::GetDoubleAsReference()
196 SAL_WARN( "formula.core", "FormulaToken::GetDouble: virtual dummy called" );
197 static double fVal = 0.0;
198 return fVal;
201 svl::SharedString FormulaToken::GetString() const
203 SAL_WARN( "formula.core", "FormulaToken::GetString: virtual dummy called" );
204 return svl::SharedString(); // invalid string
207 sal_uInt16 FormulaToken::GetIndex() const
209 SAL_WARN( "formula.core", "FormulaToken::GetIndex: virtual dummy called" );
210 return 0;
213 void FormulaToken::SetIndex( sal_uInt16 )
215 SAL_WARN( "formula.core", "FormulaToken::SetIndex: virtual dummy called" );
218 bool FormulaToken::IsGlobal() const
220 SAL_WARN( "formula.core", "FormulaToken::IsGlobal: virtual dummy called" );
221 return true;
224 void FormulaToken::SetGlobal( bool )
226 SAL_WARN( "formula.core", "FormulaToken::SetGlobal: virtual dummy called" );
229 short* FormulaToken::GetJump() const
231 SAL_WARN( "formula.core", "FormulaToken::GetJump: virtual dummy called" );
232 return NULL;
236 const OUString& FormulaToken::GetExternal() const
238 SAL_WARN( "formula.core", "FormulaToken::GetExternal: virtual dummy called" );
239 static OUString aDummyString;
240 return aDummyString;
243 FormulaToken* FormulaToken::GetFAPOrigToken() const
245 SAL_WARN( "formula.core", "FormulaToken::GetFAPOrigToken: virtual dummy called" );
246 return NULL;
249 sal_uInt16 FormulaToken::GetError() const
251 SAL_WARN( "formula.core", "FormulaToken::GetError: virtual dummy called" );
252 return 0;
255 void FormulaToken::SetError( sal_uInt16 )
257 SAL_WARN( "formula.core", "FormulaToken::SetError: virtual dummy called" );
260 const ScSingleRefData* FormulaToken::GetSingleRef() const
262 OSL_FAIL( "FormulaToken::GetSingleRef: virtual dummy called" );
263 return nullptr;
266 ScSingleRefData* FormulaToken::GetSingleRef()
268 OSL_FAIL( "FormulaToken::GetSingleRef: virtual dummy called" );
269 return nullptr;
272 const ScComplexRefData* FormulaToken::GetDoubleRef() const
274 OSL_FAIL( "FormulaToken::GetDoubleRef: virtual dummy called" );
275 return nullptr;
278 ScComplexRefData* FormulaToken::GetDoubleRef()
280 OSL_FAIL( "FormulaToken::GetDoubleRef: virtual dummy called" );
281 return nullptr;
284 const ScSingleRefData* FormulaToken::GetSingleRef2() const
286 OSL_FAIL( "FormulaToken::GetSingleRef2: virtual dummy called" );
287 return nullptr;
290 ScSingleRefData* FormulaToken::GetSingleRef2()
292 OSL_FAIL( "FormulaToken::GetSingleRef2: virtual dummy called" );
293 return nullptr;
296 const ScMatrix* FormulaToken::GetMatrix() const
298 OSL_FAIL( "FormulaToken::GetMatrix: virtual dummy called" );
299 return NULL;
302 ScMatrix* FormulaToken::GetMatrix()
304 OSL_FAIL( "FormulaToken::GetMatrix: virtual dummy called" );
305 return NULL;
308 ScJumpMatrix* FormulaToken::GetJumpMatrix() const
310 OSL_FAIL( "FormulaToken::GetJumpMatrix: virtual dummy called" );
311 return NULL;
313 const std::vector<ScComplexRefData>* FormulaToken::GetRefList() const
315 OSL_FAIL( "FormulaToken::GetRefList: virtual dummy called" );
316 return NULL;
319 std::vector<ScComplexRefData>* FormulaToken::GetRefList()
321 OSL_FAIL( "FormulaToken::GetRefList: virtual dummy called" );
322 return NULL;
325 bool FormulaToken::TextEqual( const FormulaToken& rToken ) const
327 return *this == rToken;
330 // real implementations of virtual functions
334 sal_uInt8 FormulaByteToken::GetByte() const { return nByte; }
335 void FormulaByteToken::SetByte( sal_uInt8 n ) { nByte = n; }
336 bool FormulaByteToken::HasForceArray() const { return bHasForceArray; }
337 void FormulaByteToken::SetForceArray( bool b ) { bHasForceArray = b; }
338 bool FormulaByteToken::operator==( const FormulaToken& r ) const
340 return FormulaToken::operator==( r ) && nByte == r.GetByte() &&
341 bHasForceArray == r.HasForceArray();
345 FormulaToken* FormulaFAPToken::GetFAPOrigToken() const { return pOrigToken.get(); }
346 bool FormulaFAPToken::operator==( const FormulaToken& r ) const
348 return FormulaByteToken::operator==( r ) && pOrigToken == r.GetFAPOrigToken();
352 short* FormulaJumpToken::GetJump() const { return pJump; }
353 bool FormulaJumpToken::HasForceArray() const { return bHasForceArray; }
354 void FormulaJumpToken::SetForceArray( bool b ) { bHasForceArray = b; }
355 bool FormulaJumpToken::operator==( const FormulaToken& r ) const
357 return FormulaToken::operator==( r ) && pJump[0] == r.GetJump()[0] &&
358 memcmp( pJump+1, r.GetJump()+1, pJump[0] * sizeof(short) ) == 0 &&
359 bHasForceArray == r.HasForceArray();
361 FormulaJumpToken::~FormulaJumpToken()
363 delete [] pJump;
367 bool FormulaTokenArray::AddFormulaToken(
368 const sheet::FormulaToken& rToken, svl::SharedStringPool& rSPool, ExternalReferenceHelper* /*pExtRef*/)
370 bool bError = false;
371 const OpCode eOpCode = static_cast<OpCode>(rToken.OpCode); //! assuming equal values for the moment
373 const uno::TypeClass eClass = rToken.Data.getValueTypeClass();
374 switch ( eClass )
376 case uno::TypeClass_VOID:
377 // empty data -> use AddOpCode (does some special cases)
378 AddOpCode( eOpCode );
379 break;
380 case uno::TypeClass_DOUBLE:
381 // double is only used for "push"
382 if ( eOpCode == ocPush )
383 AddDouble( rToken.Data.get<double>() );
384 else
385 bError = true;
386 break;
387 case uno::TypeClass_LONG:
389 // long is svIndex, used for name / database area, or "byte" for spaces
390 sal_Int32 nValue = rToken.Data.get<sal_Int32>();
391 if ( eOpCode == ocDBArea )
392 AddToken( formula::FormulaIndexToken( eOpCode, static_cast<sal_uInt16>(nValue) ) );
393 else if ( eOpCode == ocTableRef )
394 bError = true; /* TODO: implementation */
395 else if ( eOpCode == ocSpaces )
396 AddToken( formula::FormulaByteToken( ocSpaces, static_cast<sal_uInt8>(nValue) ) );
397 else
398 bError = true;
400 break;
401 case uno::TypeClass_STRING:
403 OUString aStrVal( rToken.Data.get<OUString>() );
404 if ( eOpCode == ocPush )
405 AddString(rSPool.intern(aStrVal));
406 else if ( eOpCode == ocBad )
407 AddBad( aStrVal );
408 else if ( eOpCode == ocStringXML )
409 AddStringXML( aStrVal );
410 else if ( eOpCode == ocExternal || eOpCode == ocMacro )
411 AddToken( formula::FormulaExternalToken( eOpCode, aStrVal ) );
412 else
413 bError = true; // unexpected string: don't know what to do with it
415 break;
416 default:
417 bError = true;
418 } // switch ( eClass )
419 return bError;
422 bool FormulaTokenArray::Fill(
423 const uno::Sequence<sheet::FormulaToken>& rSequence,
424 svl::SharedStringPool& rSPool, ExternalReferenceHelper* pExtRef )
426 bool bError = false;
427 const sal_Int32 nCount = rSequence.getLength();
428 for (sal_Int32 nPos=0; nPos<nCount; nPos++)
430 bool bOneError = AddFormulaToken(rSequence[nPos], rSPool, pExtRef);
431 if (bOneError)
433 AddOpCode( ocErrName); // add something that indicates an error
434 bError = true;
437 return bError;
439 FormulaToken* FormulaTokenArray::GetNextReference()
441 while( nIndex < nLen )
443 FormulaToken* t = pCode[ nIndex++ ];
444 switch( t->GetType() )
446 case svSingleRef:
447 case svDoubleRef:
448 case svExternalSingleRef:
449 case svExternalDoubleRef:
450 return t;
451 default:
453 // added to avoid warnings
457 return NULL;
460 FormulaToken* FormulaTokenArray::GetNextColRowName()
462 while( nIndex < nLen )
464 FormulaToken* t = pCode[ nIndex++ ];
465 if ( t->GetOpCode() == ocColRowName )
466 return t;
468 return NULL;
471 FormulaToken* FormulaTokenArray::GetNextReferenceRPN()
473 while( nIndex < nRPN )
475 FormulaToken* t = pRPN[ nIndex++ ];
476 switch( t->GetType() )
478 case svSingleRef:
479 case svDoubleRef:
480 case svExternalSingleRef:
481 case svExternalDoubleRef:
482 return t;
483 default:
485 // added to avoid warnings
489 return NULL;
492 FormulaToken* FormulaTokenArray::GetNextReferenceOrName()
494 if( pCode )
496 while ( nIndex < nLen )
498 FormulaToken* t = pCode[ nIndex++ ];
499 switch( t->GetType() )
501 case svSingleRef:
502 case svDoubleRef:
503 case svIndex:
504 case svExternalSingleRef:
505 case svExternalDoubleRef:
506 case svExternalName:
507 return t;
508 default:
510 // added to avoid warnings
515 return NULL;
518 FormulaToken* FormulaTokenArray::GetNextName()
520 if( pCode )
522 while ( nIndex < nLen )
524 FormulaToken* t = pCode[ nIndex++ ];
525 if( t->GetType() == svIndex )
526 return t;
528 } // if( pCode )
529 return NULL;
532 FormulaToken* FormulaTokenArray::Next()
534 if( pCode && nIndex < nLen )
535 return pCode[ nIndex++ ];
536 else
537 return NULL;
540 FormulaToken* FormulaTokenArray::NextNoSpaces()
542 if( pCode )
544 while( (nIndex < nLen) && (pCode[ nIndex ]->GetOpCode() == ocSpaces) )
545 ++nIndex;
546 if( nIndex < nLen )
547 return pCode[ nIndex++ ];
549 return NULL;
552 FormulaToken* FormulaTokenArray::NextRPN()
554 if( pRPN && nIndex < nRPN )
555 return pRPN[ nIndex++ ];
556 else
557 return NULL;
560 FormulaToken* FormulaTokenArray::PrevRPN()
562 if( pRPN && nIndex )
563 return pRPN[ --nIndex ];
564 else
565 return NULL;
568 void FormulaTokenArray::DelRPN()
570 if( nRPN )
572 FormulaToken** p = pRPN;
573 for( sal_uInt16 i = 0; i < nRPN; i++ )
575 (*p++)->DecRef();
577 delete [] pRPN;
579 pRPN = NULL;
580 nRPN = nIndex = 0;
583 FormulaToken* FormulaTokenArray::PeekPrev( sal_uInt16 & nIdx )
585 if (0 < nIdx && nIdx <= nLen)
586 return pCode[--nIdx];
587 return NULL;
590 FormulaToken* FormulaTokenArray::PeekNext()
592 if( pCode && nIndex < nLen )
593 return pCode[ nIndex ];
594 else
595 return NULL;
598 FormulaToken* FormulaTokenArray::PeekNextNoSpaces()
600 if( pCode && nIndex < nLen )
602 sal_uInt16 j = nIndex;
603 while ( pCode[j]->GetOpCode() == ocSpaces && j < nLen )
604 j++;
605 if ( j < nLen )
606 return pCode[ j ];
607 else
608 return NULL;
610 else
611 return NULL;
614 FormulaToken* FormulaTokenArray::PeekPrevNoSpaces()
616 if( pCode && nIndex > 1 )
618 sal_uInt16 j = nIndex - 2;
619 while ( pCode[j]->GetOpCode() == ocSpaces && j > 0 )
620 j--;
621 if ( j > 0 || pCode[j]->GetOpCode() != ocSpaces )
622 return pCode[ j ];
623 else
624 return NULL;
626 else
627 return NULL;
630 bool FormulaTokenArray::HasReferences() const
632 for (sal_uInt16 i = 0; i < nLen; ++i)
634 if (pCode[i]->IsRef())
635 return true;
638 for (sal_uInt16 i = 0; i < nRPN; ++i)
640 if (pRPN[i]->IsRef())
641 return true;
644 return false;
647 bool FormulaTokenArray::HasExternalRef() const
649 for ( sal_uInt16 j=0; j < nLen; j++ )
651 if (pCode[j]->IsExternalRef())
652 return true;
654 return false;
657 bool FormulaTokenArray::HasOpCode( OpCode eOp ) const
659 for ( sal_uInt16 j=0; j < nLen; j++ )
661 if ( pCode[j]->GetOpCode() == eOp )
662 return true;
664 return false;
667 bool FormulaTokenArray::HasOpCodeRPN( OpCode eOp ) const
669 for ( sal_uInt16 j=0; j < nRPN; j++ )
671 if ( pRPN[j]->GetOpCode() == eOp )
672 return true;
674 return false;
677 bool FormulaTokenArray::HasNameOrColRowName() const
679 for ( sal_uInt16 j=0; j < nLen; j++ )
681 if( pCode[j]->GetType() == svIndex || pCode[j]->GetOpCode() == ocColRowName )
682 return true;
684 return false;
687 bool FormulaTokenArray::HasOpCodes(const unordered_opcode_set& rOpCodes) const
689 FormulaToken** p = pCode;
690 FormulaToken** pEnd = p + static_cast<size_t>(nLen);
691 for (; p != pEnd; ++p)
693 OpCode eOp = (*p)->GetOpCode();
694 if (rOpCodes.count(eOp) > 0)
695 return true;
698 return false;
701 FormulaTokenArray::FormulaTokenArray() :
702 pCode(NULL),
703 pRPN(NULL),
704 nLen(0),
705 nRPN(0),
706 nIndex(0),
707 nError(0),
708 nMode(ScRecalcMode::NORMAL),
709 bHyperLink(false),
710 mbFromRangeName(false)
714 FormulaTokenArray::FormulaTokenArray( const FormulaTokenArray& rArr )
716 Assign( rArr );
719 FormulaTokenArray::~FormulaTokenArray()
721 Clear();
724 void FormulaTokenArray::Assign( const FormulaTokenArray& r )
726 nLen = r.nLen;
727 nRPN = r.nRPN;
728 nIndex = r.nIndex;
729 nError = r.nError;
730 nMode = r.nMode;
731 bHyperLink = r.bHyperLink;
732 mbFromRangeName = r.mbFromRangeName;
733 pCode = NULL;
734 pRPN = NULL;
735 FormulaToken** pp;
736 if( nLen )
738 pp = pCode = new FormulaToken*[ nLen ];
739 memcpy( pp, r.pCode, nLen * sizeof( FormulaToken* ) );
740 for( sal_uInt16 i = 0; i < nLen; i++ )
741 (*pp++)->IncRef();
743 if( nRPN )
745 pp = pRPN = new FormulaToken*[ nRPN ];
746 memcpy( pp, r.pRPN, nRPN * sizeof( FormulaToken* ) );
747 for( sal_uInt16 i = 0; i < nRPN; i++ )
748 (*pp++)->IncRef();
752 /// Optimisation for efficiently creating StringXML placeholders
753 void FormulaTokenArray::Assign( sal_uInt16 nCode, FormulaToken **pTokens )
755 assert( nLen == 0 );
756 assert( pCode == NULL );
758 nLen = nCode;
759 pCode = new FormulaToken*[ nLen ];
761 for( sal_uInt16 i = 0; i < nLen; i++ )
763 FormulaToken *t = pTokens[ i ];
764 assert( t->GetOpCode() == ocStringXML );
765 pCode[ i ] = t;
766 t->IncRef();
770 FormulaTokenArray& FormulaTokenArray::operator=( const FormulaTokenArray& rArr )
772 Clear();
773 Assign( rArr );
774 return *this;
777 FormulaTokenArray* FormulaTokenArray::Clone() const
779 FormulaTokenArray* p = new FormulaTokenArray;
780 p->nLen = nLen;
781 p->nRPN = nRPN;
782 p->nMode = nMode;
783 p->nError = nError;
784 p->bHyperLink = bHyperLink;
785 p->mbFromRangeName = mbFromRangeName;
786 FormulaToken** pp;
787 if( nLen )
789 pp = p->pCode = new FormulaToken*[ nLen ];
790 memcpy( pp, pCode, nLen * sizeof( FormulaToken* ) );
791 for( sal_uInt16 i = 0; i < nLen; i++, pp++ )
793 *pp = (*pp)->Clone();
794 (*pp)->IncRef();
797 if( nRPN )
799 pp = p->pRPN = new FormulaToken*[ nRPN ];
800 memcpy( pp, pRPN, nRPN * sizeof( FormulaToken* ) );
801 for( sal_uInt16 i = 0; i < nRPN; i++, pp++ )
803 FormulaToken* t = *pp;
804 if( t->GetRef() > 1 )
806 FormulaToken** p2 = pCode;
807 sal_uInt16 nIdx = 0xFFFF;
808 for( sal_uInt16 j = 0; j < nLen; j++, p2++ )
810 if( *p2 == t )
812 nIdx = j; break;
815 if( nIdx == 0xFFFF )
816 *pp = t->Clone();
817 else
818 *pp = p->pCode[ nIdx ];
820 else
821 *pp = t->Clone();
822 (*pp)->IncRef();
825 return p;
828 void FormulaTokenArray::Clear()
830 if( nRPN ) DelRPN();
831 if( pCode )
833 FormulaToken** p = pCode;
834 for( sal_uInt16 i = 0; i < nLen; i++ )
836 (*p++)->DecRef();
838 delete [] pCode;
840 pCode = NULL; pRPN = NULL;
841 nError = nLen = nIndex = nRPN = 0;
842 bHyperLink = false;
843 mbFromRangeName = false;
844 ClearRecalcMode();
847 void FormulaTokenArray::CheckToken( const FormulaToken& /*r*/ )
849 // Do nothing.
852 FormulaToken* FormulaTokenArray::AddToken( const FormulaToken& r )
854 return Add( r.Clone() );
857 FormulaToken* FormulaTokenArray::MergeArray( )
859 return NULL;
862 FormulaToken* FormulaTokenArray::ReplaceToken( sal_uInt16 nOffset, FormulaToken* t,
863 FormulaTokenArray::ReplaceMode eMode )
865 if (eMode == BACKWARD_CODE_ONLY)
866 nOffset = nLen - nOffset - 1;
868 if (nOffset < nLen)
870 CheckToken(*t);
871 t->IncRef();
872 FormulaToken* p = pCode[nOffset];
873 pCode[nOffset] = t;
874 if (eMode == FORWARD_CODE_AND_RPN && p->GetRef() > 1)
876 for (sal_uInt16 i=0; i < nRPN; ++i)
878 if (pRPN[i] == p)
880 t->IncRef();
881 pRPN[i] = t;
882 p->DecRef();
883 if (p->GetRef() == 1)
884 break; // for
888 p->DecRef(); // may be dead now
889 return t;
891 else
893 t->Delete();
894 return NULL;
898 FormulaToken* FormulaTokenArray::Add( FormulaToken* t )
900 if( !pCode )
901 pCode = new FormulaToken*[ FORMULA_MAXTOKENS ];
902 if( nLen < FORMULA_MAXTOKENS - 1 )
904 CheckToken(*t);
905 pCode[ nLen++ ] = t;
906 t->IncRef();
907 if( t->GetOpCode() == ocArrayClose )
908 return MergeArray();
909 return t;
911 else
913 t->Delete();
914 if ( nLen == FORMULA_MAXTOKENS - 1 )
916 t = new FormulaByteToken( ocStop );
917 pCode[ nLen++ ] = t;
918 t->IncRef();
920 return NULL;
924 FormulaToken* FormulaTokenArray::AddString( const svl::SharedString& rStr )
926 return Add( new FormulaStringToken( rStr ) );
929 FormulaToken* FormulaTokenArray::AddDouble( double fVal )
931 return Add( new FormulaDoubleToken( fVal ) );
934 FormulaToken* FormulaTokenArray::AddExternal( const sal_Unicode* pStr )
936 return AddExternal( OUString( pStr ) );
939 FormulaToken* FormulaTokenArray::AddExternal( const OUString& rStr,
940 OpCode eOp /* = ocExternal */ )
942 return Add( new FormulaExternalToken( eOp, rStr ) );
945 FormulaToken* FormulaTokenArray::AddBad( const OUString& rStr )
947 return Add( new FormulaStringOpToken( ocBad, rStr ) );
950 FormulaToken* FormulaTokenArray::AddStringXML( const OUString& rStr )
952 return Add( new FormulaStringOpToken( ocStringXML, rStr ) );
957 void FormulaTokenArray::AddRecalcMode( ScRecalcMode nBits )
959 //! Order is important.
960 if ( nBits & ScRecalcMode::ALWAYS )
961 SetExclusiveRecalcModeAlways();
962 else if ( !IsRecalcModeAlways() )
964 if ( nBits & ScRecalcMode::ONLOAD )
965 SetExclusiveRecalcModeOnLoad();
966 else if ( nBits & ScRecalcMode::ONLOAD_ONCE && !IsRecalcModeOnLoad() )
967 SetExclusiveRecalcModeOnLoadOnce();
969 SetCombinedBitsRecalcMode( nBits );
973 bool FormulaTokenArray::HasMatrixDoubleRefOps()
975 if ( pRPN && nRPN )
977 // RPN-Interpreter simulation.
978 // Simply assumes a double as return value of each function.
979 boost::scoped_array<FormulaToken*> pStack(new FormulaToken* [nRPN]);
980 FormulaToken* pResult = new FormulaDoubleToken( 0.0 );
981 short sp = 0;
982 for ( sal_uInt16 j = 0; j < nRPN; j++ )
984 FormulaToken* t = pRPN[j];
985 OpCode eOp = t->GetOpCode();
986 sal_uInt8 nParams = t->GetParamCount();
987 switch ( eOp )
989 case ocAdd :
990 case ocSub :
991 case ocMul :
992 case ocDiv :
993 case ocPow :
994 case ocPower :
995 case ocAmpersand :
996 case ocEqual :
997 case ocNotEqual :
998 case ocLess :
999 case ocGreater :
1000 case ocLessEqual :
1001 case ocGreaterEqual :
1003 for ( sal_uInt8 k = nParams; k; k-- )
1005 if ( sp >= k && pStack[sp-k]->GetType() == svDoubleRef )
1007 pResult->Delete();
1008 return true;
1012 break;
1013 default:
1015 // added to avoid warnings
1018 if ( eOp == ocPush || lcl_IsReference( eOp, t->GetType() ) )
1019 pStack[sp++] = t;
1020 else if ( eOp == ocIf || eOp == ocIfError || eOp == ocIfNA || eOp == ocChoose )
1021 { // ignore Jumps, pop previous Result (Condition)
1022 if ( sp )
1023 --sp;
1025 else
1026 { // pop parameters, push result
1027 sp = sal::static_int_cast<short>( sp - nParams );
1028 if ( sp < 0 )
1030 SAL_WARN("formula.core", "FormulaTokenArray::HasMatrixDoubleRefOps: sp < 0" );
1031 sp = 0;
1033 pStack[sp++] = pResult;
1036 pResult->Delete();
1039 return false;
1042 // --- Formula rewrite of a token array
1044 inline bool MissingConventionODF::isRewriteNeeded( OpCode eOp ) const
1046 switch (eOp)
1048 case ocGammaDist:
1049 case ocPoissonDist:
1050 case ocAddress:
1051 case ocLogNormDist:
1052 case ocNormDist:
1053 return true;
1054 case ocMissing:
1055 case ocLog:
1056 return isPODF(); // rewrite only for PODF
1057 default:
1058 return false;
1063 fdo 81596
1064 To be implemented yet:
1065 ocExternal: ?
1066 ocMacro: ?
1067 ocIndex: INDEX() ?
1069 inline bool MissingConventionOOXML::isRewriteNeeded( OpCode eOp )
1071 switch (eOp)
1073 case ocIf:
1075 case ocExternal:
1076 case ocEuroConvert:
1077 case ocMacro:
1079 case ocRound:
1080 case ocRoundUp:
1081 case ocRoundDown:
1083 case ocIndex:
1085 case ocCeil:
1086 case ocFloor:
1088 case ocGammaDist:
1089 case ocFDist_LT:
1090 case ocPoissonDist:
1091 case ocNormDist:
1092 case ocLogNormDist:
1093 return true;
1094 default:
1095 return false;
1099 class FormulaMissingContext
1101 public:
1102 const FormulaToken* mpFunc;
1103 int mnCurArg;
1105 void Clear() { mpFunc = NULL; mnCurArg = 0; }
1106 inline bool AddDefaultArg( FormulaTokenArray* pNewArr, int nArg, double f ) const;
1107 bool AddMissingExternal( FormulaTokenArray* pNewArr ) const;
1108 bool AddMissing( FormulaTokenArray *pNewArr, const MissingConvention & rConv ) const;
1109 void AddMoreArgs( FormulaTokenArray *pNewArr, const MissingConvention & rConv ) const;
1112 void FormulaMissingContext::AddMoreArgs( FormulaTokenArray *pNewArr, const MissingConvention & rConv ) const
1114 if ( !mpFunc )
1115 return;
1117 switch (rConv.getConvention())
1119 case MissingConvention::FORMULA_MISSING_CONVENTION_ODFF:
1120 case MissingConvention::FORMULA_MISSING_CONVENTION_PODF:
1122 switch (mpFunc->GetOpCode())
1124 case ocGammaDist:
1125 if (mnCurArg == 2)
1127 pNewArr->AddOpCode( ocSep );
1128 pNewArr->AddDouble( 1.0 ); // 4th, Cumulative=true()
1130 break;
1131 case ocPoissonDist:
1132 if (mnCurArg == 1)
1134 pNewArr->AddOpCode( ocSep );
1135 pNewArr->AddDouble( 1.0 ); // 3rd, Cumulative=true()
1137 break;
1138 case ocNormDist:
1139 if ( mnCurArg == 2 )
1141 pNewArr->AddOpCode( ocSep );
1142 pNewArr->AddDouble( 1.0 ); // 4th, Cumulative=true()
1144 break;
1145 case ocLogNormDist:
1146 if ( mnCurArg == 0 )
1148 pNewArr->AddOpCode( ocSep );
1149 pNewArr->AddDouble( 0.0 ); // 2nd, mean = 0.0
1151 if ( mnCurArg <= 1 )
1153 pNewArr->AddOpCode( ocSep );
1154 pNewArr->AddDouble( 1.0 ); // 3rd, standard deviation = 1.0
1156 break;
1157 case ocLog:
1158 if ( rConv.isPODF() && mnCurArg == 0 )
1160 pNewArr->AddOpCode( ocSep );
1161 pNewArr->AddDouble( 10.0 ); // 2nd, basis 10
1163 break;
1164 default:
1165 break;
1168 break;
1169 case MissingConvention::FORMULA_MISSING_CONVENTION_OOXML:
1171 switch (mpFunc->GetOpCode())
1173 case ocIf:
1174 if( mnCurArg == 0 )
1176 // Excel needs at least two parameters in IF function
1177 pNewArr->AddOpCode( ocSep );
1178 pNewArr->AddOpCode( ocTrue ); // 2nd, true() as function
1179 pNewArr->AddOpCode( ocOpen ); // so the result is of logical type
1180 pNewArr->AddOpCode( ocClose ); // and survives roundtrip
1182 break;
1184 case ocEuroConvert:
1185 if ( mnCurArg == 2 )
1187 pNewArr->AddOpCode( ocSep );
1188 pNewArr->AddDouble( 0.0 ); // 4th, FullPrecision = false()
1190 break;
1192 case ocPoissonDist:
1193 if (mnCurArg == 1)
1195 pNewArr->AddOpCode( ocSep );
1196 pNewArr->AddDouble( 1.0 ); // 3rd, Cumulative=true()
1198 break;
1200 case ocGammaDist:
1201 case ocFDist_LT:
1202 case ocNormDist:
1203 if (mnCurArg == 2)
1205 pNewArr->AddOpCode( ocSep );
1206 pNewArr->AddDouble( 1.0 ); // 4th, Cumulative=true()
1208 break;
1210 case ocLogNormDist:
1211 if ( mnCurArg == 0 )
1213 pNewArr->AddOpCode( ocSep );
1214 pNewArr->AddDouble( 0.0 ); // 2nd, mean = 0.0
1216 if ( mnCurArg <= 1 )
1218 pNewArr->AddOpCode( ocSep );
1219 pNewArr->AddDouble( 1.0 ); // 3rd, standard deviation = 1.0
1221 break;
1223 case ocRound:
1224 case ocRoundUp:
1225 case ocRoundDown:
1226 if( mnCurArg == 0 )
1228 // ROUND, ROUNDUP, ROUNDDOWN functions are fixed to 2 parameters in Excel
1229 pNewArr->AddOpCode( ocSep );
1230 pNewArr->AddDouble( 0.0 ); // 2nd, 0.0
1232 break;
1234 default:
1235 break;
1238 break;
1243 inline bool FormulaMissingContext::AddDefaultArg( FormulaTokenArray* pNewArr, int nArg, double f ) const
1245 if (mnCurArg == nArg)
1247 pNewArr->AddDouble( f );
1248 return true;
1250 return false;
1253 bool FormulaMissingContext::AddMissingExternal( FormulaTokenArray *pNewArr ) const
1255 // Only called for PODF, not ODFF. No need to distinguish.
1257 const OUString &rName = mpFunc->GetExternal();
1259 // initial (fast) check:
1260 sal_Unicode nLastChar = rName[ rName.getLength() - 1];
1261 if ( nLastChar != 't' && nLastChar != 'm' )
1262 return false;
1264 if (rName.equalsIgnoreAsciiCase(
1265 "com.sun.star.sheet.addin.Analysis.getAccrint" ))
1267 return AddDefaultArg( pNewArr, 4, 1000.0 );
1269 if (rName.equalsIgnoreAsciiCase(
1270 "com.sun.star.sheet.addin.Analysis.getAccrintm" ))
1272 return AddDefaultArg( pNewArr, 3, 1000.0 );
1274 return false;
1277 bool FormulaMissingContext::AddMissing( FormulaTokenArray *pNewArr, const MissingConvention & rConv ) const
1279 if ( !mpFunc )
1280 return false;
1282 bool bRet = false;
1283 const OpCode eOp = mpFunc->GetOpCode();
1285 switch (rConv.getConvention())
1287 case MissingConvention::FORMULA_MISSING_CONVENTION_ODFF:
1289 // Add for ODFF
1290 switch (eOp)
1292 case ocAddress:
1293 return AddDefaultArg( pNewArr, 2, 1.0 ); // abs
1294 default:
1295 break;
1298 break;
1299 case MissingConvention::FORMULA_MISSING_CONVENTION_PODF:
1301 // Add for PODF
1302 switch (eOp)
1304 case ocAddress:
1305 return AddDefaultArg( pNewArr, 2, 1.0 ); // abs
1306 case ocFixed:
1307 return AddDefaultArg( pNewArr, 1, 2.0 );
1308 case ocBetaDist:
1309 case ocBetaInv:
1310 case ocPMT:
1311 return AddDefaultArg( pNewArr, 3, 0.0 );
1312 case ocIpmt:
1313 case ocPpmt:
1314 return AddDefaultArg( pNewArr, 4, 0.0 );
1315 case ocPV:
1316 case ocFV:
1317 bRet |= AddDefaultArg( pNewArr, 2, 0.0 ); // pmt
1318 bRet |= AddDefaultArg( pNewArr, 3, 0.0 ); // [fp]v
1319 break;
1320 case ocRate:
1321 bRet |= AddDefaultArg( pNewArr, 1, 0.0 ); // pmt
1322 bRet |= AddDefaultArg( pNewArr, 3, 0.0 ); // fv
1323 bRet |= AddDefaultArg( pNewArr, 4, 0.0 ); // type
1324 break;
1325 case ocExternal:
1326 return AddMissingExternal( pNewArr );
1328 // --- more complex cases ---
1330 case ocOffset:
1331 // FIXME: rather tough.
1332 // if arg 3 (height) omitted, export arg1 (rows)
1333 break;
1334 default:
1335 break;
1338 break;
1339 case MissingConvention::FORMULA_MISSING_CONVENTION_OOXML:
1341 switch (eOp)
1343 case ocExternal:
1344 return AddMissingExternal( pNewArr );
1345 default:
1346 break;
1349 break;
1352 return bRet;
1355 bool FormulaTokenArray::NeedsPodfRewrite( const MissingConventionODF & rConv )
1357 for ( FormulaToken *pCur = First(); pCur; pCur = Next() )
1359 if ( rConv.isRewriteNeeded( pCur->GetOpCode()))
1360 return true;
1362 return false;
1365 bool FormulaTokenArray::NeedsOoxmlRewrite()
1367 for ( FormulaToken *pCur = First(); pCur; pCur = Next() )
1369 if ( MissingConventionOOXML::isRewriteNeeded( pCur->GetOpCode()))
1370 return true;
1372 return false;
1376 FormulaTokenArray * FormulaTokenArray::RewriteMissing( const MissingConvention & rConv )
1378 const size_t nAlloc = 256;
1379 FormulaMissingContext aCtx[ nAlloc ];
1380 int aOpCodeAddressStack[ nAlloc ]; // use of ADDRESS() function
1381 const int nOmitAddressArg = 3; // ADDRESS() 4th parameter A1/R1C1
1382 sal_uInt16 nTokens = GetLen() + 1;
1383 FormulaMissingContext* pCtx = (nAlloc < nTokens ? new FormulaMissingContext[nTokens] : &aCtx[0]);
1384 int* pOcas = (nAlloc < nTokens ? new int[nTokens] : &aOpCodeAddressStack[0]);
1385 // Never go below 0, never use 0, mpFunc always NULL.
1386 pCtx[0].Clear();
1387 int nFn = 0;
1388 int nOcas = 0;
1390 FormulaTokenArray *pNewArr = new FormulaTokenArray;
1391 // At least ScRecalcMode::ALWAYS needs to be set.
1392 pNewArr->AddRecalcMode( GetRecalcMode());
1394 for ( FormulaToken *pCur = First(); pCur; pCur = Next() )
1396 bool bAdd = true;
1397 // Don't write the expression of the new inserted ADDRESS() parameter.
1398 // Do NOT omit the new second parameter of INDIRECT() though. If that
1399 // was done for both, INDIRECT() actually could calculate different and
1400 // valid (but wrong) results with the then changed return value of
1401 // ADDRESS(). Better let it generate an error instead.
1402 for (int i = nOcas; i-- > 0 && bAdd; )
1404 if (pCtx[ pOcas[ i ] ].mnCurArg == nOmitAddressArg)
1406 // Omit erverything except a trailing separator, the leading
1407 // separator is omitted below. The other way around would leave
1408 // an extraneous separator if no parameter followed.
1409 if (!(pOcas[ i ] == nFn && pCur->GetOpCode() == ocSep))
1410 bAdd = false;
1413 switch ( pCur->GetOpCode() )
1415 case ocOpen:
1416 ++nFn; // all following operations on _that_ function
1417 pCtx[ nFn ].mpFunc = PeekPrevNoSpaces();
1418 pCtx[ nFn ].mnCurArg = 0;
1419 if (rConv.isPODF() && pCtx[ nFn ].mpFunc && pCtx[ nFn ].mpFunc->GetOpCode() == ocAddress)
1420 pOcas[ nOcas++ ] = nFn; // entering ADDRESS() if PODF
1421 break;
1422 case ocClose:
1423 pCtx[ nFn ].AddMoreArgs( pNewArr, rConv );
1424 DBG_ASSERT( nFn > 0, "FormulaTokenArray::RewriteMissing: underflow");
1425 if (nOcas > 0 && pOcas[ nOcas-1 ] == nFn)
1426 --nOcas; // leaving ADDRESS()
1427 if (nFn > 0)
1428 --nFn;
1429 break;
1430 case ocSep:
1431 pCtx[ nFn ].mnCurArg++;
1432 // Omit leading separator of ADDRESS() parameter.
1433 if (nOcas && pOcas[ nOcas-1 ] == nFn && pCtx[ nFn ].mnCurArg == nOmitAddressArg)
1435 bAdd = false;
1437 break;
1438 case ocMissing:
1439 if ( bAdd )
1440 bAdd = !pCtx[ nFn ].AddMissing( pNewArr, rConv );
1441 break;
1442 default:
1443 break;
1445 if (bAdd)
1447 if ( ( pCur->GetOpCode() == ocCeil || pCur->GetOpCode() == ocFloor ) &&
1448 rConv.getConvention() == MissingConvention::FORMULA_MISSING_CONVENTION_OOXML )
1450 FormulaToken *pToken = new FormulaToken( svByte,
1451 ( pCur->GetOpCode() == ocCeil ? ocCeil_Math : ocFloor_Math ) );
1452 pNewArr->AddToken( *pToken );
1454 else
1455 pNewArr->AddToken( *pCur );
1459 if (pOcas != &aOpCodeAddressStack[0])
1460 delete [] pOcas;
1461 if (pCtx != &aCtx[0])
1462 delete [] pCtx;
1464 return pNewArr;
1467 bool FormulaTokenArray::MayReferenceFollow()
1469 if ( pCode && nLen > 0 )
1471 // ignore trailing spaces
1472 sal_uInt16 i = nLen - 1;
1473 while ( i > 0 && pCode[i]->GetOpCode() == SC_OPCODE_SPACES )
1475 --i;
1477 if ( i > 0 || pCode[i]->GetOpCode() != SC_OPCODE_SPACES )
1479 OpCode eOp = pCode[i]->GetOpCode();
1480 if ( (SC_OPCODE_START_BIN_OP <= eOp && eOp < SC_OPCODE_STOP_BIN_OP ) ||
1481 (SC_OPCODE_START_UN_OP <= eOp && eOp < SC_OPCODE_STOP_UN_OP ) ||
1482 eOp == SC_OPCODE_OPEN || eOp == SC_OPCODE_SEP )
1484 return true;
1488 return false;
1490 FormulaToken* FormulaTokenArray::AddOpCode( OpCode eOp )
1492 FormulaToken* pRet = NULL;
1493 switch ( eOp )
1495 case ocOpen:
1496 case ocClose:
1497 case ocSep:
1498 case ocArrayOpen:
1499 case ocArrayClose:
1500 case ocArrayRowSep:
1501 case ocArrayColSep:
1502 pRet = new FormulaToken( svSep,eOp );
1503 break;
1504 case ocIf:
1505 case ocIfError:
1506 case ocIfNA:
1507 case ocChoose:
1509 short nJump[FORMULA_MAXJUMPCOUNT + 1];
1510 if ( eOp == ocIf )
1511 nJump[ 0 ] = 3;
1512 else if ( eOp == ocChoose )
1513 nJump[ 0 ] = FORMULA_MAXJUMPCOUNT + 1;
1514 else
1515 nJump[ 0 ] = 2;
1516 pRet = new FormulaJumpToken( eOp, (short*)nJump );
1518 break;
1519 default:
1520 pRet = new FormulaByteToken( eOp, 0, false );
1521 break;
1523 return AddToken( *pRet );
1527 /*----------------------------------------------------------------------*/
1529 FormulaTokenIterator::Item::Item(const FormulaTokenArray* pArray, short pc, short stop) :
1530 pArr(pArray), nPC(pc), nStop(stop)
1534 FormulaTokenIterator::FormulaTokenIterator( const FormulaTokenArray& rArr )
1536 maStack = new std::vector<FormulaTokenIterator::Item> ();
1537 Push( &rArr );
1540 FormulaTokenIterator::~FormulaTokenIterator()
1542 delete maStack;
1545 void FormulaTokenIterator::Push( const FormulaTokenArray* pArr )
1547 FormulaTokenIterator::Item item(pArr, -1, SHRT_MAX);
1549 maStack->push_back(item);
1552 void FormulaTokenIterator::Pop()
1554 maStack->pop_back();
1557 void FormulaTokenIterator::Reset()
1559 while( maStack->size() > 1 )
1560 maStack->pop_back();
1562 maStack->back().nPC = -1;
1565 const FormulaToken* FormulaTokenIterator::Next()
1567 const FormulaToken* t = GetNonEndOfPathToken( ++maStack->back().nPC );
1568 if( !t && maStack->size() > 1 )
1570 Pop();
1571 t = Next();
1573 return t;
1576 const FormulaToken* FormulaTokenIterator::PeekNextOperator()
1578 const FormulaToken* t = NULL;
1579 short nIdx = maStack->back().nPC;
1580 while (!t && ((t = GetNonEndOfPathToken( ++nIdx)) != NULL))
1582 if (t->GetOpCode() == ocPush)
1583 t = NULL; // ignore operands
1585 if (!t && maStack->size() > 1)
1587 FormulaTokenIterator::Item pHere = maStack->back();
1588 maStack->pop_back();
1589 t = PeekNextOperator();
1590 maStack->push_back(pHere);
1592 return t;
1595 //! The nPC counts after a Push() are -1
1597 void FormulaTokenIterator::Jump( short nStart, short nNext, short nStop )
1599 maStack->back().nPC = nNext;
1600 if( nStart != nNext )
1602 Push( maStack->back().pArr );
1603 maStack->back().nPC = nStart;
1604 maStack->back().nStop = nStop;
1608 const FormulaToken* FormulaTokenIterator::GetNonEndOfPathToken( short nIdx ) const
1610 FormulaTokenIterator::Item cur = maStack->back();
1612 if (nIdx < cur.pArr->nRPN && nIdx < cur.nStop)
1614 const FormulaToken* t = cur.pArr->pRPN[ nIdx ];
1615 // such an OpCode ends an IF() or CHOOSE() path
1616 return (t->GetOpCode() == ocSep || t->GetOpCode() == ocClose) ? NULL : t;
1618 return NULL;
1621 bool FormulaTokenIterator::IsEndOfPath() const
1623 return GetNonEndOfPathToken( maStack->back().nPC + 1) == NULL;
1628 // real implementations of virtual functions
1631 double FormulaDoubleToken::GetDouble() const { return fDouble; }
1632 double & FormulaDoubleToken::GetDoubleAsReference() { return fDouble; }
1633 bool FormulaDoubleToken::operator==( const FormulaToken& r ) const
1635 return FormulaToken::operator==( r ) && fDouble == r.GetDouble();
1638 FormulaStringToken::FormulaStringToken( const svl::SharedString& r ) :
1639 FormulaToken( svString ), maString( r )
1643 FormulaStringToken::FormulaStringToken( const FormulaStringToken& r ) :
1644 FormulaToken( r ), maString( r.maString ) {}
1646 FormulaToken* FormulaStringToken::Clone() const
1648 return new FormulaStringToken(*this);
1651 svl::SharedString FormulaStringToken::GetString() const
1653 return maString;
1656 bool FormulaStringToken::operator==( const FormulaToken& r ) const
1658 return FormulaToken::operator==( r ) && maString == r.GetString();
1661 FormulaStringOpToken::FormulaStringOpToken( OpCode e, const svl::SharedString& r ) :
1662 FormulaByteToken( e, 0, svString, false ), maString( r ) {}
1664 FormulaStringOpToken::FormulaStringOpToken( const FormulaStringOpToken& r ) :
1665 FormulaByteToken( r ), maString( r.maString ) {}
1667 FormulaToken* FormulaStringOpToken::Clone() const
1669 return new FormulaStringOpToken(*this);
1672 svl::SharedString FormulaStringOpToken::GetString() const
1674 return maString;
1677 bool FormulaStringOpToken::operator==( const FormulaToken& r ) const
1679 return FormulaByteToken::operator==( r ) && maString == r.GetString();
1682 sal_uInt16 FormulaIndexToken::GetIndex() const { return nIndex; }
1683 void FormulaIndexToken::SetIndex( sal_uInt16 n ) { nIndex = n; }
1684 bool FormulaIndexToken::IsGlobal() const { return mbGlobal; }
1685 void FormulaIndexToken::SetGlobal( bool b ) { mbGlobal = b; }
1686 bool FormulaIndexToken::operator==( const FormulaToken& r ) const
1688 return FormulaToken::operator==( r ) && nIndex == r.GetIndex() &&
1689 mbGlobal == r.IsGlobal();
1691 const OUString& FormulaExternalToken::GetExternal() const { return aExternal; }
1692 sal_uInt8 FormulaExternalToken::GetByte() const { return nByte; }
1693 void FormulaExternalToken::SetByte( sal_uInt8 n ) { nByte = n; }
1694 bool FormulaExternalToken::operator==( const FormulaToken& r ) const
1696 return FormulaToken::operator==( r ) && nByte == r.GetByte() &&
1697 aExternal == r.GetExternal();
1701 sal_uInt16 FormulaErrorToken::GetError() const { return nError; }
1702 void FormulaErrorToken::SetError( sal_uInt16 nErr ) { nError = nErr; }
1703 bool FormulaErrorToken::operator==( const FormulaToken& r ) const
1705 return FormulaToken::operator==( r ) &&
1706 nError == static_cast< const FormulaErrorToken & >(r).GetError();
1708 double FormulaMissingToken::GetDouble() const { return 0.0; }
1710 svl::SharedString FormulaMissingToken::GetString() const
1712 return svl::SharedString::getEmptyString();
1715 bool FormulaMissingToken::operator==( const FormulaToken& r ) const
1717 return FormulaToken::operator==( r );
1721 FormulaSubroutineToken::FormulaSubroutineToken( const FormulaSubroutineToken& r ) :
1722 FormulaToken( r ),
1723 mpArray( r.mpArray->Clone())
1726 FormulaSubroutineToken::~FormulaSubroutineToken()
1728 delete mpArray;
1730 bool FormulaSubroutineToken::operator==( const FormulaToken& r ) const
1732 // Arrays don't equal..
1733 return FormulaToken::operator==( r ) &&
1734 (mpArray == static_cast<const FormulaSubroutineToken&>(r).mpArray);
1738 bool FormulaUnknownToken::operator==( const FormulaToken& r ) const
1740 return FormulaToken::operator==( r );
1744 } // formula
1747 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */