bump product version to 4.2.0.1
[LibreOffice.git] / include / formula / tokenarray.hxx
blob9f8fed0ab27d836f9139f90733e041989f134f4e
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 .
20 #ifndef INCLUDED_FORMULA_TOKENARRAY_HXX
21 #define INCLUDED_FORMULA_TOKENARRAY_HXX
23 #include <limits.h>
24 #include <formula/token.hxx>
25 #include <formula/ExternalReferenceHelper.hxx>
26 #include <tools/solar.h>
27 #include <com/sun/star/sheet/FormulaToken.hpp>
29 namespace formula
32 // RecalcMode access only via TokenArray SetRecalcMode / IsRecalcMode...
34 typedef sal_uInt8 ScRecalcMode;
35 // Only one of the exclusive bits can be set,
36 // handled by TokenArray SetRecalcMode... methods
37 #define RECALCMODE_NORMAL 0x01 // exclusive
38 #define RECALCMODE_ALWAYS 0x02 // exclusive, always
39 #define RECALCMODE_ONLOAD 0x04 // exclusive, always after load
40 #define RECALCMODE_ONLOAD_ONCE 0x08 // exclusive, once after load
41 #define RECALCMODE_FORCED 0x10 // combined, also if cell isn't visible
42 #define RECALCMODE_ONREFMOVE 0x20 // combined, if reference was moved
43 #define RECALCMODE_EMASK 0x0F // mask of exclusive bits
44 // If new bits are to be defined, AddRecalcMode has to be adjusted!
46 class FormulaMissingContext;
48 class FORMULA_DLLPUBLIC MissingConvention
50 bool mbODFF; /// TRUE: ODFF, FALSE: PODF
51 public:
52 explicit MissingConvention( bool bODFF ) : mbODFF(bODFF) {}
53 // Implementation and usage only in token.cxx
54 inline bool isRewriteNeeded( OpCode eOp ) const;
55 inline bool isODFF() const { return mbODFF; }
58 class FORMULA_DLLPUBLIC FormulaTokenArray
60 friend class FormulaCompiler;
61 friend class FormulaTokenIterator;
62 friend class FormulaMissingContext;
64 protected:
65 FormulaToken** pCode; // Token code array
66 FormulaToken** pRPN; // RPN array
67 sal_uInt16 nLen; // Length of token array
68 sal_uInt16 nRPN; // Length of RPN array
69 sal_uInt16 nIndex; // Current step index
70 sal_uInt16 nError; // Error code
71 short nRefs; // Count of cell references
72 ScRecalcMode nMode; // Flags to indicate when to recalc this code
73 bool bHyperLink; // If HYPERLINK() occurs in the formula.
75 protected:
76 void Assign( const FormulaTokenArray& );
78 /// Also used by the compiler. The token MUST had been allocated with new!
79 FormulaToken* Add( FormulaToken* );
80 inline void SetCombinedBitsRecalcMode( ScRecalcMode nBits )
81 { nMode |= (nBits & ~RECALCMODE_EMASK); }
82 inline ScRecalcMode GetCombinedBitsRecalcMode() const
83 { return nMode & ~RECALCMODE_EMASK; }
84 /** Exclusive bits already set in nMode are
85 zero'ed, nBits may contain combined bits, but
86 only one exclusive bit may be set! */
87 inline void SetMaskedRecalcMode( ScRecalcMode nBits )
88 { nMode = GetCombinedBitsRecalcMode() | nBits; }
90 public:
91 FormulaTokenArray();
92 /// Assignment with references to FormulaToken entries (not copied!)
93 FormulaTokenArray( const FormulaTokenArray& );
94 virtual ~FormulaTokenArray();
95 FormulaTokenArray* Clone() const; /// True copy!
97 void Clear();
98 void DelRPN();
99 FormulaToken* First() { nIndex = 0; return Next(); }
100 FormulaToken* Next();
101 FormulaToken* FirstNoSpaces() { nIndex = 0; return NextNoSpaces(); }
102 FormulaToken* NextNoSpaces();
103 FormulaToken* GetNextName();
104 FormulaToken* GetNextReference();
105 FormulaToken* GetNextReferenceRPN();
106 FormulaToken* GetNextReferenceOrName();
107 FormulaToken* GetNextColRowName();
108 FormulaToken* GetNextOpCodeRPN( OpCode );
109 /// Peek at nIdx-1 if not out of bounds, decrements nIdx if successful. Returns NULL if not.
110 FormulaToken* PeekPrev( sal_uInt16 & nIdx );
111 FormulaToken* PeekNext();
112 FormulaToken* PeekPrevNoSpaces(); /// Only after Reset/First/Next/Last/Prev!
113 FormulaToken* PeekNextNoSpaces(); /// Only after Reset/First/Next/Last/Prev!
114 FormulaToken* FirstRPN() { nIndex = 0; return NextRPN(); }
115 FormulaToken* NextRPN();
116 FormulaToken* LastRPN() { nIndex = nRPN; return PrevRPN(); }
117 FormulaToken* PrevRPN();
119 bool HasReferences() const;
121 bool HasExternalRef() const;
122 bool HasOpCode( OpCode ) const;
123 bool HasOpCodeRPN( OpCode ) const;
124 /// Token of type svIndex or opcode ocColRowName
125 bool HasNameOrColRowName() const;
127 FormulaToken** GetArray() const { return pCode; }
128 FormulaToken** GetCode() const { return pRPN; }
129 sal_uInt16 GetLen() const { return nLen; }
130 sal_uInt16 GetCodeLen() const { return nRPN; }
131 void Reset() { nIndex = 0; }
132 sal_uInt16 GetCodeError() const { return nError; }
133 void SetCodeError( sal_uInt16 n ) { nError = n; }
134 short GetRefs() const { return nRefs; }
135 void IncrementRefs() { ++nRefs; }
136 void SetHyperLink( bool bVal ) { bHyperLink = bVal; }
137 bool IsHyperLink() const { return bHyperLink; }
139 inline ScRecalcMode GetRecalcMode() const { return nMode; }
140 /** Bits aren't set directly but validated and
141 maybe handled according to priority if more
142 than one exclusive bit was set. */
143 void AddRecalcMode( ScRecalcMode nBits );
145 inline void ClearRecalcMode() { nMode = RECALCMODE_NORMAL; }
146 inline void SetExclusiveRecalcModeNormal()
147 { SetMaskedRecalcMode( RECALCMODE_NORMAL ); }
148 inline void SetExclusiveRecalcModeAlways()
149 { SetMaskedRecalcMode( RECALCMODE_ALWAYS ); }
150 inline void SetExclusiveRecalcModeOnLoad()
151 { SetMaskedRecalcMode( RECALCMODE_ONLOAD ); }
152 inline void SetExclusiveRecalcModeOnLoadOnce()
153 { SetMaskedRecalcMode( RECALCMODE_ONLOAD_ONCE ); }
154 inline void SetRecalcModeForced()
155 { nMode |= RECALCMODE_FORCED; }
156 inline void ClearRecalcModeForced()
157 { nMode &= ~RECALCMODE_FORCED; }
158 inline void SetRecalcModeOnRefMove()
159 { nMode |= RECALCMODE_ONREFMOVE; }
160 inline void ClearRecalcModeOnRefMove()
161 { nMode &= ~RECALCMODE_ONREFMOVE; }
162 inline bool IsRecalcModeNormal() const
163 { return (nMode & RECALCMODE_NORMAL) != 0; }
164 inline bool IsRecalcModeAlways() const
165 { return (nMode & RECALCMODE_ALWAYS) != 0; }
166 inline bool IsRecalcModeOnLoad() const
167 { return (nMode & RECALCMODE_ONLOAD) != 0; }
168 inline bool IsRecalcModeOnLoadOnce() const
169 { return (nMode & RECALCMODE_ONLOAD_ONCE) != 0; }
170 inline bool IsRecalcModeForced() const
171 { return (nMode & RECALCMODE_FORCED) != 0; }
172 inline bool IsRecalcModeOnRefMove() const
173 { return (nMode & RECALCMODE_ONREFMOVE) != 0; }
175 /** Get OpCode of the most outer function */
176 inline OpCode GetOuterFuncOpCode();
178 /** Operators +,-,*,/,^,&,=,<>,<,>,<=,>=
179 with DoubleRef in Formula? */
180 bool HasMatrixDoubleRefOps();
182 virtual FormulaToken* AddOpCode(OpCode e);
184 /** Adds the single token to array.
185 Derived classes must overload it when they want to support derived classes from FormulaToken.
186 @return true when an error occurs
188 virtual bool AddFormulaToken(const com::sun::star::sheet::FormulaToken& _aToken, ExternalReferenceHelper* _pRef = NULL);
190 /** fill the array with the tokens from the sequence.
191 It calls AddFormulaToken for each token in the list.
192 @param _aSequence the token to add
193 @return true when an error occurs
195 bool Fill(const com::sun::star::uno::Sequence< com::sun::star::sheet::FormulaToken >& _aSequence, ExternalReferenceHelper* _pRef = NULL);
198 * Do some checking based on the individual tokens. For now, we use this
199 * only to check whether we can vectorize the token array.
201 virtual void CheckToken( const FormulaToken& t );
203 FormulaToken* AddToken( const FormulaToken& );
204 FormulaToken* AddString( const sal_Unicode* pStr );
205 FormulaToken* AddString( const OUString& rStr );
206 FormulaToken* AddDouble( double fVal );
207 FormulaToken* AddExternal( const sal_Unicode* pStr );
208 /** Xcl import may play dirty tricks with OpCode!=ocExternal.
209 Others don't use! */
210 FormulaToken* AddExternal( const OUString& rStr, OpCode eOp = ocExternal );
211 FormulaToken* AddBad( const OUString& rStr ); /// ocBad with OUString
212 FormulaToken* AddStringXML( const OUString& rStr ); /// ocStringXML with OUString, temporary during import
214 virtual FormulaToken* MergeArray( );
216 /// Assignment with references to FormulaToken entries (not copied!)
217 FormulaTokenArray& operator=( const FormulaTokenArray& );
219 /** Determines if this formula needs any changes to convert it to something
220 previous versions of OOo could consume (Plain Old Formula). */
221 bool NeedsPofRewrite(const MissingConvention & rConv);
223 /** Rewrites to Plain Old Formula, substituting missing parameters. The
224 FormulaTokenArray* returned is new'ed. */
225 FormulaTokenArray* RewriteMissingToPof(const MissingConvention & rConv);
227 /** Determines if this formula may be followed by a reference. */
228 bool MayReferenceFollow();
231 inline OpCode FormulaTokenArray::GetOuterFuncOpCode()
233 if ( pRPN && nRPN )
234 return pRPN[nRPN-1]->GetOpCode();
235 return ocNone;
238 struct ImpTokenIterator
240 ImpTokenIterator* pNext;
241 const FormulaTokenArray* pArr;
242 short nPC;
243 short nStop;
245 DECL_FIXEDMEMPOOL_NEWDEL( ImpTokenIterator );
248 class FORMULA_DLLPUBLIC FormulaTokenIterator
250 ImpTokenIterator* pCur;
252 public:
253 FormulaTokenIterator( const FormulaTokenArray& );
254 ~FormulaTokenIterator();
255 void Reset();
256 const FormulaToken* Next();
257 const FormulaToken* PeekNextOperator();
258 bool IsEndOfPath() const; /// if a jump or subroutine path is done
259 bool HasStacked() const { return pCur->pNext != 0; }
260 short GetPC() const { return pCur->nPC; }
262 /** Jump or subroutine call.
263 Program counter values will be incremented before code is executed =>
264 positions are to be passed with -1 offset.
265 @param nStart
266 Start on code at position nStart+1 (yes, pass with offset -1)
267 @param nNext
268 After subroutine continue with instruction at position nNext+1
269 @param nStop
270 Stop before reaching code at position nStop. If not specified the
271 default is to either run the entire code, or to stop if an ocSep or
272 ocClose is encountered, which are only present in ocIf or ocChose
273 jumps.
275 void Jump( short nStart, short nNext, short nStop = SHRT_MAX );
276 void Push( const FormulaTokenArray* );
277 void Pop();
279 private:
280 const FormulaToken* GetNonEndOfPathToken( short nIdx ) const;
282 // =============================================================================
283 } // formula
284 // =============================================================================
287 #endif // INCLUDED_FORMULA_TOKENARRAY_HXX
289 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */