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 sal_Int32 mnRangeOpPosInSymbol
; // if and where a range operator is in symbol
315 const Convention
*pConv
;
316 bool mbCloseBrackets
; // whether to close open brackets automatically, default TRUE
317 bool mbExtendedErrorDetection
;
318 bool mbRewind
; // whether symbol is to be rewound to some step during lexical analysis
320 BOOL
NextNewToken(bool bInArray
= false);
322 virtual void SetError(USHORT nError
);
323 xub_StrLen
NextSymbol(bool bInArray
);
324 BOOL
IsValue( const String
& );
325 BOOL
IsOpCode( const String
&, bool bInArray
);
326 BOOL
IsOpCode2( const String
& );
328 BOOL
IsReference( const String
& );
329 BOOL
IsSingleReference( const String
& );
330 BOOL
IsPredetectedReference( const String
& );
331 BOOL
IsDoubleReference( const String
& );
332 BOOL
IsMacro( const String
& );
333 BOOL
IsNamedRange( const String
& );
334 bool IsExternalNamedRange( const String
& rSymbol
);
335 BOOL
IsDBRange( const String
& );
336 BOOL
IsColRowName( const String
& );
337 BOOL
IsBoolean( const String
& );
338 void AutoCorrectParsedSymbol();
340 void SetRelNameReference();
342 static void InitCharClassEnglish();
345 ScCompiler( ScDocument
* pDocument
, const ScAddress
&);
347 ScCompiler( ScDocument
* pDocument
, const ScAddress
&,ScTokenArray
& rArr
);
350 static void DeInit(); /// all
352 // for ScAddress::Format()
353 static void CheckTabQuotes( String
& aTabName
,
354 const formula::FormulaGrammar::AddressConvention eConv
= formula::FormulaGrammar::CONV_OOO
);
356 static BOOL
EnQuote( String
& rStr
);
357 sal_Unicode
GetNativeAddressSymbol( Convention::SpecialSymbolType eType
) const;
360 // Check if it is a valid english function name
361 bool IsEnglishSymbol( const String
& rName
);
363 //! _either_ CompileForFAP _or_ AutoCorrection, _not_ both
364 // #i101512# SetCompileForFAP is in formula::FormulaCompiler
365 void SetAutoCorrection( BOOL bVal
)
366 { bAutoCorrect
= bVal
; bIgnoreErrors
= bVal
; }
367 void SetCloseBrackets( bool bVal
) { mbCloseBrackets
= bVal
; }
368 void SetRefConvention( const Convention
*pConvP
);
369 void SetRefConvention( const formula::FormulaGrammar::AddressConvention eConv
);
371 /// Set symbol map if not empty.
372 void SetFormulaLanguage( const OpCodeMapPtr
& xMap
);
374 void SetGrammar( const formula::FormulaGrammar::Grammar eGrammar
);
377 /** Set grammar and reference convention from within SetFormulaLanguage()
381 The new grammar to be set and the associated reference convention.
384 The previous grammar that was active before SetFormulaLanguage().
386 void SetGrammarAndRefConvention(
387 const formula::FormulaGrammar::Grammar eNewGrammar
,
388 const formula::FormulaGrammar::Grammar eOldGrammar
);
391 /// Set external link info for ScAddress::CONV_XL_OOX.
392 inline void SetExternalLinks(
393 const ::com::sun::star::uno::Sequence
<
394 const ::com::sun::star::sheet::ExternalLinkInfo
> & rLinks
)
396 maExternalLinks
= rLinks
;
399 void CreateStringFromXMLTokenArray( String
& rFormula
, String
& rFormulaNmsp
);
401 void SetExtendedErrorDetection( bool bVal
) { mbExtendedErrorDetection
= bVal
; }
403 BOOL
IsCorrected() { return bCorrected
; }
404 const String
& GetCorrectedFormula() { return aCorrectedFormula
; }
406 // Use convention from this->aPos by default
407 ScTokenArray
* CompileString( const String
& rFormula
);
408 ScTokenArray
* CompileString( const String
& rFormula
, const String
& rFormulaNmsp
);
409 const ScDocument
* GetDoc() const { return pDoc
; }
410 const ScAddress
& GetPos() const { return aPos
; }
412 void MoveRelWrap( SCCOL nMaxCol
, SCROW nMaxRow
);
413 static void MoveRelWrap( ScTokenArray
& rArr
, ScDocument
* pDoc
, const ScAddress
& rPos
,
414 SCCOL nMaxCol
, SCROW nMaxRow
);
416 BOOL
UpdateNameReference( UpdateRefMode eUpdateRefMode
,
418 SCsCOL nDx
, SCsROW nDy
, SCsTAB nDz
,
419 BOOL
& rChanged
, BOOL bSharedFormula
= FALSE
);
421 ScRangeData
* UpdateReference( UpdateRefMode eUpdateRefMode
,
422 const ScAddress
& rOldPos
, const ScRange
&,
423 SCsCOL nDx
, SCsROW nDy
, SCsTAB nDz
,
424 BOOL
& rChanged
, BOOL
& rRefSizeChanged
);
426 /// Only once for converted shared formulas,
427 /// token array has to be compiled afterwards.
428 void UpdateSharedFormulaReference( UpdateRefMode eUpdateRefMode
,
429 const ScAddress
& rOldPos
, const ScRange
&,
430 SCsCOL nDx
, SCsROW nDy
, SCsTAB nDz
);
432 ScRangeData
* UpdateInsertTab(SCTAB nTable
, BOOL bIsName
);
433 ScRangeData
* UpdateDeleteTab(SCTAB nTable
, BOOL bIsMove
, BOOL bIsName
, BOOL
& bCompile
);
434 ScRangeData
* UpdateMoveTab(SCTAB nOldPos
, SCTAB nNewPos
, BOOL bIsName
);
436 BOOL
HasModifiedRange();
438 /// If the character is allowed as first character in sheet names or references
439 static inline BOOL
IsCharWordChar( String
const & rStr
,
441 const formula::FormulaGrammar::AddressConvention eConv
= formula::FormulaGrammar::CONV_OOO
)
443 sal_Unicode c
= rStr
.GetChar( nPos
);
446 (pConventions
[eConv
]->mpCharTable
[ UINT8(c
) ] & SC_COMPILER_C_CHAR_WORD
) == SC_COMPILER_C_CHAR_WORD
) :
447 ScGlobal::pCharClass
->isLetterNumeric( rStr
, nPos
);
450 /// If the character is allowed in sheet names or references
451 static inline BOOL
IsWordChar( String
const & rStr
,
453 const formula::FormulaGrammar::AddressConvention eConv
= formula::FormulaGrammar::CONV_OOO
)
455 sal_Unicode c
= rStr
.GetChar( nPos
);
458 (pConventions
[eConv
]->mpCharTable
[ UINT8(c
) ] & SC_COMPILER_C_WORD
) == SC_COMPILER_C_WORD
) :
459 ScGlobal::pCharClass
->isLetterNumeric( rStr
, nPos
);
464 virtual String
FindAddInFunction( const String
& rUpperName
, BOOL bLocalFirst
) const;
465 virtual void fillFromAddInCollectionUpperName( NonConstOpCodeMapPtr xMap
) const;
466 virtual void fillFromAddInCollectionEnglishName( NonConstOpCodeMapPtr xMap
) const;
467 virtual void fillFromAddInMap( NonConstOpCodeMapPtr xMap
, formula::FormulaGrammar::Grammar _eGrammar
) const;
468 virtual void fillAddInToken(::std::vector
< ::com::sun::star::sheet::FormulaOpCodeMapEntry
>& _rVec
,bool _bIsEnglish
) const;
470 virtual BOOL
HandleExternalReference(const formula::FormulaToken
& _aToken
);
471 virtual BOOL
HandleRange();
472 virtual BOOL
HandleSingleRef();
473 virtual BOOL
HandleDbData();
475 virtual formula::FormulaTokenRef
ExtendRangeReference( formula::FormulaToken
& rTok1
, formula::FormulaToken
& rTok2
, bool bReuseDoubleRef
);
476 virtual void CreateStringFromExternal(rtl::OUStringBuffer
& rBuffer
, formula::FormulaToken
* pTokenP
);
477 virtual void CreateStringFromSingleRef(rtl::OUStringBuffer
& rBuffer
,formula::FormulaToken
* _pTokenP
);
478 virtual void CreateStringFromDoubleRef(rtl::OUStringBuffer
& rBuffer
,formula::FormulaToken
* _pTokenP
);
479 virtual void CreateStringFromMatrix( rtl::OUStringBuffer
& rBuffer
, formula::FormulaToken
* _pTokenP
);
480 virtual void CreateStringFromIndex(rtl::OUStringBuffer
& rBuffer
,formula::FormulaToken
* _pTokenP
);
481 virtual void LocalizeString( String
& rName
); // modify rName - input: exact name
482 virtual BOOL
IsImportingXML() const;
484 /// Access the CharTable flags
485 inline ULONG
GetCharTableFlags( sal_Unicode c
)
486 { return c
< 128 ? pConv
->mpCharTable
[ UINT8(c
) ] : 0; }
489 SC_DLLPUBLIC String
GetScCompilerNativeSymbol( OpCode eOp
); //CHINA001