1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: compiler.hxx,v $
10 * $Revision: 1.36.30.4 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 #ifndef SC_COMPILER_HXX
32 #define SC_COMPILER_HXX
34 #ifndef INCLUDED_STRING_H
36 #define INCLUDED_STRING_H
38 #include <tools/mempool.hxx>
41 #include "refdata.hxx"
42 #include "formula/token.hxx"
43 #include "formula/intruref.hxx"
44 #include "formula/grammar.hxx"
45 #include <unotools/charclass.hxx>
46 #include <rtl/ustrbuf.hxx>
47 #include <com/sun/star/sheet/ExternalLinkInfo.hpp>
50 #include <formula/FormulaCompiler.hxx>
53 #ifndef BOOST_SHARED_PTR_HPP_INCLUDED
54 #include <boost/shared_ptr.hpp>
57 #ifndef INCLUDED_HASH_MAP
59 #define INCLUDED_HASH_MAP
62 //-----------------------------------------------
64 // constants and data types also for external modules (ScInterpreter et al)
66 #define MAXCODE 512 /* maximum number of tokens in formula */
67 #define MAXSTRLEN 256 /* maximum length of input string of one symbol */
68 #define MAXJUMPCOUNT 32 /* maximum number of jumps (ocChose) */
70 // flag values of CharTable
71 #define SC_COMPILER_C_ILLEGAL 0x00000000
72 #define SC_COMPILER_C_CHAR 0x00000001
73 #define SC_COMPILER_C_CHAR_BOOL 0x00000002
74 #define SC_COMPILER_C_CHAR_WORD 0x00000004
75 #define SC_COMPILER_C_CHAR_VALUE 0x00000008
76 #define SC_COMPILER_C_CHAR_STRING 0x00000010
77 #define SC_COMPILER_C_CHAR_DONTCARE 0x00000020
78 #define SC_COMPILER_C_BOOL 0x00000040
79 #define SC_COMPILER_C_WORD 0x00000080
80 #define SC_COMPILER_C_WORD_SEP 0x00000100
81 #define SC_COMPILER_C_VALUE 0x00000200
82 #define SC_COMPILER_C_VALUE_SEP 0x00000400
83 #define SC_COMPILER_C_VALUE_EXP 0x00000800
84 #define SC_COMPILER_C_VALUE_SIGN 0x00001000
85 #define SC_COMPILER_C_VALUE_VALUE 0x00002000
86 #define SC_COMPILER_C_STRING_SEP 0x00004000
87 #define SC_COMPILER_C_NAME_SEP 0x00008000 // there can be only one! '\''
88 #define SC_COMPILER_C_CHAR_IDENT 0x00010000 // identifier (built-in function) or reference start
89 #define SC_COMPILER_C_IDENT 0x00020000 // identifier or reference continuation
90 #define SC_COMPILER_C_ODF_LBRACKET 0x00040000 // ODF '[' reference bracket
91 #define SC_COMPILER_C_ODF_RBRACKET 0x00080000 // ODF ']' reference bracket
92 #define SC_COMPILER_C_ODF_LABEL_OP 0x00100000 // ODF '!!' automatic intersection of labels
93 #define SC_COMPILER_C_ODF_NAME_MARKER 0x00200000 // ODF '$$' marker that starts a defined (range) name
95 #define SC_COMPILER_FILE_TAB_SEP '#' // 'Doc'#Tab
101 class ScExternalRefManager
;
104 // constants and data types internal to compiler
108 OpCode eOp; // OpCode
109 formula::StackVar eType; // type of data
110 USHORT nRefCnt; // reference count
111 BOOL bRaw; // not cloned yet and trimmed to real size
115 #define SC_TOKEN_FIX_MEMBERS \
117 formula::StackVar eType; \
121 struct ScDoubleRawToken
127 { // union only to assure alignment identical to ScRawToken
134 DECL_FIXEDMEMPOOL_NEWDEL( ScDoubleRawToken
);
139 friend class ScCompiler
;
140 // Friends that use a temporary ScRawToken on the stack (and therefor need
141 // the private dtor) and know what they're doing..
142 friend class ScTokenArray
;
143 friend USHORT
lcl_ScRawTokenOffset();
153 ScComplexRefData aRef
;
156 sal_Unicode cTabName
[MAXSTRLEN
+1];
157 ScComplexRefData aRef
;
161 sal_Unicode cName
[MAXSTRLEN
+1];
164 USHORT nIndex
; // index into name collection
165 sal_Unicode cStr
[ MAXSTRLEN
+1 ]; // string (up to 255 characters + 0)
166 short nJump
[MAXJUMPCOUNT
+1]; // If/Chose token
169 //! other members not initialized
170 ScRawToken() : bRaw( TRUE
) {}
172 ~ScRawToken() {} //! only delete via Delete()
174 DECL_FIXEDMEMPOOL_NEWDEL( ScRawToken
);
175 formula::StackVar
GetType() const { return (formula::StackVar
) eType
; }
176 OpCode
GetOpCode() const { return (OpCode
) eOp
; }
177 void NewOpCode( OpCode e
) { eOp
= e
; }
178 void IncRef() { nRefCnt
++; }
179 void DecRef() { if( !--nRefCnt
) Delete(); }
180 USHORT
GetRef() const { return nRefCnt
; }
181 SC_DLLPUBLIC
void Delete();
183 // Use these methods only on tokens that are not part of a token array,
184 // since the reference count is cleared!
185 void SetOpCode( OpCode eCode
);
186 void SetString( const sal_Unicode
* pStr
);
187 void SetSingleReference( const ScSingleRefData
& rRef
);
188 void SetDoubleReference( const ScComplexRefData
& rRef
);
189 void SetDouble( double fVal
);
190 //UNUSED2008-05 void SetInt( int nVal );
191 //UNUSED2008-05 void SetMatrix( ScMatrix* p );
193 // These methods are ok to use, reference count not cleared.
194 //UNUSED2008-05 ScComplexRefData& GetReference();
195 //UNUSED2008-05 void SetReference( ScComplexRefData& rRef );
196 void SetName( USHORT n
);
197 void SetExternalSingleRef( sal_uInt16 nFileId
, const String
& rTabName
, const ScSingleRefData
& rRef
);
198 void SetExternalDoubleRef( sal_uInt16 nFileId
, const String
& rTabName
, const ScComplexRefData
& rRef
);
199 void SetExternalName( sal_uInt16 nFileId
, const String
& rName
);
200 void SetMatrix( ScMatrix
* p
);
201 void SetExternal(const sal_Unicode
* pStr
);
203 ScRawToken
* Clone() const; // real copy!
204 formula::FormulaToken
* CreateToken() const; // create typified token
205 void Load( SvStream
&, USHORT nVer
);
207 static xub_StrLen
GetStrLen( const sal_Unicode
* pStr
); // as long as a "string" is an array
208 static size_t GetStrLenBytes( xub_StrLen nLen
)
209 { return nLen
* sizeof(sal_Unicode
); }
210 static size_t GetStrLenBytes( const sal_Unicode
* pStr
)
211 { return GetStrLenBytes( GetStrLen( pStr
) ); }
215 typedef formula::SimpleIntrusiveReference
< struct ScRawToken
> ScRawTokenRef
;
217 class SC_DLLPUBLIC ScCompiler
: public formula::FormulaCompiler
222 const formula::FormulaGrammar::AddressConvention meConv
;
223 const ULONG
* mpCharTable
;
226 Convention( formula::FormulaGrammar::AddressConvention eConvP
);
227 virtual ~Convention();
229 virtual void MakeRefStr( rtl::OUStringBuffer
& rBuffer
,
230 const ScCompiler
& rCompiler
,
231 const ScComplexRefData
& rRef
,
232 BOOL bSingleRef
) const = 0;
233 virtual ::com::sun::star::i18n::ParseResult
234 parseAnyToken( const String
& rFormula
,
236 const CharClass
* pCharClass
) const = 0;
239 * Parse the symbol string and pick up the file name and the external
242 * @return true on successful parse, or false otherwise.
244 virtual bool parseExternalName( const String
& rSymbol
, String
& rFile
, String
& rName
,
245 const ScDocument
* pDoc
,
246 const ::com::sun::star::uno::Sequence
<
247 const ::com::sun::star::sheet::ExternalLinkInfo
> * pExternalLinks
) const = 0;
249 virtual String
makeExternalNameStr( const String
& rFile
, const String
& rName
) const = 0;
251 virtual void makeExternalRefStr( ::rtl::OUStringBuffer
& rBuffer
, const ScCompiler
& rCompiler
,
252 sal_uInt16 nFileId
, const String
& rTabName
, const ScSingleRefData
& rRef
,
253 ScExternalRefManager
* pRefMgr
) const = 0;
255 virtual void makeExternalRefStr( ::rtl::OUStringBuffer
& rBuffer
, const ScCompiler
& rCompiler
,
256 sal_uInt16 nFileId
, const String
& rTabName
, const ScComplexRefData
& rRef
,
257 ScExternalRefManager
* pRefMgr
) const = 0;
259 enum SpecialSymbolType
262 * Character between sheet name and address. In OOO A1 this is
263 * '.', while XL A1 and XL R1C1 this is '!'.
268 * In OOO A1, a sheet name may be prefixed with '$' to indicate an
269 * absolute sheet position.
273 virtual sal_Unicode
getSpecialSymbol( SpecialSymbolType eSymType
) const = 0;
275 friend struct Convention
;
280 static CharClass
*pCharClassEnglish
; // character classification for en_US locale
281 static const Convention
*pConventions
[ formula::FormulaGrammar::CONV_LAST
];
283 static const Convention
* const pConvOOO_A1
;
284 static const Convention
* const pConvOOO_A1_ODF
;
285 static const Convention
* const pConvXL_A1
;
286 static const Convention
* const pConvXL_R1C1
;
287 static const Convention
* const pConvXL_OOX
;
289 static struct AddInMap
292 const char* pEnglish
;
293 bool bMapDupToInternal
; // when writing ODFF
294 const char* pOriginal
; // programmatical name
295 const char* pUpper
; // upper case programmatical name
297 static const AddInMap
* GetAddInMap();
298 static size_t GetAddInMapCount();
303 // For CONV_XL_OOX, may be set via API by MOOXML filter.
304 ::com::sun::star::uno::Sequence
< const ::com::sun::star::sheet::ExternalLinkInfo
> maExternalLinks
;
306 sal_Unicode cSymbol
[MAXSTRLEN
]; // current Symbol
307 String aFormula
; // formula source code
308 xub_StrLen nSrcPos
; // tokenizer position (source code)
309 ScRawTokenRef pRawToken
;
311 const CharClass
* pCharClass
; // which character classification is used for parseAnyToken
312 USHORT mnPredetectedReference
; // reference when reading ODF, 0 (none), 1 (single) or 2 (double)
313 SCsTAB nMaxTab
; // last sheet in document
314 const Convention
*pConv
;
315 bool mbCloseBrackets
; // whether to close open brackets automatically, default TRUE
316 bool mbExtendedErrorDetection
;
318 BOOL
NextNewToken(bool bInArray
= false);
320 virtual void SetError(USHORT nError
);
321 xub_StrLen
NextSymbol(bool bInArray
);
322 BOOL
IsValue( const String
& );
323 BOOL
IsOpCode( const String
&, bool bInArray
);
324 BOOL
IsOpCode2( const String
& );
326 BOOL
IsReference( const String
& );
327 BOOL
IsSingleReference( const String
& );
328 BOOL
IsPredetectedReference( const String
& );
329 BOOL
IsDoubleReference( const String
& );
330 BOOL
IsMacro( const String
& );
331 BOOL
IsNamedRange( const String
& );
332 bool IsExternalNamedRange( const String
& rSymbol
);
333 BOOL
IsDBRange( const String
& );
334 BOOL
IsColRowName( const String
& );
335 BOOL
IsBoolean( const String
& );
336 void AutoCorrectParsedSymbol();
338 void SetRelNameReference();
340 static void InitCharClassEnglish();
343 ScCompiler( ScDocument
* pDocument
, const ScAddress
&);
345 ScCompiler( ScDocument
* pDocument
, const ScAddress
&,ScTokenArray
& rArr
);
348 static void DeInit(); /// all
350 // for ScAddress::Format()
351 static void CheckTabQuotes( String
& aTabName
,
352 const formula::FormulaGrammar::AddressConvention eConv
= formula::FormulaGrammar::CONV_OOO
);
354 static BOOL
EnQuote( String
& rStr
);
356 sal_Unicode
GetNativeAddressSymbol( Convention::SpecialSymbolType eType
) const;
358 // Check if it is a valid english function name
359 bool IsEnglishSymbol( const String
& rName
);
361 //! _either_ CompileForFAP _or_ AutoCorrection, _not_ both
362 // #i101512# SetCompileForFAP is in formula::FormulaCompiler
363 void SetAutoCorrection( BOOL bVal
)
364 { bAutoCorrect
= bVal
; bIgnoreErrors
= bVal
; }
365 void SetCloseBrackets( bool bVal
) { mbCloseBrackets
= bVal
; }
366 void SetRefConvention( const Convention
*pConvP
);
367 void SetRefConvention( const formula::FormulaGrammar::AddressConvention eConv
);
369 /// Set symbol map if not empty.
370 void SetFormulaLanguage( const OpCodeMapPtr
& xMap
);
372 void SetGrammar( const formula::FormulaGrammar::Grammar eGrammar
);
375 /** Set grammar and reference convention from within SetFormulaLanguage()
379 The new grammar to be set and the associated reference convention.
382 The previous grammar that was active before SetFormulaLanguage().
384 void SetGrammarAndRefConvention(
385 const formula::FormulaGrammar::Grammar eNewGrammar
,
386 const formula::FormulaGrammar::Grammar eOldGrammar
);
389 /// Set external link info for ScAddress::CONV_XL_OOX.
390 inline void SetExternalLinks(
391 const ::com::sun::star::uno::Sequence
<
392 const ::com::sun::star::sheet::ExternalLinkInfo
> & rLinks
)
394 maExternalLinks
= rLinks
;
397 void SetExtendedErrorDetection( bool bVal
) { mbExtendedErrorDetection
= bVal
; }
399 BOOL
IsCorrected() { return bCorrected
; }
400 const String
& GetCorrectedFormula() { return aCorrectedFormula
; }
402 // Use convention from this->aPos by default
403 ScTokenArray
* CompileString( const String
& rFormula
);
404 const ScDocument
* GetDoc() const { return pDoc
; }
405 const ScAddress
& GetPos() const { return aPos
; }
408 static void MoveRelWrap( ScTokenArray
& rArr
, ScDocument
* pDoc
,
409 const ScAddress
& rPos
);
411 BOOL
UpdateNameReference( UpdateRefMode eUpdateRefMode
,
413 SCsCOL nDx
, SCsROW nDy
, SCsTAB nDz
,
414 BOOL
& rChanged
, BOOL bSharedFormula
= FALSE
);
416 ScRangeData
* UpdateReference( UpdateRefMode eUpdateRefMode
,
417 const ScAddress
& rOldPos
, const ScRange
&,
418 SCsCOL nDx
, SCsROW nDy
, SCsTAB nDz
,
419 BOOL
& rChanged
, BOOL
& rRefSizeChanged
);
421 /// Only once for converted shared formulas,
422 /// token array has to be compiled afterwards.
423 void UpdateSharedFormulaReference( UpdateRefMode eUpdateRefMode
,
424 const ScAddress
& rOldPos
, const ScRange
&,
425 SCsCOL nDx
, SCsROW nDy
, SCsTAB nDz
);
427 ScRangeData
* UpdateInsertTab(SCTAB nTable
, BOOL bIsName
);
428 ScRangeData
* UpdateDeleteTab(SCTAB nTable
, BOOL bIsMove
, BOOL bIsName
, BOOL
& bCompile
);
429 ScRangeData
* UpdateMoveTab(SCTAB nOldPos
, SCTAB nNewPos
, BOOL bIsName
);
431 BOOL
HasModifiedRange();
433 /// If the character is allowed as first character in sheet names or references
434 static inline BOOL
IsCharWordChar( String
const & rStr
,
436 const formula::FormulaGrammar::AddressConvention eConv
= formula::FormulaGrammar::CONV_OOO
)
438 sal_Unicode c
= rStr
.GetChar( nPos
);
441 (pConventions
[eConv
]->mpCharTable
[ UINT8(c
) ] & SC_COMPILER_C_CHAR_WORD
) == SC_COMPILER_C_CHAR_WORD
) :
442 ScGlobal::pCharClass
->isLetterNumeric( rStr
, nPos
);
445 /// If the character is allowed in sheet names or references
446 static inline BOOL
IsWordChar( String
const & rStr
,
448 const formula::FormulaGrammar::AddressConvention eConv
= formula::FormulaGrammar::CONV_OOO
)
450 sal_Unicode c
= rStr
.GetChar( nPos
);
453 (pConventions
[eConv
]->mpCharTable
[ UINT8(c
) ] & SC_COMPILER_C_WORD
) == SC_COMPILER_C_WORD
) :
454 ScGlobal::pCharClass
->isLetterNumeric( rStr
, nPos
);
459 virtual String
FindAddInFunction( const String
& rUpperName
, BOOL bLocalFirst
) const;
460 virtual void fillFromAddInCollectionUpperName( NonConstOpCodeMapPtr xMap
) const;
461 virtual void fillFromAddInCollectionEnglishName( NonConstOpCodeMapPtr xMap
) const;
462 virtual void fillFromAddInMap( NonConstOpCodeMapPtr xMap
, formula::FormulaGrammar::Grammar _eGrammar
) const;
463 virtual void fillAddInToken(::std::vector
< ::com::sun::star::sheet::FormulaOpCodeMapEntry
>& _rVec
,bool _bIsEnglish
) const;
465 virtual BOOL
HandleExternalReference(const formula::FormulaToken
& _aToken
);
466 virtual BOOL
HandleRange();
467 virtual BOOL
HandleSingleRef();
468 virtual BOOL
HandleDbData();
470 virtual formula::FormulaTokenRef
ExtendRangeReference( formula::FormulaToken
& rTok1
, formula::FormulaToken
& rTok2
, bool bReuseDoubleRef
);
471 virtual void CreateStringFromExternal(rtl::OUStringBuffer
& rBuffer
, formula::FormulaToken
* pTokenP
);
472 virtual void CreateStringFromSingleRef(rtl::OUStringBuffer
& rBuffer
,formula::FormulaToken
* _pTokenP
);
473 virtual void CreateStringFromDoubleRef(rtl::OUStringBuffer
& rBuffer
,formula::FormulaToken
* _pTokenP
);
474 virtual void CreateStringFromMatrix( rtl::OUStringBuffer
& rBuffer
, formula::FormulaToken
* _pTokenP
);
475 virtual void CreateStringFromIndex(rtl::OUStringBuffer
& rBuffer
,formula::FormulaToken
* _pTokenP
);
476 virtual void LocalizeString( String
& rName
); // modify rName - input: exact name
477 virtual BOOL
IsImportingXML() const;
479 /// Access the CharTable flags
480 inline ULONG
GetCharTableFlags( sal_Unicode c
)
481 { return c
< 128 ? pConv
->mpCharTable
[ UINT8(c
) ] : 0; }
484 SC_DLLPUBLIC String
GetScCompilerNativeSymbol( OpCode eOp
); //CHINA001