1*c25918c1SAndrew Rist /**************************************************************
2cdf0e10cSrcweir *
3*c25918c1SAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one
4*c25918c1SAndrew Rist * or more contributor license agreements. See the NOTICE file
5*c25918c1SAndrew Rist * distributed with this work for additional information
6*c25918c1SAndrew Rist * regarding copyright ownership. The ASF licenses this file
7*c25918c1SAndrew Rist * to you under the Apache License, Version 2.0 (the
8*c25918c1SAndrew Rist * "License"); you may not use this file except in compliance
9*c25918c1SAndrew Rist * with the License. You may obtain a copy of the License at
10cdf0e10cSrcweir *
11*c25918c1SAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0
12cdf0e10cSrcweir *
13*c25918c1SAndrew Rist * Unless required by applicable law or agreed to in writing,
14*c25918c1SAndrew Rist * software distributed under the License is distributed on an
15*c25918c1SAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*c25918c1SAndrew Rist * KIND, either express or implied. See the License for the
17*c25918c1SAndrew Rist * specific language governing permissions and limitations
18*c25918c1SAndrew Rist * under the License.
19cdf0e10cSrcweir *
20*c25918c1SAndrew Rist *************************************************************/
21*c25918c1SAndrew Rist
22*c25918c1SAndrew Rist
23cdf0e10cSrcweir
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_formula.hxx"
26cdf0e10cSrcweir
27cdf0e10cSrcweir
28cdf0e10cSrcweir
29cdf0e10cSrcweir // INCLUDE ---------------------------------------------------------------
30cdf0e10cSrcweir
31cdf0e10cSrcweir #include <cstddef>
32cdf0e10cSrcweir #include <cstdio>
33cdf0e10cSrcweir
34cdf0e10cSrcweir #include <string.h>
35cdf0e10cSrcweir #include <limits.h>
36cdf0e10cSrcweir #include <tools/debug.hxx>
37cdf0e10cSrcweir
38cdf0e10cSrcweir #include "formula/token.hxx"
39cdf0e10cSrcweir #include "formula/tokenarray.hxx"
40cdf0e10cSrcweir #include "formula/FormulaCompiler.hxx"
41cdf0e10cSrcweir #include <formula/compiler.hrc>
42cdf0e10cSrcweir //#include "rechead.hxx"
43cdf0e10cSrcweir //#include "parclass.hxx"
44cdf0e10cSrcweir //#include "jumpmatrix.hxx"
45cdf0e10cSrcweir #define MAXJUMPCOUNT 32 /* maximum number of jumps (ocChose) */
46cdf0e10cSrcweir
47cdf0e10cSrcweir namespace formula
48cdf0e10cSrcweir {
49cdf0e10cSrcweir using namespace com::sun::star;
50cdf0e10cSrcweir // ImpTokenIterator wird je Interpreter angelegt, mehrfache auch durch
51cdf0e10cSrcweir // SubCode via FormulaTokenIterator Push/Pop moeglich
52cdf0e10cSrcweir IMPL_FIXEDMEMPOOL_NEWDEL( ImpTokenIterator, 32, 16 )
53cdf0e10cSrcweir
54cdf0e10cSrcweir // Align MemPools on 4k boundaries - 64 bytes (4k is a MUST for OS/2)
55cdf0e10cSrcweir
56cdf0e10cSrcweir // Need a lot of FormulaDoubleToken
57cdf0e10cSrcweir const sal_uInt16 nMemPoolDoubleToken = (0x3000 - 64) / sizeof(FormulaDoubleToken);
58cdf0e10cSrcweir IMPL_FIXEDMEMPOOL_NEWDEL_DLL( FormulaDoubleToken, nMemPoolDoubleToken, nMemPoolDoubleToken )
59cdf0e10cSrcweir // Need a lot of FormulaByteToken
60cdf0e10cSrcweir const sal_uInt16 nMemPoolByteToken = (0x3000 - 64) / sizeof(FormulaByteToken);
61cdf0e10cSrcweir IMPL_FIXEDMEMPOOL_NEWDEL_DLL( FormulaByteToken, nMemPoolByteToken, nMemPoolByteToken )
62cdf0e10cSrcweir // Need several FormulaStringToken
63cdf0e10cSrcweir const sal_uInt16 nMemPoolStringToken = (0x1000 - 64) / sizeof(FormulaStringToken);
IMPL_FIXEDMEMPOOL_NEWDEL_DLL(FormulaStringToken,nMemPoolStringToken,nMemPoolStringToken)64cdf0e10cSrcweir IMPL_FIXEDMEMPOOL_NEWDEL_DLL( FormulaStringToken, nMemPoolStringToken, nMemPoolStringToken )
65cdf0e10cSrcweir
66cdf0e10cSrcweir
67cdf0e10cSrcweir // --- helpers --------------------------------------------------------------
68cdf0e10cSrcweir
69cdf0e10cSrcweir inline sal_Bool lcl_IsReference( OpCode eOp, StackVar eType )
70cdf0e10cSrcweir {
71cdf0e10cSrcweir return
72cdf0e10cSrcweir (eOp == ocPush && (eType == svSingleRef || eType == svDoubleRef))
73cdf0e10cSrcweir || (eOp == ocColRowNameAuto && eType == svDoubleRef)
74cdf0e10cSrcweir || (eOp == ocColRowName && eType == svSingleRef)
75cdf0e10cSrcweir || (eOp == ocMatRef && eType == svSingleRef)
76cdf0e10cSrcweir ;
77cdf0e10cSrcweir }
78cdf0e10cSrcweir
79cdf0e10cSrcweir // --- class FormulaToken --------------------------------------------------------
~FormulaToken()80cdf0e10cSrcweir FormulaToken::~FormulaToken()
81cdf0e10cSrcweir {
82cdf0e10cSrcweir }
83cdf0e10cSrcweir
Is3DRef() const84cdf0e10cSrcweir sal_Bool FormulaToken::Is3DRef() const
85cdf0e10cSrcweir {
86cdf0e10cSrcweir return sal_False;
87cdf0e10cSrcweir }
88cdf0e10cSrcweir
IsFunction() const89cdf0e10cSrcweir sal_Bool FormulaToken::IsFunction() const
90cdf0e10cSrcweir {
91cdf0e10cSrcweir // OpCode eOp = GetOpCode();
92cdf0e10cSrcweir return (eOp != ocPush && eOp != ocBad && eOp != ocColRowName &&
93cdf0e10cSrcweir eOp != ocColRowNameAuto && eOp != ocName && eOp != ocDBArea &&
94cdf0e10cSrcweir (GetByte() != 0 // x parameters
95cdf0e10cSrcweir || (SC_OPCODE_START_NO_PAR <= eOp && eOp < SC_OPCODE_STOP_NO_PAR) // no parameter
96cdf0e10cSrcweir || (ocIf == eOp || ocChose == eOp ) // @ jump commands
97cdf0e10cSrcweir || (SC_OPCODE_START_1_PAR <= eOp && eOp < SC_OPCODE_STOP_1_PAR) // one parameter
98cdf0e10cSrcweir || (SC_OPCODE_START_2_PAR <= eOp && eOp < SC_OPCODE_STOP_2_PAR) // x parameters (cByte==0 in
99cdf0e10cSrcweir // FuncAutoPilot)
100cdf0e10cSrcweir || eOp == ocMacro || eOp == ocExternal // macros, AddIns
101cdf0e10cSrcweir || eOp == ocAnd || eOp == ocOr // former binary, now x parameters
102cdf0e10cSrcweir || eOp == ocNot || eOp == ocNeg // unary but function
103cdf0e10cSrcweir || (eOp >= ocInternalBegin && eOp <= ocInternalEnd) // internal
104cdf0e10cSrcweir ));
105cdf0e10cSrcweir }
106cdf0e10cSrcweir
107cdf0e10cSrcweir
GetParamCount() const108cdf0e10cSrcweir sal_uInt8 FormulaToken::GetParamCount() const
109cdf0e10cSrcweir {
110cdf0e10cSrcweir // OpCode eOp = GetOpCode();
111cdf0e10cSrcweir if ( eOp < SC_OPCODE_STOP_DIV && eOp != ocExternal && eOp != ocMacro &&
112cdf0e10cSrcweir eOp != ocIf && eOp != ocChose && eOp != ocPercentSign )
113cdf0e10cSrcweir return 0; // parameters and specials
114cdf0e10cSrcweir // ocIf and ocChose not for FAP, have cByte then
115cdf0e10cSrcweir //2do: sal_Bool parameter whether FAP or not?
116cdf0e10cSrcweir else if ( GetByte() )
117cdf0e10cSrcweir return GetByte(); // all functions, also ocExternal and ocMacro
118cdf0e10cSrcweir else if (SC_OPCODE_START_BIN_OP <= eOp && eOp < SC_OPCODE_STOP_BIN_OP)
119cdf0e10cSrcweir return 2; // binary
120cdf0e10cSrcweir else if ((SC_OPCODE_START_UN_OP <= eOp && eOp < SC_OPCODE_STOP_UN_OP)
121cdf0e10cSrcweir || eOp == ocPercentSign)
122cdf0e10cSrcweir return 1; // unary
123cdf0e10cSrcweir else if (SC_OPCODE_START_NO_PAR <= eOp && eOp < SC_OPCODE_STOP_NO_PAR)
124cdf0e10cSrcweir return 0; // no parameter
125cdf0e10cSrcweir else if (SC_OPCODE_START_1_PAR <= eOp && eOp < SC_OPCODE_STOP_1_PAR)
126cdf0e10cSrcweir return 1; // one parameter
127cdf0e10cSrcweir else if ( eOp == ocIf || eOp == ocChose )
128cdf0e10cSrcweir return 1; // only the condition counts as parameter
129cdf0e10cSrcweir else
130cdf0e10cSrcweir return 0; // all the rest, no Parameter, or
131cdf0e10cSrcweir // if so then it should be in cByte
132cdf0e10cSrcweir }
133cdf0e10cSrcweir
134cdf0e10cSrcweir
IsMatrixFunction() const135cdf0e10cSrcweir sal_Bool FormulaToken::IsMatrixFunction() const
136cdf0e10cSrcweir {
137cdf0e10cSrcweir return formula::FormulaCompiler::IsMatrixFunction(GetOpCode());
138cdf0e10cSrcweir }
139cdf0e10cSrcweir
operator ==(const FormulaToken & rToken) const140cdf0e10cSrcweir sal_Bool FormulaToken::operator==( const FormulaToken& rToken ) const
141cdf0e10cSrcweir {
142cdf0e10cSrcweir // don't compare reference count!
143cdf0e10cSrcweir return eType == rToken.eType && GetOpCode() == rToken.GetOpCode();
144cdf0e10cSrcweir }
145cdf0e10cSrcweir
146cdf0e10cSrcweir
147cdf0e10cSrcweir // --- virtual dummy methods -------------------------------------------------
148cdf0e10cSrcweir
GetByte() const149cdf0e10cSrcweir sal_uInt8 FormulaToken::GetByte() const
150cdf0e10cSrcweir {
151cdf0e10cSrcweir // ok to be called for any derived class
152cdf0e10cSrcweir return 0;
153cdf0e10cSrcweir }
154cdf0e10cSrcweir
SetByte(sal_uInt8)155cdf0e10cSrcweir void FormulaToken::SetByte( sal_uInt8 )
156cdf0e10cSrcweir {
157cdf0e10cSrcweir DBG_ERRORFILE( "FormulaToken::SetByte: virtual dummy called" );
158cdf0e10cSrcweir }
159cdf0e10cSrcweir
HasForceArray() const160cdf0e10cSrcweir bool FormulaToken::HasForceArray() const
161cdf0e10cSrcweir {
162cdf0e10cSrcweir // ok to be called for any derived class
163cdf0e10cSrcweir return false;
164cdf0e10cSrcweir }
165cdf0e10cSrcweir
SetForceArray(bool)166cdf0e10cSrcweir void FormulaToken::SetForceArray( bool )
167cdf0e10cSrcweir {
168cdf0e10cSrcweir DBG_ERRORFILE( "FormulaToken::SetForceArray: virtual dummy called" );
169cdf0e10cSrcweir }
170cdf0e10cSrcweir
GetDouble() const171cdf0e10cSrcweir double FormulaToken::GetDouble() const
172cdf0e10cSrcweir {
173cdf0e10cSrcweir DBG_ERRORFILE( "FormulaToken::GetDouble: virtual dummy called" );
174cdf0e10cSrcweir return 0.0;
175cdf0e10cSrcweir }
176cdf0e10cSrcweir
GetDoubleAsReference()177cdf0e10cSrcweir double & FormulaToken::GetDoubleAsReference()
178cdf0e10cSrcweir {
179cdf0e10cSrcweir DBG_ERRORFILE( "FormulaToken::GetDouble: virtual dummy called" );
180cdf0e10cSrcweir static double fVal = 0.0;
181cdf0e10cSrcweir return fVal;
182cdf0e10cSrcweir }
183cdf0e10cSrcweir
GetString() const184cdf0e10cSrcweir const String& FormulaToken::GetString() const
185cdf0e10cSrcweir {
186cdf0e10cSrcweir DBG_ERRORFILE( "FormulaToken::GetString: virtual dummy called" );
187cdf0e10cSrcweir static String aDummyString;
188cdf0e10cSrcweir return aDummyString;
189cdf0e10cSrcweir }
190cdf0e10cSrcweir
GetIndex() const191cdf0e10cSrcweir sal_uInt16 FormulaToken::GetIndex() const
192cdf0e10cSrcweir {
193cdf0e10cSrcweir DBG_ERRORFILE( "FormulaToken::GetIndex: virtual dummy called" );
194cdf0e10cSrcweir return 0;
195cdf0e10cSrcweir }
196cdf0e10cSrcweir
SetIndex(sal_uInt16)197cdf0e10cSrcweir void FormulaToken::SetIndex( sal_uInt16 )
198cdf0e10cSrcweir {
199cdf0e10cSrcweir DBG_ERRORFILE( "FormulaToken::SetIndex: virtual dummy called" );
200cdf0e10cSrcweir }
201cdf0e10cSrcweir
GetJump() const202cdf0e10cSrcweir short* FormulaToken::GetJump() const
203cdf0e10cSrcweir {
204cdf0e10cSrcweir DBG_ERRORFILE( "FormulaToken::GetJump: virtual dummy called" );
205cdf0e10cSrcweir return NULL;
206cdf0e10cSrcweir }
207cdf0e10cSrcweir
208cdf0e10cSrcweir
GetExternal() const209cdf0e10cSrcweir const String& FormulaToken::GetExternal() const
210cdf0e10cSrcweir {
211cdf0e10cSrcweir DBG_ERRORFILE( "FormulaToken::GetExternal: virtual dummy called" );
212cdf0e10cSrcweir static String aDummyString;
213cdf0e10cSrcweir return aDummyString;
214cdf0e10cSrcweir }
215cdf0e10cSrcweir
GetFAPOrigToken() const216cdf0e10cSrcweir FormulaToken* FormulaToken::GetFAPOrigToken() const
217cdf0e10cSrcweir {
218cdf0e10cSrcweir DBG_ERRORFILE( "FormulaToken::GetFAPOrigToken: virtual dummy called" );
219cdf0e10cSrcweir return NULL;
220cdf0e10cSrcweir }
221cdf0e10cSrcweir
GetError() const222cdf0e10cSrcweir sal_uInt16 FormulaToken::GetError() const
223cdf0e10cSrcweir {
224cdf0e10cSrcweir DBG_ERRORFILE( "FormulaToken::GetError: virtual dummy called" );
225cdf0e10cSrcweir return 0;
226cdf0e10cSrcweir }
227cdf0e10cSrcweir
SetError(sal_uInt16)228cdf0e10cSrcweir void FormulaToken::SetError( sal_uInt16 )
229cdf0e10cSrcweir {
230cdf0e10cSrcweir DBG_ERRORFILE( "FormulaToken::SetError: virtual dummy called" );
231cdf0e10cSrcweir }
TextEqual(const FormulaToken & rToken) const232cdf0e10cSrcweir sal_Bool FormulaToken::TextEqual( const FormulaToken& rToken ) const
233cdf0e10cSrcweir {
234cdf0e10cSrcweir return *this == rToken;
235cdf0e10cSrcweir }
236cdf0e10cSrcweir // ==========================================================================
237cdf0e10cSrcweir // real implementations of virtual functions
238cdf0e10cSrcweir // --------------------------------------------------------------------------
239cdf0e10cSrcweir
240cdf0e10cSrcweir
GetByte() const241cdf0e10cSrcweir sal_uInt8 FormulaByteToken::GetByte() const { return nByte; }
SetByte(sal_uInt8 n)242cdf0e10cSrcweir void FormulaByteToken::SetByte( sal_uInt8 n ) { nByte = n; }
HasForceArray() const243cdf0e10cSrcweir bool FormulaByteToken::HasForceArray() const { return bHasForceArray; }
SetForceArray(bool b)244cdf0e10cSrcweir void FormulaByteToken::SetForceArray( bool b ) { bHasForceArray = b; }
operator ==(const FormulaToken & r) const245cdf0e10cSrcweir sal_Bool FormulaByteToken::operator==( const FormulaToken& r ) const
246cdf0e10cSrcweir {
247cdf0e10cSrcweir return FormulaToken::operator==( r ) && nByte == r.GetByte() &&
248cdf0e10cSrcweir bHasForceArray == r.HasForceArray();
249cdf0e10cSrcweir }
250cdf0e10cSrcweir
251cdf0e10cSrcweir
GetFAPOrigToken() const252cdf0e10cSrcweir FormulaToken* FormulaFAPToken::GetFAPOrigToken() const { return pOrigToken; }
operator ==(const FormulaToken & r) const253cdf0e10cSrcweir sal_Bool FormulaFAPToken::operator==( const FormulaToken& r ) const
254cdf0e10cSrcweir {
255cdf0e10cSrcweir return FormulaByteToken::operator==( r ) && pOrigToken == r.GetFAPOrigToken();
256cdf0e10cSrcweir }
GetJump() const257cdf0e10cSrcweir short* FormulaJumpToken::GetJump() const { return pJump; }
operator ==(const FormulaToken & r) const258cdf0e10cSrcweir sal_Bool FormulaJumpToken::operator==( const FormulaToken& r ) const
259cdf0e10cSrcweir {
260cdf0e10cSrcweir return FormulaToken::operator==( r ) && pJump[0] == r.GetJump()[0] &&
261cdf0e10cSrcweir memcmp( pJump+1, r.GetJump()+1, pJump[0] * sizeof(short) ) == 0;
262cdf0e10cSrcweir }
~FormulaJumpToken()263cdf0e10cSrcweir FormulaJumpToken::~FormulaJumpToken()
264cdf0e10cSrcweir {
265cdf0e10cSrcweir delete [] pJump;
266cdf0e10cSrcweir }
267cdf0e10cSrcweir
268cdf0e10cSrcweir
AddFormulaToken(const sheet::FormulaToken & _aToken,ExternalReferenceHelper *)269cdf0e10cSrcweir bool FormulaTokenArray::AddFormulaToken(const sheet::FormulaToken& _aToken,ExternalReferenceHelper* /*_pRef*/)
270cdf0e10cSrcweir {
271cdf0e10cSrcweir bool bError = false;
272cdf0e10cSrcweir const OpCode eOpCode = static_cast<OpCode>(_aToken.OpCode); //! assuming equal values for the moment
273cdf0e10cSrcweir
274cdf0e10cSrcweir const uno::TypeClass eClass = _aToken.Data.getValueTypeClass();
275cdf0e10cSrcweir switch ( eClass )
276cdf0e10cSrcweir {
277cdf0e10cSrcweir case uno::TypeClass_VOID:
278cdf0e10cSrcweir // empty data -> use AddOpCode (does some special cases)
279cdf0e10cSrcweir AddOpCode( eOpCode );
280cdf0e10cSrcweir break;
281cdf0e10cSrcweir case uno::TypeClass_DOUBLE:
282cdf0e10cSrcweir // double is only used for "push"
283cdf0e10cSrcweir if ( eOpCode == ocPush )
284cdf0e10cSrcweir AddDouble( _aToken.Data.get<double>() );
285cdf0e10cSrcweir else
286cdf0e10cSrcweir bError = true;
287cdf0e10cSrcweir break;
288cdf0e10cSrcweir case uno::TypeClass_LONG:
289cdf0e10cSrcweir {
290cdf0e10cSrcweir // long is svIndex, used for name / database area, or "byte" for spaces
291cdf0e10cSrcweir sal_Int32 nValue = _aToken.Data.get<sal_Int32>();
292cdf0e10cSrcweir if ( eOpCode == ocName || eOpCode == ocDBArea )
293cdf0e10cSrcweir AddToken( formula::FormulaIndexToken( eOpCode, static_cast<sal_uInt16>(nValue) ) );
294cdf0e10cSrcweir else if ( eOpCode == ocSpaces )
295cdf0e10cSrcweir AddToken( formula::FormulaByteToken( ocSpaces, static_cast<sal_uInt8>(nValue) ) );
296cdf0e10cSrcweir else
297cdf0e10cSrcweir bError = true;
298cdf0e10cSrcweir }
299cdf0e10cSrcweir break;
300cdf0e10cSrcweir case uno::TypeClass_STRING:
301cdf0e10cSrcweir {
302cdf0e10cSrcweir String aStrVal( _aToken.Data.get<rtl::OUString>() );
303cdf0e10cSrcweir if ( eOpCode == ocPush )
304cdf0e10cSrcweir AddString( aStrVal );
305cdf0e10cSrcweir else if ( eOpCode == ocBad )
306cdf0e10cSrcweir AddBad( aStrVal );
307cdf0e10cSrcweir else if ( eOpCode == ocExternal || eOpCode == ocMacro )
308cdf0e10cSrcweir AddToken( formula::FormulaExternalToken( eOpCode, aStrVal ) );
309cdf0e10cSrcweir else
310cdf0e10cSrcweir bError = true; // unexpected string: don't know what to do with it
311cdf0e10cSrcweir }
312cdf0e10cSrcweir break;
313cdf0e10cSrcweir default:
314cdf0e10cSrcweir bError = true;
315cdf0e10cSrcweir } // switch ( eClass )
316cdf0e10cSrcweir return bError;
317cdf0e10cSrcweir }
Fill(const uno::Sequence<sheet::FormulaToken> & _aSequence,ExternalReferenceHelper * _pRef)318cdf0e10cSrcweir bool FormulaTokenArray::Fill(const uno::Sequence< sheet::FormulaToken >& _aSequence,ExternalReferenceHelper* _pRef)
319cdf0e10cSrcweir {
320cdf0e10cSrcweir bool bError = false;
321cdf0e10cSrcweir const sal_Int32 nCount = _aSequence.getLength();
322cdf0e10cSrcweir for (sal_Int32 nPos=0; nPos<nCount; nPos++)
323cdf0e10cSrcweir {
324cdf0e10cSrcweir bError |= AddFormulaToken( _aSequence[nPos] ,_pRef);
325cdf0e10cSrcweir }
326cdf0e10cSrcweir return bError;
327cdf0e10cSrcweir }
328cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////////
GetNextReference()329cdf0e10cSrcweir FormulaToken* FormulaTokenArray::GetNextReference()
330cdf0e10cSrcweir {
331cdf0e10cSrcweir while( nIndex < nLen )
332cdf0e10cSrcweir {
333cdf0e10cSrcweir FormulaToken* t = pCode[ nIndex++ ];
334cdf0e10cSrcweir switch( t->GetType() )
335cdf0e10cSrcweir {
336cdf0e10cSrcweir case svSingleRef:
337cdf0e10cSrcweir case svDoubleRef:
338cdf0e10cSrcweir case svExternalSingleRef:
339cdf0e10cSrcweir case svExternalDoubleRef:
340cdf0e10cSrcweir return t;
341cdf0e10cSrcweir default:
342cdf0e10cSrcweir {
343cdf0e10cSrcweir // added to avoid warnings
344cdf0e10cSrcweir }
345cdf0e10cSrcweir }
346cdf0e10cSrcweir }
347cdf0e10cSrcweir return NULL;
348cdf0e10cSrcweir }
349cdf0e10cSrcweir
GetNextColRowName()350cdf0e10cSrcweir FormulaToken* FormulaTokenArray::GetNextColRowName()
351cdf0e10cSrcweir {
352cdf0e10cSrcweir while( nIndex < nLen )
353cdf0e10cSrcweir {
354cdf0e10cSrcweir FormulaToken* t = pCode[ nIndex++ ];
355cdf0e10cSrcweir if ( t->GetOpCode() == ocColRowName )
356cdf0e10cSrcweir return t;
357cdf0e10cSrcweir }
358cdf0e10cSrcweir return NULL;
359cdf0e10cSrcweir }
360cdf0e10cSrcweir
GetNextReferenceRPN()361cdf0e10cSrcweir FormulaToken* FormulaTokenArray::GetNextReferenceRPN()
362cdf0e10cSrcweir {
363cdf0e10cSrcweir while( nIndex < nRPN )
364cdf0e10cSrcweir {
365cdf0e10cSrcweir FormulaToken* t = pRPN[ nIndex++ ];
366cdf0e10cSrcweir switch( t->GetType() )
367cdf0e10cSrcweir {
368cdf0e10cSrcweir case svSingleRef:
369cdf0e10cSrcweir case svDoubleRef:
370cdf0e10cSrcweir case svExternalSingleRef:
371cdf0e10cSrcweir case svExternalDoubleRef:
372cdf0e10cSrcweir return t;
373cdf0e10cSrcweir default:
374cdf0e10cSrcweir {
375cdf0e10cSrcweir // added to avoid warnings
376cdf0e10cSrcweir }
377cdf0e10cSrcweir }
378cdf0e10cSrcweir }
379cdf0e10cSrcweir return NULL;
380cdf0e10cSrcweir }
381cdf0e10cSrcweir
GetNextReferenceOrName()382cdf0e10cSrcweir FormulaToken* FormulaTokenArray::GetNextReferenceOrName()
383cdf0e10cSrcweir {
384cdf0e10cSrcweir if( pCode )
385cdf0e10cSrcweir {
386cdf0e10cSrcweir while ( nIndex < nLen )
387cdf0e10cSrcweir {
388cdf0e10cSrcweir FormulaToken* t = pCode[ nIndex++ ];
389cdf0e10cSrcweir switch( t->GetType() )
390cdf0e10cSrcweir {
391cdf0e10cSrcweir case svSingleRef:
392cdf0e10cSrcweir case svDoubleRef:
393cdf0e10cSrcweir case svIndex:
394cdf0e10cSrcweir case svExternalSingleRef:
395cdf0e10cSrcweir case svExternalDoubleRef:
396cdf0e10cSrcweir case svExternalName:
397cdf0e10cSrcweir return t;
398cdf0e10cSrcweir default:
399cdf0e10cSrcweir {
400cdf0e10cSrcweir // added to avoid warnings
401cdf0e10cSrcweir }
402cdf0e10cSrcweir }
403cdf0e10cSrcweir }
404cdf0e10cSrcweir }
405cdf0e10cSrcweir return NULL;
406cdf0e10cSrcweir }
407cdf0e10cSrcweir
GetNextName()408cdf0e10cSrcweir FormulaToken* FormulaTokenArray::GetNextName()
409cdf0e10cSrcweir {
410cdf0e10cSrcweir if( pCode )
411cdf0e10cSrcweir {
412cdf0e10cSrcweir while ( nIndex < nLen )
413cdf0e10cSrcweir {
414cdf0e10cSrcweir FormulaToken* t = pCode[ nIndex++ ];
415cdf0e10cSrcweir if( t->GetType() == svIndex )
416cdf0e10cSrcweir return t;
417cdf0e10cSrcweir }
418cdf0e10cSrcweir } // if( pCode )
419cdf0e10cSrcweir return NULL;
420cdf0e10cSrcweir }
421cdf0e10cSrcweir
GetNextDBArea()422cdf0e10cSrcweir FormulaToken* FormulaTokenArray::GetNextDBArea()
423cdf0e10cSrcweir {
424cdf0e10cSrcweir if( pCode )
425cdf0e10cSrcweir {
426cdf0e10cSrcweir while ( nIndex < nLen )
427cdf0e10cSrcweir {
428cdf0e10cSrcweir FormulaToken* t = pCode[ nIndex++ ];
429cdf0e10cSrcweir if( t->GetOpCode() == ocDBArea )
430cdf0e10cSrcweir return t;
431cdf0e10cSrcweir } // while ( nIndex < nLen )+
432cdf0e10cSrcweir }
433cdf0e10cSrcweir return NULL;
434cdf0e10cSrcweir }
435cdf0e10cSrcweir
GetNextOpCodeRPN(OpCode eOp)436cdf0e10cSrcweir FormulaToken* FormulaTokenArray::GetNextOpCodeRPN( OpCode eOp )
437cdf0e10cSrcweir {
438cdf0e10cSrcweir while( nIndex < nRPN )
439cdf0e10cSrcweir {
440cdf0e10cSrcweir FormulaToken* t = pRPN[ nIndex++ ];
441cdf0e10cSrcweir if ( t->GetOpCode() == eOp )
442cdf0e10cSrcweir return t;
443cdf0e10cSrcweir }
444cdf0e10cSrcweir return NULL;
445cdf0e10cSrcweir }
446cdf0e10cSrcweir
Next()447cdf0e10cSrcweir FormulaToken* FormulaTokenArray::Next()
448cdf0e10cSrcweir {
449cdf0e10cSrcweir if( pCode && nIndex < nLen )
450cdf0e10cSrcweir return pCode[ nIndex++ ];
451cdf0e10cSrcweir else
452cdf0e10cSrcweir return NULL;
453cdf0e10cSrcweir }
454cdf0e10cSrcweir
NextNoSpaces()455cdf0e10cSrcweir FormulaToken* FormulaTokenArray::NextNoSpaces()
456cdf0e10cSrcweir {
457cdf0e10cSrcweir if( pCode )
458cdf0e10cSrcweir {
459cdf0e10cSrcweir while( (nIndex < nLen) && (pCode[ nIndex ]->GetOpCode() == ocSpaces) )
460cdf0e10cSrcweir ++nIndex;
461cdf0e10cSrcweir if( nIndex < nLen )
462cdf0e10cSrcweir return pCode[ nIndex++ ];
463cdf0e10cSrcweir }
464cdf0e10cSrcweir return NULL;
465cdf0e10cSrcweir }
466cdf0e10cSrcweir
NextRPN()467cdf0e10cSrcweir FormulaToken* FormulaTokenArray::NextRPN()
468cdf0e10cSrcweir {
469cdf0e10cSrcweir if( pRPN && nIndex < nRPN )
470cdf0e10cSrcweir return pRPN[ nIndex++ ];
471cdf0e10cSrcweir else
472cdf0e10cSrcweir return NULL;
473cdf0e10cSrcweir }
474cdf0e10cSrcweir
PrevRPN()475cdf0e10cSrcweir FormulaToken* FormulaTokenArray::PrevRPN()
476cdf0e10cSrcweir {
477cdf0e10cSrcweir if( pRPN && nIndex )
478cdf0e10cSrcweir return pRPN[ --nIndex ];
479cdf0e10cSrcweir else
480cdf0e10cSrcweir return NULL;
481cdf0e10cSrcweir }
482cdf0e10cSrcweir
DelRPN()483cdf0e10cSrcweir void FormulaTokenArray::DelRPN()
484cdf0e10cSrcweir {
485cdf0e10cSrcweir if( nRPN )
486cdf0e10cSrcweir {
487cdf0e10cSrcweir FormulaToken** p = pRPN;
488cdf0e10cSrcweir for( sal_uInt16 i = 0; i < nRPN; i++ )
489cdf0e10cSrcweir {
490cdf0e10cSrcweir (*p++)->DecRef();
491cdf0e10cSrcweir }
492cdf0e10cSrcweir delete [] pRPN;
493cdf0e10cSrcweir }
494cdf0e10cSrcweir pRPN = NULL;
495cdf0e10cSrcweir nRPN = nIndex = 0;
496cdf0e10cSrcweir }
497cdf0e10cSrcweir
PeekPrev(sal_uInt16 & nIdx)498cdf0e10cSrcweir FormulaToken* FormulaTokenArray::PeekPrev( sal_uInt16 & nIdx )
499cdf0e10cSrcweir {
500cdf0e10cSrcweir if (0 < nIdx && nIdx <= nLen)
501cdf0e10cSrcweir return pCode[--nIdx];
502cdf0e10cSrcweir return NULL;
503cdf0e10cSrcweir }
504cdf0e10cSrcweir
PeekNext()505cdf0e10cSrcweir FormulaToken* FormulaTokenArray::PeekNext()
506cdf0e10cSrcweir {
507cdf0e10cSrcweir if( pCode && nIndex < nLen )
508cdf0e10cSrcweir return pCode[ nIndex ];
509cdf0e10cSrcweir else
510cdf0e10cSrcweir return NULL;
511cdf0e10cSrcweir }
512cdf0e10cSrcweir
PeekNextNoSpaces()513cdf0e10cSrcweir FormulaToken* FormulaTokenArray::PeekNextNoSpaces()
514cdf0e10cSrcweir {
515cdf0e10cSrcweir if( pCode && nIndex < nLen )
516cdf0e10cSrcweir {
517cdf0e10cSrcweir sal_uInt16 j = nIndex;
518cdf0e10cSrcweir while ( pCode[j]->GetOpCode() == ocSpaces && j < nLen )
519cdf0e10cSrcweir j++;
520cdf0e10cSrcweir if ( j < nLen )
521cdf0e10cSrcweir return pCode[ j ];
522cdf0e10cSrcweir else
523cdf0e10cSrcweir return NULL;
524cdf0e10cSrcweir }
525cdf0e10cSrcweir else
526cdf0e10cSrcweir return NULL;
527cdf0e10cSrcweir }
528cdf0e10cSrcweir
PeekPrevNoSpaces()529cdf0e10cSrcweir FormulaToken* FormulaTokenArray::PeekPrevNoSpaces()
530cdf0e10cSrcweir {
531cdf0e10cSrcweir if( pCode && nIndex > 1 )
532cdf0e10cSrcweir {
533cdf0e10cSrcweir sal_uInt16 j = nIndex - 2;
534cdf0e10cSrcweir while ( pCode[j]->GetOpCode() == ocSpaces && j > 0 )
535cdf0e10cSrcweir j--;
536cdf0e10cSrcweir if ( j > 0 || pCode[j]->GetOpCode() != ocSpaces )
537cdf0e10cSrcweir return pCode[ j ];
538cdf0e10cSrcweir else
539cdf0e10cSrcweir return NULL;
540cdf0e10cSrcweir }
541cdf0e10cSrcweir else
542cdf0e10cSrcweir return NULL;
543cdf0e10cSrcweir }
544cdf0e10cSrcweir
HasOpCode(OpCode eOp) const545cdf0e10cSrcweir sal_Bool FormulaTokenArray::HasOpCode( OpCode eOp ) const
546cdf0e10cSrcweir {
547cdf0e10cSrcweir for ( sal_uInt16 j=0; j < nLen; j++ )
548cdf0e10cSrcweir {
549cdf0e10cSrcweir if ( pCode[j]->GetOpCode() == eOp )
550cdf0e10cSrcweir return sal_True;
551cdf0e10cSrcweir }
552cdf0e10cSrcweir return sal_False;
553cdf0e10cSrcweir }
554cdf0e10cSrcweir
HasOpCodeRPN(OpCode eOp) const555cdf0e10cSrcweir sal_Bool FormulaTokenArray::HasOpCodeRPN( OpCode eOp ) const
556cdf0e10cSrcweir {
557cdf0e10cSrcweir for ( sal_uInt16 j=0; j < nRPN; j++ )
558cdf0e10cSrcweir {
559cdf0e10cSrcweir if ( pRPN[j]->GetOpCode() == eOp )
560cdf0e10cSrcweir return sal_True;
561cdf0e10cSrcweir }
562cdf0e10cSrcweir return sal_False;
563cdf0e10cSrcweir }
564cdf0e10cSrcweir
HasNameOrColRowName() const565cdf0e10cSrcweir sal_Bool FormulaTokenArray::HasNameOrColRowName() const
566cdf0e10cSrcweir {
567cdf0e10cSrcweir for ( sal_uInt16 j=0; j < nLen; j++ )
568cdf0e10cSrcweir {
569cdf0e10cSrcweir if( pCode[j]->GetType() == svIndex || pCode[j]->GetOpCode() == ocColRowName )
570cdf0e10cSrcweir return sal_True;
571cdf0e10cSrcweir }
572cdf0e10cSrcweir return sal_False;
573cdf0e10cSrcweir }
574cdf0e10cSrcweir
575cdf0e10cSrcweir ////////////////////////////////////////////////////////////////////////////
576cdf0e10cSrcweir
FormulaTokenArray()577cdf0e10cSrcweir FormulaTokenArray::FormulaTokenArray()
578cdf0e10cSrcweir {
579cdf0e10cSrcweir pCode = NULL; pRPN = NULL;
580cdf0e10cSrcweir nError = nLen = nIndex = nRPN = nRefs = 0;
581cdf0e10cSrcweir bHyperLink = sal_False;
582cdf0e10cSrcweir ClearRecalcMode();
583cdf0e10cSrcweir }
584cdf0e10cSrcweir
FormulaTokenArray(const FormulaTokenArray & rArr)585cdf0e10cSrcweir FormulaTokenArray::FormulaTokenArray( const FormulaTokenArray& rArr )
586cdf0e10cSrcweir {
587cdf0e10cSrcweir Assign( rArr );
588cdf0e10cSrcweir }
589cdf0e10cSrcweir
~FormulaTokenArray()590cdf0e10cSrcweir FormulaTokenArray::~FormulaTokenArray()
591cdf0e10cSrcweir {
592cdf0e10cSrcweir Clear();
593cdf0e10cSrcweir }
594cdf0e10cSrcweir
Assign(const FormulaTokenArray & r)595cdf0e10cSrcweir void FormulaTokenArray::Assign( const FormulaTokenArray& r )
596cdf0e10cSrcweir {
597cdf0e10cSrcweir nLen = r.nLen;
598cdf0e10cSrcweir nRPN = r.nRPN;
599cdf0e10cSrcweir nIndex = r.nIndex;
600cdf0e10cSrcweir nError = r.nError;
601cdf0e10cSrcweir nRefs = r.nRefs;
602cdf0e10cSrcweir nMode = r.nMode;
603cdf0e10cSrcweir bHyperLink = r.bHyperLink;
604cdf0e10cSrcweir pCode = NULL;
605cdf0e10cSrcweir pRPN = NULL;
606cdf0e10cSrcweir FormulaToken** pp;
607cdf0e10cSrcweir if( nLen )
608cdf0e10cSrcweir {
609cdf0e10cSrcweir pp = pCode = new FormulaToken*[ nLen ];
610cdf0e10cSrcweir memcpy( pp, r.pCode, nLen * sizeof( FormulaToken* ) );
611cdf0e10cSrcweir for( sal_uInt16 i = 0; i < nLen; i++ )
612cdf0e10cSrcweir (*pp++)->IncRef();
613cdf0e10cSrcweir }
614cdf0e10cSrcweir if( nRPN )
615cdf0e10cSrcweir {
616cdf0e10cSrcweir pp = pRPN = new FormulaToken*[ nRPN ];
617cdf0e10cSrcweir memcpy( pp, r.pRPN, nRPN * sizeof( FormulaToken* ) );
618cdf0e10cSrcweir for( sal_uInt16 i = 0; i < nRPN; i++ )
619cdf0e10cSrcweir (*pp++)->IncRef();
620cdf0e10cSrcweir }
621cdf0e10cSrcweir }
622cdf0e10cSrcweir
operator =(const FormulaTokenArray & rArr)623cdf0e10cSrcweir FormulaTokenArray& FormulaTokenArray::operator=( const FormulaTokenArray& rArr )
624cdf0e10cSrcweir {
625cdf0e10cSrcweir Clear();
626cdf0e10cSrcweir Assign( rArr );
627cdf0e10cSrcweir return *this;
628cdf0e10cSrcweir }
629cdf0e10cSrcweir
Clone() const630cdf0e10cSrcweir FormulaTokenArray* FormulaTokenArray::Clone() const
631cdf0e10cSrcweir {
632cdf0e10cSrcweir FormulaTokenArray* p = new FormulaTokenArray;
633cdf0e10cSrcweir p->nLen = nLen;
634cdf0e10cSrcweir p->nRPN = nRPN;
635cdf0e10cSrcweir p->nRefs = nRefs;
636cdf0e10cSrcweir p->nMode = nMode;
637cdf0e10cSrcweir p->nError = nError;
638cdf0e10cSrcweir p->bHyperLink = bHyperLink;
639cdf0e10cSrcweir FormulaToken** pp;
640cdf0e10cSrcweir if( nLen )
641cdf0e10cSrcweir {
642cdf0e10cSrcweir pp = p->pCode = new FormulaToken*[ nLen ];
643cdf0e10cSrcweir memcpy( pp, pCode, nLen * sizeof( FormulaToken* ) );
644cdf0e10cSrcweir for( sal_uInt16 i = 0; i < nLen; i++, pp++ )
645cdf0e10cSrcweir {
646cdf0e10cSrcweir *pp = (*pp)->Clone();
647cdf0e10cSrcweir (*pp)->IncRef();
648cdf0e10cSrcweir }
649cdf0e10cSrcweir }
650cdf0e10cSrcweir if( nRPN )
651cdf0e10cSrcweir {
652cdf0e10cSrcweir pp = p->pRPN = new FormulaToken*[ nRPN ];
653cdf0e10cSrcweir memcpy( pp, pRPN, nRPN * sizeof( FormulaToken* ) );
654cdf0e10cSrcweir for( sal_uInt16 i = 0; i < nRPN; i++, pp++ )
655cdf0e10cSrcweir {
656cdf0e10cSrcweir FormulaToken* t = *pp;
657cdf0e10cSrcweir if( t->GetRef() > 1 )
658cdf0e10cSrcweir {
659cdf0e10cSrcweir FormulaToken** p2 = pCode;
660cdf0e10cSrcweir sal_uInt16 nIdx = 0xFFFF;
661cdf0e10cSrcweir for( sal_uInt16 j = 0; j < nLen; j++, p2++ )
662cdf0e10cSrcweir {
663cdf0e10cSrcweir if( *p2 == t )
664cdf0e10cSrcweir {
665cdf0e10cSrcweir nIdx = j; break;
666cdf0e10cSrcweir }
667cdf0e10cSrcweir }
668cdf0e10cSrcweir if( nIdx == 0xFFFF )
669cdf0e10cSrcweir *pp = t->Clone();
670cdf0e10cSrcweir else
671cdf0e10cSrcweir *pp = p->pCode[ nIdx ];
672cdf0e10cSrcweir }
673cdf0e10cSrcweir else
674cdf0e10cSrcweir *pp = t->Clone();
675cdf0e10cSrcweir (*pp)->IncRef();
676cdf0e10cSrcweir }
677cdf0e10cSrcweir }
678cdf0e10cSrcweir return p;
679cdf0e10cSrcweir }
680cdf0e10cSrcweir
Clear()681cdf0e10cSrcweir void FormulaTokenArray::Clear()
682cdf0e10cSrcweir {
683cdf0e10cSrcweir if( nRPN ) DelRPN();
684cdf0e10cSrcweir if( pCode )
685cdf0e10cSrcweir {
686cdf0e10cSrcweir FormulaToken** p = pCode;
687cdf0e10cSrcweir for( sal_uInt16 i = 0; i < nLen; i++ )
688cdf0e10cSrcweir {
689cdf0e10cSrcweir (*p++)->DecRef();
690cdf0e10cSrcweir }
691cdf0e10cSrcweir delete [] pCode;
692cdf0e10cSrcweir }
693cdf0e10cSrcweir pCode = NULL; pRPN = NULL;
694cdf0e10cSrcweir nError = nLen = nIndex = nRPN = nRefs = 0;
695cdf0e10cSrcweir bHyperLink = sal_False;
696cdf0e10cSrcweir ClearRecalcMode();
697cdf0e10cSrcweir }
698cdf0e10cSrcweir
AddToken(const FormulaToken & r)699cdf0e10cSrcweir FormulaToken* FormulaTokenArray::AddToken( const FormulaToken& r )
700cdf0e10cSrcweir {
701cdf0e10cSrcweir return Add( r.Clone() );
702cdf0e10cSrcweir }
703cdf0e10cSrcweir
MergeArray()704cdf0e10cSrcweir FormulaToken* FormulaTokenArray::MergeArray( )
705cdf0e10cSrcweir {
706cdf0e10cSrcweir return NULL;
707cdf0e10cSrcweir }
708cdf0e10cSrcweir
Add(FormulaToken * t)709cdf0e10cSrcweir FormulaToken* FormulaTokenArray::Add( FormulaToken* t )
710cdf0e10cSrcweir {
711cdf0e10cSrcweir if( !pCode )
712cdf0e10cSrcweir pCode = new FormulaToken*[ MAXCODE ];
713cdf0e10cSrcweir if( nLen < MAXCODE-1 )
714cdf0e10cSrcweir {
715cdf0e10cSrcweir // fprintf (stderr, "Add : %d\n", t->GetOpCode());
716cdf0e10cSrcweir pCode[ nLen++ ] = t;
717cdf0e10cSrcweir if( t->GetOpCode() == ocPush
718cdf0e10cSrcweir && ( t->GetType() == svSingleRef || t->GetType() == svDoubleRef ) )
719cdf0e10cSrcweir nRefs++;
720cdf0e10cSrcweir t->IncRef();
721cdf0e10cSrcweir if( t->GetOpCode() == ocArrayClose )
722cdf0e10cSrcweir return MergeArray();
723cdf0e10cSrcweir return t;
724cdf0e10cSrcweir }
725cdf0e10cSrcweir else
726cdf0e10cSrcweir {
727cdf0e10cSrcweir t->Delete();
728cdf0e10cSrcweir if ( nLen == MAXCODE-1 )
729cdf0e10cSrcweir {
730cdf0e10cSrcweir t = new FormulaByteToken( ocStop );
731cdf0e10cSrcweir pCode[ nLen++ ] = t;
732cdf0e10cSrcweir t->IncRef();
733cdf0e10cSrcweir }
734cdf0e10cSrcweir return NULL;
735cdf0e10cSrcweir }
736cdf0e10cSrcweir }
737cdf0e10cSrcweir
AddString(const sal_Unicode * pStr)738cdf0e10cSrcweir FormulaToken* FormulaTokenArray::AddString( const sal_Unicode* pStr )
739cdf0e10cSrcweir {
740cdf0e10cSrcweir return AddString( String( pStr ) );
741cdf0e10cSrcweir }
742cdf0e10cSrcweir
AddString(const String & rStr)743cdf0e10cSrcweir FormulaToken* FormulaTokenArray::AddString( const String& rStr )
744cdf0e10cSrcweir {
745cdf0e10cSrcweir return Add( new FormulaStringToken( rStr ) );
746cdf0e10cSrcweir }
747cdf0e10cSrcweir
AddDouble(double fVal)748cdf0e10cSrcweir FormulaToken* FormulaTokenArray::AddDouble( double fVal )
749cdf0e10cSrcweir {
750cdf0e10cSrcweir return Add( new FormulaDoubleToken( fVal ) );
751cdf0e10cSrcweir }
752cdf0e10cSrcweir
AddName(sal_uInt16 n)753cdf0e10cSrcweir FormulaToken* FormulaTokenArray::AddName( sal_uInt16 n )
754cdf0e10cSrcweir {
755cdf0e10cSrcweir return Add( new FormulaIndexToken( ocName, n ) );
756cdf0e10cSrcweir }
757cdf0e10cSrcweir
AddExternal(const sal_Unicode * pStr)758cdf0e10cSrcweir FormulaToken* FormulaTokenArray::AddExternal( const sal_Unicode* pStr )
759cdf0e10cSrcweir {
760cdf0e10cSrcweir return AddExternal( String( pStr ) );
761cdf0e10cSrcweir }
762cdf0e10cSrcweir
AddExternal(const String & rStr,OpCode eOp)763cdf0e10cSrcweir FormulaToken* FormulaTokenArray::AddExternal( const String& rStr,
764cdf0e10cSrcweir OpCode eOp /* = ocExternal */ )
765cdf0e10cSrcweir {
766cdf0e10cSrcweir return Add( new FormulaExternalToken( eOp, rStr ) );
767cdf0e10cSrcweir }
768cdf0e10cSrcweir
AddBad(const sal_Unicode * pStr)769cdf0e10cSrcweir FormulaToken* FormulaTokenArray::AddBad( const sal_Unicode* pStr )
770cdf0e10cSrcweir {
771cdf0e10cSrcweir return AddBad( String( pStr ) );
772cdf0e10cSrcweir }
773cdf0e10cSrcweir
AddBad(const String & rStr)774cdf0e10cSrcweir FormulaToken* FormulaTokenArray::AddBad( const String& rStr )
775cdf0e10cSrcweir {
776cdf0e10cSrcweir return Add( new FormulaStringOpToken( ocBad, rStr ) );
777cdf0e10cSrcweir }
778cdf0e10cSrcweir
779cdf0e10cSrcweir
780cdf0e10cSrcweir
AddRecalcMode(ScRecalcMode nBits)781cdf0e10cSrcweir void FormulaTokenArray::AddRecalcMode( ScRecalcMode nBits )
782cdf0e10cSrcweir {
783cdf0e10cSrcweir //! Reihenfolge ist wichtig
784cdf0e10cSrcweir if ( nBits & RECALCMODE_ALWAYS )
785cdf0e10cSrcweir SetRecalcModeAlways();
786cdf0e10cSrcweir else if ( !IsRecalcModeAlways() )
787cdf0e10cSrcweir {
788cdf0e10cSrcweir if ( nBits & RECALCMODE_ONLOAD )
789cdf0e10cSrcweir SetRecalcModeOnLoad();
790cdf0e10cSrcweir else if ( nBits & RECALCMODE_ONLOAD_ONCE && !IsRecalcModeOnLoad() )
791cdf0e10cSrcweir SetRecalcModeOnLoadOnce();
792cdf0e10cSrcweir }
793cdf0e10cSrcweir SetCombinedBitsRecalcMode( nBits );
794cdf0e10cSrcweir }
795cdf0e10cSrcweir
796cdf0e10cSrcweir
HasMatrixDoubleRefOps()797cdf0e10cSrcweir sal_Bool FormulaTokenArray::HasMatrixDoubleRefOps()
798cdf0e10cSrcweir {
799cdf0e10cSrcweir if ( pRPN && nRPN )
800cdf0e10cSrcweir {
801cdf0e10cSrcweir // RPN-Interpreter Simulation
802cdf0e10cSrcweir // als Ergebnis jeder Funktion wird einfach ein Double angenommen
803cdf0e10cSrcweir FormulaToken** pStack = new FormulaToken* [nRPN];
804cdf0e10cSrcweir FormulaToken* pResult = new FormulaDoubleToken( 0.0 );
805cdf0e10cSrcweir short sp = 0;
806cdf0e10cSrcweir for ( sal_uInt16 j = 0; j < nRPN; j++ )
807cdf0e10cSrcweir {
808cdf0e10cSrcweir FormulaToken* t = pRPN[j];
809cdf0e10cSrcweir OpCode eOp = t->GetOpCode();
810cdf0e10cSrcweir sal_uInt8 nParams = t->GetParamCount();
811cdf0e10cSrcweir switch ( eOp )
812cdf0e10cSrcweir {
813cdf0e10cSrcweir case ocAdd :
814cdf0e10cSrcweir case ocSub :
815cdf0e10cSrcweir case ocMul :
816cdf0e10cSrcweir case ocDiv :
817cdf0e10cSrcweir case ocPow :
818cdf0e10cSrcweir case ocPower :
819cdf0e10cSrcweir case ocAmpersand :
820cdf0e10cSrcweir case ocEqual :
821cdf0e10cSrcweir case ocNotEqual :
822cdf0e10cSrcweir case ocLess :
823cdf0e10cSrcweir case ocGreater :
824cdf0e10cSrcweir case ocLessEqual :
825cdf0e10cSrcweir case ocGreaterEqual :
826cdf0e10cSrcweir {
827cdf0e10cSrcweir for ( sal_uInt8 k = nParams; k; k-- )
828cdf0e10cSrcweir {
829cdf0e10cSrcweir if ( sp >= k && pStack[sp-k]->GetType() == svDoubleRef )
830cdf0e10cSrcweir {
831cdf0e10cSrcweir pResult->Delete();
832cdf0e10cSrcweir delete [] pStack;
833cdf0e10cSrcweir return sal_True;
834cdf0e10cSrcweir }
835cdf0e10cSrcweir }
836cdf0e10cSrcweir }
837cdf0e10cSrcweir break;
838cdf0e10cSrcweir default:
839cdf0e10cSrcweir {
840cdf0e10cSrcweir // added to avoid warnings
841cdf0e10cSrcweir }
842cdf0e10cSrcweir }
843cdf0e10cSrcweir if ( eOp == ocPush || lcl_IsReference( eOp, t->GetType() ) )
844cdf0e10cSrcweir pStack[sp++] = t;
845cdf0e10cSrcweir else if ( eOp == ocIf || eOp == ocChose )
846cdf0e10cSrcweir { // Jumps ignorieren, vorheriges Result (Condition) poppen
847cdf0e10cSrcweir if ( sp )
848cdf0e10cSrcweir --sp;
849cdf0e10cSrcweir }
850cdf0e10cSrcweir else
851cdf0e10cSrcweir { // pop parameters, push result
852cdf0e10cSrcweir sp = sal::static_int_cast<short>( sp - nParams );
853cdf0e10cSrcweir if ( sp < 0 )
854cdf0e10cSrcweir {
855cdf0e10cSrcweir DBG_ERROR( "FormulaTokenArray::HasMatrixDoubleRefOps: sp < 0" );
856cdf0e10cSrcweir sp = 0;
857cdf0e10cSrcweir }
858cdf0e10cSrcweir pStack[sp++] = pResult;
859cdf0e10cSrcweir }
860cdf0e10cSrcweir }
861cdf0e10cSrcweir pResult->Delete();
862cdf0e10cSrcweir delete [] pStack;
863cdf0e10cSrcweir }
864cdf0e10cSrcweir
865cdf0e10cSrcweir return sal_False;
866cdf0e10cSrcweir }
867cdf0e10cSrcweir
868cdf0e10cSrcweir
869cdf0e10cSrcweir
870cdf0e10cSrcweir // --- POF (plain old formula) rewrite of a token array ---------------------
871cdf0e10cSrcweir
872cdf0e10cSrcweir #if 0
873cdf0e10cSrcweir // static function can't be compiled if not used (warning)
874cdf0e10cSrcweir //#if OSL_DEBUG_LEVEL > 0
875cdf0e10cSrcweir static void DumpTokArr( FormulaTokenArray *pCode )
876cdf0e10cSrcweir {
877cdf0e10cSrcweir fprintf (stderr, "TokenArr: ");
878cdf0e10cSrcweir for ( FormulaToken *pCur = pCode->First(); pCur; pCur = pCode->Next() )
879cdf0e10cSrcweir fprintf( stderr, "t%d,o%d ",
880cdf0e10cSrcweir pCur->GetType(), pCur->GetOpCode() );
881cdf0e10cSrcweir fprintf (stderr, "\n");
882cdf0e10cSrcweir }
883cdf0e10cSrcweir #endif
884cdf0e10cSrcweir
isRewriteNeeded(OpCode eOp) const885cdf0e10cSrcweir inline bool MissingConvention::isRewriteNeeded( OpCode eOp ) const
886cdf0e10cSrcweir {
887cdf0e10cSrcweir switch (eOp)
888cdf0e10cSrcweir {
889cdf0e10cSrcweir case ocGammaDist:
890cdf0e10cSrcweir case ocPoissonDist:
891cdf0e10cSrcweir case ocAddress:
892cdf0e10cSrcweir case ocLogNormDist:
893cdf0e10cSrcweir case ocNormDist:
894cdf0e10cSrcweir return true;
895cdf0e10cSrcweir case ocMissing:
896cdf0e10cSrcweir case ocLog:
897cdf0e10cSrcweir return !isODFF(); // rewrite only for PODF
898cdf0e10cSrcweir default:
899cdf0e10cSrcweir return false;
900cdf0e10cSrcweir }
901cdf0e10cSrcweir }
902cdf0e10cSrcweir
903cdf0e10cSrcweir class FormulaMissingContext
904cdf0e10cSrcweir {
905cdf0e10cSrcweir public:
906cdf0e10cSrcweir const FormulaToken* mpFunc;
907cdf0e10cSrcweir int mnCurArg;
908cdf0e10cSrcweir
Clear()909cdf0e10cSrcweir void Clear() { mpFunc = NULL; mnCurArg = 0; }
910cdf0e10cSrcweir inline bool AddDefaultArg( FormulaTokenArray* pNewArr, int nArg, double f ) const;
911cdf0e10cSrcweir bool AddMissingExternal( FormulaTokenArray* pNewArr ) const;
912cdf0e10cSrcweir bool AddMissing( FormulaTokenArray *pNewArr, const MissingConvention & rConv ) const;
913cdf0e10cSrcweir void AddMoreArgs( FormulaTokenArray *pNewArr, const MissingConvention & rConv ) const;
914cdf0e10cSrcweir };
915cdf0e10cSrcweir
AddMoreArgs(FormulaTokenArray * pNewArr,const MissingConvention & rConv) const916cdf0e10cSrcweir void FormulaMissingContext::AddMoreArgs( FormulaTokenArray *pNewArr, const MissingConvention & rConv ) const
917cdf0e10cSrcweir {
918cdf0e10cSrcweir if ( !mpFunc )
919cdf0e10cSrcweir return;
920cdf0e10cSrcweir
921cdf0e10cSrcweir switch (mpFunc->GetOpCode())
922cdf0e10cSrcweir {
923cdf0e10cSrcweir case ocGammaDist:
924cdf0e10cSrcweir if (mnCurArg == 2)
925cdf0e10cSrcweir {
926cdf0e10cSrcweir pNewArr->AddOpCode( ocSep );
927cdf0e10cSrcweir pNewArr->AddDouble( 1.0 ); // 4th, Cumulative=sal_True()
928cdf0e10cSrcweir }
929cdf0e10cSrcweir break;
930cdf0e10cSrcweir case ocPoissonDist:
931cdf0e10cSrcweir if (mnCurArg == 1)
932cdf0e10cSrcweir {
933cdf0e10cSrcweir pNewArr->AddOpCode( ocSep );
934cdf0e10cSrcweir pNewArr->AddDouble( 1.0 ); // 3rd, Cumulative=sal_True()
935cdf0e10cSrcweir }
936cdf0e10cSrcweir break;
937cdf0e10cSrcweir case ocNormDist:
938cdf0e10cSrcweir if ( mnCurArg == 2 )
939cdf0e10cSrcweir {
940cdf0e10cSrcweir pNewArr->AddOpCode( ocSep );
941cdf0e10cSrcweir pNewArr->AddDouble( 1.0 ); // 4th, Cumulative=sal_True()
942cdf0e10cSrcweir }
943cdf0e10cSrcweir break;
944cdf0e10cSrcweir case ocLogNormDist:
945cdf0e10cSrcweir if ( mnCurArg == 0 )
946cdf0e10cSrcweir {
947cdf0e10cSrcweir pNewArr->AddOpCode( ocSep );
948cdf0e10cSrcweir pNewArr->AddDouble( 0.0 ); // 2nd, mean = 0.0
949cdf0e10cSrcweir }
950cdf0e10cSrcweir if ( mnCurArg <= 1 )
951cdf0e10cSrcweir {
952cdf0e10cSrcweir pNewArr->AddOpCode( ocSep );
953cdf0e10cSrcweir pNewArr->AddDouble( 1.0 ); // 3rd, standard deviation = 1.0
954cdf0e10cSrcweir }
955cdf0e10cSrcweir break;
956cdf0e10cSrcweir case ocLog:
957cdf0e10cSrcweir if ( !rConv.isODFF() && mnCurArg == 0 )
958cdf0e10cSrcweir {
959cdf0e10cSrcweir pNewArr->AddOpCode( ocSep );
960cdf0e10cSrcweir pNewArr->AddDouble( 10.0 ); // 2nd, basis 10
961cdf0e10cSrcweir }
962cdf0e10cSrcweir break;
963cdf0e10cSrcweir default:
964cdf0e10cSrcweir break;
965cdf0e10cSrcweir }
966cdf0e10cSrcweir }
967cdf0e10cSrcweir
AddDefaultArg(FormulaTokenArray * pNewArr,int nArg,double f) const968cdf0e10cSrcweir inline bool FormulaMissingContext::AddDefaultArg( FormulaTokenArray* pNewArr, int nArg, double f ) const
969cdf0e10cSrcweir {
970cdf0e10cSrcweir if (mnCurArg == nArg)
971cdf0e10cSrcweir {
972cdf0e10cSrcweir pNewArr->AddDouble( f );
973cdf0e10cSrcweir return true;
974cdf0e10cSrcweir }
975cdf0e10cSrcweir return false;
976cdf0e10cSrcweir }
977cdf0e10cSrcweir
AddMissingExternal(FormulaTokenArray * pNewArr) const978cdf0e10cSrcweir bool FormulaMissingContext::AddMissingExternal( FormulaTokenArray *pNewArr ) const
979cdf0e10cSrcweir {
980cdf0e10cSrcweir // Only called for PODF, not ODFF. No need to distinguish.
981cdf0e10cSrcweir
982cdf0e10cSrcweir const String &rName = mpFunc->GetExternal();
983cdf0e10cSrcweir
984cdf0e10cSrcweir // initial (fast) check:
985cdf0e10cSrcweir sal_Unicode nLastChar = rName.GetChar( rName.Len() - 1);
986cdf0e10cSrcweir if ( nLastChar != 't' && nLastChar != 'm' )
987cdf0e10cSrcweir return false;
988cdf0e10cSrcweir
989cdf0e10cSrcweir if (rName.EqualsIgnoreCaseAscii(
990cdf0e10cSrcweir "com.sun.star.sheet.addin.Analysis.getAccrint" ))
991cdf0e10cSrcweir {
992cdf0e10cSrcweir return AddDefaultArg( pNewArr, 4, 1000.0 );
993cdf0e10cSrcweir }
994cdf0e10cSrcweir if (rName.EqualsIgnoreCaseAscii(
995cdf0e10cSrcweir "com.sun.star.sheet.addin.Analysis.getAccrintm" ))
996cdf0e10cSrcweir {
997cdf0e10cSrcweir return AddDefaultArg( pNewArr, 3, 1000.0 );
998cdf0e10cSrcweir }
999cdf0e10cSrcweir return false;
1000cdf0e10cSrcweir }
1001cdf0e10cSrcweir
AddMissing(FormulaTokenArray * pNewArr,const MissingConvention & rConv) const1002cdf0e10cSrcweir bool FormulaMissingContext::AddMissing( FormulaTokenArray *pNewArr, const MissingConvention & rConv ) const
1003cdf0e10cSrcweir {
1004cdf0e10cSrcweir if ( !mpFunc )
1005cdf0e10cSrcweir return false;
1006cdf0e10cSrcweir
1007cdf0e10cSrcweir bool bRet = false;
1008cdf0e10cSrcweir const OpCode eOp = mpFunc->GetOpCode();
1009cdf0e10cSrcweir
1010cdf0e10cSrcweir // Add for both, PODF and ODFF
1011cdf0e10cSrcweir switch (eOp)
1012cdf0e10cSrcweir {
1013cdf0e10cSrcweir case ocAddress:
1014cdf0e10cSrcweir return AddDefaultArg( pNewArr, 2, 1.0 ); // abs
1015cdf0e10cSrcweir default:
1016cdf0e10cSrcweir break;
1017cdf0e10cSrcweir }
1018cdf0e10cSrcweir
1019cdf0e10cSrcweir if (rConv.isODFF())
1020cdf0e10cSrcweir {
1021cdf0e10cSrcweir // Add for ODFF
1022cdf0e10cSrcweir }
1023cdf0e10cSrcweir else
1024cdf0e10cSrcweir {
1025cdf0e10cSrcweir // Add for PODF
1026cdf0e10cSrcweir switch (eOp)
1027cdf0e10cSrcweir {
1028cdf0e10cSrcweir case ocFixed:
1029cdf0e10cSrcweir return AddDefaultArg( pNewArr, 1, 2.0 );
1030cdf0e10cSrcweir case ocBetaDist:
1031cdf0e10cSrcweir case ocBetaInv:
1032cdf0e10cSrcweir case ocRMZ: // PMT
1033cdf0e10cSrcweir return AddDefaultArg( pNewArr, 3, 0.0 );
1034cdf0e10cSrcweir case ocZinsZ: // IPMT
1035cdf0e10cSrcweir case ocKapz: // PPMT
1036cdf0e10cSrcweir return AddDefaultArg( pNewArr, 4, 0.0 );
1037cdf0e10cSrcweir case ocBW: // PV
1038cdf0e10cSrcweir case ocZW: // FV
1039cdf0e10cSrcweir bRet |= AddDefaultArg( pNewArr, 2, 0.0 ); // pmt
1040cdf0e10cSrcweir bRet |= AddDefaultArg( pNewArr, 3, 0.0 ); // [fp]v
1041cdf0e10cSrcweir break;
1042cdf0e10cSrcweir case ocZins: // RATE
1043cdf0e10cSrcweir bRet |= AddDefaultArg( pNewArr, 1, 0.0 ); // pmt
1044cdf0e10cSrcweir bRet |= AddDefaultArg( pNewArr, 3, 0.0 ); // fv
1045cdf0e10cSrcweir bRet |= AddDefaultArg( pNewArr, 4, 0.0 ); // type
1046cdf0e10cSrcweir break;
1047cdf0e10cSrcweir case ocExternal:
1048cdf0e10cSrcweir return AddMissingExternal( pNewArr );
1049cdf0e10cSrcweir
1050cdf0e10cSrcweir // --- more complex cases ---
1051cdf0e10cSrcweir
1052cdf0e10cSrcweir case ocOffset:
1053cdf0e10cSrcweir // FIXME: rather tough.
1054cdf0e10cSrcweir // if arg 3 (height) ommitted, export arg1 (rows)
1055cdf0e10cSrcweir break;
1056cdf0e10cSrcweir default:
1057cdf0e10cSrcweir break;
1058cdf0e10cSrcweir }
1059cdf0e10cSrcweir }
1060cdf0e10cSrcweir
1061cdf0e10cSrcweir return bRet;
1062cdf0e10cSrcweir }
1063cdf0e10cSrcweir
NeedsPofRewrite(const MissingConvention & rConv)1064cdf0e10cSrcweir bool FormulaTokenArray::NeedsPofRewrite( const MissingConvention & rConv )
1065cdf0e10cSrcweir {
1066cdf0e10cSrcweir for ( FormulaToken *pCur = First(); pCur; pCur = Next() )
1067cdf0e10cSrcweir {
1068cdf0e10cSrcweir if ( rConv.isRewriteNeeded( pCur->GetOpCode()))
1069cdf0e10cSrcweir return true;
1070cdf0e10cSrcweir }
1071cdf0e10cSrcweir return false;
1072cdf0e10cSrcweir }
1073cdf0e10cSrcweir
1074cdf0e10cSrcweir
RewriteMissingToPof(const MissingConvention & rConv)1075cdf0e10cSrcweir FormulaTokenArray * FormulaTokenArray::RewriteMissingToPof( const MissingConvention & rConv )
1076cdf0e10cSrcweir {
1077cdf0e10cSrcweir const size_t nAlloc = 256;
1078cdf0e10cSrcweir FormulaMissingContext aCtx[ nAlloc ];
1079cdf0e10cSrcweir int aOpCodeAddressStack[ nAlloc ]; // use of ADDRESS() function
1080cdf0e10cSrcweir const int nOmitAddressArg = 3; // ADDRESS() 4th parameter A1/R1C1
1081cdf0e10cSrcweir sal_uInt16 nTokens = GetLen() + 1;
1082cdf0e10cSrcweir FormulaMissingContext* pCtx = (nAlloc < nTokens ? new FormulaMissingContext[nTokens] : &aCtx[0]);
1083cdf0e10cSrcweir int* pOcas = (nAlloc < nTokens ? new int[nTokens] : &aOpCodeAddressStack[0]);
1084cdf0e10cSrcweir // Never go below 0, never use 0, mpFunc always NULL.
1085cdf0e10cSrcweir pCtx[0].Clear();
1086cdf0e10cSrcweir int nFn = 0;
1087cdf0e10cSrcweir int nOcas = 0;
1088cdf0e10cSrcweir
1089cdf0e10cSrcweir FormulaTokenArray *pNewArr = new FormulaTokenArray;
1090cdf0e10cSrcweir // At least RECALCMODE_ALWAYS needs to be set.
1091cdf0e10cSrcweir pNewArr->AddRecalcMode( GetRecalcMode());
1092cdf0e10cSrcweir
1093cdf0e10cSrcweir for ( FormulaToken *pCur = First(); pCur; pCur = Next() )
1094cdf0e10cSrcweir {
1095cdf0e10cSrcweir bool bAdd = true;
1096cdf0e10cSrcweir // Don't write the expression of the new inserted ADDRESS() parameter.
1097cdf0e10cSrcweir // Do NOT omit the new second parameter of INDIRECT() though. If that
1098cdf0e10cSrcweir // was done for both, INDIRECT() actually could calculate different and
1099cdf0e10cSrcweir // valid (but wrong) results with the then changed return value of
1100cdf0e10cSrcweir // ADDRESS(). Better let it generate an error instead.
1101cdf0e10cSrcweir for (int i = nOcas; i-- > 0 && bAdd; )
1102cdf0e10cSrcweir {
1103cdf0e10cSrcweir if (pCtx[ pOcas[ i ] ].mnCurArg == nOmitAddressArg)
1104cdf0e10cSrcweir {
1105cdf0e10cSrcweir // Omit erverything except a trailing separator, the leading
1106cdf0e10cSrcweir // separator is omitted below. The other way around would leave
1107cdf0e10cSrcweir // an extraneous separator if no parameter followed.
1108cdf0e10cSrcweir if (!(pOcas[ i ] == nFn && pCur->GetOpCode() == ocSep))
1109cdf0e10cSrcweir bAdd = false;
1110cdf0e10cSrcweir }
1111cdf0e10cSrcweir //fprintf( stderr, "ocAddress %d arg %d%s\n", (int)i, (int)pCtx[ pOcas[ i ] ].mnCurArg, (bAdd ? "" : " omitted"));
1112cdf0e10cSrcweir }
1113cdf0e10cSrcweir switch ( pCur->GetOpCode() )
1114cdf0e10cSrcweir {
1115cdf0e10cSrcweir case ocOpen:
1116cdf0e10cSrcweir ++nFn; // all following operations on _that_ function
1117cdf0e10cSrcweir pCtx[ nFn ].mpFunc = PeekPrevNoSpaces();
1118cdf0e10cSrcweir pCtx[ nFn ].mnCurArg = 0;
1119cdf0e10cSrcweir if (pCtx[ nFn ].mpFunc && pCtx[ nFn ].mpFunc->GetOpCode() == ocAddress && !rConv.isODFF())
1120cdf0e10cSrcweir pOcas[ nOcas++ ] = nFn; // entering ADDRESS() if PODF
1121cdf0e10cSrcweir break;
1122cdf0e10cSrcweir case ocClose:
1123cdf0e10cSrcweir pCtx[ nFn ].AddMoreArgs( pNewArr, rConv );
1124cdf0e10cSrcweir DBG_ASSERT( nFn > 0, "FormulaTokenArray::RewriteMissingToPof: underflow");
1125cdf0e10cSrcweir if (nOcas > 0 && pOcas[ nOcas-1 ] == nFn)
1126cdf0e10cSrcweir --nOcas; // leaving ADDRESS()
1127cdf0e10cSrcweir if (nFn > 0)
1128cdf0e10cSrcweir --nFn;
1129cdf0e10cSrcweir break;
1130cdf0e10cSrcweir case ocSep:
1131cdf0e10cSrcweir pCtx[ nFn ].mnCurArg++;
1132cdf0e10cSrcweir // Omit leading separator of ADDRESS() parameter.
1133cdf0e10cSrcweir if (nOcas && pOcas[ nOcas-1 ] == nFn && pCtx[ nFn ].mnCurArg == nOmitAddressArg)
1134cdf0e10cSrcweir {
1135cdf0e10cSrcweir bAdd = false;
1136cdf0e10cSrcweir //fprintf( stderr, "ocAddress %d sep %d omitted\n", (int)nOcas-1, nOmitAddressArg);
1137cdf0e10cSrcweir }
1138cdf0e10cSrcweir break;
1139cdf0e10cSrcweir case ocMissing:
1140cdf0e10cSrcweir if (bAdd)
1141cdf0e10cSrcweir bAdd = !pCtx[ nFn ].AddMissing( pNewArr, rConv );
1142cdf0e10cSrcweir break;
1143cdf0e10cSrcweir default:
1144cdf0e10cSrcweir break;
1145cdf0e10cSrcweir }
1146cdf0e10cSrcweir if (bAdd)
1147cdf0e10cSrcweir pNewArr->AddToken( *pCur );
1148cdf0e10cSrcweir }
1149cdf0e10cSrcweir
1150cdf0e10cSrcweir if (pOcas != &aOpCodeAddressStack[0])
1151cdf0e10cSrcweir delete [] pOcas;
1152cdf0e10cSrcweir if (pCtx != &aCtx[0])
1153cdf0e10cSrcweir delete [] pCtx;
1154cdf0e10cSrcweir
1155cdf0e10cSrcweir return pNewArr;
1156cdf0e10cSrcweir }
1157cdf0e10cSrcweir
MayReferenceFollow()1158cdf0e10cSrcweir bool FormulaTokenArray::MayReferenceFollow()
1159cdf0e10cSrcweir {
1160cdf0e10cSrcweir if ( pCode && nLen > 0 )
1161cdf0e10cSrcweir {
1162cdf0e10cSrcweir // ignore trailing spaces
1163cdf0e10cSrcweir sal_uInt16 i = nLen - 1;
1164cdf0e10cSrcweir while ( i > 0 && pCode[i]->GetOpCode() == SC_OPCODE_SPACES )
1165cdf0e10cSrcweir {
1166cdf0e10cSrcweir --i;
1167cdf0e10cSrcweir }
1168cdf0e10cSrcweir if ( i > 0 || pCode[i]->GetOpCode() != SC_OPCODE_SPACES )
1169cdf0e10cSrcweir {
1170cdf0e10cSrcweir OpCode eOp = pCode[i]->GetOpCode();
1171cdf0e10cSrcweir if ( (SC_OPCODE_START_BIN_OP <= eOp && eOp < SC_OPCODE_STOP_BIN_OP ) ||
1172cdf0e10cSrcweir (SC_OPCODE_START_UN_OP <= eOp && eOp < SC_OPCODE_STOP_UN_OP ) ||
1173cdf0e10cSrcweir eOp == SC_OPCODE_OPEN || eOp == SC_OPCODE_SEP )
1174cdf0e10cSrcweir {
1175cdf0e10cSrcweir return true;
1176cdf0e10cSrcweir }
1177cdf0e10cSrcweir }
1178cdf0e10cSrcweir }
1179cdf0e10cSrcweir return false;
1180cdf0e10cSrcweir }
AddOpCode(OpCode eOp)1181cdf0e10cSrcweir FormulaToken* FormulaTokenArray::AddOpCode( OpCode eOp )
1182cdf0e10cSrcweir {
1183cdf0e10cSrcweir FormulaToken* pRet = NULL;
1184cdf0e10cSrcweir switch ( eOp )
1185cdf0e10cSrcweir {
1186cdf0e10cSrcweir case ocOpen:
1187cdf0e10cSrcweir case ocClose:
1188cdf0e10cSrcweir case ocSep:
1189cdf0e10cSrcweir case ocArrayOpen:
1190cdf0e10cSrcweir case ocArrayClose:
1191cdf0e10cSrcweir case ocArrayRowSep:
1192cdf0e10cSrcweir case ocArrayColSep:
1193cdf0e10cSrcweir pRet = new FormulaToken( svSep,eOp );
1194cdf0e10cSrcweir break;
1195cdf0e10cSrcweir case ocIf:
1196cdf0e10cSrcweir case ocChose:
1197cdf0e10cSrcweir {
1198cdf0e10cSrcweir short nJump[MAXJUMPCOUNT + 1];
1199cdf0e10cSrcweir nJump[ 0 ] = ocIf == eOp ? 3 : MAXJUMPCOUNT+1;
1200cdf0e10cSrcweir pRet = new FormulaJumpToken( eOp, (short*)nJump );
1201cdf0e10cSrcweir }
1202cdf0e10cSrcweir break;
1203cdf0e10cSrcweir default:
1204cdf0e10cSrcweir pRet = new FormulaByteToken( eOp, 0, sal_False );
1205cdf0e10cSrcweir break;
1206cdf0e10cSrcweir }
1207cdf0e10cSrcweir return AddToken( *pRet );
1208cdf0e10cSrcweir }
1209cdf0e10cSrcweir
1210cdf0e10cSrcweir
1211cdf0e10cSrcweir /*----------------------------------------------------------------------*/
1212cdf0e10cSrcweir
FormulaTokenIterator(const FormulaTokenArray & rArr)1213cdf0e10cSrcweir FormulaTokenIterator::FormulaTokenIterator( const FormulaTokenArray& rArr )
1214cdf0e10cSrcweir {
1215cdf0e10cSrcweir pCur = NULL;
1216cdf0e10cSrcweir Push( &rArr );
1217cdf0e10cSrcweir }
1218cdf0e10cSrcweir
~FormulaTokenIterator()1219cdf0e10cSrcweir FormulaTokenIterator::~FormulaTokenIterator()
1220cdf0e10cSrcweir {
1221cdf0e10cSrcweir while( pCur )
1222cdf0e10cSrcweir Pop();
1223cdf0e10cSrcweir }
1224cdf0e10cSrcweir
Push(const FormulaTokenArray * pArr)1225cdf0e10cSrcweir void FormulaTokenIterator::Push( const FormulaTokenArray* pArr )
1226cdf0e10cSrcweir {
1227cdf0e10cSrcweir ImpTokenIterator* p = new ImpTokenIterator;
1228cdf0e10cSrcweir p->pArr = pArr;
1229cdf0e10cSrcweir p->nPC = -1;
1230cdf0e10cSrcweir p->nStop = SHRT_MAX;
1231cdf0e10cSrcweir p->pNext = pCur;
1232cdf0e10cSrcweir pCur = p;
1233cdf0e10cSrcweir }
1234cdf0e10cSrcweir
Pop()1235cdf0e10cSrcweir void FormulaTokenIterator::Pop()
1236cdf0e10cSrcweir {
1237cdf0e10cSrcweir ImpTokenIterator* p = pCur;
1238cdf0e10cSrcweir if( p )
1239cdf0e10cSrcweir {
1240cdf0e10cSrcweir pCur = p->pNext;
1241cdf0e10cSrcweir delete p;
1242cdf0e10cSrcweir }
1243cdf0e10cSrcweir }
1244cdf0e10cSrcweir
Reset()1245cdf0e10cSrcweir void FormulaTokenIterator::Reset()
1246cdf0e10cSrcweir {
1247cdf0e10cSrcweir while( pCur->pNext )
1248cdf0e10cSrcweir Pop();
1249cdf0e10cSrcweir pCur->nPC = -1;
1250cdf0e10cSrcweir }
1251cdf0e10cSrcweir
First()1252cdf0e10cSrcweir const FormulaToken* FormulaTokenIterator::First()
1253cdf0e10cSrcweir {
1254cdf0e10cSrcweir Reset();
1255cdf0e10cSrcweir return Next();
1256cdf0e10cSrcweir }
1257cdf0e10cSrcweir
Next()1258cdf0e10cSrcweir const FormulaToken* FormulaTokenIterator::Next()
1259cdf0e10cSrcweir {
1260cdf0e10cSrcweir const FormulaToken* t = GetNonEndOfPathToken( ++pCur->nPC );
1261cdf0e10cSrcweir if( !t && pCur->pNext )
1262cdf0e10cSrcweir {
1263cdf0e10cSrcweir Pop();
1264cdf0e10cSrcweir t = Next();
1265cdf0e10cSrcweir }
1266cdf0e10cSrcweir return t;
1267cdf0e10cSrcweir }
1268cdf0e10cSrcweir
PeekNextOperator()1269cdf0e10cSrcweir const FormulaToken* FormulaTokenIterator::PeekNextOperator()
1270cdf0e10cSrcweir {
1271cdf0e10cSrcweir const FormulaToken* t = NULL;
1272cdf0e10cSrcweir short nIdx = pCur->nPC;
1273cdf0e10cSrcweir while (!t && ((t = GetNonEndOfPathToken( ++nIdx)) != NULL))
1274cdf0e10cSrcweir {
1275cdf0e10cSrcweir if (t->GetOpCode() == ocPush)
1276cdf0e10cSrcweir t = NULL; // ignore operands
1277cdf0e10cSrcweir }
1278cdf0e10cSrcweir if (!t && pCur->pNext)
1279cdf0e10cSrcweir {
1280cdf0e10cSrcweir ImpTokenIterator* pHere = pCur;
1281cdf0e10cSrcweir pCur = pCur->pNext;
1282cdf0e10cSrcweir t = PeekNextOperator();
1283cdf0e10cSrcweir pCur = pHere;
1284cdf0e10cSrcweir }
1285cdf0e10cSrcweir return t;
1286cdf0e10cSrcweir }
1287cdf0e10cSrcweir
1288cdf0e10cSrcweir //! The nPC counts after a Push() are -1
1289cdf0e10cSrcweir
Jump(short nStart,short nNext,short nStop)1290cdf0e10cSrcweir void FormulaTokenIterator::Jump( short nStart, short nNext, short nStop )
1291cdf0e10cSrcweir {
1292cdf0e10cSrcweir pCur->nPC = nNext;
1293cdf0e10cSrcweir if( nStart != nNext )
1294cdf0e10cSrcweir {
1295cdf0e10cSrcweir Push( pCur->pArr );
1296cdf0e10cSrcweir pCur->nPC = nStart;
1297cdf0e10cSrcweir pCur->nStop = nStop;
1298cdf0e10cSrcweir }
1299cdf0e10cSrcweir }
1300cdf0e10cSrcweir
GetNonEndOfPathToken(short nIdx) const1301cdf0e10cSrcweir const FormulaToken* FormulaTokenIterator::GetNonEndOfPathToken( short nIdx ) const
1302cdf0e10cSrcweir {
1303cdf0e10cSrcweir if (nIdx < pCur->pArr->nRPN && nIdx < pCur->nStop)
1304cdf0e10cSrcweir {
1305cdf0e10cSrcweir const FormulaToken* t = pCur->pArr->pRPN[ nIdx ];
1306cdf0e10cSrcweir // such an OpCode ends an IF() or CHOOSE() path
1307cdf0e10cSrcweir return (t->GetOpCode() == ocSep || t->GetOpCode() == ocClose) ? NULL : t;
1308cdf0e10cSrcweir }
1309cdf0e10cSrcweir return NULL;
1310cdf0e10cSrcweir }
1311cdf0e10cSrcweir
IsEndOfPath() const1312cdf0e10cSrcweir bool FormulaTokenIterator::IsEndOfPath() const
1313cdf0e10cSrcweir {
13147aaaedbaSEike Rathke return GetNonEndOfPathToken( pCur->nPC + 1) == NULL;
1315cdf0e10cSrcweir }
1316cdf0e10cSrcweir
1317cdf0e10cSrcweir // -----------------------------------------------------------------------------
1318cdf0e10cSrcweir // ==========================================================================
1319cdf0e10cSrcweir // real implementations of virtual functions
1320cdf0e10cSrcweir // --------------------------------------------------------------------------
1321cdf0e10cSrcweir
GetDouble() const1322cdf0e10cSrcweir double FormulaDoubleToken::GetDouble() const { return fDouble; }
GetDoubleAsReference()1323cdf0e10cSrcweir double & FormulaDoubleToken::GetDoubleAsReference() { return fDouble; }
operator ==(const FormulaToken & r) const1324cdf0e10cSrcweir sal_Bool FormulaDoubleToken::operator==( const FormulaToken& r ) const
1325cdf0e10cSrcweir {
1326cdf0e10cSrcweir return FormulaToken::operator==( r ) && fDouble == r.GetDouble();
1327cdf0e10cSrcweir }
1328cdf0e10cSrcweir
1329cdf0e10cSrcweir
GetString() const1330cdf0e10cSrcweir const String& FormulaStringToken::GetString() const { return aString; }
operator ==(const FormulaToken & r) const1331cdf0e10cSrcweir sal_Bool FormulaStringToken::operator==( const FormulaToken& r ) const
1332cdf0e10cSrcweir {
1333cdf0e10cSrcweir return FormulaToken::operator==( r ) && aString == r.GetString();
1334cdf0e10cSrcweir }
1335cdf0e10cSrcweir
1336cdf0e10cSrcweir
GetString() const1337cdf0e10cSrcweir const String& FormulaStringOpToken::GetString() const { return aString; }
operator ==(const FormulaToken & r) const1338cdf0e10cSrcweir sal_Bool FormulaStringOpToken::operator==( const FormulaToken& r ) const
1339cdf0e10cSrcweir {
1340cdf0e10cSrcweir return FormulaByteToken::operator==( r ) && aString == r.GetString();
1341cdf0e10cSrcweir }
1342cdf0e10cSrcweir
GetIndex() const1343cdf0e10cSrcweir sal_uInt16 FormulaIndexToken::GetIndex() const { return nIndex; }
SetIndex(sal_uInt16 n)1344cdf0e10cSrcweir void FormulaIndexToken::SetIndex( sal_uInt16 n ) { nIndex = n; }
operator ==(const FormulaToken & r) const1345cdf0e10cSrcweir sal_Bool FormulaIndexToken::operator==( const FormulaToken& r ) const
1346cdf0e10cSrcweir {
1347cdf0e10cSrcweir return FormulaToken::operator==( r ) && nIndex == r.GetIndex();
1348cdf0e10cSrcweir }
GetExternal() const1349cdf0e10cSrcweir const String& FormulaExternalToken::GetExternal() const { return aExternal; }
GetByte() const1350cdf0e10cSrcweir sal_uInt8 FormulaExternalToken::GetByte() const { return nByte; }
SetByte(sal_uInt8 n)1351cdf0e10cSrcweir void FormulaExternalToken::SetByte( sal_uInt8 n ) { nByte = n; }
operator ==(const FormulaToken & r) const1352cdf0e10cSrcweir sal_Bool FormulaExternalToken::operator==( const FormulaToken& r ) const
1353cdf0e10cSrcweir {
1354cdf0e10cSrcweir return FormulaToken::operator==( r ) && nByte == r.GetByte() &&
1355cdf0e10cSrcweir aExternal == r.GetExternal();
1356cdf0e10cSrcweir }
1357cdf0e10cSrcweir
1358cdf0e10cSrcweir
GetError() const1359cdf0e10cSrcweir sal_uInt16 FormulaErrorToken::GetError() const { return nError; }
SetError(sal_uInt16 nErr)1360cdf0e10cSrcweir void FormulaErrorToken::SetError( sal_uInt16 nErr ) { nError = nErr; }
operator ==(const FormulaToken & r) const1361cdf0e10cSrcweir sal_Bool FormulaErrorToken::operator==( const FormulaToken& r ) const
1362cdf0e10cSrcweir {
1363cdf0e10cSrcweir return FormulaToken::operator==( r ) &&
1364cdf0e10cSrcweir nError == static_cast< const FormulaErrorToken & >(r).GetError();
1365cdf0e10cSrcweir }
GetDouble() const1366cdf0e10cSrcweir double FormulaMissingToken::GetDouble() const { return 0.0; }
GetString() const1367cdf0e10cSrcweir const String& FormulaMissingToken::GetString() const
1368cdf0e10cSrcweir {
1369cdf0e10cSrcweir static String aDummyString;
1370cdf0e10cSrcweir return aDummyString;
1371cdf0e10cSrcweir }
operator ==(const FormulaToken & r) const1372cdf0e10cSrcweir sal_Bool FormulaMissingToken::operator==( const FormulaToken& r ) const
1373cdf0e10cSrcweir {
1374cdf0e10cSrcweir return FormulaToken::operator==( r );
1375cdf0e10cSrcweir }
1376cdf0e10cSrcweir
1377cdf0e10cSrcweir
FormulaSubroutineToken(const FormulaSubroutineToken & r)1378cdf0e10cSrcweir FormulaSubroutineToken::FormulaSubroutineToken( const FormulaSubroutineToken& r ) :
1379cdf0e10cSrcweir FormulaToken( r ),
1380cdf0e10cSrcweir mpArray( r.mpArray->Clone())
1381cdf0e10cSrcweir {
1382cdf0e10cSrcweir }
~FormulaSubroutineToken()1383cdf0e10cSrcweir FormulaSubroutineToken::~FormulaSubroutineToken()
1384cdf0e10cSrcweir {
1385cdf0e10cSrcweir delete mpArray;
1386cdf0e10cSrcweir }
GetTokenArray() const1387cdf0e10cSrcweir const FormulaTokenArray* FormulaSubroutineToken::GetTokenArray() const
1388cdf0e10cSrcweir {
1389cdf0e10cSrcweir return mpArray;
1390cdf0e10cSrcweir }
operator ==(const FormulaToken & r) const1391cdf0e10cSrcweir sal_Bool FormulaSubroutineToken::operator==( const FormulaToken& r ) const
1392cdf0e10cSrcweir {
1393cdf0e10cSrcweir // Arrays don't equal..
1394cdf0e10cSrcweir return FormulaToken::operator==( r ) &&
1395cdf0e10cSrcweir (mpArray == static_cast<const FormulaSubroutineToken&>(r).mpArray);
1396cdf0e10cSrcweir }
1397cdf0e10cSrcweir
1398cdf0e10cSrcweir
operator ==(const FormulaToken & r) const1399cdf0e10cSrcweir sal_Bool FormulaUnknownToken::operator==( const FormulaToken& r ) const
1400cdf0e10cSrcweir {
1401cdf0e10cSrcweir return FormulaToken::operator==( r );
1402cdf0e10cSrcweir }
1403cdf0e10cSrcweir
1404cdf0e10cSrcweir // -----------------------------------------------------------------------------
1405cdf0e10cSrcweir } // formula
1406cdf0e10cSrcweir // -----------------------------------------------------------------------------
1407cdf0e10cSrcweir
1408