cid#1608328 Overflowed constant
[LibreOffice.git] / include / formula / token.hxx
blob89043877a4fd9b121dc958e8fe2da6828ea811d9
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_TOKEN_HXX
21 #define INCLUDED_FORMULA_TOKEN_HXX
23 #include <sal/config.h>
25 #include <cstring>
26 #include <memory>
27 #include <utility>
28 #include <vector>
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>
39 class ScJumpMatrix;
40 class ScMatrix;
41 struct ScComplexRefData;
42 struct ScSingleRefData;
43 enum class FormulaError : sal_uInt16;
45 namespace formula
48 enum StackVar : sal_uInt8
50 svByte,
51 svDouble,
52 svString,
53 svSingleRef,
54 svDoubleRef,
55 svMatrix,
56 svIndex,
57 svJump,
58 svExternal, // Byte + String
59 svFAP, // FormulaAutoPilot only, ever exported
60 svJumpMatrix,
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
66 // formula result.
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.
73 svExternalSingleRef,
74 svExternalDoubleRef,
75 svExternalName,
76 svSingleVectorRef,
77 svDoubleVectorRef,
78 svError, // error token
79 svMissing, // 0 or ""
80 svSep, // separator, ocSep, ocOpen, ocClose
81 svUnknown // unknown StackType
84 // Only to be used for debugging output. No guarantee of stability of the
85 // return value.
87 // Turn this into an operator<< when StackVar becomes a scoped enum
89 inline std::string StackVarEnumToString(StackVar const e)
91 switch (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);
120 return os.str();
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
132 OpCode eOp;
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;
138 public:
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;
150 bool IsRef() const;
152 sal_uInt8 GetParamCount() const;
154 void IncRef() const
156 switch (eRefCntPolicy)
158 case RefCntPolicy::ThreadSafe:
159 default:
160 osl_atomic_increment(&mnRefCnt);
161 break;
162 case RefCntPolicy::UnsafeRef:
163 ++mnRefCnt;
164 break;
165 case RefCntPolicy::None:
166 break;
170 void DecRef() const
172 switch (eRefCntPolicy)
174 case RefCntPolicy::ThreadSafe:
175 default:
176 if (!osl_atomic_decrement(&mnRefCnt))
177 const_cast<FormulaToken*>(this)->Delete();
178 break;
179 case RefCntPolicy::UnsafeRef:
180 if (!--mnRefCnt)
181 const_cast<FormulaToken*>(this)->Delete();
182 break;
183 case RefCntPolicy::None:
184 break;
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
203 override it.
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)
256 p->IncRef();
259 inline void intrusive_ptr_release(const FormulaToken* p)
261 p->DecRef();
264 class FORMULA_DLLPUBLIC FormulaSpaceToken final : public FormulaToken
266 private:
267 sal_uInt8 nByte;
268 sal_Unicode cChar;
269 public:
270 FormulaSpaceToken( sal_uInt8 n, sal_Unicode c ) :
271 FormulaToken( svByte, ocWhitespace ),
272 nByte( n ), cChar( c ) {}
273 FormulaSpaceToken( const FormulaSpaceToken& r ) :
274 FormulaToken( 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
285 private:
286 sal_uInt8 nByte;
287 ParamClass eInForceArray;
288 protected:
289 FormulaByteToken( OpCode e, sal_uInt8 n, StackVar v, ParamClass c ) :
290 FormulaToken( v,e ), nByte( n ),
291 eInForceArray( c ) {}
292 public:
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
319 private:
320 FormulaTokenRef pOrigToken;
321 public:
322 FormulaFAPToken( OpCode e, sal_uInt8 n, FormulaToken* p ) :
323 FormulaByteToken( e, n, svFAP, ParamClass::Unknown ),
324 pOrigToken( p ) {}
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
335 private:
336 double fDouble;
337 public:
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
352 private:
353 sal_Int16 mnType; /**< Can hold, for example, a value
354 of SvNumFormatType, or by
355 contract any other
356 classification. */
357 public:
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;
373 public:
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;
389 public:
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
401 private:
402 sal_uInt16 nIndex;
403 sal_Int16 mnSheet;
404 public:
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
421 private:
422 OUString aExternal;
423 public:
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
441 public:
442 FormulaMissingToken() :
443 FormulaToken( svMissing,ocMissing ) {}
444 FormulaMissingToken( const FormulaMissingToken& r ) :
445 FormulaToken( 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
455 private:
456 std::unique_ptr<short[]>
457 pJump;
458 ParamClass eInForceArray;
459 public:
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 ) :
468 FormulaToken( 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
485 public:
486 FormulaUnknownToken( OpCode e ) :
487 FormulaToken( svUnknown, e ) {}
488 FormulaUnknownToken( const FormulaUnknownToken& r ) :
489 FormulaToken( 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
498 FormulaError nError;
499 public:
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;
512 } // formula
515 #endif
517 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */