xref: /trunk/main/formula/inc/formula/token.hxx (revision 5116778e)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 #ifndef FORMULA_TOKEN_HXX
25 #define FORMULA_TOKEN_HXX
26 
27 #include <memory>
28 #include <string.h>
29 #include <vector>
30 #include "formula/opcode.hxx"
31 //#include "refdata.hxx"
32 //#include "scmatrix.hxx"
33 #include "formula/intruref.hxx"
34 #include <tools/mempool.hxx>
35 #include "formula/IFunctionDescription.hxx"
36 #include "formula/formuladllapi.h"
37 
38 namespace formula
39 {
40 
41 enum StackVarEnum
42 {
43     svByte,
44     svDouble,
45     svString,
46     svSingleRef,
47     svDoubleRef,
48     svMatrix,
49     svIndex,
50     svJump,
51     svExternal,                         // Byte + String
52     svFAP,                              // FormulaAutoPilot only, ever exported
53     svJumpMatrix,                       // 2003-07-02
54     svRefList,                          // ocUnion result
55     svEmptyCell,                        // Result is an empty cell, e.g. in LOOKUP()
56 
57     svMatrixCell,                       // Result is a matrix with bells and
58                                         // whistles as needed for _the_ matrix
59                                         // formula result.
60 
61     svHybridCell,                       // A temporary condition of a formula
62                                         // cell during import, having a double
63                                         // and/or string result and a formula
64                                         // string to be compiled.
65 
66     svExternalSingleRef,
67     svExternalDoubleRef,
68     svExternalName,
69     svSubroutine,                       // A token with a subroutine token array.
70     svError,                            // error token
71     svMissing = 0x70,                   // 0 or ""
72     svSep,                              // separator, ocSep, ocOpen, ocClose
73     svUnknown                           // unknown StackType
74 };
75 
76 #ifndef DBG_UTIL
77 // save memory since compilers tend to int an enum
78 typedef sal_uInt8 StackVar;
79 #else
80 // have enum names in debugger
81 typedef StackVarEnum StackVar;
82 #endif
83 
84 
85 class FormulaToken;
86 typedef SimpleIntrusiveReference< class FormulaToken > FormulaTokenRef;
87 typedef SimpleIntrusiveReference< const class FormulaToken > FormulaConstTokenRef;
88 
89 class FormulaTokenArray;
90 
91 class FORMULA_DLLPUBLIC FormulaToken : public IFormulaToken
92 {
93     OpCode                      eOp;
94     // not implemented, prevent usage
95             FormulaToken();
96             FormulaToken&            operator=( const FormulaToken& );
97 protected:
98 
99             const StackVar      eType;          // type of data
100             mutable sal_uInt16      nRefCnt;        // reference count
101 
102 public:
FormulaToken(StackVar eTypeP,OpCode e=ocPush)103                                 FormulaToken( StackVar eTypeP,OpCode e = ocPush ) :
104                                     eOp(e), eType( eTypeP ), nRefCnt(0) {}
FormulaToken(const FormulaToken & r)105                                 FormulaToken( const FormulaToken& r ) : IFormulaToken(),
106                                     eOp(r.eOp), eType( r.eType ), nRefCnt(0) {}
107 
108     virtual                     ~FormulaToken();
109 
Delete()110     inline  void                Delete()                { delete this; }
GetType() const111     inline  StackVar      		GetType() const         { return eType; }
112             sal_Bool                IsFunction() const; // pure functions, no operators
113             sal_Bool                IsMatrixFunction() const;   // if a function _always_ returns a Matrix
114             sal_uInt8                GetParamCount() const;
IncRef() const115     inline  void                IncRef() const          { nRefCnt++; }
DecRef() const116     inline  void                DecRef() const
117                                     {
118                                         if (!--nRefCnt)
119                                             const_cast<FormulaToken*>(this)->Delete();
120                                     }
GetRef() const121     inline  sal_uInt16              GetRef() const          { return nRefCnt; }
GetOpCode() const122     inline OpCode               GetOpCode() const       { return eOp; }
123 
124     /**
125         Dummy methods to avoid switches and casts where possible,
126         the real token classes have to overload the appropriate method[s].
127         The only methods valid anytime if not overloaded are:
128 
129         - GetByte() since this represents the count of parameters to a function
130           which of course is 0 on non-functions. FormulaByteToken and ScExternal do
131           overload it.
132 
133         - HasForceArray() since also this is only used for operators and
134           functions and is 0 for other tokens.
135 
136         Any other non-overloaded method pops up an assertion.
137      */
138 
139     virtual sal_uInt8                GetByte() const;
140     virtual void                SetByte( sal_uInt8 n );
141     virtual bool                HasForceArray() const;
142     virtual void                SetForceArray( bool b );
143     virtual double              GetDouble() const;
144     virtual double&             GetDoubleAsReference();
145     virtual const String&       GetString() const;
146     virtual sal_uInt16              GetIndex() const;
147     virtual void                SetIndex( sal_uInt16 n );
148     virtual short*              GetJump() const;
149     virtual const String&       GetExternal() const;
150     virtual FormulaToken*       GetFAPOrigToken() const;
151     virtual sal_uInt16              GetError() const;
152     virtual void                SetError( sal_uInt16 );
153 
Clone() const154     virtual FormulaToken*       Clone() const { return new FormulaToken(*this); }
155 
156     virtual sal_Bool                Is3DRef() const;    // reference with 3D flag set
157     virtual sal_Bool                TextEqual( const formula::FormulaToken& rToken ) const;
158     virtual sal_Bool                operator==( const FormulaToken& rToken ) const;
159 
isFunction() const160     virtual bool isFunction() const
161     {
162         return IsFunction();
163     }
164 
getArgumentCount() const165     virtual sal_uInt32 getArgumentCount() const
166     {
167         return GetParamCount();
168     }
169 
170     /** This is dirty and only the compiler should use it! */
PrivateAccessformula::FormulaToken::PrivateAccess171     struct PrivateAccess { friend class FormulaCompiler; private: PrivateAccess() { }  };
NewOpCode(OpCode e,const PrivateAccess &)172     inline  void                NewOpCode( OpCode e, const PrivateAccess&  ) { eOp = e; }
173 
GetStrLenBytes(xub_StrLen nLen)174     static  size_t              GetStrLenBytes( xub_StrLen nLen )
175                                     { return nLen * sizeof(sal_Unicode); }
GetStrLenBytes(const String & rStr)176     static  size_t              GetStrLenBytes( const String& rStr )
177                                     { return GetStrLenBytes( rStr.Len() ); }
178 };
179 
180 class FORMULA_DLLPUBLIC FormulaByteToken : public FormulaToken
181 {
182 private:
183             sal_uInt8                nByte;
184             bool                bHasForceArray;
185 protected:
FormulaByteToken(OpCode e,sal_uInt8 n,StackVar v,bool b)186                                 FormulaByteToken( OpCode e, sal_uInt8 n, StackVar v, bool b ) :
187                                     FormulaToken( v,e ), nByte( n ),
188                                     bHasForceArray( b ) {}
189 public:
FormulaByteToken(OpCode e,sal_uInt8 n,bool b)190                                 FormulaByteToken( OpCode e, sal_uInt8 n, bool b ) :
191                                     FormulaToken( svByte,e ), nByte( n ),
192                                     bHasForceArray( b ) {}
FormulaByteToken(OpCode e,sal_uInt8 n)193                                 FormulaByteToken( OpCode e, sal_uInt8 n ) :
194                                     FormulaToken( svByte,e ), nByte( n ),
195                                     bHasForceArray( false ) {}
FormulaByteToken(OpCode e)196                                 FormulaByteToken( OpCode e ) :
197                                     FormulaToken( svByte,e ), nByte( 0 ),
198                                     bHasForceArray( false ) {}
FormulaByteToken(const FormulaByteToken & r)199                                 FormulaByteToken( const FormulaByteToken& r ) :
200                                     FormulaToken( r ), nByte( r.nByte ),
201                                     bHasForceArray( r.bHasForceArray ) {}
202 
Clone() const203     virtual FormulaToken*       Clone() const { return new FormulaByteToken(*this); }
204     virtual sal_uInt8                GetByte() const;
205     virtual void                SetByte( sal_uInt8 n );
206     virtual bool                HasForceArray() const;
207     virtual void                SetForceArray( bool b );
208     virtual sal_Bool                operator==( const FormulaToken& rToken ) const;
209 
210     DECL_FIXEDMEMPOOL_NEWDEL_DLL( FormulaByteToken )
211 };
212 
213 
214 // A special token for the FormulaAutoPilot only. Keeps a reference pointer of
215 // the token of which it was created for comparison.
216 class FORMULA_DLLPUBLIC FormulaFAPToken : public FormulaByteToken
217 {
218 private:
219             FormulaTokenRef          pOrigToken;
220 public:
FormulaFAPToken(OpCode e,sal_uInt8 n,FormulaToken * p)221                                 FormulaFAPToken( OpCode e, sal_uInt8 n, FormulaToken* p ) :
222                                     FormulaByteToken( e, n, svFAP, false ),
223                                     pOrigToken( p ) {}
FormulaFAPToken(const FormulaFAPToken & r)224                                 FormulaFAPToken( const FormulaFAPToken& r ) :
225                                     FormulaByteToken( r ), pOrigToken( r.pOrigToken ) {}
226 
Clone() const227     virtual FormulaToken*       Clone() const { return new FormulaFAPToken(*this); }
228     virtual FormulaToken*       GetFAPOrigToken() const;
229     virtual sal_Bool                operator==( const FormulaToken& rToken ) const;
230 };
231 
232 class FORMULA_DLLPUBLIC FormulaDoubleToken : public FormulaToken
233 {
234 private:
235             double              fDouble;
236 public:
FormulaDoubleToken(double f)237                                 FormulaDoubleToken( double f ) :
238                                     FormulaToken( svDouble ), fDouble( f ) {}
FormulaDoubleToken(const FormulaDoubleToken & r)239                                 FormulaDoubleToken( const FormulaDoubleToken& r ) :
240                                     FormulaToken( r ), fDouble( r.fDouble ) {}
241 
Clone() const242     virtual FormulaToken*       Clone() const { return new FormulaDoubleToken(*this); }
243     virtual double              GetDouble() const;
244     virtual double&             GetDoubleAsReference();
245     virtual sal_Bool                operator==( const FormulaToken& rToken ) const;
246 
247     DECL_FIXEDMEMPOOL_NEWDEL_DLL( FormulaDoubleToken )
248 };
249 
250 
251 class FORMULA_DLLPUBLIC FormulaStringToken : public FormulaToken
252 {
253 private:
254             String              aString;
255 public:
FormulaStringToken(const String & r)256                                 FormulaStringToken( const String& r ) :
257                                     FormulaToken( svString ), aString( r ) {}
FormulaStringToken(const FormulaStringToken & r)258                                 FormulaStringToken( const FormulaStringToken& r ) :
259                                     FormulaToken( r ), aString( r.aString ) {}
260 
Clone() const261     virtual FormulaToken*       Clone() const { return new FormulaStringToken(*this); }
262     virtual const String&       GetString() const;
263     virtual sal_Bool                operator==( const FormulaToken& rToken ) const;
264 
265     DECL_FIXEDMEMPOOL_NEWDEL_DLL( FormulaStringToken )
266 };
267 
268 
269 /** Identical to FormulaStringToken, but with explicit OpCode instead of implicit
270     ocPush, and an optional sal_uInt8 for ocBad tokens. */
271 class FORMULA_DLLPUBLIC FormulaStringOpToken : public FormulaByteToken
272 {
273 private:
274             String              aString;
275 public:
FormulaStringOpToken(OpCode e,const String & r)276                                 FormulaStringOpToken( OpCode e, const String& r ) :
277                                     FormulaByteToken( e, 0, svString, false ), aString( r ) {}
FormulaStringOpToken(const FormulaStringOpToken & r)278                                 FormulaStringOpToken( const FormulaStringOpToken& r ) :
279                                     FormulaByteToken( r ), aString( r.aString ) {}
280 
Clone() const281     virtual FormulaToken*       Clone() const { return new FormulaStringOpToken(*this); }
282     virtual const String&       GetString() const;
283     virtual sal_Bool                operator==( const FormulaToken& rToken ) const;
284 };
285 
286 class FORMULA_DLLPUBLIC FormulaIndexToken : public FormulaToken
287 {
288 private:
289             sal_uInt16              nIndex;
290 public:
FormulaIndexToken(OpCode e,sal_uInt16 n)291                                 FormulaIndexToken( OpCode e, sal_uInt16 n ) :
292                                     FormulaToken(  svIndex, e ), nIndex( n ) {}
FormulaIndexToken(const FormulaIndexToken & r)293                                 FormulaIndexToken( const FormulaIndexToken& r ) :
294                                     FormulaToken( r ), nIndex( r.nIndex ) {}
295 
Clone() const296     virtual FormulaToken*       Clone() const { return new FormulaIndexToken(*this); }
297     virtual sal_uInt16              GetIndex() const;
298     virtual void                SetIndex( sal_uInt16 n );
299     virtual sal_Bool                operator==( const FormulaToken& rToken ) const;
300 };
301 
302 
303 class FORMULA_DLLPUBLIC FormulaExternalToken : public FormulaToken
304 {
305 private:
306             String              aExternal;
307             sal_uInt8                nByte;
308 public:
FormulaExternalToken(OpCode e,sal_uInt8 n,const String & r)309                                 FormulaExternalToken( OpCode e, sal_uInt8 n, const String& r ) :
310                                     FormulaToken( svExternal, e ), aExternal( r ),
311                                     nByte( n ) {}
FormulaExternalToken(OpCode e,const String & r)312                                 FormulaExternalToken( OpCode e, const String& r ) :
313                                     FormulaToken(svExternal, e ), aExternal( r ),
314                                     nByte( 0 ) {}
FormulaExternalToken(const FormulaExternalToken & r)315                                 FormulaExternalToken( const FormulaExternalToken& r ) :
316                                     FormulaToken( r ), aExternal( r.aExternal ),
317                                     nByte( r.nByte ) {}
318 
Clone() const319     virtual FormulaToken*       Clone() const { return new FormulaExternalToken(*this); }
320     virtual const String&       GetExternal() const;
321     virtual sal_uInt8                GetByte() const;
322     virtual void                SetByte( sal_uInt8 n );
323     virtual sal_Bool                operator==( const FormulaToken& rToken ) const;
324 };
325 
326 
327 class FORMULA_DLLPUBLIC FormulaMissingToken : public FormulaToken
328 {
329 public:
FormulaMissingToken()330                                 FormulaMissingToken() :
331                                     FormulaToken( svMissing,ocMissing ) {}
FormulaMissingToken(const FormulaMissingToken & r)332                                 FormulaMissingToken( const FormulaMissingToken& r ) :
333                                     FormulaToken( r ) {}
334 
Clone() const335     virtual FormulaToken*       Clone() const { return new FormulaMissingToken(*this); }
336     virtual double              GetDouble() const;
337     virtual const String&       GetString() const;
338     virtual sal_Bool                operator==( const FormulaToken& rToken ) const;
339 };
340 
341 class FORMULA_DLLPUBLIC FormulaJumpToken : public FormulaToken
342 {
343 private:
344             short*              pJump;
345 public:
FormulaJumpToken(OpCode e,short * p)346                                 FormulaJumpToken( OpCode e, short* p ) :
347                                     FormulaToken( formula::svJump , e)
348                                 {
349                                     pJump = new short[ p[0] + 1 ];
350                                     memcpy( pJump, p, (p[0] + 1) * sizeof(short) );
351                                 }
FormulaJumpToken(const FormulaJumpToken & r)352                                 FormulaJumpToken( const FormulaJumpToken& r ) :
353                                     FormulaToken( r )
354                                 {
355                                     pJump = new short[ r.pJump[0] + 1 ];
356                                     memcpy( pJump, r.pJump, (r.pJump[0] + 1) * sizeof(short) );
357                                 }
358     virtual                     ~FormulaJumpToken();
359     virtual short*              GetJump() const;
360     virtual sal_Bool                operator==( const formula::FormulaToken& rToken ) const;
Clone() const361     virtual FormulaToken*       Clone() const { return new FormulaJumpToken(*this); }
362 };
363 
364 
365 class FORMULA_DLLPUBLIC FormulaSubroutineToken : public FormulaToken
366 {
367 public:
368     /** Takes ownership of pArray and deletes it upon destruction! */
FormulaSubroutineToken(const FormulaTokenArray * pArray)369                                 FormulaSubroutineToken( const FormulaTokenArray* pArray ) :
370                                     FormulaToken( svSubroutine, ocCall ), mpArray( pArray) {}
371                                 FormulaSubroutineToken( const FormulaSubroutineToken& r );
372     virtual                     ~FormulaSubroutineToken();
Clone() const373     virtual FormulaToken*       Clone() const { return new FormulaSubroutineToken(*this); }
374     virtual sal_Bool            operator==( const FormulaToken& rToken ) const;
375     const FormulaTokenArray*    GetTokenArray() const;
376 
377 private:
378     const FormulaTokenArray*    mpArray;
379 };
380 
381 
382 class FORMULA_DLLPUBLIC FormulaUnknownToken : public FormulaToken
383 {
384 public:
FormulaUnknownToken(OpCode e)385                                 FormulaUnknownToken( OpCode e ) :
386                                     FormulaToken( svUnknown, e ) {}
FormulaUnknownToken(const FormulaUnknownToken & r)387                                 FormulaUnknownToken( const FormulaUnknownToken& r ) :
388                                     FormulaToken( r ) {}
389 
Clone() const390     virtual FormulaToken*       Clone() const { return new FormulaUnknownToken(*this); }
391     virtual sal_Bool                operator==( const FormulaToken& rToken ) const;
392 };
393 
394 
395 class FORMULA_DLLPUBLIC FormulaErrorToken : public FormulaToken
396 {
397             sal_uInt16              nError;
398 public:
FormulaErrorToken(sal_uInt16 nErr)399                                 FormulaErrorToken( sal_uInt16 nErr ) :
400                                     FormulaToken( svError ), nError( nErr) {}
FormulaErrorToken(const FormulaErrorToken & r)401                                 FormulaErrorToken( const FormulaErrorToken& r ) :
402                                     FormulaToken( r ), nError( r.nError) {}
403 
Clone() const404     virtual FormulaToken*       Clone() const { return new FormulaErrorToken(*this); }
405     virtual sal_uInt16              GetError() const;
406     virtual void                SetError( sal_uInt16 nErr );
407     virtual sal_Bool                operator==( const FormulaToken& rToken ) const;
408 };
409 
410 // =============================================================================
411 } // formula
412 // =============================================================================
413 
414 #endif
415