1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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 FORMULA_TOKENARRAY_HXX
21 #define FORMULA_TOKENARRAY_HXX
24 #include "formula/token.hxx"
25 #include "formula/ExternalReferenceHelper.hxx"
26 #include <tools/solar.h>
27 #include <com/sun/star/sheet/FormulaToken.hpp>
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
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
;
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.
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
; }
92 /// Assignment with references to FormulaToken entries (not copied!)
93 FormulaTokenArray( const FormulaTokenArray
& );
94 virtual ~FormulaTokenArray();
95 FormulaTokenArray
* Clone() const; /// True copy!
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 HasExternalRef() const;
120 bool HasOpCode( OpCode
) const;
121 bool HasOpCodeRPN( OpCode
) const;
122 /// Token of type svIndex or opcode ocColRowName
123 bool HasNameOrColRowName() const;
125 FormulaToken
** GetArray() const { return pCode
; }
126 FormulaToken
** GetCode() const { return pRPN
; }
127 sal_uInt16
GetLen() const { return nLen
; }
128 sal_uInt16
GetCodeLen() const { return nRPN
; }
129 void Reset() { nIndex
= 0; }
130 sal_uInt16
GetCodeError() const { return nError
; }
131 void SetCodeError( sal_uInt16 n
) { nError
= n
; }
132 short GetRefs() const { return nRefs
; }
133 void IncrementRefs() { ++nRefs
; }
134 void SetHyperLink( bool bVal
) { bHyperLink
= bVal
; }
135 bool IsHyperLink() const { return bHyperLink
; }
137 inline ScRecalcMode
GetRecalcMode() const { return nMode
; }
138 /** Bits aren't set directly but validated and
139 maybe handled according to priority if more
140 than one exclusive bit was set. */
141 void AddRecalcMode( ScRecalcMode nBits
);
143 inline void ClearRecalcMode() { nMode
= RECALCMODE_NORMAL
; }
144 inline void SetExclusiveRecalcModeNormal()
145 { SetMaskedRecalcMode( RECALCMODE_NORMAL
); }
146 inline void SetExclusiveRecalcModeAlways()
147 { SetMaskedRecalcMode( RECALCMODE_ALWAYS
); }
148 inline void SetExclusiveRecalcModeOnLoad()
149 { SetMaskedRecalcMode( RECALCMODE_ONLOAD
); }
150 inline void SetExclusiveRecalcModeOnLoadOnce()
151 { SetMaskedRecalcMode( RECALCMODE_ONLOAD_ONCE
); }
152 inline void SetRecalcModeForced()
153 { nMode
|= RECALCMODE_FORCED
; }
154 inline void ClearRecalcModeForced()
155 { nMode
&= ~RECALCMODE_FORCED
; }
156 inline void SetRecalcModeOnRefMove()
157 { nMode
|= RECALCMODE_ONREFMOVE
; }
158 inline void ClearRecalcModeOnRefMove()
159 { nMode
&= ~RECALCMODE_ONREFMOVE
; }
160 inline bool IsRecalcModeNormal() const
161 { return (nMode
& RECALCMODE_NORMAL
) != 0; }
162 inline bool IsRecalcModeAlways() const
163 { return (nMode
& RECALCMODE_ALWAYS
) != 0; }
164 inline bool IsRecalcModeOnLoad() const
165 { return (nMode
& RECALCMODE_ONLOAD
) != 0; }
166 inline bool IsRecalcModeOnLoadOnce() const
167 { return (nMode
& RECALCMODE_ONLOAD_ONCE
) != 0; }
168 inline bool IsRecalcModeForced() const
169 { return (nMode
& RECALCMODE_FORCED
) != 0; }
170 inline bool IsRecalcModeOnRefMove() const
171 { return (nMode
& RECALCMODE_ONREFMOVE
) != 0; }
173 /** Get OpCode of the most outer function */
174 inline OpCode
GetOuterFuncOpCode();
176 /** Operators +,-,*,/,^,&,=,<>,<,>,<=,>=
177 with DoubleRef in Formula? */
178 bool HasMatrixDoubleRefOps();
180 virtual FormulaToken
* AddOpCode(OpCode e
);
182 /** Adds the single token to array.
183 Derived classes must overload it when they want to support derived classes from FormulaToken.
184 @return true when an error occurs
186 virtual bool AddFormulaToken(const com::sun::star::sheet::FormulaToken
& _aToken
, ExternalReferenceHelper
* _pRef
= NULL
);
188 /** fill the array with the tokens from the sequence.
189 It calls AddFormulaToken for each token in the list.
190 @param _aSequence the token to add
191 @return true when an error occurs
193 bool Fill(const com::sun::star::uno::Sequence
< com::sun::star::sheet::FormulaToken
>& _aSequence
, ExternalReferenceHelper
* _pRef
= NULL
);
196 * Do some checking based on the individual tokens. For now, we use this
197 * only to check whether we can vectorize the token array.
199 virtual void CheckToken( const FormulaToken
& t
);
201 FormulaToken
* AddToken( const FormulaToken
& );
202 FormulaToken
* AddString( const sal_Unicode
* pStr
);
203 FormulaToken
* AddString( const String
& rStr
);
204 FormulaToken
* AddDouble( double fVal
);
205 FormulaToken
* AddExternal( const sal_Unicode
* pStr
);
206 /** Xcl import may play dirty tricks with OpCode!=ocExternal.
208 FormulaToken
* AddExternal( const String
& rStr
, OpCode eOp
= ocExternal
);
209 FormulaToken
* AddBad( const String
& rStr
); /// ocBad with String
210 FormulaToken
* AddStringXML( const String
& rStr
); /// ocStringXML with String, temporary during import
212 virtual FormulaToken
* MergeArray( );
214 /// Assignment with references to FormulaToken entries (not copied!)
215 FormulaTokenArray
& operator=( const FormulaTokenArray
& );
217 /** Determines if this formula needs any changes to convert it to something
218 previous versions of OOo could consume (Plain Old Formula). */
219 bool NeedsPofRewrite(const MissingConvention
& rConv
);
221 /** Rewrites to Plain Old Formula, substituting missing parameters. The
222 FormulaTokenArray* returned is new'ed. */
223 FormulaTokenArray
* RewriteMissingToPof(const MissingConvention
& rConv
);
225 /** Determines if this formula may be followed by a reference. */
226 bool MayReferenceFollow();
229 inline OpCode
FormulaTokenArray::GetOuterFuncOpCode()
232 return pRPN
[nRPN
-1]->GetOpCode();
236 struct ImpTokenIterator
238 ImpTokenIterator
* pNext
;
239 const FormulaTokenArray
* pArr
;
243 DECL_FIXEDMEMPOOL_NEWDEL( ImpTokenIterator
);
246 class FORMULA_DLLPUBLIC FormulaTokenIterator
248 ImpTokenIterator
* pCur
;
251 FormulaTokenIterator( const FormulaTokenArray
& );
252 ~FormulaTokenIterator();
254 const FormulaToken
* Next();
255 const FormulaToken
* PeekNextOperator();
256 bool IsEndOfPath() const; /// if a jump or subroutine path is done
257 bool HasStacked() const { return pCur
->pNext
!= 0; }
258 short GetPC() const { return pCur
->nPC
; }
260 /** Jump or subroutine call.
261 Program counter values will be incremented before code is executed =>
262 positions are to be passed with -1 offset.
264 Start on code at position nStart+1 (yes, pass with offset -1)
266 After subroutine continue with instruction at position nNext+1
268 Stop before reaching code at position nStop. If not specified the
269 default is to either run the entire code, or to stop if an ocSep or
270 ocClose is encountered, which are only present in ocIf or ocChose
273 void Jump( short nStart
, short nNext
, short nStop
= SHRT_MAX
);
274 void Push( const FormulaTokenArray
* );
278 const FormulaToken
* GetNonEndOfPathToken( short nIdx
) const;
280 // =============================================================================
282 // =============================================================================
285 #endif // FORMULA_TOKENARRAY_HXX
287 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */