1*cdf0e10cSrcweir /************************************************************************* 2*cdf0e10cSrcweir * 3*cdf0e10cSrcweir * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4*cdf0e10cSrcweir * 5*cdf0e10cSrcweir * Copyright 2000, 2010 Oracle and/or its affiliates. 6*cdf0e10cSrcweir * 7*cdf0e10cSrcweir * OpenOffice.org - a multi-platform office productivity suite 8*cdf0e10cSrcweir * 9*cdf0e10cSrcweir * This file is part of OpenOffice.org. 10*cdf0e10cSrcweir * 11*cdf0e10cSrcweir * OpenOffice.org is free software: you can redistribute it and/or modify 12*cdf0e10cSrcweir * it under the terms of the GNU Lesser General Public License version 3 13*cdf0e10cSrcweir * only, as published by the Free Software Foundation. 14*cdf0e10cSrcweir * 15*cdf0e10cSrcweir * OpenOffice.org is distributed in the hope that it will be useful, 16*cdf0e10cSrcweir * but WITHOUT ANY WARRANTY; without even the implied warranty of 17*cdf0e10cSrcweir * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18*cdf0e10cSrcweir * GNU Lesser General Public License version 3 for more details 19*cdf0e10cSrcweir * (a copy is included in the LICENSE file that accompanied this code). 20*cdf0e10cSrcweir * 21*cdf0e10cSrcweir * You should have received a copy of the GNU Lesser General Public License 22*cdf0e10cSrcweir * version 3 along with OpenOffice.org. If not, see 23*cdf0e10cSrcweir * <http://www.openoffice.org/license.html> 24*cdf0e10cSrcweir * for a copy of the LGPLv3 License. 25*cdf0e10cSrcweir * 26*cdf0e10cSrcweir ************************************************************************/ 27*cdf0e10cSrcweir 28*cdf0e10cSrcweir #ifndef SC_COMPILER_HXX 29*cdf0e10cSrcweir #define SC_COMPILER_HXX 30*cdf0e10cSrcweir 31*cdf0e10cSrcweir #ifndef INCLUDED_STRING_H 32*cdf0e10cSrcweir #include <string.h> 33*cdf0e10cSrcweir #define INCLUDED_STRING_H 34*cdf0e10cSrcweir #endif 35*cdf0e10cSrcweir #include <tools/mempool.hxx> 36*cdf0e10cSrcweir #include "scdllapi.h" 37*cdf0e10cSrcweir #include "global.hxx" 38*cdf0e10cSrcweir #include "refdata.hxx" 39*cdf0e10cSrcweir #include "formula/token.hxx" 40*cdf0e10cSrcweir #include "formula/intruref.hxx" 41*cdf0e10cSrcweir #include "formula/grammar.hxx" 42*cdf0e10cSrcweir #include <unotools/charclass.hxx> 43*cdf0e10cSrcweir #include <rtl/ustrbuf.hxx> 44*cdf0e10cSrcweir #include <com/sun/star/sheet/ExternalLinkInfo.hpp> 45*cdf0e10cSrcweir #include <vector> 46*cdf0e10cSrcweir 47*cdf0e10cSrcweir #include <formula/FormulaCompiler.hxx> 48*cdf0e10cSrcweir 49*cdf0e10cSrcweir 50*cdf0e10cSrcweir #ifndef BOOST_SHARED_PTR_HPP_INCLUDED 51*cdf0e10cSrcweir #include <boost/shared_ptr.hpp> 52*cdf0e10cSrcweir #endif 53*cdf0e10cSrcweir 54*cdf0e10cSrcweir #ifndef INCLUDED_HASH_MAP 55*cdf0e10cSrcweir #include <hash_map> 56*cdf0e10cSrcweir #define INCLUDED_HASH_MAP 57*cdf0e10cSrcweir #endif 58*cdf0e10cSrcweir 59*cdf0e10cSrcweir //----------------------------------------------- 60*cdf0e10cSrcweir 61*cdf0e10cSrcweir // constants and data types also for external modules (ScInterpreter et al) 62*cdf0e10cSrcweir 63*cdf0e10cSrcweir #define MAXCODE 512 /* maximum number of tokens in formula */ 64*cdf0e10cSrcweir #define MAXSTRLEN 1024 /* maximum length of input string of one symbol */ 65*cdf0e10cSrcweir #define MAXJUMPCOUNT 32 /* maximum number of jumps (ocChose) */ 66*cdf0e10cSrcweir 67*cdf0e10cSrcweir // flag values of CharTable 68*cdf0e10cSrcweir #define SC_COMPILER_C_ILLEGAL 0x00000000 69*cdf0e10cSrcweir #define SC_COMPILER_C_CHAR 0x00000001 70*cdf0e10cSrcweir #define SC_COMPILER_C_CHAR_BOOL 0x00000002 71*cdf0e10cSrcweir #define SC_COMPILER_C_CHAR_WORD 0x00000004 72*cdf0e10cSrcweir #define SC_COMPILER_C_CHAR_VALUE 0x00000008 73*cdf0e10cSrcweir #define SC_COMPILER_C_CHAR_STRING 0x00000010 74*cdf0e10cSrcweir #define SC_COMPILER_C_CHAR_DONTCARE 0x00000020 75*cdf0e10cSrcweir #define SC_COMPILER_C_BOOL 0x00000040 76*cdf0e10cSrcweir #define SC_COMPILER_C_WORD 0x00000080 77*cdf0e10cSrcweir #define SC_COMPILER_C_WORD_SEP 0x00000100 78*cdf0e10cSrcweir #define SC_COMPILER_C_VALUE 0x00000200 79*cdf0e10cSrcweir #define SC_COMPILER_C_VALUE_SEP 0x00000400 80*cdf0e10cSrcweir #define SC_COMPILER_C_VALUE_EXP 0x00000800 81*cdf0e10cSrcweir #define SC_COMPILER_C_VALUE_SIGN 0x00001000 82*cdf0e10cSrcweir #define SC_COMPILER_C_VALUE_VALUE 0x00002000 83*cdf0e10cSrcweir #define SC_COMPILER_C_STRING_SEP 0x00004000 84*cdf0e10cSrcweir #define SC_COMPILER_C_NAME_SEP 0x00008000 // there can be only one! '\'' 85*cdf0e10cSrcweir #define SC_COMPILER_C_CHAR_IDENT 0x00010000 // identifier (built-in function) or reference start 86*cdf0e10cSrcweir #define SC_COMPILER_C_IDENT 0x00020000 // identifier or reference continuation 87*cdf0e10cSrcweir #define SC_COMPILER_C_ODF_LBRACKET 0x00040000 // ODF '[' reference bracket 88*cdf0e10cSrcweir #define SC_COMPILER_C_ODF_RBRACKET 0x00080000 // ODF ']' reference bracket 89*cdf0e10cSrcweir #define SC_COMPILER_C_ODF_LABEL_OP 0x00100000 // ODF '!!' automatic intersection of labels 90*cdf0e10cSrcweir #define SC_COMPILER_C_ODF_NAME_MARKER 0x00200000 // ODF '$$' marker that starts a defined (range) name 91*cdf0e10cSrcweir #define SC_COMPILER_C_CHAR_NAME 0x00400000 // start character of a defined name 92*cdf0e10cSrcweir #define SC_COMPILER_C_NAME 0x00800000 // continuation character of a defined name 93*cdf0e10cSrcweir 94*cdf0e10cSrcweir #define SC_COMPILER_FILE_TAB_SEP '#' // 'Doc'#Tab 95*cdf0e10cSrcweir 96*cdf0e10cSrcweir 97*cdf0e10cSrcweir class ScDocument; 98*cdf0e10cSrcweir class ScMatrix; 99*cdf0e10cSrcweir class ScRangeData; 100*cdf0e10cSrcweir class ScExternalRefManager; 101*cdf0e10cSrcweir class ScTokenArray; 102*cdf0e10cSrcweir 103*cdf0e10cSrcweir // constants and data types internal to compiler 104*cdf0e10cSrcweir 105*cdf0e10cSrcweir #if 0 106*cdf0e10cSrcweir /* 107*cdf0e10cSrcweir OpCode eOp; // OpCode 108*cdf0e10cSrcweir formula::StackVar eType; // type of data 109*cdf0e10cSrcweir sal_uInt16 nRefCnt; // reference count 110*cdf0e10cSrcweir sal_Bool bRaw; // not cloned yet and trimmed to real size 111*cdf0e10cSrcweir */ 112*cdf0e10cSrcweir #endif 113*cdf0e10cSrcweir 114*cdf0e10cSrcweir #define SC_TOKEN_FIX_MEMBERS \ 115*cdf0e10cSrcweir OpCode eOp; \ 116*cdf0e10cSrcweir formula::StackVar eType; \ 117*cdf0e10cSrcweir sal_uInt16 nRefCnt; \ 118*cdf0e10cSrcweir sal_Bool bRaw; 119*cdf0e10cSrcweir 120*cdf0e10cSrcweir struct ScDoubleRawToken 121*cdf0e10cSrcweir { 122*cdf0e10cSrcweir private: 123*cdf0e10cSrcweir SC_TOKEN_FIX_MEMBERS 124*cdf0e10cSrcweir public: 125*cdf0e10cSrcweir union 126*cdf0e10cSrcweir { // union only to assure alignment identical to ScRawToken 127*cdf0e10cSrcweir double nValue; 128*cdf0e10cSrcweir struct { 129*cdf0e10cSrcweir sal_uInt8 cByte; 130*cdf0e10cSrcweir bool bHasForceArray; 131*cdf0e10cSrcweir } sbyte; 132*cdf0e10cSrcweir }; 133*cdf0e10cSrcweir DECL_FIXEDMEMPOOL_NEWDEL( ScDoubleRawToken ); 134*cdf0e10cSrcweir }; 135*cdf0e10cSrcweir 136*cdf0e10cSrcweir struct ScRawToken 137*cdf0e10cSrcweir { 138*cdf0e10cSrcweir friend class ScCompiler; 139*cdf0e10cSrcweir // Friends that use a temporary ScRawToken on the stack (and therefor need 140*cdf0e10cSrcweir // the private dtor) and know what they're doing.. 141*cdf0e10cSrcweir friend class ScTokenArray; 142*cdf0e10cSrcweir friend sal_uInt16 lcl_ScRawTokenOffset(); 143*cdf0e10cSrcweir private: 144*cdf0e10cSrcweir SC_TOKEN_FIX_MEMBERS 145*cdf0e10cSrcweir public: 146*cdf0e10cSrcweir union { 147*cdf0e10cSrcweir double nValue; 148*cdf0e10cSrcweir struct { 149*cdf0e10cSrcweir sal_uInt8 cByte; 150*cdf0e10cSrcweir bool bHasForceArray; 151*cdf0e10cSrcweir } sbyte; 152*cdf0e10cSrcweir ScComplexRefData aRef; 153*cdf0e10cSrcweir struct { 154*cdf0e10cSrcweir sal_uInt16 nFileId; 155*cdf0e10cSrcweir sal_Unicode cTabName[MAXSTRLEN+1]; 156*cdf0e10cSrcweir ScComplexRefData aRef; 157*cdf0e10cSrcweir } extref; 158*cdf0e10cSrcweir struct { 159*cdf0e10cSrcweir sal_uInt16 nFileId; 160*cdf0e10cSrcweir sal_Unicode cName[MAXSTRLEN+1]; 161*cdf0e10cSrcweir } extname; 162*cdf0e10cSrcweir ScMatrix* pMat; 163*cdf0e10cSrcweir sal_uInt16 nIndex; // index into name collection 164*cdf0e10cSrcweir sal_Unicode cStr[ MAXSTRLEN+1 ]; // string (up to 255 characters + 0) 165*cdf0e10cSrcweir short nJump[MAXJUMPCOUNT+1]; // If/Chose token 166*cdf0e10cSrcweir }; 167*cdf0e10cSrcweir 168*cdf0e10cSrcweir //! other members not initialized 169*cdf0e10cSrcweir ScRawToken() : bRaw( sal_True ) {} 170*cdf0e10cSrcweir private: 171*cdf0e10cSrcweir ~ScRawToken() {} //! only delete via Delete() 172*cdf0e10cSrcweir public: 173*cdf0e10cSrcweir DECL_FIXEDMEMPOOL_NEWDEL( ScRawToken ); 174*cdf0e10cSrcweir formula::StackVar GetType() const { return (formula::StackVar) eType; } 175*cdf0e10cSrcweir OpCode GetOpCode() const { return (OpCode) eOp; } 176*cdf0e10cSrcweir void NewOpCode( OpCode e ) { eOp = e; } 177*cdf0e10cSrcweir void IncRef() { nRefCnt++; } 178*cdf0e10cSrcweir void DecRef() { if( !--nRefCnt ) Delete(); } 179*cdf0e10cSrcweir sal_uInt16 GetRef() const { return nRefCnt; } 180*cdf0e10cSrcweir SC_DLLPUBLIC void Delete(); 181*cdf0e10cSrcweir 182*cdf0e10cSrcweir // Use these methods only on tokens that are not part of a token array, 183*cdf0e10cSrcweir // since the reference count is cleared! 184*cdf0e10cSrcweir void SetOpCode( OpCode eCode ); 185*cdf0e10cSrcweir void SetString( const sal_Unicode* pStr ); 186*cdf0e10cSrcweir void SetSingleReference( const ScSingleRefData& rRef ); 187*cdf0e10cSrcweir void SetDoubleReference( const ScComplexRefData& rRef ); 188*cdf0e10cSrcweir void SetDouble( double fVal ); 189*cdf0e10cSrcweir //UNUSED2008-05 void SetInt( int nVal ); 190*cdf0e10cSrcweir //UNUSED2008-05 void SetMatrix( ScMatrix* p ); 191*cdf0e10cSrcweir 192*cdf0e10cSrcweir // These methods are ok to use, reference count not cleared. 193*cdf0e10cSrcweir //UNUSED2008-05 ScComplexRefData& GetReference(); 194*cdf0e10cSrcweir //UNUSED2008-05 void SetReference( ScComplexRefData& rRef ); 195*cdf0e10cSrcweir void SetName( sal_uInt16 n ); 196*cdf0e10cSrcweir void SetExternalSingleRef( sal_uInt16 nFileId, const String& rTabName, const ScSingleRefData& rRef ); 197*cdf0e10cSrcweir void SetExternalDoubleRef( sal_uInt16 nFileId, const String& rTabName, const ScComplexRefData& rRef ); 198*cdf0e10cSrcweir void SetExternalName( sal_uInt16 nFileId, const String& rName ); 199*cdf0e10cSrcweir void SetMatrix( ScMatrix* p ); 200*cdf0e10cSrcweir void SetExternal(const sal_Unicode* pStr); 201*cdf0e10cSrcweir 202*cdf0e10cSrcweir ScRawToken* Clone() const; // real copy! 203*cdf0e10cSrcweir formula::FormulaToken* CreateToken() const; // create typified token 204*cdf0e10cSrcweir void Load( SvStream&, sal_uInt16 nVer ); 205*cdf0e10cSrcweir 206*cdf0e10cSrcweir static xub_StrLen GetStrLen( const sal_Unicode* pStr ); // as long as a "string" is an array 207*cdf0e10cSrcweir static size_t GetStrLenBytes( xub_StrLen nLen ) 208*cdf0e10cSrcweir { return nLen * sizeof(sal_Unicode); } 209*cdf0e10cSrcweir static size_t GetStrLenBytes( const sal_Unicode* pStr ) 210*cdf0e10cSrcweir { return GetStrLenBytes( GetStrLen( pStr ) ); } 211*cdf0e10cSrcweir }; 212*cdf0e10cSrcweir 213*cdf0e10cSrcweir 214*cdf0e10cSrcweir typedef formula::SimpleIntrusiveReference< struct ScRawToken > ScRawTokenRef; 215*cdf0e10cSrcweir 216*cdf0e10cSrcweir class SC_DLLPUBLIC ScCompiler : public formula::FormulaCompiler 217*cdf0e10cSrcweir { 218*cdf0e10cSrcweir public: 219*cdf0e10cSrcweir 220*cdf0e10cSrcweir enum EncodeUrlMode 221*cdf0e10cSrcweir { 222*cdf0e10cSrcweir ENCODE_BY_GRAMMAR, 223*cdf0e10cSrcweir ENCODE_ALWAYS, 224*cdf0e10cSrcweir ENCODE_NEVER, 225*cdf0e10cSrcweir }; 226*cdf0e10cSrcweir 227*cdf0e10cSrcweir struct Convention 228*cdf0e10cSrcweir { 229*cdf0e10cSrcweir const formula::FormulaGrammar::AddressConvention meConv; 230*cdf0e10cSrcweir const sal_uLong* mpCharTable; 231*cdf0e10cSrcweir 232*cdf0e10cSrcweir 233*cdf0e10cSrcweir Convention( formula::FormulaGrammar::AddressConvention eConvP ); 234*cdf0e10cSrcweir virtual ~Convention(); 235*cdf0e10cSrcweir 236*cdf0e10cSrcweir virtual void MakeRefStr( rtl::OUStringBuffer& rBuffer, 237*cdf0e10cSrcweir const ScCompiler& rCompiler, 238*cdf0e10cSrcweir const ScComplexRefData& rRef, 239*cdf0e10cSrcweir sal_Bool bSingleRef ) const = 0; 240*cdf0e10cSrcweir virtual ::com::sun::star::i18n::ParseResult 241*cdf0e10cSrcweir parseAnyToken( const String& rFormula, 242*cdf0e10cSrcweir xub_StrLen nSrcPos, 243*cdf0e10cSrcweir const CharClass* pCharClass) const = 0; 244*cdf0e10cSrcweir 245*cdf0e10cSrcweir /** 246*cdf0e10cSrcweir * Parse the symbol string and pick up the file name and the external 247*cdf0e10cSrcweir * range name. 248*cdf0e10cSrcweir * 249*cdf0e10cSrcweir * @return true on successful parse, or false otherwise. 250*cdf0e10cSrcweir */ 251*cdf0e10cSrcweir virtual bool parseExternalName( const String& rSymbol, String& rFile, String& rName, 252*cdf0e10cSrcweir const ScDocument* pDoc, 253*cdf0e10cSrcweir const ::com::sun::star::uno::Sequence< 254*cdf0e10cSrcweir const ::com::sun::star::sheet::ExternalLinkInfo > * pExternalLinks ) const = 0; 255*cdf0e10cSrcweir 256*cdf0e10cSrcweir virtual String makeExternalNameStr( const String& rFile, const String& rName ) const = 0; 257*cdf0e10cSrcweir 258*cdf0e10cSrcweir virtual void makeExternalRefStr( ::rtl::OUStringBuffer& rBuffer, const ScCompiler& rCompiler, 259*cdf0e10cSrcweir sal_uInt16 nFileId, const String& rTabName, const ScSingleRefData& rRef, 260*cdf0e10cSrcweir ScExternalRefManager* pRefMgr ) const = 0; 261*cdf0e10cSrcweir 262*cdf0e10cSrcweir virtual void makeExternalRefStr( ::rtl::OUStringBuffer& rBuffer, const ScCompiler& rCompiler, 263*cdf0e10cSrcweir sal_uInt16 nFileId, const String& rTabName, const ScComplexRefData& rRef, 264*cdf0e10cSrcweir ScExternalRefManager* pRefMgr ) const = 0; 265*cdf0e10cSrcweir 266*cdf0e10cSrcweir enum SpecialSymbolType 267*cdf0e10cSrcweir { 268*cdf0e10cSrcweir /** 269*cdf0e10cSrcweir * Character between sheet name and address. In OOO A1 this is 270*cdf0e10cSrcweir * '.', while XL A1 and XL R1C1 this is '!'. 271*cdf0e10cSrcweir */ 272*cdf0e10cSrcweir SHEET_SEPARATOR, 273*cdf0e10cSrcweir 274*cdf0e10cSrcweir /** 275*cdf0e10cSrcweir * In OOO A1, a sheet name may be prefixed with '$' to indicate an 276*cdf0e10cSrcweir * absolute sheet position. 277*cdf0e10cSrcweir */ 278*cdf0e10cSrcweir ABS_SHEET_PREFIX 279*cdf0e10cSrcweir }; 280*cdf0e10cSrcweir virtual sal_Unicode getSpecialSymbol( SpecialSymbolType eSymType ) const = 0; 281*cdf0e10cSrcweir }; 282*cdf0e10cSrcweir friend struct Convention; 283*cdf0e10cSrcweir 284*cdf0e10cSrcweir private: 285*cdf0e10cSrcweir 286*cdf0e10cSrcweir 287*cdf0e10cSrcweir static CharClass *pCharClassEnglish; // character classification for en_US locale 288*cdf0e10cSrcweir static const Convention *pConventions[ formula::FormulaGrammar::CONV_LAST ]; 289*cdf0e10cSrcweir 290*cdf0e10cSrcweir static const Convention * const pConvOOO_A1; 291*cdf0e10cSrcweir static const Convention * const pConvOOO_A1_ODF; 292*cdf0e10cSrcweir static const Convention * const pConvXL_A1; 293*cdf0e10cSrcweir static const Convention * const pConvXL_R1C1; 294*cdf0e10cSrcweir static const Convention * const pConvXL_OOX; 295*cdf0e10cSrcweir 296*cdf0e10cSrcweir static struct AddInMap 297*cdf0e10cSrcweir { 298*cdf0e10cSrcweir const char* pODFF; 299*cdf0e10cSrcweir const char* pEnglish; 300*cdf0e10cSrcweir bool bMapDupToInternal; // when writing ODFF 301*cdf0e10cSrcweir const char* pOriginal; // programmatical name 302*cdf0e10cSrcweir const char* pUpper; // upper case programmatical name 303*cdf0e10cSrcweir } maAddInMap[]; 304*cdf0e10cSrcweir static const AddInMap* GetAddInMap(); 305*cdf0e10cSrcweir static size_t GetAddInMapCount(); 306*cdf0e10cSrcweir 307*cdf0e10cSrcweir ScDocument* pDoc; 308*cdf0e10cSrcweir ScAddress aPos; 309*cdf0e10cSrcweir 310*cdf0e10cSrcweir // For CONV_XL_OOX, may be set via API by MOOXML filter. 311*cdf0e10cSrcweir ::com::sun::star::uno::Sequence< const ::com::sun::star::sheet::ExternalLinkInfo > maExternalLinks; 312*cdf0e10cSrcweir 313*cdf0e10cSrcweir sal_Unicode cSymbol[MAXSTRLEN]; // current Symbol 314*cdf0e10cSrcweir String aFormula; // formula source code 315*cdf0e10cSrcweir xub_StrLen nSrcPos; // tokenizer position (source code) 316*cdf0e10cSrcweir ScRawTokenRef pRawToken; 317*cdf0e10cSrcweir 318*cdf0e10cSrcweir const CharClass* pCharClass; // which character classification is used for parseAnyToken 319*cdf0e10cSrcweir sal_uInt16 mnPredetectedReference; // reference when reading ODF, 0 (none), 1 (single) or 2 (double) 320*cdf0e10cSrcweir SCsTAB nMaxTab; // last sheet in document 321*cdf0e10cSrcweir sal_Int32 mnRangeOpPosInSymbol; // if and where a range operator is in symbol 322*cdf0e10cSrcweir const Convention *pConv; 323*cdf0e10cSrcweir EncodeUrlMode meEncodeUrlMode; 324*cdf0e10cSrcweir bool mbCloseBrackets; // whether to close open brackets automatically, default TRUE 325*cdf0e10cSrcweir bool mbExtendedErrorDetection; 326*cdf0e10cSrcweir bool mbRewind; // whether symbol is to be rewound to some step during lexical analysis 327*cdf0e10cSrcweir 328*cdf0e10cSrcweir sal_Bool NextNewToken(bool bInArray = false); 329*cdf0e10cSrcweir 330*cdf0e10cSrcweir virtual void SetError(sal_uInt16 nError); 331*cdf0e10cSrcweir xub_StrLen NextSymbol(bool bInArray); 332*cdf0e10cSrcweir sal_Bool IsValue( const String& ); 333*cdf0e10cSrcweir sal_Bool IsOpCode( const String&, bool bInArray ); 334*cdf0e10cSrcweir sal_Bool IsOpCode2( const String& ); 335*cdf0e10cSrcweir sal_Bool IsString(); 336*cdf0e10cSrcweir sal_Bool IsReference( const String& ); 337*cdf0e10cSrcweir sal_Bool IsSingleReference( const String& ); 338*cdf0e10cSrcweir sal_Bool IsPredetectedReference( const String& ); 339*cdf0e10cSrcweir sal_Bool IsDoubleReference( const String& ); 340*cdf0e10cSrcweir sal_Bool IsMacro( const String& ); 341*cdf0e10cSrcweir sal_Bool IsNamedRange( const String& ); 342*cdf0e10cSrcweir bool IsExternalNamedRange( const String& rSymbol ); 343*cdf0e10cSrcweir sal_Bool IsDBRange( const String& ); 344*cdf0e10cSrcweir sal_Bool IsColRowName( const String& ); 345*cdf0e10cSrcweir sal_Bool IsBoolean( const String& ); 346*cdf0e10cSrcweir void AutoCorrectParsedSymbol(); 347*cdf0e10cSrcweir 348*cdf0e10cSrcweir void SetRelNameReference(); 349*cdf0e10cSrcweir 350*cdf0e10cSrcweir static void InitCharClassEnglish(); 351*cdf0e10cSrcweir 352*cdf0e10cSrcweir public: 353*cdf0e10cSrcweir ScCompiler( ScDocument* pDocument, const ScAddress&); 354*cdf0e10cSrcweir 355*cdf0e10cSrcweir ScCompiler( ScDocument* pDocument, const ScAddress&,ScTokenArray& rArr); 356*cdf0e10cSrcweir 357*cdf0e10cSrcweir public: 358*cdf0e10cSrcweir static void DeInit(); /// all 359*cdf0e10cSrcweir 360*cdf0e10cSrcweir // for ScAddress::Format() 361*cdf0e10cSrcweir static void CheckTabQuotes( String& aTabName, 362*cdf0e10cSrcweir const formula::FormulaGrammar::AddressConvention eConv = formula::FormulaGrammar::CONV_OOO ); 363*cdf0e10cSrcweir 364*cdf0e10cSrcweir /** Analyzes a string for a 'Doc'#Tab construct, or 'Do''c'#Tab etc.. 365*cdf0e10cSrcweir 366*cdf0e10cSrcweir @returns the position of the unquoted # hash mark in 'Doc'#Tab, or 367*cdf0e10cSrcweir STRING_NOTFOUND if none. */ 368*cdf0e10cSrcweir static xub_StrLen GetDocTabPos( const String& rString ); 369*cdf0e10cSrcweir 370*cdf0e10cSrcweir static sal_Bool EnQuote( String& rStr ); 371*cdf0e10cSrcweir sal_Unicode GetNativeAddressSymbol( Convention::SpecialSymbolType eType ) const; 372*cdf0e10cSrcweir 373*cdf0e10cSrcweir 374*cdf0e10cSrcweir // Check if it is a valid english function name 375*cdf0e10cSrcweir bool IsEnglishSymbol( const String& rName ); 376*cdf0e10cSrcweir 377*cdf0e10cSrcweir //! _either_ CompileForFAP _or_ AutoCorrection, _not_ both 378*cdf0e10cSrcweir // #i101512# SetCompileForFAP is in formula::FormulaCompiler 379*cdf0e10cSrcweir void SetAutoCorrection( sal_Bool bVal ) 380*cdf0e10cSrcweir { bAutoCorrect = bVal; bIgnoreErrors = bVal; } 381*cdf0e10cSrcweir void SetCloseBrackets( bool bVal ) { mbCloseBrackets = bVal; } 382*cdf0e10cSrcweir void SetRefConvention( const Convention *pConvP ); 383*cdf0e10cSrcweir void SetRefConvention( const formula::FormulaGrammar::AddressConvention eConv ); 384*cdf0e10cSrcweir 385*cdf0e10cSrcweir /// Set symbol map if not empty. 386*cdf0e10cSrcweir void SetFormulaLanguage( const OpCodeMapPtr & xMap ); 387*cdf0e10cSrcweir 388*cdf0e10cSrcweir void SetGrammar( const formula::FormulaGrammar::Grammar eGrammar ); 389*cdf0e10cSrcweir 390*cdf0e10cSrcweir void SetEncodeUrlMode( EncodeUrlMode eMode ); 391*cdf0e10cSrcweir EncodeUrlMode GetEncodeUrlMode() const; 392*cdf0e10cSrcweir private: 393*cdf0e10cSrcweir /** Set grammar and reference convention from within SetFormulaLanguage() 394*cdf0e10cSrcweir or SetGrammar(). 395*cdf0e10cSrcweir 396*cdf0e10cSrcweir @param eNewGrammar 397*cdf0e10cSrcweir The new grammar to be set and the associated reference convention. 398*cdf0e10cSrcweir 399*cdf0e10cSrcweir @param eOldGrammar 400*cdf0e10cSrcweir The previous grammar that was active before SetFormulaLanguage(). 401*cdf0e10cSrcweir */ 402*cdf0e10cSrcweir void SetGrammarAndRefConvention( 403*cdf0e10cSrcweir const formula::FormulaGrammar::Grammar eNewGrammar, 404*cdf0e10cSrcweir const formula::FormulaGrammar::Grammar eOldGrammar ); 405*cdf0e10cSrcweir public: 406*cdf0e10cSrcweir 407*cdf0e10cSrcweir /// Set external link info for ScAddress::CONV_XL_OOX. 408*cdf0e10cSrcweir inline void SetExternalLinks( 409*cdf0e10cSrcweir const ::com::sun::star::uno::Sequence< 410*cdf0e10cSrcweir const ::com::sun::star::sheet::ExternalLinkInfo > & rLinks ) 411*cdf0e10cSrcweir { 412*cdf0e10cSrcweir maExternalLinks = rLinks; 413*cdf0e10cSrcweir } 414*cdf0e10cSrcweir 415*cdf0e10cSrcweir void CreateStringFromXMLTokenArray( String& rFormula, String& rFormulaNmsp ); 416*cdf0e10cSrcweir 417*cdf0e10cSrcweir void SetExtendedErrorDetection( bool bVal ) { mbExtendedErrorDetection = bVal; } 418*cdf0e10cSrcweir 419*cdf0e10cSrcweir sal_Bool IsCorrected() { return bCorrected; } 420*cdf0e10cSrcweir const String& GetCorrectedFormula() { return aCorrectedFormula; } 421*cdf0e10cSrcweir 422*cdf0e10cSrcweir // Use convention from this->aPos by default 423*cdf0e10cSrcweir ScTokenArray* CompileString( const String& rFormula ); 424*cdf0e10cSrcweir ScTokenArray* CompileString( const String& rFormula, const String& rFormulaNmsp ); 425*cdf0e10cSrcweir const ScDocument* GetDoc() const { return pDoc; } 426*cdf0e10cSrcweir const ScAddress& GetPos() const { return aPos; } 427*cdf0e10cSrcweir 428*cdf0e10cSrcweir void MoveRelWrap( SCCOL nMaxCol, SCROW nMaxRow ); 429*cdf0e10cSrcweir static void MoveRelWrap( ScTokenArray& rArr, ScDocument* pDoc, const ScAddress& rPos, 430*cdf0e10cSrcweir SCCOL nMaxCol, SCROW nMaxRow ); 431*cdf0e10cSrcweir 432*cdf0e10cSrcweir sal_Bool UpdateNameReference( UpdateRefMode eUpdateRefMode, 433*cdf0e10cSrcweir const ScRange&, 434*cdf0e10cSrcweir SCsCOL nDx, SCsROW nDy, SCsTAB nDz, 435*cdf0e10cSrcweir sal_Bool& rChanged, sal_Bool bSharedFormula = sal_False); 436*cdf0e10cSrcweir 437*cdf0e10cSrcweir ScRangeData* UpdateReference( UpdateRefMode eUpdateRefMode, 438*cdf0e10cSrcweir const ScAddress& rOldPos, const ScRange&, 439*cdf0e10cSrcweir SCsCOL nDx, SCsROW nDy, SCsTAB nDz, 440*cdf0e10cSrcweir sal_Bool& rChanged, sal_Bool& rRefSizeChanged ); 441*cdf0e10cSrcweir 442*cdf0e10cSrcweir /// Only once for converted shared formulas, 443*cdf0e10cSrcweir /// token array has to be compiled afterwards. 444*cdf0e10cSrcweir void UpdateSharedFormulaReference( UpdateRefMode eUpdateRefMode, 445*cdf0e10cSrcweir const ScAddress& rOldPos, const ScRange&, 446*cdf0e10cSrcweir SCsCOL nDx, SCsROW nDy, SCsTAB nDz ); 447*cdf0e10cSrcweir 448*cdf0e10cSrcweir ScRangeData* UpdateInsertTab(SCTAB nTable, sal_Bool bIsName ); 449*cdf0e10cSrcweir ScRangeData* UpdateDeleteTab(SCTAB nTable, sal_Bool bIsMove, sal_Bool bIsName, sal_Bool& bCompile); 450*cdf0e10cSrcweir ScRangeData* UpdateMoveTab(SCTAB nOldPos, SCTAB nNewPos, sal_Bool bIsName ); 451*cdf0e10cSrcweir 452*cdf0e10cSrcweir sal_Bool HasModifiedRange(); 453*cdf0e10cSrcweir 454*cdf0e10cSrcweir /** If the character is allowed as first character in sheet names or 455*cdf0e10cSrcweir references, includes '$' and '?'. */ 456*cdf0e10cSrcweir static inline sal_Bool IsCharWordChar( String const & rStr, 457*cdf0e10cSrcweir xub_StrLen nPos, 458*cdf0e10cSrcweir const formula::FormulaGrammar::AddressConvention eConv = formula::FormulaGrammar::CONV_OOO ) 459*cdf0e10cSrcweir { 460*cdf0e10cSrcweir sal_Unicode c = rStr.GetChar( nPos ); 461*cdf0e10cSrcweir if (c < 128) 462*cdf0e10cSrcweir { 463*cdf0e10cSrcweir return pConventions[eConv] ? static_cast<sal_Bool>( 464*cdf0e10cSrcweir (pConventions[eConv]->mpCharTable[ sal_uInt8(c) ] & SC_COMPILER_C_CHAR_WORD) == SC_COMPILER_C_CHAR_WORD) : 465*cdf0e10cSrcweir sal_False; // no convention => assume invalid 466*cdf0e10cSrcweir } 467*cdf0e10cSrcweir else 468*cdf0e10cSrcweir return ScGlobal::pCharClass->isLetterNumeric( rStr, nPos ); 469*cdf0e10cSrcweir } 470*cdf0e10cSrcweir 471*cdf0e10cSrcweir /** If the character is allowed in sheet names, thus may be part of a 472*cdf0e10cSrcweir reference, includes '$' and '?' and such. */ 473*cdf0e10cSrcweir static inline sal_Bool IsWordChar( String const & rStr, 474*cdf0e10cSrcweir xub_StrLen nPos, 475*cdf0e10cSrcweir const formula::FormulaGrammar::AddressConvention eConv = formula::FormulaGrammar::CONV_OOO ) 476*cdf0e10cSrcweir { 477*cdf0e10cSrcweir sal_Unicode c = rStr.GetChar( nPos ); 478*cdf0e10cSrcweir if (c < 128) 479*cdf0e10cSrcweir { 480*cdf0e10cSrcweir return pConventions[eConv] ? static_cast<sal_Bool>( 481*cdf0e10cSrcweir (pConventions[eConv]->mpCharTable[ sal_uInt8(c) ] & SC_COMPILER_C_WORD) == SC_COMPILER_C_WORD) : 482*cdf0e10cSrcweir sal_False; // convention not known => assume invalid 483*cdf0e10cSrcweir } 484*cdf0e10cSrcweir else 485*cdf0e10cSrcweir return ScGlobal::pCharClass->isLetterNumeric( rStr, nPos ); 486*cdf0e10cSrcweir } 487*cdf0e10cSrcweir 488*cdf0e10cSrcweir /** If the character is allowed as tested by nFlags (SC_COMPILER_C_... 489*cdf0e10cSrcweir bits) for all known address conventions. If more than one bit is given 490*cdf0e10cSrcweir in nFlags, all bits must match. If bTestLetterNumeric is sal_False and 491*cdf0e10cSrcweir char>=128, no LetterNumeric test is done and sal_False is returned. */ 492*cdf0e10cSrcweir static inline bool IsCharFlagAllConventions( String const & rStr, 493*cdf0e10cSrcweir xub_StrLen nPos, 494*cdf0e10cSrcweir sal_uLong nFlags, 495*cdf0e10cSrcweir bool bTestLetterNumeric = true ) 496*cdf0e10cSrcweir { 497*cdf0e10cSrcweir sal_Unicode c = rStr.GetChar( nPos ); 498*cdf0e10cSrcweir if (c < 128) 499*cdf0e10cSrcweir { 500*cdf0e10cSrcweir for ( int nConv = formula::FormulaGrammar::CONV_UNSPECIFIED; 501*cdf0e10cSrcweir ++nConv < formula::FormulaGrammar::CONV_LAST; ) 502*cdf0e10cSrcweir { 503*cdf0e10cSrcweir if (pConventions[nConv] && 504*cdf0e10cSrcweir ((pConventions[nConv]->mpCharTable[ sal_uInt8(c) ] & nFlags) != nFlags)) 505*cdf0e10cSrcweir return false; 506*cdf0e10cSrcweir // convention not known => assume valid 507*cdf0e10cSrcweir } 508*cdf0e10cSrcweir return true; 509*cdf0e10cSrcweir } 510*cdf0e10cSrcweir else if (bTestLetterNumeric) 511*cdf0e10cSrcweir return ScGlobal::pCharClass->isLetterNumeric( rStr, nPos ); 512*cdf0e10cSrcweir else 513*cdf0e10cSrcweir return false; 514*cdf0e10cSrcweir } 515*cdf0e10cSrcweir 516*cdf0e10cSrcweir private: 517*cdf0e10cSrcweir // FormulaCompiler 518*cdf0e10cSrcweir virtual String FindAddInFunction( const String& rUpperName, sal_Bool bLocalFirst ) const; 519*cdf0e10cSrcweir virtual void fillFromAddInCollectionUpperName( NonConstOpCodeMapPtr xMap ) const; 520*cdf0e10cSrcweir virtual void fillFromAddInCollectionEnglishName( NonConstOpCodeMapPtr xMap ) const; 521*cdf0e10cSrcweir virtual void fillFromAddInMap( NonConstOpCodeMapPtr xMap, formula::FormulaGrammar::Grammar _eGrammar ) const; 522*cdf0e10cSrcweir virtual void fillAddInToken(::std::vector< ::com::sun::star::sheet::FormulaOpCodeMapEntry >& _rVec,bool _bIsEnglish) const; 523*cdf0e10cSrcweir 524*cdf0e10cSrcweir virtual sal_Bool HandleExternalReference(const formula::FormulaToken& _aToken); 525*cdf0e10cSrcweir virtual sal_Bool HandleRange(); 526*cdf0e10cSrcweir virtual sal_Bool HandleSingleRef(); 527*cdf0e10cSrcweir virtual sal_Bool HandleDbData(); 528*cdf0e10cSrcweir 529*cdf0e10cSrcweir virtual formula::FormulaTokenRef ExtendRangeReference( formula::FormulaToken & rTok1, formula::FormulaToken & rTok2, bool bReuseDoubleRef ); 530*cdf0e10cSrcweir virtual void CreateStringFromExternal(rtl::OUStringBuffer& rBuffer, formula::FormulaToken* pTokenP); 531*cdf0e10cSrcweir virtual void CreateStringFromSingleRef(rtl::OUStringBuffer& rBuffer,formula::FormulaToken* _pTokenP); 532*cdf0e10cSrcweir virtual void CreateStringFromDoubleRef(rtl::OUStringBuffer& rBuffer,formula::FormulaToken* _pTokenP); 533*cdf0e10cSrcweir virtual void CreateStringFromMatrix( rtl::OUStringBuffer& rBuffer, formula::FormulaToken* _pTokenP); 534*cdf0e10cSrcweir virtual void CreateStringFromIndex(rtl::OUStringBuffer& rBuffer,formula::FormulaToken* _pTokenP); 535*cdf0e10cSrcweir virtual void LocalizeString( String& rName ); // modify rName - input: exact name 536*cdf0e10cSrcweir virtual sal_Bool IsImportingXML() const; 537*cdf0e10cSrcweir 538*cdf0e10cSrcweir /// Access the CharTable flags 539*cdf0e10cSrcweir inline sal_uLong GetCharTableFlags( sal_Unicode c ) 540*cdf0e10cSrcweir { return c < 128 ? pConv->mpCharTable[ sal_uInt8(c) ] : 0; } 541*cdf0e10cSrcweir }; 542*cdf0e10cSrcweir 543*cdf0e10cSrcweir SC_DLLPUBLIC String GetScCompilerNativeSymbol( OpCode eOp ); //CHINA001 544*cdf0e10cSrcweir 545*cdf0e10cSrcweir #endif 546