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_TOKEN_HXX
21 : : #define FORMULA_TOKEN_HXX
22 : :
23 : : #include <memory>
24 : : #include <string.h>
25 : : #include <vector>
26 : : #include "formula/opcode.hxx"
27 : : #include <tools/mempool.hxx>
28 : : #include "formula/IFunctionDescription.hxx"
29 : : #include "formula/formuladllapi.h"
30 : :
31 : : #include <boost/intrusive_ptr.hpp>
32 : :
33 : : namespace formula
34 : : {
35 : :
36 : : enum StackVarEnum
37 : : {
38 : : svByte,
39 : : svDouble,
40 : : svString,
41 : : svSingleRef,
42 : : svDoubleRef,
43 : : svMatrix,
44 : : svIndex,
45 : : svJump,
46 : : svExternal, // Byte + String
47 : : svFAP, // FormulaAutoPilot only, ever exported
48 : : svJumpMatrix, // 2003-07-02
49 : : svRefList, // ocUnion result
50 : : svEmptyCell, // Result is an empty cell, e.g. in LOOKUP()
51 : :
52 : : svMatrixCell, // Result is a matrix with bells and
53 : : // whistles as needed for _the_ matrix
54 : : // formula result.
55 : :
56 : : svHybridCell, // A temporary condition of a formula
57 : : // cell during import, having a double
58 : : // and/or string result and a formula
59 : : // string to be compiled.
60 : :
61 : : svExternalSingleRef,
62 : : svExternalDoubleRef,
63 : : svExternalName,
64 : : svSubroutine, // A token with a subroutine token array.
65 : : svError, // error token
66 : : svMissing = 0x70, // 0 or ""
67 : : svSep, // separator, ocSep, ocOpen, ocClose
68 : : svUnknown // unknown StackType
69 : : };
70 : :
71 : : #ifndef DBG_UTIL
72 : : // save memory since compilers tend to int an enum
73 : : typedef sal_uInt8 StackVar;
74 : : #else
75 : : // have enum names in debugger
76 : : typedef StackVarEnum StackVar;
77 : : #endif
78 : :
79 : :
80 : : class FormulaToken;
81 : : typedef ::boost::intrusive_ptr<FormulaToken> FormulaTokenRef;
82 : : typedef ::boost::intrusive_ptr<const FormulaToken> FormulaConstTokenRef;
83 : :
84 : : class FormulaTokenArray;
85 : :
86 : : class FORMULA_DLLPUBLIC FormulaToken : public IFormulaToken
87 : : {
88 : : OpCode eOp;
89 : : // not implemented, prevent usage
90 : : FormulaToken();
91 : : FormulaToken& operator=( const FormulaToken& );
92 : : protected:
93 : :
94 : : const StackVar eType; // type of data
95 : : mutable sal_uInt16 nRefCnt; // reference count
96 : :
97 : : public:
98 : 98408 : FormulaToken( StackVar eTypeP,OpCode e = ocPush ) :
99 : 98408 : eOp(e), eType( eTypeP ), nRefCnt(0) {}
100 : 14805 : FormulaToken( const FormulaToken& r ) : IFormulaToken(),
101 : 14805 : eOp(r.eOp), eType( r.eType ), nRefCnt(0) {}
102 : :
103 : : virtual ~FormulaToken();
104 : :
105 [ + - ]: 98053 : inline void Delete() { delete this; }
106 : 395501 : inline StackVar GetType() const { return eType; }
107 : : bool IsFunction() const; // pure functions, no operators
108 : : bool IsExternalRef() const;
109 : : sal_uInt8 GetParamCount() const;
110 : 352341 : inline void IncRef() const { nRefCnt++; }
111 : 350482 : inline void DecRef() const
112 : : {
113 [ + + ]: 350482 : if (!--nRefCnt)
114 : 98053 : const_cast<FormulaToken*>(this)->Delete();
115 : 350482 : }
116 : 4092 : inline sal_uInt16 GetRef() const { return nRefCnt; }
117 : 1269921 : inline OpCode GetOpCode() const { return eOp; }
118 : :
119 : : /**
120 : : Dummy methods to avoid switches and casts where possible,
121 : : the real token classes have to overload the appropriate method[s].
122 : : The only methods valid anytime if not overloaded are:
123 : :
124 : : - GetByte() since this represents the count of parameters to a function
125 : : which of course is 0 on non-functions. FormulaByteToken and ScExternal do
126 : : overload it.
127 : :
128 : : - HasForceArray() since also this is only used for operators and
129 : : functions and is 0 for other tokens.
130 : :
131 : : Any other non-overloaded method pops up an assertion.
132 : : */
133 : :
134 : : virtual sal_uInt8 GetByte() const;
135 : : virtual void SetByte( sal_uInt8 n );
136 : : virtual bool HasForceArray() const;
137 : : virtual void SetForceArray( bool b );
138 : : virtual double GetDouble() const;
139 : : virtual double& GetDoubleAsReference();
140 : : virtual const String& GetString() const;
141 : : virtual sal_uInt16 GetIndex() const;
142 : : virtual void SetIndex( sal_uInt16 n );
143 : : virtual bool IsGlobal() const;
144 : : virtual void SetGlobal( bool b );
145 : : virtual short* GetJump() const;
146 : : virtual const String& GetExternal() const;
147 : : virtual FormulaToken* GetFAPOrigToken() const;
148 : : virtual sal_uInt16 GetError() const;
149 : : virtual void SetError( sal_uInt16 );
150 : :
151 : 638 : virtual FormulaToken* Clone() const { return new FormulaToken(*this); }
152 : :
153 : : virtual bool Is3DRef() const; // reference with 3D flag set
154 : : virtual bool TextEqual( const formula::FormulaToken& rToken ) const;
155 : : virtual bool operator==( const FormulaToken& rToken ) const;
156 : :
157 : 0 : virtual bool isFunction() const
158 : : {
159 : 0 : return IsFunction();
160 : : }
161 : :
162 : 0 : virtual sal_uInt32 getArgumentCount() const
163 : : {
164 : 0 : return GetParamCount();
165 : : }
166 : :
167 : : /** This is dirty and only the compiler should use it! */
168 : 0 : struct PrivateAccess { friend class FormulaCompiler; private: PrivateAccess() { } };
169 : 0 : inline void NewOpCode( OpCode e, const PrivateAccess& ) { eOp = e; }
170 : :
171 : : static size_t GetStrLenBytes( xub_StrLen nLen )
172 : : { return nLen * sizeof(sal_Unicode); }
173 : : static size_t GetStrLenBytes( const String& rStr )
174 : : { return GetStrLenBytes( rStr.Len() ); }
175 : : };
176 : :
177 : 133627 : inline void intrusive_ptr_add_ref(const FormulaToken* p)
178 : : {
179 : 133627 : p->IncRef();
180 : 133627 : }
181 : :
182 : 133564 : inline void intrusive_ptr_release(const FormulaToken* p)
183 : : {
184 : 133564 : p->DecRef();
185 : 133564 : }
186 : :
187 [ - + ]: 47241 : class FORMULA_DLLPUBLIC FormulaByteToken : public FormulaToken
188 : : {
189 : : private:
190 : : sal_uInt8 nByte;
191 : : bool bHasForceArray;
192 : : protected:
193 : 1262 : FormulaByteToken( OpCode e, sal_uInt8 n, StackVar v, bool b ) :
194 : : FormulaToken( v,e ), nByte( n ),
195 : 1262 : bHasForceArray( b ) {}
196 : : public:
197 : 16903 : FormulaByteToken( OpCode e, sal_uInt8 n, bool b ) :
198 : : FormulaToken( svByte,e ), nByte( n ),
199 : 16903 : bHasForceArray( b ) {}
200 : 6 : FormulaByteToken( OpCode e, sal_uInt8 n ) :
201 : : FormulaToken( svByte,e ), nByte( n ),
202 : 6 : bHasForceArray( false ) {}
203 : 8045 : FormulaByteToken( OpCode e ) :
204 : : FormulaToken( svByte,e ), nByte( 0 ),
205 : 8045 : bHasForceArray( false ) {}
206 : 343 : FormulaByteToken( const FormulaByteToken& r ) :
207 : : FormulaToken( r ), nByte( r.nByte ),
208 : 343 : bHasForceArray( r.bHasForceArray ) {}
209 : :
210 [ + - ]: 331 : virtual FormulaToken* Clone() const { return new FormulaByteToken(*this); }
211 : : virtual sal_uInt8 GetByte() const;
212 : : virtual void SetByte( sal_uInt8 n );
213 : : virtual bool HasForceArray() const;
214 : : virtual void SetForceArray( bool b );
215 : : virtual bool operator==( const FormulaToken& rToken ) const;
216 : :
217 : : DECL_FIXEDMEMPOOL_NEWDEL_DLL( FormulaByteToken )
218 : : };
219 : :
220 : :
221 : : // A special token for the FormulaAutoPilot only. Keeps a reference pointer of
222 : : // the token of which it was created for comparison.
223 [ # # ][ # # ]: 0 : class FORMULA_DLLPUBLIC FormulaFAPToken : public FormulaByteToken
224 : : {
225 : : private:
226 : : FormulaTokenRef pOrigToken;
227 : : public:
228 : 0 : FormulaFAPToken( OpCode e, sal_uInt8 n, FormulaToken* p ) :
229 : : FormulaByteToken( e, n, svFAP, false ),
230 : 0 : pOrigToken( p ) {}
231 : 0 : FormulaFAPToken( const FormulaFAPToken& r ) :
232 : 0 : FormulaByteToken( r ), pOrigToken( r.pOrigToken ) {}
233 : :
234 [ # # ]: 0 : virtual FormulaToken* Clone() const { return new FormulaFAPToken(*this); }
235 : : virtual FormulaToken* GetFAPOrigToken() const;
236 : : virtual bool operator==( const FormulaToken& rToken ) const;
237 : : };
238 : :
239 [ - + ]: 7928 : class FORMULA_DLLPUBLIC FormulaDoubleToken : public FormulaToken
240 : : {
241 : : private:
242 : : double fDouble;
243 : : public:
244 : 3938 : FormulaDoubleToken( double f ) :
245 : 3938 : FormulaToken( svDouble ), fDouble( f ) {}
246 : 74 : FormulaDoubleToken( const FormulaDoubleToken& r ) :
247 : 74 : FormulaToken( r ), fDouble( r.fDouble ) {}
248 : :
249 [ + - ]: 74 : virtual FormulaToken* Clone() const { return new FormulaDoubleToken(*this); }
250 : : virtual double GetDouble() const;
251 : : virtual double& GetDoubleAsReference();
252 : : virtual bool operator==( const FormulaToken& rToken ) const;
253 : :
254 : : DECL_FIXEDMEMPOOL_NEWDEL_DLL( FormulaDoubleToken )
255 : : };
256 : :
257 : :
258 [ + - ][ - + ]: 16998 : class FORMULA_DLLPUBLIC FormulaStringToken : public FormulaToken
259 : : {
260 : : private:
261 : : String aString;
262 : : public:
263 : 8553 : FormulaStringToken( const String& r ) :
264 [ + - ]: 8553 : FormulaToken( svString ), aString( r ) {}
265 : 57 : FormulaStringToken( const FormulaStringToken& r ) :
266 [ + - ]: 57 : FormulaToken( r ), aString( r.aString ) {}
267 : :
268 [ + - ]: 57 : virtual FormulaToken* Clone() const { return new FormulaStringToken(*this); }
269 : : virtual const String& GetString() const;
270 : : virtual bool operator==( const FormulaToken& rToken ) const;
271 : :
272 : : DECL_FIXEDMEMPOOL_NEWDEL_DLL( FormulaStringToken )
273 : : };
274 : :
275 : :
276 : : /** Identical to FormulaStringToken, but with explicit OpCode instead of implicit
277 : : ocPush, and an optional sal_uInt8 for ocBad tokens. */
278 [ + - ][ - + ]: 2362 : class FORMULA_DLLPUBLIC FormulaStringOpToken : public FormulaByteToken
279 : : {
280 : : private:
281 : : String aString;
282 : : public:
283 : 1262 : FormulaStringOpToken( OpCode e, const String& r ) :
284 [ + - ]: 1262 : FormulaByteToken( e, 0, svString, false ), aString( r ) {}
285 : 12 : FormulaStringOpToken( const FormulaStringOpToken& r ) :
286 [ + - ]: 12 : FormulaByteToken( r ), aString( r.aString ) {}
287 : :
288 [ + - ]: 12 : virtual FormulaToken* Clone() const { return new FormulaStringOpToken(*this); }
289 : : virtual const String& GetString() const;
290 : : virtual bool operator==( const FormulaToken& rToken ) const;
291 : : };
292 : :
293 [ - + ]: 482 : class FORMULA_DLLPUBLIC FormulaIndexToken : public FormulaToken
294 : : {
295 : : private:
296 : : sal_uInt16 nIndex;
297 : : bool mbGlobal;
298 : : public:
299 : 212 : FormulaIndexToken( OpCode e, sal_uInt16 n, bool bGlobal = true ) :
300 : 212 : FormulaToken( svIndex, e ), nIndex( n ), mbGlobal( bGlobal ) {}
301 : 52 : FormulaIndexToken( const FormulaIndexToken& r ) :
302 : 52 : FormulaToken( r ), nIndex( r.nIndex ), mbGlobal( r.mbGlobal ) {}
303 : :
304 [ + - ]: 52 : virtual FormulaToken* Clone() const { return new FormulaIndexToken(*this); }
305 : : virtual sal_uInt16 GetIndex() const;
306 : : virtual void SetIndex( sal_uInt16 n );
307 : : virtual bool IsGlobal() const;
308 : : virtual void SetGlobal( bool b );
309 : : virtual bool operator==( const FormulaToken& rToken ) const;
310 : : };
311 : :
312 : :
313 [ + - ][ - + ]: 6 : class FORMULA_DLLPUBLIC FormulaExternalToken : public FormulaToken
314 : : {
315 : : private:
316 : : String aExternal;
317 : : sal_uInt8 nByte;
318 : : public:
319 : 0 : FormulaExternalToken( OpCode e, sal_uInt8 n, const String& r ) :
320 : : FormulaToken( svExternal, e ), aExternal( r ),
321 [ # # ]: 0 : nByte( n ) {}
322 : 3 : FormulaExternalToken( OpCode e, const String& r ) :
323 : : FormulaToken(svExternal, e ), aExternal( r ),
324 [ + - ]: 3 : nByte( 0 ) {}
325 : 0 : FormulaExternalToken( const FormulaExternalToken& r ) :
326 : : FormulaToken( r ), aExternal( r.aExternal ),
327 [ # # ]: 0 : nByte( r.nByte ) {}
328 : :
329 [ # # ]: 0 : virtual FormulaToken* Clone() const { return new FormulaExternalToken(*this); }
330 : : virtual const String& GetExternal() const;
331 : : virtual sal_uInt8 GetByte() const;
332 : : virtual void SetByte( sal_uInt8 n );
333 : : virtual bool operator==( const FormulaToken& rToken ) const;
334 : : };
335 : :
336 : :
337 [ - + ]: 72 : class FORMULA_DLLPUBLIC FormulaMissingToken : public FormulaToken
338 : : {
339 : : public:
340 : 36 : FormulaMissingToken() :
341 : 36 : FormulaToken( svMissing,ocMissing ) {}
342 : 0 : FormulaMissingToken( const FormulaMissingToken& r ) :
343 : 0 : FormulaToken( r ) {}
344 : :
345 [ # # ]: 0 : virtual FormulaToken* Clone() const { return new FormulaMissingToken(*this); }
346 : : virtual double GetDouble() const;
347 : : virtual const String& GetString() const;
348 : : virtual bool operator==( const FormulaToken& rToken ) const;
349 : : };
350 : :
351 : : class FORMULA_DLLPUBLIC FormulaJumpToken : public FormulaToken
352 : : {
353 : : private:
354 : : short* pJump;
355 : : public:
356 : 42 : FormulaJumpToken( OpCode e, short* p ) :
357 : 42 : FormulaToken( formula::svJump , e)
358 : : {
359 [ + - ]: 42 : pJump = new short[ p[0] + 1 ];
360 : 42 : memcpy( pJump, p, (p[0] + 1) * sizeof(short) );
361 : 42 : }
362 : 0 : FormulaJumpToken( const FormulaJumpToken& r ) :
363 : 0 : FormulaToken( r )
364 : : {
365 [ # # ]: 0 : pJump = new short[ r.pJump[0] + 1 ];
366 : 0 : memcpy( pJump, r.pJump, (r.pJump[0] + 1) * sizeof(short) );
367 : 0 : }
368 : : virtual ~FormulaJumpToken();
369 : : virtual short* GetJump() const;
370 : : virtual bool operator==( const formula::FormulaToken& rToken ) const;
371 [ # # ]: 0 : virtual FormulaToken* Clone() const { return new FormulaJumpToken(*this); }
372 : : };
373 : :
374 : :
375 : : class FORMULA_DLLPUBLIC FormulaSubroutineToken : public FormulaToken
376 : : {
377 : : public:
378 : : /** Takes ownership of pArray and deletes it upon destruction! */
379 : : FormulaSubroutineToken( const FormulaTokenArray* pArray ) :
380 : : FormulaToken( svSubroutine, ocCall ), mpArray( pArray) {}
381 : : FormulaSubroutineToken( const FormulaSubroutineToken& r );
382 : : virtual ~FormulaSubroutineToken();
383 [ # # ]: 0 : virtual FormulaToken* Clone() const { return new FormulaSubroutineToken(*this); }
384 : : virtual bool operator==( const FormulaToken& rToken ) const;
385 : :
386 : : private:
387 : : const FormulaTokenArray* mpArray;
388 : : };
389 : :
390 : :
391 [ # # ]: 0 : class FORMULA_DLLPUBLIC FormulaUnknownToken : public FormulaToken
392 : : {
393 : : public:
394 : 0 : FormulaUnknownToken( OpCode e ) :
395 : 0 : FormulaToken( svUnknown, e ) {}
396 : 0 : FormulaUnknownToken( const FormulaUnknownToken& r ) :
397 : 0 : FormulaToken( r ) {}
398 : :
399 [ # # ]: 0 : virtual FormulaToken* Clone() const { return new FormulaUnknownToken(*this); }
400 : : virtual bool operator==( const FormulaToken& rToken ) const;
401 : : };
402 : :
403 : :
404 [ - + ]: 682 : class FORMULA_DLLPUBLIC FormulaErrorToken : public FormulaToken
405 : : {
406 : : sal_uInt16 nError;
407 : : public:
408 : 340 : FormulaErrorToken( sal_uInt16 nErr ) :
409 : 340 : FormulaToken( svError ), nError( nErr) {}
410 : 1 : FormulaErrorToken( const FormulaErrorToken& r ) :
411 : 1 : FormulaToken( r ), nError( r.nError) {}
412 : :
413 [ + - ]: 1 : virtual FormulaToken* Clone() const { return new FormulaErrorToken(*this); }
414 : : virtual sal_uInt16 GetError() const;
415 : : virtual void SetError( sal_uInt16 nErr );
416 : : virtual bool operator==( const FormulaToken& rToken ) const;
417 : : };
418 : :
419 : : // =============================================================================
420 : : } // formula
421 : : // =============================================================================
422 : :
423 : : #endif
424 : :
425 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|