/src/libreoffice/sc/inc/compiler.hxx
Line | Count | Source |
1 | | /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ |
2 | | /* |
3 | | * This file is part of the LibreOffice project. |
4 | | * |
5 | | * This Source Code Form is subject to the terms of the Mozilla Public |
6 | | * License, v. 2.0. If a copy of the MPL was not distributed with this |
7 | | * file, You can obtain one at http://mozilla.org/MPL/2.0/. |
8 | | * |
9 | | * This file incorporates work covered by the following license notice: |
10 | | * |
11 | | * Licensed to the Apache Software Foundation (ASF) under one or more |
12 | | * contributor license agreements. See the NOTICE file distributed |
13 | | * with this work for additional information regarding copyright |
14 | | * ownership. The ASF licenses this file to you under the Apache |
15 | | * License, Version 2.0 (the "License"); you may not use this file |
16 | | * except in compliance with the License. You may obtain a copy of |
17 | | * the License at http://www.apache.org/licenses/LICENSE-2.0 . |
18 | | */ |
19 | | |
20 | | #pragma once |
21 | | |
22 | | #include <string.h> |
23 | | |
24 | | #include "scdllapi.h" |
25 | | #include "global.hxx" |
26 | | #include "refdata.hxx" |
27 | | #include "token.hxx" |
28 | | #include <formula/token.hxx> |
29 | | #include <formula/grammar.hxx> |
30 | | #include <rtl/ustrbuf.hxx> |
31 | | #include <com/sun/star/sheet/ExternalLinkInfo.hpp> |
32 | | #include <com/sun/star/i18n/ParseResult.hpp> |
33 | | #include <queue> |
34 | | #include <vector> |
35 | | #include <memory> |
36 | | #include <unordered_set> |
37 | | #include <set> |
38 | | #include <com/sun/star/uno/Sequence.hxx> |
39 | | #include <o3tl/typed_flags_set.hxx> |
40 | | |
41 | | #include <formula/FormulaCompiler.hxx> |
42 | | |
43 | | struct ScSheetLimits; |
44 | | |
45 | | // constants and data types also for external modules (ScInterpreter et al) |
46 | | |
47 | 35.4M | #define MAXSTRLEN 1024 /* maximum length of input string of one symbol */ |
48 | | |
49 | | // flag values of CharTable |
50 | | enum class ScCharFlags : sal_uInt32 { |
51 | | NONE = 0x00000000, |
52 | | Illegal = 0x00000000, |
53 | | Char = 0x00000001, |
54 | | CharBool = 0x00000002, |
55 | | CharWord = 0x00000004, |
56 | | CharValue = 0x00000008, |
57 | | CharString = 0x00000010, |
58 | | CharDontCare = 0x00000020, |
59 | | Bool = 0x00000040, |
60 | | Word = 0x00000080, |
61 | | WordSep = 0x00000100, |
62 | | Value = 0x00000200, |
63 | | ValueSep = 0x00000400, |
64 | | ValueExp = 0x00000800, |
65 | | ValueSign = 0x00001000, |
66 | | ValueValue = 0x00002000, |
67 | | StringSep = 0x00004000, |
68 | | NameSep = 0x00008000, // there can be only one! '\'' |
69 | | CharIdent = 0x00010000, // identifier (built-in function) or reference start |
70 | | Ident = 0x00020000, // identifier or reference continuation |
71 | | OdfLBracket = 0x00040000, // ODF '[' reference bracket |
72 | | OdfRBracket = 0x00080000, // ODF ']' reference bracket |
73 | | OdfLabelOp = 0x00100000, // ODF '!!' automatic intersection of labels |
74 | | OdfNameMarker = 0x00200000, // ODF '$$' marker that starts a defined (range) name |
75 | | CharName = 0x00400000, // start character of a defined name |
76 | | Name = 0x00800000, // continuation character of a defined name |
77 | | CharErrConst = 0x01000000, // start character of an error constant ('#') |
78 | | }; |
79 | | namespace o3tl { |
80 | | template<> struct typed_flags<ScCharFlags> : is_typed_flags<ScCharFlags, 0x01ffffff> {}; |
81 | | } |
82 | | |
83 | 2.29M | #define SC_COMPILER_FILE_TAB_SEP '#' // 'Doc'#Tab |
84 | | |
85 | | class ScDocument; |
86 | | class ScMatrix; |
87 | | class ScRangeData; |
88 | | class ScTokenArray; |
89 | | struct ScInterpreterContext; |
90 | | class CharClass; |
91 | | |
92 | | namespace sc { |
93 | | |
94 | | class CompileFormulaContext; |
95 | | |
96 | | } |
97 | | |
98 | | // constants and data types internal to compiler |
99 | | |
100 | | struct ScRawToken final |
101 | | { |
102 | | friend class ScCompiler; |
103 | | // Friends that use a temporary ScRawToken on the stack (and therefore need |
104 | | // the private dtor) and know what they're doing... |
105 | | friend class ScTokenArray; |
106 | | OpCode eOp; |
107 | | formula::StackVar eType; // type of data; this determines how the unions are used |
108 | | public: |
109 | | union { |
110 | | double nValue; |
111 | | struct { |
112 | | sal_uInt8 nCount; |
113 | | sal_Unicode cChar; |
114 | | } whitespace; |
115 | | struct { |
116 | | sal_uInt8 cByte; |
117 | | formula::ParamClass eInForceArray; |
118 | | } sbyte; |
119 | | ScComplexRefData aRef; |
120 | | struct { |
121 | | sal_uInt16 nFileId; |
122 | | ScComplexRefData aRef; |
123 | | } extref; |
124 | | struct { |
125 | | sal_uInt16 nFileId; |
126 | | } extname; |
127 | | struct { |
128 | | sal_Int16 nSheet; |
129 | | sal_uInt16 nIndex; |
130 | | } name; |
131 | | struct { |
132 | | sal_uInt16 nIndex; |
133 | | ScTableRefToken::Item eItem; |
134 | | } table; |
135 | | struct { |
136 | | rtl_uString* mpData; |
137 | | rtl_uString* mpDataIgnoreCase; |
138 | | } sharedstring; |
139 | | ScMatrix* pMat; |
140 | | FormulaError nError; |
141 | | short nJump[ FORMULA_MAXPARAMS + 1 ]; // If/Choose/Let/Lambda token |
142 | | }; |
143 | | OUString maExternalName; // depending on the opcode, this is either the external, or the external name, or the external table name |
144 | | |
145 | | // coverity[uninit_member] - members deliberately not initialized |
146 | 16.1M | ScRawToken() {} |
147 | | private: |
148 | 16.1M | ~ScRawToken() {} //! only delete via Delete() |
149 | | public: |
150 | 23.2M | formula::StackVar GetType() const { return eType; } |
151 | 25.2M | OpCode GetOpCode() const { return eOp; } |
152 | 2.56M | void NewOpCode( OpCode e ) { eOp = e; } |
153 | | |
154 | | // Use these methods only on tokens that are not part of a token array, |
155 | | // since the reference count is cleared! |
156 | | void SetOpCode( OpCode eCode ); |
157 | | void SetString( rtl_uString* pData, rtl_uString* pDataIgnoreCase ); |
158 | | void SetStringName( rtl_uString* pData, rtl_uString* pDataIgnoreCase ); |
159 | | void SetDPFieldName( rtl_uString* pData, rtl_uString* pDataIgnoreCase ); |
160 | | void SetSingleReference( const ScSingleRefData& rRef ); |
161 | | void SetDoubleReference( const ScComplexRefData& rRef ); |
162 | | void SetDouble( double fVal ); |
163 | | void SetErrorConstant( FormulaError nErr ); |
164 | | |
165 | | // These methods are ok to use, reference count not cleared. |
166 | | void SetName(sal_Int16 nSheet, sal_uInt16 nIndex); |
167 | | void SetExternalSingleRef( sal_uInt16 nFileId, const OUString& rTabName, const ScSingleRefData& rRef ); |
168 | | void SetExternalDoubleRef( sal_uInt16 nFileId, const OUString& rTabName, const ScComplexRefData& rRef ); |
169 | | void SetExternalName( sal_uInt16 nFileId, const OUString& rName ); |
170 | | void SetExternal(const OUString& rStr, OpCode eCode = ocExternal); |
171 | | |
172 | | /** If the token is a non-external reference, determine if the reference is |
173 | | valid. If the token is an external reference, return true. Else return |
174 | | false. Used only in ScCompiler::NextNewToken() to preserve non-existing |
175 | | sheet names in otherwise valid references. |
176 | | */ |
177 | | bool IsValidReference(const ScDocument& rDoc) const; |
178 | | |
179 | | formula::FormulaToken* CreateToken(ScSheetLimits& rLimits) const; // create typified token |
180 | | }; |
181 | | |
182 | | class SAL_DLLPUBLIC_RTTI ScCompiler final : public formula::FormulaCompiler |
183 | | { |
184 | | public: |
185 | | |
186 | | enum ExtendedErrorDetection |
187 | | { |
188 | | EXTENDED_ERROR_DETECTION_NONE = 0, // no error on unknown symbols, default (interpreter handles it) |
189 | | EXTENDED_ERROR_DETECTION_NAME_BREAK, // name error on unknown symbols and break, pCode incomplete |
190 | | EXTENDED_ERROR_DETECTION_NAME_NO_BREAK // name error on unknown symbols, don't break, continue |
191 | | }; |
192 | | |
193 | | struct Convention |
194 | | { |
195 | | const formula::FormulaGrammar::AddressConvention meConv; |
196 | | |
197 | | Convention( formula::FormulaGrammar::AddressConvention eConvP ); |
198 | | virtual ~Convention(); |
199 | | |
200 | | virtual void makeRefStr( |
201 | | ScSheetLimits& rLimits, |
202 | | OUStringBuffer& rBuffer, |
203 | | formula::FormulaGrammar::Grammar eGram, |
204 | | const ScAddress& rPos, |
205 | | const OUString& rErrRef, const std::vector<OUString>& rTabNames, |
206 | | const ScComplexRefData& rRef, bool bSingleRef, bool bFromRangeName ) const = 0; |
207 | | |
208 | | virtual css::i18n::ParseResult |
209 | | parseAnyToken( const OUString& rFormula, |
210 | | sal_Int32 nSrcPos, |
211 | | const CharClass* pCharClass, |
212 | | bool bGroupSeparator) const = 0; |
213 | | |
214 | | /** |
215 | | * Parse the symbol string and pick up the file name and the external |
216 | | * range name. |
217 | | * |
218 | | * @return true on successful parse, or false otherwise. |
219 | | */ |
220 | | virtual bool parseExternalName( const OUString& rSymbol, OUString& rFile, OUString& rName, |
221 | | const ScDocument& rDoc, |
222 | | const css::uno::Sequence< css::sheet::ExternalLinkInfo>* pExternalLinks ) const = 0; |
223 | | |
224 | | virtual OUString makeExternalNameStr( sal_uInt16 nFileId, const OUString& rFile, |
225 | | const OUString& rName ) const = 0; |
226 | | |
227 | | virtual void makeExternalRefStr( |
228 | | ScSheetLimits& rLimits, |
229 | | OUStringBuffer& rBuffer, const ScAddress& rPos, sal_uInt16 nFileId, const OUString& rFileName, |
230 | | const OUString& rTabName, const ScSingleRefData& rRef ) const = 0; |
231 | | |
232 | | virtual void makeExternalRefStr( |
233 | | ScSheetLimits& rLimits, |
234 | | OUStringBuffer& rBuffer, const ScAddress& rPos, |
235 | | sal_uInt16 nFileId, const OUString& rFileName, const std::vector<OUString>& rTabNames, |
236 | | const OUString& rTabName, const ScComplexRefData& rRef ) const = 0; |
237 | | |
238 | | enum SpecialSymbolType |
239 | | { |
240 | | /** |
241 | | * Character between sheet name and address. In OOO A1 this is |
242 | | * '.', while XL A1 and XL R1C1 this is '!'. |
243 | | */ |
244 | | SHEET_SEPARATOR, |
245 | | |
246 | | /** |
247 | | * In OOO A1, a sheet name may be prefixed with '$' to indicate an |
248 | | * absolute sheet position. |
249 | | */ |
250 | | ABS_SHEET_PREFIX |
251 | | }; |
252 | | virtual sal_Unicode getSpecialSymbol( SpecialSymbolType eSymType ) const = 0; |
253 | | |
254 | | virtual ScCharFlags getCharTableFlags( sal_Unicode c, sal_Unicode cLast ) const = 0; |
255 | | |
256 | | protected: |
257 | | const std::array<ScCharFlags, 128>& mrCharTable; |
258 | | }; |
259 | | friend struct Convention; |
260 | | |
261 | | private: |
262 | | |
263 | | static const CharClass *pCharClassEnglish; // character classification for en_US locale |
264 | | static const CharClass *pCharClassLocalized; // character classification for UI locale |
265 | | static const Convention *pConventions[ formula::FormulaGrammar::CONV_LAST ]; |
266 | | |
267 | | static const struct AddInMap |
268 | | { |
269 | | const char* pODFF; |
270 | | const char* pEnglish; |
271 | | const char* pOriginal; // programmatical name |
272 | | const char* pUpper; // upper case programmatical name |
273 | | } g_aAddInMap[]; |
274 | | static size_t GetAddInMapCount(); |
275 | | |
276 | | ScDocument& rDoc; |
277 | | ScAddress aPos; |
278 | | |
279 | | ScInterpreterContext& mrInterpreterContext; |
280 | | |
281 | | SCTAB mnCurrentSheetTab; // indicates current sheet number parsed so far |
282 | | sal_Int32 mnCurrentSheetEndPos; // position after current sheet name if parsed |
283 | | |
284 | | // For CONV_XL_OOX, may be set via API by MOOXML filter. |
285 | | css::uno::Sequence<css::sheet::ExternalLinkInfo> maExternalLinks; |
286 | | |
287 | | sal_Unicode cSymbol[MAXSTRLEN+1]; // current Symbol + 0 |
288 | | OUString aFormula; // formula source code |
289 | | sal_Int32 nSrcPos; // tokenizer position (source code) |
290 | | ScRawToken maRawToken; |
291 | | |
292 | | std::queue<OpCode> maPendingOpCodes; // additional opcodes generated from a single symbol |
293 | | |
294 | | const CharClass* pCharClass; // which character classification is used for parseAnyToken and upper/lower |
295 | | bool mbCharClassesDiffer; // whether pCharClass and current system locale's CharClass differ |
296 | | sal_uInt16 mnPredetectedReference; // reference when reading ODF, 0 (none), 1 (single) or 2 (double) |
297 | | sal_Int32 mnRangeOpPosInSymbol; // if and where a range operator is in symbol |
298 | | const Convention *pConv; |
299 | | ExtendedErrorDetection meExtendedErrorDetection; |
300 | | bool mbCloseBrackets; // whether to close open brackets automatically, default TRUE |
301 | | bool mbRewind; // whether symbol is to be rewound to some step during lexical analysis |
302 | | bool mbRefConventionChartOOXML; // whether to use special ooxml chart syntax in case of OOXML reference convention, |
303 | | // when parsing a formula string. [0]!GlobalNamedRange, LocalSheet!LocalNamedRange |
304 | | bool mbOptionalLocalName = false; // true when the local name just resolved was a LAMBDA optional |
305 | | // parameter, written with the _xlop. prefix instead of _xlpm. |
306 | | std::vector<sal_uInt16> maExternalFiles; |
307 | | |
308 | | std::vector<OUString> maTabNames; /// sheet names mangled for the current grammar for output |
309 | | std::vector<OUString> maPivotFieldNames; /// Available Pivot Table Field names for calculation of pivot table formulas |
310 | | std::vector<OUString> &GetSetupTabNames() const; /// get or setup tab names for the current grammar |
311 | | |
312 | | struct TableRefEntry |
313 | | { |
314 | | boost::intrusive_ptr<ScTableRefToken> mxToken; |
315 | | sal_uInt16 mnLevel; |
316 | 661 | TableRefEntry( ScTableRefToken* p ) : mxToken(p), mnLevel(0) {} |
317 | | }; |
318 | | std::vector<TableRefEntry> maTableRefs; /// "stack" of currently active ocTableRef tokens |
319 | | |
320 | | // Optimizing implicit intersection is done only at the end of code generation, because the usage context may |
321 | | // be important. Store candidate parameters and the operation they are the argument for. |
322 | | struct PendingImplicitIntersectionOptimization |
323 | | { |
324 | | PendingImplicitIntersectionOptimization(formula::FormulaToken** p, formula::FormulaToken* o) |
325 | 366k | : parameterLocation( p ), parameter( *p ), operation( o ) {} |
326 | | formula::FormulaToken** parameterLocation; |
327 | | formula::FormulaTokenRef parameter; |
328 | | formula::FormulaTokenRef operation; |
329 | | }; |
330 | | std::vector< PendingImplicitIntersectionOptimization > mPendingImplicitIntersectionOptimizations; |
331 | | std::unordered_set<formula::FormulaTokenRef> mUnhandledPossibleImplicitIntersections; |
332 | | #ifdef DBG_UTIL |
333 | | std::set<OpCode> mUnhandledPossibleImplicitIntersectionsOpCodes; |
334 | | #endif |
335 | | |
336 | | bool NextNewToken(bool bInArray); |
337 | | bool ToUpperAsciiOrI18nIsAscii( OUString& rUpper, const OUString& rOrg ) const; |
338 | | short GetPossibleParaCount( std::u16string_view rLambdaFormula ) const; |
339 | | |
340 | | virtual void SetError(FormulaError nError) override; |
341 | | |
342 | | struct Whitespace final |
343 | | { |
344 | | sal_Int32 nCount; |
345 | | sal_Unicode cChar; |
346 | | |
347 | 10.6M | Whitespace() : nCount(0), cChar(0x20) {} |
348 | 60.0k | void reset( sal_Unicode c ) { nCount = 0; cChar = c; } |
349 | | }; |
350 | | |
351 | | static void addWhitespace( std::vector<ScCompiler::Whitespace> & rvSpaces, |
352 | | ScCompiler::Whitespace & rSpace, sal_Unicode c, sal_Int32 n = 1 ); |
353 | | |
354 | | std::vector<Whitespace> NextSymbol(bool bInArray); |
355 | | |
356 | | bool ParseValue( const OUString&, bool bInArray = false ); |
357 | | bool ParseOpCode( const OUString&, bool bInArray ); |
358 | | bool ParseOpCode2( std::u16string_view ); |
359 | | bool ParseLiteralString(); |
360 | | bool ParseReference( const OUString& rSymbol, const OUString* pErrRef = nullptr ); |
361 | | bool ParseSingleReference( const OUString& rSymbol, const OUString* pErrRef = nullptr ); |
362 | | bool ParseDoubleReference( const OUString& rSymbol, const OUString* pErrRef = nullptr ); |
363 | | bool ParsePredetectedReference( const OUString& rSymbol ); |
364 | | bool ParsePredetectedErrRefReference( const OUString& rName, const OUString* pErrRef ); |
365 | | bool ParseMacro( const OUString& ); |
366 | | bool ParseNamedRange( const OUString&, bool onlyCheck = false ); |
367 | | bool ParseLocalName( const OUString& ); |
368 | | bool ParseExternalNamedRange( const OUString& rSymbol, bool& rbInvalidExternalNameRange ); |
369 | | bool ParseDBRange( const OUString& ); |
370 | | bool ParseDPFieldName( const OUString& ); |
371 | | bool ParseColRowName( const OUString& ); |
372 | | void AutoCorrectParsedSymbol(); |
373 | | const ScRangeData* GetRangeData( SCTAB& rSheet, const OUString& rUpperName ) const; |
374 | | |
375 | | void AdjustSheetLocalNameRelReferences( SCTAB nDelta ); |
376 | | void SetRelNameReference(); |
377 | | |
378 | | /** Obtain range data for ocName token, global or sheet local. |
379 | | */ |
380 | | ScRangeData* GetRangeData( const formula::FormulaIndexToken& pToken ) const; |
381 | | |
382 | | bool HasPossibleNamedRangeConflict(SCTAB nTab) const; |
383 | | |
384 | | public: |
385 | | static const CharClass* GetCharClassLocalized(); |
386 | | static const CharClass* GetCharClassEnglish(); |
387 | | |
388 | | public: |
389 | | ScCompiler( sc::CompileFormulaContext& rCxt, const ScAddress& rPos, |
390 | | bool bComputeII = false, bool bMatrixFlag = false, ScInterpreterContext* pContext = nullptr ); |
391 | | |
392 | | /** If eGrammar == GRAM_UNSPECIFIED then the grammar of rDocument is used, |
393 | | */ |
394 | | SC_DLLPUBLIC ScCompiler( ScDocument& rDocument, const ScAddress&, |
395 | | formula::FormulaGrammar::Grammar eGrammar = formula::FormulaGrammar::GRAM_UNSPECIFIED, |
396 | | bool bComputeII = false, bool bMatrixFlag = false, ScInterpreterContext* pContext = nullptr ); |
397 | | |
398 | | SC_DLLPUBLIC ScCompiler( sc::CompileFormulaContext& rCxt, const ScAddress& rPos, ScTokenArray& rArr, |
399 | | bool bComputeII = false, bool bMatrixFlag = false, ScInterpreterContext* pContext = nullptr ); |
400 | | |
401 | | /** If eGrammar == GRAM_UNSPECIFIED then the grammar of rDocument is used, |
402 | | */ |
403 | | SC_DLLPUBLIC ScCompiler( ScDocument& rDocument, const ScAddress&, ScTokenArray& rArr, |
404 | | formula::FormulaGrammar::Grammar eGrammar = formula::FormulaGrammar::GRAM_UNSPECIFIED, |
405 | | bool bComputeII = false, bool bMatrixFlag = false, ScInterpreterContext* pContext = nullptr ); |
406 | | |
407 | | SC_DLLPUBLIC virtual ~ScCompiler() override; |
408 | | |
409 | | public: |
410 | | static void DeInit(); /// all |
411 | | |
412 | | // for ScAddress::Format() |
413 | | SC_DLLPUBLIC static void CheckTabQuotes( OUString& aTabName, |
414 | | const formula::FormulaGrammar::AddressConvention eConv = formula::FormulaGrammar::CONV_OOO ); |
415 | | |
416 | | /** Concatenates two sheet names in Excel syntax, i.e. 'Sheet1:Sheet2' |
417 | | instead of 'Sheet1':'Sheet2' or 'Sheet1':Sheet2 or Sheet1:'Sheet2'. |
418 | | |
419 | | @param rBuf |
420 | | Contains the first sheet name already, in the correct quoted 'Sheet''1' or |
421 | | unquoted Sheet1 form if plain name. |
422 | | |
423 | | @param nQuotePos |
424 | | Start position, of the first sheet name if unquoted, or its |
425 | | opening quote. |
426 | | |
427 | | @param rEndTabName |
428 | | Second sheet name to append, in the correct quoted 'Sheet''2' |
429 | | or unquoted Sheet2 form if plain name. |
430 | | */ |
431 | | static void FormExcelSheetRange( OUStringBuffer& rBuf, sal_Int32 nQuotePos, const OUString& rEndTabName ); |
432 | | |
433 | | /** Analyzes a string for a 'Doc'#Tab construct, or 'Do''c'#Tab etc... |
434 | | |
435 | | @returns the position of the unquoted # hash mark in 'Doc'#Tab, or |
436 | | -1 if none. */ |
437 | | static sal_Int32 GetDocTabPos( const OUString& rString ); |
438 | | |
439 | | // Check if it is a valid english function name |
440 | | SC_DLLPUBLIC static bool IsEnglishSymbol( const OUString& rName ); |
441 | | |
442 | | bool ParseErrorConstant( const OUString& ); |
443 | | bool ParseTableRefItem( const OUString& ); |
444 | | bool ParseTableRefColumn( const OUString& ); |
445 | | |
446 | | /** Calls GetToken() if PeekNextNoSpaces() is of given OpCode. */ |
447 | | bool GetTokenIfOpCode( OpCode eOp ); |
448 | | |
449 | | /** |
450 | | * When auto correction is set, the jump command reorder must be enabled. |
451 | | */ |
452 | | void SetAutoCorrection( bool bVal ); |
453 | 0 | void SetCloseBrackets( bool bVal ) { mbCloseBrackets = bVal; } |
454 | 5.34k | void SetRefConventionChartOOXML( bool bVal ) { mbRefConventionChartOOXML = bVal; } |
455 | | void SetRefConvention( const Convention *pConvP ); |
456 | | void SetRefConvention( const formula::FormulaGrammar::AddressConvention eConv ); |
457 | | |
458 | | static const Convention* GetRefConvention( formula::FormulaGrammar::AddressConvention eConv ); |
459 | | |
460 | | /** Overwrite FormulaCompiler::GetOpCodeMap() forwarding to |
461 | | GetFinalOpCodeMap(). |
462 | | */ |
463 | 7.88k | OpCodeMapPtr GetOpCodeMap( const sal_Int32 nLanguage ) const { return GetFinalOpCodeMap(nLanguage); } |
464 | | |
465 | | /// Set symbol map if not empty. |
466 | | void SetFormulaLanguage( const OpCodeMapPtr & xMap ); |
467 | | |
468 | | SC_DLLPUBLIC void SetGrammar( const formula::FormulaGrammar::Grammar eGrammar ); |
469 | | SC_DLLPUBLIC void SetAvailablePivotFields( const OUString& rPivotFieldName ); |
470 | | |
471 | | private: |
472 | | /** Set grammar and reference convention from within SetFormulaLanguage() |
473 | | or SetGrammar(). |
474 | | |
475 | | @param eNewGrammar |
476 | | The new grammar to be set and the associated reference convention. |
477 | | |
478 | | @param eOldGrammar |
479 | | The previous grammar that was active before SetFormulaLanguage(). |
480 | | */ |
481 | | void SetGrammarAndRefConvention( |
482 | | const formula::FormulaGrammar::Grammar eNewGrammar, |
483 | | const formula::FormulaGrammar::Grammar eOldGrammar ); |
484 | | public: |
485 | | |
486 | | /// Set external link info for ScAddress::CONV_XL_OOX. |
487 | | void SetExternalLinks( |
488 | | const css::uno::Sequence< |
489 | | css::sheet::ExternalLinkInfo>& rLinks ) |
490 | 50.9k | { |
491 | 50.9k | maExternalLinks = rLinks; |
492 | 50.9k | } |
493 | | |
494 | | void CreateStringFromXMLTokenArray( OUString& rFormula, OUString& rFormulaNmsp ); |
495 | | |
496 | 0 | void SetExtendedErrorDetection( ExtendedErrorDetection eVal ) { meExtendedErrorDetection = eVal; } |
497 | | |
498 | 0 | bool IsCorrected() const { return mbCorrected; } |
499 | 0 | const OUString& GetCorrectedFormula() const { return maCorrectedFormula; } |
500 | | |
501 | | /** |
502 | | * Tokenize formula expression string into an array of tokens. |
503 | | * |
504 | | * @param rFormula formula expression to tokenize. |
505 | | * |
506 | | * @return heap allocated token array object. The caller <i>must</i> |
507 | | * manage the life cycle of this object. |
508 | | */ |
509 | | SC_DLLPUBLIC std::unique_ptr<ScTokenArray> CompileString( const OUString& rFormula ); |
510 | | std::unique_ptr<ScTokenArray> CompileString( const OUString& rFormula, const OUString& rFormulaNmsp ); |
511 | 15 | const ScAddress& GetPos() const { return aPos; } |
512 | | |
513 | | void MoveRelWrap(); |
514 | | SC_DLLPUBLIC static void MoveRelWrap( const ScTokenArray& rArr, const ScDocument& rDoc, const ScAddress& rPos, |
515 | | SCCOL nMaxCol, SCROW nMaxRow ); |
516 | | |
517 | | /** If the character is allowed as tested by nFlags (SC_COMPILER_C_... |
518 | | bits) for all known address conventions. If more than one bit is given |
519 | | in nFlags, all bits must match. */ |
520 | | SC_DLLPUBLIC static bool IsCharFlagAllConventions( |
521 | | OUString const & rStr, sal_Int32 nPos, ScCharFlags nFlags ); |
522 | | |
523 | | /** TODO : Move this to somewhere appropriate. */ |
524 | | static bool DoubleRefToPosSingleRefScalarCase(const ScRange& rRange, ScAddress& rAdr, |
525 | | const ScAddress& rFormulaPos); |
526 | | |
527 | 0 | bool HasUnhandledPossibleImplicitIntersections() const { return !mUnhandledPossibleImplicitIntersections.empty(); } |
528 | | |
529 | | SC_DLLPUBLIC static OUString SanitizeDefinedName(const OUString& rStr, const ScDocument& rDoc); |
530 | | |
531 | | #ifdef DBG_UTIL |
532 | | const std::set<OpCode>& UnhandledPossibleImplicitIntersectionsOpCodes() { return mUnhandledPossibleImplicitIntersectionsOpCodes; } |
533 | | #endif |
534 | | |
535 | | private: |
536 | | // FormulaCompiler |
537 | | virtual OUString FindAddInFunction( const OUString& rUpperName, bool bLocalFirst ) const override; |
538 | | virtual void fillFromAddInCollectionUpperName( const NonConstOpCodeMapPtr& xMap ) const override; |
539 | | virtual void fillFromAddInCollectionEnglishName( const NonConstOpCodeMapPtr& xMap ) const override; |
540 | | virtual void fillFromAddInCollectionExcelName( const NonConstOpCodeMapPtr& xMap ) const override; |
541 | | virtual void fillFromAddInMap( const NonConstOpCodeMapPtr& xMap, formula::FormulaGrammar::Grammar _eGrammar ) const override; |
542 | | virtual void fillAddInToken(::std::vector< css::sheet::FormulaOpCodeMapEntry >& _rVec,bool _bIsEnglish) const override; |
543 | | |
544 | | virtual bool HandleExternalReference(const formula::FormulaToken& _aToken) override; |
545 | | virtual bool HandleStringName() override; |
546 | | virtual bool HandleDPFieldName() override; |
547 | | virtual bool HandleRange() override; |
548 | | virtual bool HandleColRowName() override; |
549 | | virtual bool HandleDbData() override; |
550 | | virtual bool HandleTableRef() override; |
551 | | |
552 | | virtual formula::FormulaTokenRef ExtendRangeReference( formula::FormulaToken & rTok1, formula::FormulaToken & rTok2 ) override; |
553 | | virtual void CreateStringFromExternal( OUStringBuffer& rBuffer, const formula::FormulaToken* pToken ) const override; |
554 | | virtual void CreateStringFromSingleRef( OUStringBuffer& rBuffer, const formula::FormulaToken* pToken ) const override; |
555 | | virtual void CreateStringFromDoubleRef( OUStringBuffer& rBuffer, const formula::FormulaToken* pToken ) const override; |
556 | | virtual void CreateStringFromMatrix( OUStringBuffer& rBuffer, const formula::FormulaToken* pToken ) const override; |
557 | | virtual void CreateStringFromIndex( OUStringBuffer& rBuffer, const formula::FormulaToken* pToken ) const override; |
558 | | virtual void CreateStringFromDPFieldName( OUStringBuffer& rBuffer, const formula::FormulaToken* pToken ) const override; |
559 | | virtual void LocalizeString( OUString& rName ) const override; // modify rName - input: exact name |
560 | | virtual bool GetExcelName( OUString& rName ) const override; // modify rName - input: exact name |
561 | | |
562 | | virtual formula::ParamClass GetForceArrayParameter( const formula::FormulaToken* pToken, sal_uInt16 nParam ) const override; |
563 | | |
564 | | bool GetRefColRowNames(const formula::FormulaToken* pToken, ScComplexRefData& rRef, |
565 | | bool& bInList, FormulaError& nError, bool bLookUpColRowNames) const; |
566 | | OUString CreateStringFromLabel(const formula::FormulaToken* pToken) const; |
567 | | |
568 | | /// Access the CharTable flags |
569 | | ScCharFlags GetCharTableFlags( sal_Unicode c, sal_Unicode cLast ) |
570 | 35.6M | { return c < 128 ? pConv->getCharTableFlags(c, cLast) : ScCharFlags::NONE; } |
571 | | |
572 | | virtual void HandleIIOpCode(formula::FormulaToken* token, formula::FormulaToken*** pppToken, sal_uInt8 nNumParams) override; |
573 | | bool HandleIIOpCodeInternal(formula::FormulaToken* token, formula::FormulaToken*** pppToken, sal_uInt8 nNumParams); |
574 | | bool SkipImplicitIntersectionOptimization(const formula::FormulaToken* token) const; |
575 | | virtual void PostProcessCode() override; |
576 | | virtual void AnnotateOperands() override; |
577 | | static bool ParameterMayBeImplicitIntersection(const formula::FormulaToken* token, int parameter); |
578 | | void ReplaceDoubleRefII(formula::FormulaToken** ppDoubleRefTok); |
579 | | bool AdjustSumRangeShape(const ScComplexRefData& rBaseRange, ScComplexRefData& rSumRange); |
580 | | void CorrectSumRange(const ScComplexRefData& rBaseRange, ScComplexRefData& rSumRange, formula::FormulaToken** ppSumRangeToken); |
581 | | void AnnotateTrimOnDoubleRefs(); |
582 | | }; |
583 | | |
584 | | /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |