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 INCLUDED_FORMULA_TOKEN_HXX
21 #define INCLUDED_FORMULA_TOKEN_HXX
23 #include <sal/config.h>
30 #include <formula/formuladllapi.h>
31 #include <formula/opcode.hxx>
32 #include <formula/types.hxx>
33 #include <formula/paramclass.hxx>
34 #include <osl/interlck.h>
35 #include <rtl/ustring.hxx>
36 #include <sal/types.h>
37 #include <svl/sharedstring.hxx>
41 struct ScComplexRefData
;
42 struct ScSingleRefData
;
43 enum class FormulaError
: sal_uInt16
;
48 enum StackVar
: sal_uInt8
58 svExternal
, // Byte + String
59 svFAP
, // FormulaAutoPilot only, ever exported
61 svRefList
, // ocUnion result
62 svEmptyCell
, // Result is an empty cell, e.g. in LOOKUP()
64 svMatrixCell
, // Result is a matrix with bells and
65 // whistles as needed for _the_ matrix
68 svHybridCell
, // A temporary condition of a formula
69 // cell during import, having a double
70 // and/or string result and a formula
71 // string to be compiled.
78 svError
, // error token
80 svSep
, // separator, ocSep, ocOpen, ocClose
81 svUnknown
// unknown StackType
84 // Only to be used for debugging output. No guarantee of stability of the
87 // Turn this into an operator<< when StackVar becomes a scoped enum
89 inline std::string
StackVarEnumToString(StackVar
const e
)
93 case svByte
: return "Byte";
94 case svDouble
: return "Double";
95 case svString
: return "String";
96 case svSingleRef
: return "SingleRef";
97 case svDoubleRef
: return "DoubleRef";
98 case svMatrix
: return "Matrix";
99 case svIndex
: return "Index";
100 case svJump
: return "Jump";
101 case svExternal
: return "External";
102 case svFAP
: return "FAP";
103 case svJumpMatrix
: return "JumpMatrix";
104 case svRefList
: return "RefList";
105 case svEmptyCell
: return "EmptyCell";
106 case svMatrixCell
: return "MatrixCell";
107 case svHybridCell
: return "HybridCell";
108 case svExternalSingleRef
: return "ExternalSingleRef";
109 case svExternalDoubleRef
: return "ExternalDoubleRef";
110 case svExternalName
: return "ExternalName";
111 case svSingleVectorRef
: return "SingleVectorRef";
112 case svDoubleVectorRef
: return "DoubleVectorRef";
113 case svError
: return "Error";
114 case svMissing
: return "Missing";
115 case svSep
: return "Sep";
116 case svUnknown
: return "Unknown";
118 std::ostringstream os
;
119 os
<< static_cast<int>(e
);
123 enum class RefCntPolicy
: sal_uInt8
125 ThreadSafe
, // refcounting via thread-safe oslInterlockedCount
126 UnsafeRef
, // refcounting done with no locking/guarding against concurrent access
127 None
// no ref counting done
130 class FORMULA_DLLPUBLIC FormulaToken
133 const StackVar eType
; // type of data
134 RefCntPolicy eRefCntPolicy
; // style of reference counting
135 mutable oslInterlockedCount mnRefCnt
; // reference count
137 FormulaToken
& operator=( const FormulaToken
& ) = delete;
139 FormulaToken( StackVar eTypeP
,OpCode e
= ocPush
);
140 FormulaToken( const FormulaToken
& r
);
142 virtual ~FormulaToken();
144 void Delete() { delete this; }
145 void DeleteIfZeroRef() { if (mnRefCnt
== 0) delete this; }
146 StackVar
GetType() const { return eType
; }
147 bool IsFunction() const; // pure functions, no operators
149 bool IsExternalRef() const;
152 sal_uInt8
GetParamCount() const;
156 switch (eRefCntPolicy
)
158 case RefCntPolicy::ThreadSafe
:
160 osl_atomic_increment(&mnRefCnt
);
162 case RefCntPolicy::UnsafeRef
:
165 case RefCntPolicy::None
:
172 switch (eRefCntPolicy
)
174 case RefCntPolicy::ThreadSafe
:
176 if (!osl_atomic_decrement(&mnRefCnt
))
177 const_cast<FormulaToken
*>(this)->Delete();
179 case RefCntPolicy::UnsafeRef
:
181 const_cast<FormulaToken
*>(this)->Delete();
183 case RefCntPolicy::None
:
188 void SetRefCntPolicy(RefCntPolicy ePolicy
) { eRefCntPolicy
= ePolicy
; }
189 RefCntPolicy
GetRefCntPolicy() const { return eRefCntPolicy
; }
191 oslInterlockedCount
GetRef() const { return mnRefCnt
; }
192 OpCode
GetOpCode() const { return eOp
; }
194 bool IsInForceArray() const;
197 Dummy methods to avoid switches and casts where possible,
198 the real token classes have to override the appropriate method[s].
199 The only methods valid anytime if not overridden are:
201 - GetByte() since this represents the count of parameters to a function
202 which of course is 0 on non-functions. FormulaByteToken and ScExternal do
205 - GetInForceArray() since also this is only used for operators and
206 functions and is ParamClass::Unknown for other tokens.
208 Any other non-overridden method pops up an assertion.
211 virtual sal_uInt8
GetByte() const;
212 virtual void SetByte( sal_uInt8 n
);
213 virtual ParamClass
GetInForceArray() const;
214 virtual void SetInForceArray( ParamClass c
);
215 virtual double GetDouble() const;
216 virtual void SetDouble(double fValue
);
217 virtual sal_Int16
GetDoubleType() const;
218 virtual void SetDoubleType( sal_Int16 nType
);
219 virtual const svl::SharedString
& GetString() const;
220 virtual void SetString( const svl::SharedString
& rStr
);
221 virtual sal_uInt16
GetIndex() const;
222 virtual void SetIndex( sal_uInt16 n
);
223 virtual sal_Int16
GetSheet() const;
224 virtual void SetSheet( sal_Int16 n
);
225 virtual sal_Unicode
GetChar() const;
226 virtual short* GetJump() const;
227 virtual const OUString
& GetExternal() const;
228 virtual FormulaToken
* GetFAPOrigToken() const;
229 virtual FormulaError
GetError() const;
230 virtual void SetError( FormulaError
);
232 virtual const ScSingleRefData
* GetSingleRef() const;
233 virtual ScSingleRefData
* GetSingleRef();
234 virtual const ScComplexRefData
* GetDoubleRef() const;
235 virtual ScComplexRefData
* GetDoubleRef();
236 virtual const ScSingleRefData
* GetSingleRef2() const;
237 virtual ScSingleRefData
* GetSingleRef2();
238 virtual const ScMatrix
* GetMatrix() const;
239 virtual ScMatrix
* GetMatrix();
240 virtual ScJumpMatrix
* GetJumpMatrix() const;
241 virtual const std::vector
<ScComplexRefData
>* GetRefList() const;
242 virtual std::vector
<ScComplexRefData
>* GetRefList();
244 virtual FormulaToken
* Clone() const { return new FormulaToken(*this); }
246 virtual bool TextEqual( const formula::FormulaToken
& rToken
) const;
247 virtual bool operator==( const FormulaToken
& rToken
) const;
249 /** This is dirty and only the compiler should use it! */
250 struct PrivateAccess
{ friend class FormulaCompiler
; private: PrivateAccess() { } };
251 void NewOpCode( OpCode e
, const PrivateAccess
& ) { eOp
= e
; }
254 inline void intrusive_ptr_add_ref(const FormulaToken
* p
)
259 inline void intrusive_ptr_release(const FormulaToken
* p
)
264 class FORMULA_DLLPUBLIC FormulaSpaceToken final
: public FormulaToken
270 FormulaSpaceToken( sal_uInt8 n
, sal_Unicode c
) :
271 FormulaToken( svByte
, ocWhitespace
),
272 nByte( n
), cChar( c
) {}
273 FormulaSpaceToken( const FormulaSpaceToken
& r
) :
275 nByte( r
.nByte
), cChar( r
.cChar
) {}
277 virtual FormulaToken
* Clone() const override
{ return new FormulaSpaceToken(*this); }
278 virtual sal_uInt8
GetByte() const override
;
279 virtual sal_Unicode
GetChar() const override
;
280 virtual bool operator==( const FormulaToken
& rToken
) const override
;
283 class FORMULA_DLLPUBLIC FormulaByteToken
: public FormulaToken
287 ParamClass eInForceArray
;
289 FormulaByteToken( OpCode e
, sal_uInt8 n
, StackVar v
, ParamClass c
) :
290 FormulaToken( v
,e
), nByte( n
),
291 eInForceArray( c
) {}
293 FormulaByteToken( OpCode e
, sal_uInt8 n
, ParamClass c
) :
294 FormulaToken( svByte
,e
), nByte( n
),
295 eInForceArray( c
) {}
296 FormulaByteToken( OpCode e
, sal_uInt8 n
) :
297 FormulaToken( svByte
,e
), nByte( n
),
298 eInForceArray( ParamClass::Unknown
) {}
299 FormulaByteToken( OpCode e
) :
300 FormulaToken( svByte
,e
), nByte( 0 ),
301 eInForceArray( ParamClass::Unknown
) {}
302 FormulaByteToken( const FormulaByteToken
& r
) :
303 FormulaToken( r
), nByte( r
.nByte
),
304 eInForceArray( r
.eInForceArray
) {}
306 virtual FormulaToken
* Clone() const override
{ return new FormulaByteToken(*this); }
307 virtual sal_uInt8
GetByte() const override final
;
308 virtual void SetByte( sal_uInt8 n
) override final
;
309 virtual ParamClass
GetInForceArray() const override final
;
310 virtual void SetInForceArray( ParamClass c
) override final
;
311 virtual bool operator==( const FormulaToken
& rToken
) const override
;
315 // A special token for the FormulaAutoPilot only. Keeps a reference pointer of
316 // the token of which it was created for comparison.
317 class FORMULA_DLLPUBLIC FormulaFAPToken final
: public FormulaByteToken
320 FormulaTokenRef pOrigToken
;
322 FormulaFAPToken( OpCode e
, sal_uInt8 n
, FormulaToken
* p
) :
323 FormulaByteToken( e
, n
, svFAP
, ParamClass::Unknown
),
325 FormulaFAPToken( const FormulaFAPToken
& r
) :
326 FormulaByteToken( r
), pOrigToken( r
.pOrigToken
) {}
328 virtual FormulaToken
* Clone() const override
{ return new FormulaFAPToken(*this); }
329 virtual FormulaToken
* GetFAPOrigToken() const override
;
330 virtual bool operator==( const FormulaToken
& rToken
) const override
;
333 class FORMULA_DLLPUBLIC FormulaDoubleToken
: public FormulaToken
338 FormulaDoubleToken( double f
) :
339 FormulaToken( svDouble
), fDouble( f
) {}
340 FormulaDoubleToken( const FormulaDoubleToken
& r
) :
341 FormulaToken( r
), fDouble( r
.fDouble
) {}
343 virtual FormulaToken
* Clone() const override
{ return new FormulaDoubleToken(*this); }
344 virtual double GetDouble() const override final
{ return fDouble
; }
345 virtual void SetDouble(double fValue
) override final
{ fDouble
= fValue
; }
346 virtual sal_Int16
GetDoubleType() const override
; ///< always returns 0 for "not typed"
347 virtual bool operator==( const FormulaToken
& rToken
) const override
;
350 class FORMULA_DLLPUBLIC FormulaTypedDoubleToken final
: public FormulaDoubleToken
353 sal_Int16 mnType
; /**< Can hold, for example, a value
354 of SvNumFormatType, or by
358 FormulaTypedDoubleToken( double f
, sal_Int16 nType
) :
359 FormulaDoubleToken( f
), mnType( nType
) {}
360 FormulaTypedDoubleToken( const FormulaTypedDoubleToken
& r
) :
361 FormulaDoubleToken( r
), mnType( r
.mnType
) {}
363 virtual FormulaToken
* Clone() const override
{ return new FormulaTypedDoubleToken(*this); }
364 virtual sal_Int16
GetDoubleType() const override
;
365 virtual void SetDoubleType( sal_Int16 nType
) override
;
366 virtual bool operator==( const FormulaToken
& rToken
) const override
;
370 class FORMULA_DLLPUBLIC FormulaStringToken final
: public FormulaToken
372 svl::SharedString maString
;
374 FormulaStringToken( svl::SharedString r
);
375 FormulaStringToken( const FormulaStringToken
& r
);
377 virtual FormulaToken
* Clone() const override
;
378 virtual const svl::SharedString
& GetString() const override
;
379 virtual void SetString( const svl::SharedString
& rStr
) override
;
380 virtual bool operator==( const FormulaToken
& rToken
) const override
;
384 /** Identical to FormulaStringToken, but with explicit OpCode instead of implicit
385 ocPush, and an optional sal_uInt8 for ocBad tokens. */
386 class FORMULA_DLLPUBLIC FormulaStringOpToken final
: public FormulaByteToken
388 svl::SharedString maString
;
390 FormulaStringOpToken( OpCode e
, svl::SharedString r
);
391 FormulaStringOpToken( const FormulaStringOpToken
& r
);
393 virtual FormulaToken
* Clone() const override
;
394 virtual const svl::SharedString
& GetString() const override
;
395 virtual void SetString( const svl::SharedString
& rStr
) override
;
396 virtual bool operator==( const FormulaToken
& rToken
) const override
;
399 class FORMULA_DLLPUBLIC FormulaIndexToken final
: public FormulaToken
405 FormulaIndexToken( OpCode e
, sal_uInt16 n
, sal_Int16 nSheet
= -1 ) :
406 FormulaToken( svIndex
, e
), nIndex( n
), mnSheet( nSheet
) {}
407 FormulaIndexToken( const FormulaIndexToken
& r
) :
408 FormulaToken( r
), nIndex( r
.nIndex
), mnSheet( r
.mnSheet
) {}
410 virtual FormulaToken
* Clone() const override
{ return new FormulaIndexToken(*this); }
411 virtual sal_uInt16
GetIndex() const override
;
412 virtual void SetIndex( sal_uInt16 n
) override
;
413 virtual sal_Int16
GetSheet() const override
;
414 virtual void SetSheet( sal_Int16 n
) override
;
415 virtual bool operator==( const FormulaToken
& rToken
) const override
;
419 class FORMULA_DLLPUBLIC FormulaExternalToken final
: public FormulaByteToken
424 FormulaExternalToken( OpCode e
, sal_uInt8 n
, OUString r
) :
425 FormulaByteToken( e
, n
, svExternal
, ParamClass::Unknown
),
426 aExternal(std::move( r
)) {}
427 FormulaExternalToken( OpCode e
, OUString r
) :
428 FormulaByteToken( e
, 0, svExternal
, ParamClass::Unknown
),
429 aExternal(std::move( r
)) {}
430 FormulaExternalToken( const FormulaExternalToken
& r
) :
431 FormulaByteToken( r
), aExternal( r
.aExternal
) {}
433 virtual FormulaToken
* Clone() const override
{ return new FormulaExternalToken(*this); }
434 virtual const OUString
& GetExternal() const override
;
435 virtual bool operator==( const FormulaToken
& rToken
) const override
;
439 class FORMULA_DLLPUBLIC FormulaMissingToken final
: public FormulaToken
442 FormulaMissingToken() :
443 FormulaToken( svMissing
,ocMissing
) {}
444 FormulaMissingToken( const FormulaMissingToken
& r
) :
447 virtual FormulaToken
* Clone() const override
{ return new FormulaMissingToken(*this); }
448 virtual double GetDouble() const override
;
449 virtual const svl::SharedString
& GetString() const override
;
450 virtual bool operator==( const FormulaToken
& rToken
) const override
;
453 class FORMULA_DLLPUBLIC FormulaJumpToken final
: public FormulaToken
456 std::unique_ptr
<short[]>
458 ParamClass eInForceArray
;
460 FormulaJumpToken( OpCode e
, short const * p
) :
461 FormulaToken( formula::svJump
, e
),
462 eInForceArray( ParamClass::Unknown
)
464 pJump
.reset( new short[ p
[0] + 1 ] );
465 memcpy( pJump
.get(), p
, (p
[0] + 1) * sizeof(short) );
467 FormulaJumpToken( const FormulaJumpToken
& r
) :
469 eInForceArray( r
.eInForceArray
)
471 pJump
.reset( new short[ r
.pJump
[0] + 1 ] );
472 memcpy( pJump
.get(), r
.pJump
.get(), (r
.pJump
[0] + 1) * sizeof(short) );
474 virtual ~FormulaJumpToken() override
;
475 virtual short* GetJump() const override
;
476 virtual bool operator==( const formula::FormulaToken
& rToken
) const override
;
477 virtual FormulaToken
* Clone() const override
{ return new FormulaJumpToken(*this); }
478 virtual ParamClass
GetInForceArray() const override
;
479 virtual void SetInForceArray( ParamClass c
) override
;
483 class FORMULA_DLLPUBLIC FormulaUnknownToken final
: public FormulaToken
486 FormulaUnknownToken( OpCode e
) :
487 FormulaToken( svUnknown
, e
) {}
488 FormulaUnknownToken( const FormulaUnknownToken
& r
) :
491 virtual FormulaToken
* Clone() const override
{ return new FormulaUnknownToken(*this); }
492 virtual bool operator==( const FormulaToken
& rToken
) const override
;
496 class FORMULA_DLLPUBLIC FormulaErrorToken final
: public FormulaToken
500 FormulaErrorToken( FormulaError nErr
) :
501 FormulaToken( svError
), nError( nErr
) {}
502 FormulaErrorToken( const FormulaErrorToken
& r
) :
503 FormulaToken( r
), nError( r
.nError
) {}
505 virtual FormulaToken
* Clone() const override
{ return new FormulaErrorToken(*this); }
506 virtual FormulaError
GetError() const override
;
507 virtual void SetError( FormulaError nErr
) override
;
508 virtual bool operator==( const FormulaToken
& rToken
) const override
;
517 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */