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