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