1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
26 #include "refdata.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>
36 #include <unordered_set>
38 #include <com/sun/star/uno/Sequence.hxx>
39 #include <o3tl/typed_flags_set.hxx>
41 #include <formula/FormulaCompiler.hxx>
45 // constants and data types also for external modules (ScInterpreter et al)
47 #define MAXSTRLEN 1024 /* maximum length of input string of one symbol */
49 // flag values of CharTable
50 enum class ScCharFlags
: sal_uInt32
{
54 CharBool
= 0x00000002,
55 CharWord
= 0x00000004,
56 CharValue
= 0x00000008,
57 CharString
= 0x00000010,
58 CharDontCare
= 0x00000020,
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 ('#')
80 template<> struct typed_flags
<ScCharFlags
> : is_typed_flags
<ScCharFlags
, 0x01ffffff> {};
83 #define SC_COMPILER_FILE_TAB_SEP '#' // 'Doc'#Tab
89 struct ScInterpreterContext
;
94 class CompileFormulaContext
;
98 // constants and data types internal to compiler
100 struct ScRawToken final
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
;
107 formula::StackVar eType
; // type of data; this determines how the unions are used
117 formula::ParamClass eInForceArray
;
119 ScComplexRefData aRef
;
122 ScComplexRefData aRef
;
133 ScTableRefToken::Item eItem
;
137 rtl_uString
* mpDataIgnoreCase
;
141 short nJump
[ FORMULA_MAXPARAMS
+ 1 ]; // If/Choose/Let token
143 OUString maExternalName
; // depending on the opcode, this is either the external, or the external name, or the external table name
145 // coverity[uninit_member] - members deliberately not initialized
148 ~ScRawToken() {} //! only delete via Delete()
150 formula::StackVar
GetType() const { return eType
; }
151 OpCode
GetOpCode() const { return eOp
; }
152 void NewOpCode( OpCode e
) { eOp
= e
; }
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 SetSingleReference( const ScSingleRefData
& rRef
);
160 void SetDoubleReference( const ScComplexRefData
& rRef
);
161 void SetDouble( double fVal
);
162 void SetErrorConstant( FormulaError nErr
);
164 // These methods are ok to use, reference count not cleared.
165 void SetName(sal_Int16 nSheet
, sal_uInt16 nIndex
);
166 void SetExternalSingleRef( sal_uInt16 nFileId
, const OUString
& rTabName
, const ScSingleRefData
& rRef
);
167 void SetExternalDoubleRef( sal_uInt16 nFileId
, const OUString
& rTabName
, const ScComplexRefData
& rRef
);
168 void SetExternalName( sal_uInt16 nFileId
, const OUString
& rName
);
169 void SetExternal(const OUString
& rStr
);
171 /** If the token is a non-external reference, determine if the reference is
172 valid. If the token is an external reference, return true. Else return
173 false. Used only in ScCompiler::NextNewToken() to preserve non-existing
174 sheet names in otherwise valid references.
176 bool IsValidReference(const ScDocument
& rDoc
) const;
178 formula::FormulaToken
* CreateToken(ScSheetLimits
& rLimits
) const; // create typified token
181 class SAL_DLLPUBLIC_RTTI ScCompiler final
: public formula::FormulaCompiler
185 enum ExtendedErrorDetection
187 EXTENDED_ERROR_DETECTION_NONE
= 0, // no error on unknown symbols, default (interpreter handles it)
188 EXTENDED_ERROR_DETECTION_NAME_BREAK
, // name error on unknown symbols and break, pCode incomplete
189 EXTENDED_ERROR_DETECTION_NAME_NO_BREAK
// name error on unknown symbols, don't break, continue
194 const formula::FormulaGrammar::AddressConvention meConv
;
196 Convention( formula::FormulaGrammar::AddressConvention eConvP
);
197 virtual ~Convention();
199 virtual void makeRefStr(
200 ScSheetLimits
& rLimits
,
201 OUStringBuffer
& rBuffer
,
202 formula::FormulaGrammar::Grammar eGram
,
203 const ScAddress
& rPos
,
204 const OUString
& rErrRef
, const std::vector
<OUString
>& rTabNames
,
205 const ScComplexRefData
& rRef
, bool bSingleRef
, bool bFromRangeName
) const = 0;
207 virtual css::i18n::ParseResult
208 parseAnyToken( const OUString
& rFormula
,
210 const CharClass
* pCharClass
,
211 bool bGroupSeparator
) const = 0;
214 * Parse the symbol string and pick up the file name and the external
217 * @return true on successful parse, or false otherwise.
219 virtual bool parseExternalName( const OUString
& rSymbol
, OUString
& rFile
, OUString
& rName
,
220 const ScDocument
& rDoc
,
221 const css::uno::Sequence
< css::sheet::ExternalLinkInfo
>* pExternalLinks
) const = 0;
223 virtual OUString
makeExternalNameStr( sal_uInt16 nFileId
, const OUString
& rFile
,
224 const OUString
& rName
) const = 0;
226 virtual void makeExternalRefStr(
227 ScSheetLimits
& rLimits
,
228 OUStringBuffer
& rBuffer
, const ScAddress
& rPos
, sal_uInt16 nFileId
, const OUString
& rFileName
,
229 const OUString
& rTabName
, const ScSingleRefData
& rRef
) const = 0;
231 virtual void makeExternalRefStr(
232 ScSheetLimits
& rLimits
,
233 OUStringBuffer
& rBuffer
, const ScAddress
& rPos
,
234 sal_uInt16 nFileId
, const OUString
& rFileName
, const std::vector
<OUString
>& rTabNames
,
235 const OUString
& rTabName
, const ScComplexRefData
& rRef
) const = 0;
237 enum SpecialSymbolType
240 * Character between sheet name and address. In OOO A1 this is
241 * '.', while XL A1 and XL R1C1 this is '!'.
246 * In OOO A1, a sheet name may be prefixed with '$' to indicate an
247 * absolute sheet position.
251 virtual sal_Unicode
getSpecialSymbol( SpecialSymbolType eSymType
) const = 0;
253 virtual ScCharFlags
getCharTableFlags( sal_Unicode c
, sal_Unicode cLast
) const = 0;
256 std::unique_ptr
<ScCharFlags
[]> mpCharTable
;
258 friend struct Convention
;
262 static const CharClass
*pCharClassEnglish
; // character classification for en_US locale
263 static const CharClass
*pCharClassLocalized
; // character classification for UI locale
264 static const Convention
*pConventions
[ formula::FormulaGrammar::CONV_LAST
];
266 static const struct AddInMap
269 const char* pEnglish
;
270 const char* pOriginal
; // programmatical name
271 const char* pUpper
; // upper case programmatical name
273 static size_t GetAddInMapCount();
278 ScInterpreterContext
& mrInterpreterContext
;
280 SCTAB mnCurrentSheetTab
; // indicates current sheet number parsed so far
281 sal_Int32 mnCurrentSheetEndPos
; // position after current sheet name if parsed
283 // For CONV_XL_OOX, may be set via API by MOOXML filter.
284 css::uno::Sequence
<css::sheet::ExternalLinkInfo
> maExternalLinks
;
286 sal_Unicode cSymbol
[MAXSTRLEN
+1]; // current Symbol + 0
287 OUString aFormula
; // formula source code
288 sal_Int32 nSrcPos
; // tokenizer position (source code)
289 ScRawToken maRawToken
;
291 std::queue
<OpCode
> maPendingOpCodes
; // additional opcodes generated from a single symbol
293 const CharClass
* pCharClass
; // which character classification is used for parseAnyToken and upper/lower
294 bool mbCharClassesDiffer
; // whether pCharClass and current system locale's CharClass differ
295 sal_uInt16 mnPredetectedReference
; // reference when reading ODF, 0 (none), 1 (single) or 2 (double)
296 sal_Int32 mnRangeOpPosInSymbol
; // if and where a range operator is in symbol
297 const Convention
*pConv
;
298 ExtendedErrorDetection meExtendedErrorDetection
;
299 bool mbCloseBrackets
; // whether to close open brackets automatically, default TRUE
300 bool mbRewind
; // whether symbol is to be rewound to some step during lexical analysis
301 bool mbRefConventionChartOOXML
; // whether to use special ooxml chart syntax in case of OOXML reference convention,
302 // when parsing a formula string. [0]!GlobalNamedRange, LocalSheet!LocalNamedRange
303 std::vector
<sal_uInt16
> maExternalFiles
;
305 std::vector
<OUString
> maTabNames
; /// sheet names mangled for the current grammar for output
306 std::vector
<OUString
> &GetSetupTabNames() const; /// get or setup tab names for the current grammar
310 boost::intrusive_ptr
<ScTableRefToken
> mxToken
;
312 TableRefEntry( ScTableRefToken
* p
) : mxToken(p
), mnLevel(0) {}
314 std::vector
<TableRefEntry
> maTableRefs
; /// "stack" of currently active ocTableRef tokens
316 // Optimizing implicit intersection is done only at the end of code generation, because the usage context may
317 // be important. Store candidate parameters and the operation they are the argument for.
318 struct PendingImplicitIntersectionOptimization
320 PendingImplicitIntersectionOptimization(formula::FormulaToken
** p
, formula::FormulaToken
* o
)
321 : parameterLocation( p
), parameter( *p
), operation( o
) {}
322 formula::FormulaToken
** parameterLocation
;
323 formula::FormulaTokenRef parameter
;
324 formula::FormulaTokenRef operation
;
326 std::vector
< PendingImplicitIntersectionOptimization
> mPendingImplicitIntersectionOptimizations
;
327 std::unordered_set
<formula::FormulaTokenRef
> mUnhandledPossibleImplicitIntersections
;
329 std::set
<OpCode
> mUnhandledPossibleImplicitIntersectionsOpCodes
;
332 bool NextNewToken(bool bInArray
);
333 bool ToUpperAsciiOrI18nIsAscii( OUString
& rUpper
, const OUString
& rOrg
) const;
334 short GetPossibleParaCount( std::u16string_view rLambdaFormula
) const;
336 virtual void SetError(FormulaError nError
) override
;
338 struct Whitespace final
343 Whitespace() : nCount(0), cChar(0x20) {}
344 void reset( sal_Unicode c
) { nCount
= 0; cChar
= c
; }
347 static void addWhitespace( std::vector
<ScCompiler::Whitespace
> & rvSpaces
,
348 ScCompiler::Whitespace
& rSpace
, sal_Unicode c
, sal_Int32 n
= 1 );
350 std::vector
<Whitespace
> NextSymbol(bool bInArray
);
352 bool ParseValue( const OUString
& );
353 bool ParseOpCode( const OUString
&, bool bInArray
);
354 bool ParseOpCode2( std::u16string_view
);
356 bool ParseReference( const OUString
& rSymbol
, const OUString
* pErrRef
= nullptr );
357 bool ParseSingleReference( const OUString
& rSymbol
, const OUString
* pErrRef
= nullptr );
358 bool ParseDoubleReference( const OUString
& rSymbol
, const OUString
* pErrRef
= nullptr );
359 bool ParsePredetectedReference( const OUString
& rSymbol
);
360 bool ParsePredetectedErrRefReference( const OUString
& rName
, const OUString
* pErrRef
);
361 bool ParseMacro( const OUString
& );
362 bool ParseNamedRange( const OUString
&, bool onlyCheck
= false );
363 bool ParseLambdaFuncName( const OUString
& );
364 bool ParseExternalNamedRange( const OUString
& rSymbol
, bool& rbInvalidExternalNameRange
);
365 bool ParseDBRange( const OUString
& );
366 bool ParseColRowName( const OUString
& );
367 bool ParseBoolean( const OUString
& );
368 void AutoCorrectParsedSymbol();
369 const ScRangeData
* GetRangeData( SCTAB
& rSheet
, const OUString
& rUpperName
) const;
371 void AdjustSheetLocalNameRelReferences( SCTAB nDelta
);
372 void SetRelNameReference();
374 /** Obtain range data for ocName token, global or sheet local.
376 Prerequisite: rToken is a FormulaIndexToken so IsGlobal() and
377 GetIndex() can be called on it. We don't check with RTTI.
379 ScRangeData
* GetRangeData( const formula::FormulaToken
& pToken
) const;
381 bool HasPossibleNamedRangeConflict(SCTAB nTab
) const;
384 static const CharClass
* GetCharClassLocalized();
385 static const CharClass
* GetCharClassEnglish();
388 ScCompiler( sc::CompileFormulaContext
& rCxt
, const ScAddress
& rPos
,
389 bool bComputeII
= false, bool bMatrixFlag
= false, ScInterpreterContext
* pContext
= nullptr );
391 /** If eGrammar == GRAM_UNSPECIFIED then the grammar of rDocument is used,
393 SC_DLLPUBLIC
ScCompiler( ScDocument
& rDocument
, const ScAddress
&,
394 formula::FormulaGrammar::Grammar eGrammar
= formula::FormulaGrammar::GRAM_UNSPECIFIED
,
395 bool bComputeII
= false, bool bMatrixFlag
= false, ScInterpreterContext
* pContext
= nullptr );
397 SC_DLLPUBLIC
ScCompiler( sc::CompileFormulaContext
& rCxt
, const ScAddress
& rPos
, ScTokenArray
& rArr
,
398 bool bComputeII
= false, bool bMatrixFlag
= false, ScInterpreterContext
* pContext
= nullptr );
400 /** If eGrammar == GRAM_UNSPECIFIED then the grammar of rDocument is used,
402 SC_DLLPUBLIC
ScCompiler( ScDocument
& rDocument
, const ScAddress
&, ScTokenArray
& rArr
,
403 formula::FormulaGrammar::Grammar eGrammar
= formula::FormulaGrammar::GRAM_UNSPECIFIED
,
404 bool bComputeII
= false, bool bMatrixFlag
= false, ScInterpreterContext
* pContext
= nullptr );
406 SC_DLLPUBLIC
virtual ~ScCompiler() override
;
409 static void DeInit(); /// all
411 // for ScAddress::Format()
412 SC_DLLPUBLIC
static void CheckTabQuotes( OUString
& aTabName
,
413 const formula::FormulaGrammar::AddressConvention eConv
= formula::FormulaGrammar::CONV_OOO
);
415 /** Concatenates two sheet names in Excel syntax, i.e. 'Sheet1:Sheet2'
416 instead of 'Sheet1':'Sheet2' or 'Sheet1':Sheet2 or Sheet1:'Sheet2'.
419 Contains the first sheet name already, in the correct quoted 'Sheet''1' or
420 unquoted Sheet1 form if plain name.
423 Start position, of the first sheet name if unquoted, or its
427 Second sheet name to append, in the correct quoted 'Sheet''2'
428 or unquoted Sheet2 form if plain name.
430 static void FormExcelSheetRange( OUStringBuffer
& rBuf
, sal_Int32 nQuotePos
, const OUString
& rEndTabName
);
432 /** Analyzes a string for a 'Doc'#Tab construct, or 'Do''c'#Tab etc...
434 @returns the position of the unquoted # hash mark in 'Doc'#Tab, or
436 static sal_Int32
GetDocTabPos( const OUString
& rString
);
438 // Check if it is a valid english function name
439 SC_DLLPUBLIC
static bool IsEnglishSymbol( const OUString
& rName
);
441 bool ParseErrorConstant( const OUString
& );
442 bool ParseTableRefItem( const OUString
& );
443 bool ParseTableRefColumn( const OUString
& );
445 /** Calls GetToken() if PeekNextNoSpaces() is of given OpCode. */
446 bool GetTokenIfOpCode( OpCode eOp
);
449 * When auto correction is set, the jump command reorder must be enabled.
451 void SetAutoCorrection( bool bVal
);
452 void SetCloseBrackets( bool bVal
) { mbCloseBrackets
= bVal
; }
453 void SetRefConventionChartOOXML( bool bVal
) { mbRefConventionChartOOXML
= bVal
; }
454 void SetRefConvention( const Convention
*pConvP
);
455 void SetRefConvention( const formula::FormulaGrammar::AddressConvention eConv
);
457 static const Convention
* GetRefConvention( formula::FormulaGrammar::AddressConvention eConv
);
459 /** Overwrite FormulaCompiler::GetOpCodeMap() forwarding to
462 OpCodeMapPtr
GetOpCodeMap( const sal_Int32 nLanguage
) const { return GetFinalOpCodeMap(nLanguage
); }
464 /// Set symbol map if not empty.
465 void SetFormulaLanguage( const OpCodeMapPtr
& xMap
);
467 SC_DLLPUBLIC
void SetGrammar( const formula::FormulaGrammar::Grammar eGrammar
);
470 /** Set grammar and reference convention from within SetFormulaLanguage()
474 The new grammar to be set and the associated reference convention.
477 The previous grammar that was active before SetFormulaLanguage().
479 void SetGrammarAndRefConvention(
480 const formula::FormulaGrammar::Grammar eNewGrammar
,
481 const formula::FormulaGrammar::Grammar eOldGrammar
);
484 /// Set external link info for ScAddress::CONV_XL_OOX.
485 void SetExternalLinks(
486 const css::uno::Sequence
<
487 css::sheet::ExternalLinkInfo
>& rLinks
)
489 maExternalLinks
= rLinks
;
492 void CreateStringFromXMLTokenArray( OUString
& rFormula
, OUString
& rFormulaNmsp
);
494 void SetExtendedErrorDetection( ExtendedErrorDetection eVal
) { meExtendedErrorDetection
= eVal
; }
496 bool IsCorrected() const { return bCorrected
; }
497 const OUString
& GetCorrectedFormula() const { return aCorrectedFormula
; }
500 * Tokenize formula expression string into an array of tokens.
502 * @param rFormula formula expression to tokenize.
504 * @return heap allocated token array object. The caller <i>must</i>
505 * manage the life cycle of this object.
507 SC_DLLPUBLIC
std::unique_ptr
<ScTokenArray
> CompileString( const OUString
& rFormula
);
508 std::unique_ptr
<ScTokenArray
> CompileString( const OUString
& rFormula
, const OUString
& rFormulaNmsp
);
509 const ScAddress
& GetPos() const { return aPos
; }
512 SC_DLLPUBLIC
static void MoveRelWrap( const ScTokenArray
& rArr
, const ScDocument
& rDoc
, const ScAddress
& rPos
,
513 SCCOL nMaxCol
, SCROW nMaxRow
);
515 /** If the character is allowed as tested by nFlags (SC_COMPILER_C_...
516 bits) for all known address conventions. If more than one bit is given
517 in nFlags, all bits must match. */
518 SC_DLLPUBLIC
static bool IsCharFlagAllConventions(
519 OUString
const & rStr
, sal_Int32 nPos
, ScCharFlags nFlags
);
521 /** TODO : Move this to somewhere appropriate. */
522 static bool DoubleRefToPosSingleRefScalarCase(const ScRange
& rRange
, ScAddress
& rAdr
,
523 const ScAddress
& rFormulaPos
);
525 bool HasUnhandledPossibleImplicitIntersections() const { return !mUnhandledPossibleImplicitIntersections
.empty(); }
527 const std::set
<OpCode
>& UnhandledPossibleImplicitIntersectionsOpCodes() { return mUnhandledPossibleImplicitIntersectionsOpCodes
; }
532 virtual OUString
FindAddInFunction( const OUString
& rUpperName
, bool bLocalFirst
) const override
;
533 virtual void fillFromAddInCollectionUpperName( const NonConstOpCodeMapPtr
& xMap
) const override
;
534 virtual void fillFromAddInCollectionEnglishName( const NonConstOpCodeMapPtr
& xMap
) const override
;
535 virtual void fillFromAddInCollectionExcelName( const NonConstOpCodeMapPtr
& xMap
) const override
;
536 virtual void fillFromAddInMap( const NonConstOpCodeMapPtr
& xMap
, formula::FormulaGrammar::Grammar _eGrammar
) const override
;
537 virtual void fillAddInToken(::std::vector
< css::sheet::FormulaOpCodeMapEntry
>& _rVec
,bool _bIsEnglish
) const override
;
539 virtual bool HandleExternalReference(const formula::FormulaToken
& _aToken
) override
;
540 virtual bool HandleStringName() override
;
541 virtual bool HandleRange() override
;
542 virtual bool HandleColRowName() override
;
543 virtual bool HandleDbData() override
;
544 virtual bool HandleTableRef() override
;
546 virtual formula::FormulaTokenRef
ExtendRangeReference( formula::FormulaToken
& rTok1
, formula::FormulaToken
& rTok2
) override
;
547 virtual void CreateStringFromExternal( OUStringBuffer
& rBuffer
, const formula::FormulaToken
* pToken
) const override
;
548 virtual void CreateStringFromSingleRef( OUStringBuffer
& rBuffer
, const formula::FormulaToken
* pToken
) const override
;
549 virtual void CreateStringFromDoubleRef( OUStringBuffer
& rBuffer
, const formula::FormulaToken
* pToken
) const override
;
550 virtual void CreateStringFromMatrix( OUStringBuffer
& rBuffer
, const formula::FormulaToken
* pToken
) const override
;
551 virtual void CreateStringFromIndex( OUStringBuffer
& rBuffer
, const formula::FormulaToken
* pToken
) const override
;
552 virtual void LocalizeString( OUString
& rName
) const override
; // modify rName - input: exact name
553 virtual bool GetExcelName( OUString
& rName
) const override
; // modify rName - input: exact name
555 virtual formula::ParamClass
GetForceArrayParameter( const formula::FormulaToken
* pToken
, sal_uInt16 nParam
) const override
;
557 /// Access the CharTable flags
558 ScCharFlags
GetCharTableFlags( sal_Unicode c
, sal_Unicode cLast
)
559 { return c
< 128 ? pConv
->getCharTableFlags(c
, cLast
) : ScCharFlags::NONE
; }
561 virtual void HandleIIOpCode(formula::FormulaToken
* token
, formula::FormulaToken
*** pppToken
, sal_uInt8 nNumParams
) override
;
562 bool HandleIIOpCodeInternal(formula::FormulaToken
* token
, formula::FormulaToken
*** pppToken
, sal_uInt8 nNumParams
);
563 bool SkipImplicitIntersectionOptimization(const formula::FormulaToken
* token
) const;
564 virtual void PostProcessCode() override
;
565 virtual void AnnotateOperands() override
;
566 static bool ParameterMayBeImplicitIntersection(const formula::FormulaToken
* token
, int parameter
);
567 void ReplaceDoubleRefII(formula::FormulaToken
** ppDoubleRefTok
);
568 bool AdjustSumRangeShape(const ScComplexRefData
& rBaseRange
, ScComplexRefData
& rSumRange
);
569 void CorrectSumRange(const ScComplexRefData
& rBaseRange
, ScComplexRefData
& rSumRange
, formula::FormulaToken
** ppSumRangeToken
);
570 void AnnotateTrimOnDoubleRefs();
573 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */