LibreOffice Module sc (master) 1
xeformula.cxx
Go to the documentation of this file.
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#include <map>
21#include <addincol.hxx>
22#include <compiler.hxx>
23#include <document.hxx>
24#include <externalrefmgr.hxx>
25#include <rangelst.hxx>
26#include <tokenarray.hxx>
27#include <scmatrix.hxx>
28#include <utility>
29#include <xeformula.hxx>
30#include <xehelper.hxx>
31#include <xelink.hxx>
32#include <xename.hxx>
33#include <xestring.hxx>
34#include <xllink.hxx>
35#include <xltools.hxx>
36#include <o3tl/safeint.hxx>
37#include <sal/log.hxx>
38
39using namespace ::formula;
40
41// External reference log =====================================================
42
44 mpUrl( nullptr ),
45 mpFirstTab( nullptr ),
46 mpLastTab( nullptr ),
47 mnFirstXclTab( EXC_TAB_DELETED ),
48 mnLastXclTab( EXC_TAB_DELETED )
49{
50}
51
52// Formula compiler ===========================================================
53
54namespace {
55
58struct XclExpScToken
59{
60 const FormulaToken* mpScToken;
61 sal_uInt8 mnSpaces;
62
63 explicit XclExpScToken() : mpScToken( nullptr ), mnSpaces( 0 ) {}
64 bool Is() const { return mpScToken != nullptr; }
65 StackVar GetType() const { return mpScToken ? mpScToken->GetType() : svUnknown; }
66 OpCode GetOpCode() const { return mpScToken ? mpScToken->GetOpCode() : ocNone; }
67};
68
70enum XclExpClassConv
71{
72 EXC_CLASSCONV_ORG,
73 EXC_CLASSCONV_VAL,
74 EXC_CLASSCONV_ARR
75};
76
78struct XclExpTokenConvInfo
79{
80 sal_uInt16 mnTokPos;
81 XclFuncParamConv meConv;
82 bool mbValType;
83};
84
87struct XclExpOperandList : public std::vector< XclExpTokenConvInfo >
88{
89 explicit XclExpOperandList() { reserve( 2 ); }
90 void AppendOperand( sal_uInt16 nTokPos, XclFuncParamConv eConv, bool bValType );
91};
92
93void XclExpOperandList::AppendOperand( sal_uInt16 nTokPos, XclFuncParamConv eConv, bool bValType )
94{
95 resize( size() + 1 );
96 XclExpTokenConvInfo& rConvInfo = back();
97 rConvInfo.mnTokPos = nTokPos;
98 rConvInfo.meConv = eConv;
99 rConvInfo.mbValType = bValType;
100}
101
102typedef std::shared_ptr< XclExpOperandList > XclExpOperandListRef;
103
105struct XclExpExtFuncData
106{
107 OUString maFuncName;
108 bool mbVBasic;
109 bool mbHidden;
110
111 explicit XclExpExtFuncData() : mbVBasic( false ), mbHidden( false ) {}
112 void Set( const OUString& rFuncName, bool bVBasic, bool bHidden );
113};
114
115void XclExpExtFuncData::Set( const OUString& rFuncName, bool bVBasic, bool bHidden )
116{
117 maFuncName = rFuncName;
118 mbVBasic = bVBasic;
119 mbHidden = bHidden;
120}
121
123class XclExpFuncData
124{
125public:
126 explicit XclExpFuncData(
127 const XclExpScToken& rTokData,
128 const XclFunctionInfo& rFuncInfo,
129 XclExpExtFuncData aExtFuncData );
130
131 const FormulaToken& GetScToken() const { return *mrTokData.mpScToken; }
132 OpCode GetOpCode() const { return mrFuncInfo.meOpCode; }
133 sal_uInt16 GetXclFuncIdx() const { return mrFuncInfo.mnXclFunc; }
134 bool IsVolatile() const { return mrFuncInfo.IsVolatile(); }
135 bool IsFixedParamCount() const { return mrFuncInfo.IsFixedParamCount(); }
136 bool IsAddInEquivalent() const { return mrFuncInfo.IsAddInEquivalent(); }
137 bool IsMacroFunc() const { return mrFuncInfo.IsMacroFunc(); }
138 sal_uInt8 GetSpaces() const { return mrTokData.mnSpaces; }
139 const XclExpExtFuncData& GetExtFuncData() const { return maExtFuncData; }
140 sal_uInt8 GetReturnClass() const { return mrFuncInfo.mnRetClass; }
141
142 const XclFuncParamInfo& GetParamInfo() const;
143 bool IsCalcOnlyParam() const;
144 bool IsExcelOnlyParam() const;
145 void IncParamInfoIdx();
146
147 sal_uInt8 GetMinParamCount() const { return mrFuncInfo.mnMinParamCount; }
148 sal_uInt8 GetMaxParamCount() const { return mrFuncInfo.mnMaxParamCount; }
149 sal_uInt8 GetParamCount() const { return static_cast< sal_uInt8 >( mxOperands->size() ); }
150 void FinishParam( sal_uInt16 nTokPos );
151 const XclExpOperandListRef& GetOperandList() const { return mxOperands; }
152
153 ScfUInt16Vec& GetAttrPosVec() { return maAttrPosVec; }
154 void AppendAttrPos( sal_uInt16 nPos ) { maAttrPosVec.push_back( nPos ); }
155
156private:
157 ScfUInt16Vec maAttrPosVec;
158 const XclExpScToken& mrTokData;
159 const XclFunctionInfo& mrFuncInfo;
160 XclExpExtFuncData maExtFuncData;
161 XclExpOperandListRef mxOperands;
162 const XclFuncParamInfo* mpParamInfo;
163};
164
165XclExpFuncData::XclExpFuncData( const XclExpScToken& rTokData,
166 const XclFunctionInfo& rFuncInfo, XclExpExtFuncData aExtFuncData ) :
167 mrTokData( rTokData ),
168 mrFuncInfo( rFuncInfo ),
169 maExtFuncData(std::move( aExtFuncData )),
170 mxOperands( std::make_shared<XclExpOperandList>() ),
171 mpParamInfo( rFuncInfo.mpParamInfos )
172{
173 OSL_ENSURE( mrTokData.mpScToken, "XclExpFuncData::XclExpFuncData - missing core token" );
174 // set name of an add-in function
175 if( (maExtFuncData.maFuncName.isEmpty()) && dynamic_cast< const FormulaExternalToken* >( mrTokData.mpScToken ) )
176 maExtFuncData.Set( GetScToken().GetExternal(), true, false );
177}
178
179const XclFuncParamInfo& XclExpFuncData::GetParamInfo() const
180{
181 static const XclFuncParamInfo saInvalidInfo = { EXC_PARAM_NONE, EXC_PARAMCONV_ORG, false };
182 return mpParamInfo ? *mpParamInfo : saInvalidInfo;
183}
184
185bool XclExpFuncData::IsCalcOnlyParam() const
186{
187 return mpParamInfo && (mpParamInfo->meValid == EXC_PARAM_CALCONLY);
188}
189
190bool XclExpFuncData::IsExcelOnlyParam() const
191{
192 return mpParamInfo && (mpParamInfo->meValid == EXC_PARAM_EXCELONLY);
193}
194
195void XclExpFuncData::IncParamInfoIdx()
196{
197 if( !mpParamInfo )
198 return;
199
200 // move pointer to next entry, if something explicit follows
201 if( (o3tl::make_unsigned( mpParamInfo - mrFuncInfo.mpParamInfos + 1 ) < EXC_FUNCINFO_PARAMINFO_COUNT) && (mpParamInfo[ 1 ].meValid != EXC_PARAM_NONE) )
202 ++mpParamInfo;
203 // if last parameter type is 'Excel-only' or 'Calc-only', do not repeat it
204 else if( IsExcelOnlyParam() || IsCalcOnlyParam() )
205 mpParamInfo = nullptr;
206 // points to last info, but parameter pairs expected, move to previous info
207 else if( mrFuncInfo.IsParamPairs() )
208 --mpParamInfo;
209 // otherwise: repeat last parameter class
210}
211
212void XclExpFuncData::FinishParam( sal_uInt16 nTokPos )
213{
214 // write token class conversion info for this parameter
215 const XclFuncParamInfo& rParamInfo = GetParamInfo();
216 mxOperands->AppendOperand( nTokPos, rParamInfo.meConv, rParamInfo.mbValType );
217 // move to next parameter info structure
218 IncParamInfoIdx();
219}
220
221// compiler configuration -----------------------------------------------------
222
224enum XclExpFmlaClassType
225{
226 EXC_CLASSTYPE_CELL,
227 EXC_CLASSTYPE_ARRAY,
228 EXC_CLASSTYPE_NAME
229};
230
232struct XclExpCompConfig
233{
235 XclExpFmlaClassType meClassType;
236 bool mbLocalLinkMgr;
237 bool mbFromCell;
238 bool mb3DRefOnly;
239 bool mbAllowArrays;
240};
241
243const XclExpCompConfig spConfigTable[] =
244{
245 // formula type token class type lclLM inCell 3dOnly allowArray
246 { EXC_FMLATYPE_CELL, EXC_CLASSTYPE_CELL, true, true, false, true },
247 { EXC_FMLATYPE_SHARED, EXC_CLASSTYPE_CELL, true, true, false, true },
248 { EXC_FMLATYPE_MATRIX, EXC_CLASSTYPE_ARRAY, true, true, false, true },
249 { EXC_FMLATYPE_CONDFMT, EXC_CLASSTYPE_ARRAY, true, false, false, false },
250 { EXC_FMLATYPE_DATAVAL, EXC_CLASSTYPE_ARRAY, true, false, false, false },
251 { EXC_FMLATYPE_NAME, EXC_CLASSTYPE_NAME, false, false, true, true },
252 { EXC_FMLATYPE_CHART, EXC_CLASSTYPE_NAME, true, false, true, true },
253 { EXC_FMLATYPE_CONTROL, EXC_CLASSTYPE_NAME, true, false, false, false },
254 { EXC_FMLATYPE_WQUERY, EXC_CLASSTYPE_NAME, true, false, true, false },
255 { EXC_FMLATYPE_LISTVAL, EXC_CLASSTYPE_NAME, true, false, false, false }
256};
257
259struct XclExpCompData
260{
261 typedef std::shared_ptr< ScTokenArray > ScTokenArrayRef;
262
263 const XclExpCompConfig& mrCfg;
264 ScTokenArrayRef mxOwnScTokArr;
265 XclTokenArrayIterator maTokArrIt;
266 XclExpLinkManager* mpLinkMgr;
267 XclExpRefLog* mpRefLog;
268 const ScAddress* mpScBasePos;
269
270 ScfUInt8Vec maTokVec;
271 ScfUInt8Vec maExtDataVec;
272 std::vector< XclExpOperandListRef >
273 maOpListVec;
274 ScfUInt16Vec maOpPosStack;
275 bool mbStopAtSep;
276 bool mbVolatile;
277 bool mbOk;
278
279 explicit XclExpCompData( const XclExpCompConfig* pCfg );
280};
281
282XclExpCompData::XclExpCompData( const XclExpCompConfig* pCfg ) :
283 mrCfg( pCfg ? *pCfg : spConfigTable[ 0 ] ),
284 mpLinkMgr( nullptr ),
285 mpRefLog( nullptr ),
286 mpScBasePos( nullptr ),
287 mbStopAtSep( false ),
288 mbVolatile( false ),
289 mbOk( pCfg != nullptr )
290{
291 OSL_ENSURE( pCfg, "XclExpFmlaCompImpl::Init - unknown formula type" );
292}
293
294} // namespace
295
298{
299public:
300 explicit XclExpFmlaCompImpl( const XclExpRoot& rRoot );
301
304 XclFormulaType eType, const ScTokenArray& rScTokArr,
305 const ScAddress* pScBasePos = nullptr, XclExpRefLog* pRefLog = nullptr );
311 XclTokenArrayRef CreateNameXFormula( sal_uInt16 nExtSheet, sal_uInt16 nExtName );
312
314 bool Is3DRefOnly( XclFormulaType eType ) const;
315
316 bool IsRef2D( const ScSingleRefData& rRefData, bool bCheck3DFlag ) const;
317 bool IsRef2D( const ScComplexRefData& rRefData, bool bCheck3DFlag ) const;
318
319private:
320 const XclExpCompConfig* GetConfigForType( XclFormulaType eType ) const;
321 sal_uInt16 GetSize() const { return static_cast< sal_uInt16 >( mxData->maTokVec.size() ); }
322
323 void Init( XclFormulaType eType );
324 void Init( XclFormulaType eType, const ScTokenArray& rScTokArr,
325 const ScAddress* pScBasePos, XclExpRefLog* pRefLog );
326
327 void RecalcTokenClasses();
328 void RecalcTokenClass( const XclExpTokenConvInfo& rConvInfo, XclFuncParamConv ePrevConv, XclExpClassConv ePrevClassConv, bool bWasRefClass );
329
330 void FinalizeFormula();
332
333 // compiler ---------------------------------------------------------------
334 // XclExpScToken: pass-by-value and return-by-value is intended
335
336 const FormulaToken* GetNextRawToken();
337 const FormulaToken* PeekNextRawToken() const;
338
339 bool GetNextToken( XclExpScToken& rTokData );
340 XclExpScToken GetNextToken();
341
342 XclExpScToken Expression( XclExpScToken aTokData, bool bInParentheses, bool bStopAtSep );
343 XclExpScToken SkipExpression( XclExpScToken aTokData, bool bStopAtSep );
344
345 XclExpScToken OrTerm( XclExpScToken aTokData, bool bInParentheses );
346 XclExpScToken AndTerm( XclExpScToken aTokData, bool bInParentheses );
347 XclExpScToken CompareTerm( XclExpScToken aTokData, bool bInParentheses );
348 XclExpScToken ConcatTerm( XclExpScToken aTokData, bool bInParentheses );
349 XclExpScToken AddSubTerm( XclExpScToken aTokData, bool bInParentheses );
350 XclExpScToken MulDivTerm( XclExpScToken aTokData, bool bInParentheses );
351 XclExpScToken PowTerm( XclExpScToken aTokData, bool bInParentheses );
352 XclExpScToken UnaryPostTerm( XclExpScToken aTokData, bool bInParentheses );
353 XclExpScToken UnaryPreTerm( XclExpScToken aTokData, bool bInParentheses );
354 XclExpScToken ListTerm( XclExpScToken aTokData, bool bInParentheses );
355 XclExpScToken IntersectTerm( XclExpScToken aTokData, bool& rbHasRefOp );
356 XclExpScToken RangeTerm( XclExpScToken aTokData, bool& rbHasRefOp );
357 XclExpScToken Factor( XclExpScToken aTokData );
358
359 // formula structure ------------------------------------------------------
360
361 void ProcessDouble( const XclExpScToken& rTokData );
362 void ProcessString( const XclExpScToken& rTokData );
363 void ProcessMissing( const XclExpScToken& rTokData );
364 void ProcessBad( const XclExpScToken& rTokData );
365 void ProcessParentheses( const XclExpScToken& rTokData );
366 void ProcessBoolean( const XclExpScToken& rTokData );
367 void ProcessDdeLink( const XclExpScToken& rTokData );
368 void ProcessExternal( const XclExpScToken& rTokData );
369 void ProcessMatrix( const XclExpScToken& rTokData );
370
371 void ProcessFunction( const XclExpScToken& rTokData );
372 void PrepareFunction( const XclExpFuncData& rFuncData );
373 void FinishFunction( XclExpFuncData& rFuncData, sal_uInt8 nCloseSpaces );
374 void FinishIfFunction( XclExpFuncData& rFuncData );
375 void FinishChooseFunction( XclExpFuncData& rFuncData );
376
377 XclExpScToken ProcessParam( XclExpScToken aTokData, XclExpFuncData& rFuncData );
378 void PrepareParam( XclExpFuncData& rFuncData );
379 void FinishParam( XclExpFuncData& rFuncData );
380 void AppendDefaultParam( XclExpFuncData& rFuncData );
381 void AppendTrailingParam( XclExpFuncData& rFuncData );
382
383 // reference handling -----------------------------------------------------
384
385 SCTAB GetScTab( const ScSingleRefData& rRefData ) const;
386
387 void ConvertRefData( ScSingleRefData& rRefData, XclAddress& rXclPos,
388 bool bNatLangRef, bool bTruncMaxCol, bool bTruncMaxRow ) const;
389 void ConvertRefData( ScComplexRefData& rRefData, XclRange& rXclRange,
390 bool bNatLangRef ) const;
391
393 void ProcessCellRef( const XclExpScToken& rTokData );
394 void ProcessRangeRef( const XclExpScToken& rTokData );
395 void ProcessExternalCellRef( const XclExpScToken& rTokData );
396 void ProcessExternalRangeRef( const XclExpScToken& rTokData );
397 void ProcessDefinedName( const XclExpScToken& rTokData );
398 void ProcessExternalName( const XclExpScToken& rTokData );
399
400 // token vector -----------------------------------------------------------
401
402 void PushOperandPos( sal_uInt16 nTokPos );
403 void PushOperatorPos( sal_uInt16 nTokPos, const XclExpOperandListRef& rxOperands );
404 sal_uInt16 PopOperandPos();
405
406 void Append( sal_uInt8 nData );
407 void Append( sal_uInt8 nData, size_t nCount );
408 void Append( sal_uInt16 nData );
409 void Append( sal_uInt32 nData );
410 void Append( double fData );
411 void Append( const OUString& rString );
412
413 void AppendAddress( const XclAddress& rXclPos );
414 void AppendRange( const XclRange& rXclRange );
415
417
418 void AppendOperandTokenId( sal_uInt8 nTokenId, sal_uInt8 nSpaces = 0 );
419 void AppendIntToken( sal_uInt16 nValue, sal_uInt8 nSpaces = 0 );
420 void AppendNumToken( double fValue, sal_uInt8 nSpaces = 0 );
421 void AppendBoolToken( bool bValue, sal_uInt8 nSpaces = 0 );
422 void AppendErrorToken( sal_uInt8 nErrCode, sal_uInt8 nSpaces = 0 );
423 void AppendMissingToken( sal_uInt8 nSpaces = 0 );
424 void AppendNameToken( sal_uInt16 nNameIdx, sal_uInt8 nSpaces = 0 );
425 void AppendMissingNameToken( const OUString& rName, sal_uInt8 nSpaces = 0 );
426 void AppendNameXToken( sal_uInt16 nExtSheet, sal_uInt16 nExtName, sal_uInt8 nSpaces = 0 );
427 void AppendMacroCallToken( const XclExpExtFuncData& rExtFuncData );
428 void AppendAddInCallToken( const XclExpExtFuncData& rExtFuncData );
429 void AppendEuroToolCallToken( const XclExpExtFuncData& rExtFuncData );
430
431 void AppendOperatorTokenId( sal_uInt8 nTokenId, const XclExpOperandListRef& rxOperands, sal_uInt8 nSpaces = 0 );
432 void AppendUnaryOperatorToken( sal_uInt8 nTokenId, sal_uInt8 nSpaces = 0 );
433 void AppendBinaryOperatorToken( sal_uInt8 nTokenId, bool bValType, sal_uInt8 nSpaces = 0 );
434 void AppendLogicalOperatorToken( sal_uInt16 nXclFuncIdx, sal_uInt8 nOpCount );
435 void AppendFuncToken( const XclExpFuncData& rFuncData );
436
437 void AppendParenToken( sal_uInt8 nOpenSpaces = 0, sal_uInt8 nCloseSpaces = 0 );
438 void AppendJumpToken( XclExpFuncData& rFuncData, sal_uInt8 nAttrType );
439
440 void InsertZeros( sal_uInt16 nInsertPos, sal_uInt16 nInsertSize );
441 void Overwrite( sal_uInt16 nWriteToPos, sal_uInt16 nOffset );
442
443 void UpdateAttrGoto( sal_uInt16 nAttrPos );
444
445 bool IsSpaceToken( sal_uInt16 nPos ) const;
446 void RemoveTrailingParen();
447
448 void AppendExt( sal_uInt8 nData );
449 void AppendExt( sal_uInt8 nData, size_t nCount );
450 void AppendExt( sal_uInt16 nData );
451 void AppendExt( double fData );
452 void AppendExt( const OUString& rString );
453
454private:
455 typedef std::map< XclFormulaType, XclExpCompConfig > XclExpCompConfigMap;
456 typedef std::shared_ptr< XclExpCompData > XclExpCompDataRef;
457
461 std::vector< XclExpCompDataRef >
468 const sal_uInt16 mnMaxColMask;
469 const sal_uInt32 mnMaxRowMask;
470};
471
473 XclExpRoot( rRoot ),
474 maFuncProv( rRoot ),
475 meBiff( rRoot.GetBiff() ),
476 mnMaxAbsCol( rRoot.GetXclMaxPos().Col() ),
477 mnMaxAbsRow( rRoot.GetXclMaxPos().Row() ),
478 mnMaxScCol( rRoot.GetScMaxPos().Col() ),
479 mnMaxScRow( rRoot.GetScMaxPos().Row() ),
480 mnMaxColMask( static_cast< sal_uInt16 >( rRoot.GetXclMaxPos().Col() ) ),
481 mnMaxRowMask( static_cast< sal_uInt32 >( rRoot.GetXclMaxPos().Row() ) )
482{
483 // build the configuration map
484 for(auto const &rEntry : spConfigTable)
485 maCfgMap[ rEntry.meType ] = rEntry;
486}
487
489 const ScTokenArray& rScTokArr, const ScAddress* pScBasePos, XclExpRefLog* pRefLog )
490{
491 // initialize the compiler
492 Init( eType, rScTokArr, pScBasePos, pRefLog );
493
494 // start compilation, if initialization didn't fail
495 if( mxData->mbOk )
496 {
497 XclExpScToken aTokData( GetNextToken() );
498 FormulaError nScError = rScTokArr.GetCodeError();
499 if( (nScError != FormulaError::NONE) && (!aTokData.Is() || (aTokData.GetOpCode() == ocStop)) )
500 {
501 // #i50253# convert simple ocStop token to error code formula (e.g. =#VALUE!)
502 AppendErrorToken( XclTools::GetXclErrorCode( nScError ), aTokData.mnSpaces );
503 }
504 else if( aTokData.Is() )
505 {
506 aTokData = Expression( aTokData, false, false );
507 }
508 else
509 {
510 OSL_FAIL( "XclExpFmlaCompImpl::CreateFormula - empty token array" );
511 mxData->mbOk = false;
512 }
513
514 if( mxData->mbOk )
515 {
516 // #i44907# auto-generated SUBTOTAL formula cells have trailing ocStop token
517 mxData->mbOk = !aTokData.Is() || (aTokData.GetOpCode() == ocStop);
518 OSL_ENSURE( mxData->mbOk, "XclExpFmlaCompImpl::CreateFormula - unknown garbage behind formula" );
519 }
520 }
521
522 // finalize (add tAttrVolatile token, calculate all token classes)
525
526 // leave recursive call, create and return the final token array
527 return CreateTokenArray();
528}
529
531{
533 AppendErrorToken( nErrCode );
534 return CreateTokenArray();
535}
536
538{
540 AppendOperandTokenId( nTokenId );
541 Append( static_cast<sal_uInt16>(rXclPos.mnRow) );
542 Append( rXclPos.mnCol ); // do not use AppendAddress(), we always need 16-bit column here
543 return CreateTokenArray();
544}
545
546XclTokenArrayRef XclExpFmlaCompImpl::CreateNameXFormula( sal_uInt16 nExtSheet, sal_uInt16 nExtName )
547{
549 AppendNameXToken( nExtSheet, nExtName );
550 return CreateTokenArray();
551}
552
554{
555 const XclExpCompConfig* pCfg = GetConfigForType( eType );
556 return pCfg && pCfg->mb3DRefOnly;
557}
558
559// private --------------------------------------------------------------------
560
561const XclExpCompConfig* XclExpFmlaCompImpl::GetConfigForType( XclFormulaType eType ) const
562{
563 XclExpCompConfigMap::const_iterator aIt = maCfgMap.find( eType );
564 OSL_ENSURE( aIt != maCfgMap.end(), "XclExpFmlaCompImpl::GetConfigForType - unknown formula type" );
565 return (aIt == maCfgMap.end()) ? nullptr : &aIt->second;
566}
567
569{
570 // compiler invoked recursively? - store old working data
571 if( mxData )
572 maDataStack.push_back( mxData );
573 // new compiler working data structure
574 mxData = std::make_shared<XclExpCompData>( GetConfigForType( eType ) );
575}
576
578 const ScAddress* pScBasePos, XclExpRefLog* pRefLog )
579{
580 // common initialization
581 Init( eType );
582
583 // special initialization
584 if( mxData->mbOk ) switch( mxData->mrCfg.meType )
585 {
589 mxData->mbOk = pScBasePos != nullptr;
590 OSL_ENSURE( mxData->mbOk, "XclExpFmlaCompImpl::Init - missing cell address" );
591 mxData->mpScBasePos = pScBasePos;
592 break;
594 mxData->mbOk = pScBasePos != nullptr;
595 assert(mxData->mbOk && "XclExpFmlaCompImpl::Init - missing cell address");
596 if (mxData->mbOk)
597 {
598 // clone the passed token array, convert references relative to current cell position
599 mxData->mxOwnScTokArr = rScTokArr.Clone();
600 ScCompiler::MoveRelWrap( *mxData->mxOwnScTokArr, GetDoc(), *pScBasePos, GetDoc().MaxCol(), GetDoc().MaxRow() );
601 // don't remember pScBasePos in mxData->mpScBasePos, shared formulas use real relative refs
602 }
603 break;
604 default:;
605 }
606
607 if( mxData->mbOk )
608 {
609 // link manager to be used
610 mxData->mpLinkMgr = mxData->mrCfg.mbLocalLinkMgr ? &GetLocalLinkManager() : &GetGlobalLinkManager();
611
612 // token array iterator (use cloned token array if present)
613 mxData->maTokArrIt.Init( mxData->mxOwnScTokArr ? *mxData->mxOwnScTokArr : rScTokArr, false );
614 mxData->mpRefLog = pRefLog;
615 // Only for OOXML
617 mxData->mpScBasePos = pScBasePos;
618 }
619}
620
622{
623 if( !mxData->mbOk )
624 return;
625
626 mxData->mbOk = mxData->maOpPosStack.size() == 1;
627 OSL_ENSURE( mxData->mbOk, "XclExpFmlaCompImpl::RecalcTokenClasses - position of root token expected on stack" );
628 if( mxData->mbOk )
629 {
630 /* Cell and array formulas start with VAL conversion and VALTYPE
631 parameter type, defined names start with ARR conversion and
632 REFTYPE parameter type for the root token. */
633 bool bNameFmla = mxData->mrCfg.meClassType == EXC_CLASSTYPE_NAME;
634 XclFuncParamConv eParamConv = bNameFmla ? EXC_PARAMCONV_ARR : EXC_PARAMCONV_VAL;
635 XclExpClassConv eClassConv = bNameFmla ? EXC_CLASSCONV_ARR : EXC_CLASSCONV_VAL;
636 XclExpTokenConvInfo aConvInfo = { PopOperandPos(), eParamConv, !bNameFmla };
637 RecalcTokenClass( aConvInfo, eParamConv, eClassConv, bNameFmla );
638 }
639
640 // clear operand vectors (calls to the expensive InsertZeros() may follow)
641 mxData->maOpListVec.clear();
642 mxData->maOpPosStack.clear();
643}
644
645void XclExpFmlaCompImpl::RecalcTokenClass( const XclExpTokenConvInfo& rConvInfo,
646 XclFuncParamConv ePrevConv, XclExpClassConv ePrevClassConv, bool bWasRefClass )
647{
648 OSL_ENSURE( rConvInfo.mnTokPos < GetSize(), "XclExpFmlaCompImpl::RecalcTokenClass - invalid token position" );
649 sal_uInt8& rnTokenId = mxData->maTokVec[ rConvInfo.mnTokPos ];
650 sal_uInt8 nTokClass = GetTokenClass( rnTokenId );
651
652 // REF tokens in VALTYPE parameters behave like VAL tokens
653 if( rConvInfo.mbValType && (nTokClass == EXC_TOKCLASS_REF) )
654 {
655 nTokClass = EXC_TOKCLASS_VAL;
656 ChangeTokenClass( rnTokenId, nTokClass );
657 }
658
659 // replace RPO conversion of operator with parent conversion
660 XclFuncParamConv eConv = (rConvInfo.meConv == EXC_PARAMCONV_RPO) ? ePrevConv : rConvInfo.meConv;
661
662 // find the effective token class conversion to be performed for this token
663 XclExpClassConv eClassConv = EXC_CLASSCONV_ORG;
664 switch( eConv )
665 {
667 // conversion is forced independent of parent conversion
668 eClassConv = EXC_CLASSCONV_ORG;
669 break;
671 // conversion is forced independent of parent conversion
672 eClassConv = EXC_CLASSCONV_VAL;
673 break;
675 // conversion is forced independent of parent conversion
676 eClassConv = EXC_CLASSCONV_ARR;
677 break;
679 switch( ePrevConv )
680 {
684 /* If parent token has REF class (REF token in REFTYPE
685 function parameter), then RPT does not repeat the
686 previous explicit ORG or ARR conversion, but always
687 falls back to VAL conversion. */
688 eClassConv = bWasRefClass ? EXC_CLASSCONV_VAL : ePrevClassConv;
689 break;
691 // nested RPT repeats the previous effective conversion
692 eClassConv = ePrevClassConv;
693 break;
695 /* If parent token has REF class (REF token in REFTYPE
696 function parameter), then RPX repeats the previous
697 effective conversion (which will be either ORG or ARR,
698 but never VAL), otherwise falls back to ORG conversion. */
699 eClassConv = bWasRefClass ? ePrevClassConv : EXC_CLASSCONV_ORG;
700 break;
701 case EXC_PARAMCONV_RPO: // does not occur
702 break;
703 }
704 break;
706 /* If current token still has REF class, set previous effective
707 conversion as current conversion. This will not have an effect
708 on the REF token but is needed for RPT parameters of this
709 function that want to repeat this conversion type. If current
710 token is VAL or ARR class, the previous ARR conversion will be
711 repeated on the token, but VAL conversion will not. */
712 eClassConv = ((nTokClass == EXC_TOKCLASS_REF) || (ePrevClassConv == EXC_CLASSCONV_ARR)) ?
713 ePrevClassConv : EXC_CLASSCONV_ORG;
714 break;
715 case EXC_PARAMCONV_RPO: // does not occur (see above)
716 break;
717 }
718
719 // do the token class conversion
720 switch( eClassConv )
721 {
722 case EXC_CLASSCONV_ORG:
723 /* Cell formulas: leave the current token class. Cell formulas
724 are the only type of formulas where all tokens can keep
725 their original token class.
726 Array and defined name formulas: convert VAL to ARR. */
727 if( (mxData->mrCfg.meClassType != EXC_CLASSTYPE_CELL) && (nTokClass == EXC_TOKCLASS_VAL) )
728 {
729 nTokClass = EXC_TOKCLASS_ARR;
730 ChangeTokenClass( rnTokenId, nTokClass );
731 }
732 break;
733 case EXC_CLASSCONV_VAL:
734 // convert ARR to VAL
735 if( nTokClass == EXC_TOKCLASS_ARR )
736 {
737 nTokClass = EXC_TOKCLASS_VAL;
738 ChangeTokenClass( rnTokenId, nTokClass );
739 }
740 break;
741 case EXC_CLASSCONV_ARR:
742 // convert VAL to ARR
743 if( nTokClass == EXC_TOKCLASS_VAL )
744 {
745 nTokClass = EXC_TOKCLASS_ARR;
746 ChangeTokenClass( rnTokenId, nTokClass );
747 }
748 break;
749 }
750
751 // do conversion for nested operands, if token is an operator or function
752 if( rConvInfo.mnTokPos < mxData->maOpListVec.size() )
753 if( const XclExpOperandList* pOperands = mxData->maOpListVec[ rConvInfo.mnTokPos ].get() )
754 for( const auto& rOperand : *pOperands )
755 RecalcTokenClass( rOperand, eConv, eClassConv, nTokClass == EXC_TOKCLASS_REF );
756}
757
759{
760 if( mxData->mbOk )
761 {
762 // Volatile? Add a tAttrVolatile token at the beginning of the token array.
763 if( mxData->mbVolatile )
764 {
765 // tAttrSpace token can be extended with volatile flag
766 if( !IsSpaceToken( 0 ) )
767 {
768 InsertZeros( 0, 4 );
769 mxData->maTokVec[ 0 ] = EXC_TOKID_ATTR;
770 }
771 mxData->maTokVec[ 1 ] |= EXC_TOK_ATTR_VOLATILE;
772 }
773
774 // Token array too long? -> error
775 mxData->mbOk = mxData->maTokVec.size() <= EXC_TOKARR_MAXLEN;
776 }
777
778 if( !mxData->mbOk )
779 {
780 // Any unrecoverable error? -> Create a =#NA formula.
781 mxData->maTokVec.clear();
782 mxData->maExtDataVec.clear();
783 mxData->mbVolatile = false;
785 }
786}
787
789{
790 // create the Excel token array from working data before resetting mxData
791 OSL_ENSURE( mxData->mrCfg.mbAllowArrays || mxData->maExtDataVec.empty(), "XclExpFmlaCompImpl::CreateTokenArray - unexpected extended data" );
792 if( !mxData->mrCfg.mbAllowArrays )
793 mxData->maExtDataVec.clear();
794 XclTokenArrayRef xTokArr = std::make_shared<XclTokenArray>( mxData->maTokVec, mxData->maExtDataVec, mxData->mbVolatile );
795 mxData.reset();
796
797 // compiler invoked recursively? - restore old working data
798 if( !maDataStack.empty() )
799 {
800 mxData = maDataStack.back();
801 maDataStack.pop_back();
802 }
803
804 return xTokArr;
805}
806
807// compiler -------------------------------------------------------------------
808
810{
811 const FormulaToken* pScToken = mxData->maTokArrIt.Get();
812 ++mxData->maTokArrIt;
813 return pScToken;
814}
815
816const FormulaToken* XclExpFmlaCompImpl::PeekNextRawToken() const
817{
818 /* Returns pointer to next raw token in the token array. The token array
819 iterator already points to the next token (A call to GetNextToken()
820 always increases the iterator), so this function just returns the token
821 the iterator points to. To skip space tokens, a copy of the iterator is
822 created and set to the passed skip-spaces mode. If spaces have to be
823 skipped, and the iterator currently points to a space token, the
824 constructor will move it to the next non-space token. */
825 XclTokenArrayIterator aTempIt( mxData->maTokArrIt, true/*bSkipSpaces*/ );
826 return aTempIt.Get();
827}
828
829bool XclExpFmlaCompImpl::GetNextToken( XclExpScToken& rTokData )
830{
831 rTokData.mpScToken = GetNextRawToken();
832 rTokData.mnSpaces = 0;
833 /* TODO: handle ocWhitespace characters? */
834 while (rTokData.GetOpCode() == ocSpaces || rTokData.GetOpCode() == ocWhitespace)
835 {
836 rTokData.mnSpaces += rTokData.mpScToken->GetByte();
837 rTokData.mpScToken = GetNextRawToken();
838 }
839 return rTokData.Is();
840}
841
843{
844 XclExpScToken aTokData;
845 GetNextToken( aTokData );
846 return aTokData;
847}
848
849namespace {
850
852sal_uInt8 lclGetCompareTokenId( OpCode eOpCode )
853{
854 switch( eOpCode )
855 {
856 case ocLess: return EXC_TOKID_LT;
857 case ocLessEqual: return EXC_TOKID_LE;
858 case ocEqual: return EXC_TOKID_EQ;
859 case ocGreaterEqual: return EXC_TOKID_GE;
860 case ocGreater: return EXC_TOKID_GT;
861 case ocNotEqual: return EXC_TOKID_NE;
862 default:;
863 }
864 return EXC_TOKID_NONE;
865}
866
868sal_uInt8 lclGetConcatTokenId( OpCode eOpCode )
869{
870 return (eOpCode == ocAmpersand) ? EXC_TOKID_CONCAT : EXC_TOKID_NONE;
871}
872
874sal_uInt8 lclGetAddSubTokenId( OpCode eOpCode )
875{
876 switch( eOpCode )
877 {
878 case ocAdd: return EXC_TOKID_ADD;
879 case ocSub: return EXC_TOKID_SUB;
880 default:;
881 }
882 return EXC_TOKID_NONE;
883}
884
886sal_uInt8 lclGetMulDivTokenId( OpCode eOpCode )
887{
888 switch( eOpCode )
889 {
890 case ocMul: return EXC_TOKID_MUL;
891 case ocDiv: return EXC_TOKID_DIV;
892 default:;
893 }
894 return EXC_TOKID_NONE;
895}
896
898sal_uInt8 lclGetPowTokenId( OpCode eOpCode )
899{
900 return (eOpCode == ocPow) ? EXC_TOKID_POWER : EXC_TOKID_NONE;
901}
902
904sal_uInt8 lclGetUnaryPostTokenId( OpCode eOpCode )
905{
906 return (eOpCode == ocPercentSign) ? EXC_TOKID_PERCENT : EXC_TOKID_NONE;
907}
908
910sal_uInt8 lclGetUnaryPreTokenId( OpCode eOpCode )
911{
912 switch( eOpCode )
913 {
914 case ocAdd: return EXC_TOKID_UPLUS; // +(1)
915 case ocNeg: return EXC_TOKID_UMINUS; // NEG(1)
916 case ocNegSub: return EXC_TOKID_UMINUS; // -(1)
917 default:;
918 }
919 return EXC_TOKID_NONE;
920}
921
923sal_uInt8 lclGetListTokenId( OpCode eOpCode, bool bStopAtSep )
924{
925 return ((eOpCode == ocUnion) || (!bStopAtSep && (eOpCode == ocSep))) ? EXC_TOKID_LIST : EXC_TOKID_NONE;
926}
927
929sal_uInt8 lclGetIntersectTokenId( OpCode eOpCode )
930{
931 return (eOpCode == ocIntersect) ? EXC_TOKID_ISECT : EXC_TOKID_NONE;
932}
933
935sal_uInt8 lclGetRangeTokenId( OpCode eOpCode )
936{
937 return (eOpCode == ocRange) ? EXC_TOKID_RANGE : EXC_TOKID_NONE;
938}
939
940} // namespace
941
942XclExpScToken XclExpFmlaCompImpl::Expression( XclExpScToken aTokData, bool bInParentheses, bool bStopAtSep )
943{
944 if( mxData->mbOk && aTokData.Is() )
945 {
946 // remember old stop-at-ocSep mode, restored below
947 bool bOldStopAtSep = mxData->mbStopAtSep;
948 mxData->mbStopAtSep = bStopAtSep;
949 // start compilation of the subexpression
950 aTokData = OrTerm( aTokData, bInParentheses );
951 // restore old stop-at-ocSep mode
952 mxData->mbStopAtSep = bOldStopAtSep;
953 }
954 return aTokData;
955}
956
957XclExpScToken XclExpFmlaCompImpl::SkipExpression( XclExpScToken aTokData, bool bStopAtSep )
958{
959 while( mxData->mbOk && aTokData.Is() && (aTokData.GetOpCode() != ocClose) && (!bStopAtSep || (aTokData.GetOpCode() != ocSep)) )
960 {
961 if( aTokData.GetOpCode() == ocOpen )
962 {
963 aTokData = SkipExpression( GetNextToken(), false );
964 if( mxData->mbOk ) mxData->mbOk = aTokData.GetOpCode() == ocClose;
965 }
966 aTokData = GetNextToken();
967 }
968 return aTokData;
969}
970
971XclExpScToken XclExpFmlaCompImpl::OrTerm( XclExpScToken aTokData, bool bInParentheses )
972{
973 aTokData = AndTerm( aTokData, bInParentheses );
974 sal_uInt8 nParamCount = 1;
975 while( mxData->mbOk && (aTokData.GetOpCode() == ocOr) )
976 {
978 aTokData = AndTerm( GetNextToken(), bInParentheses );
980 ++nParamCount;
981 if( mxData->mbOk ) mxData->mbOk = nParamCount <= EXC_FUNC_MAXPARAM;
982 }
983 if( mxData->mbOk && (nParamCount > 1) )
985 return aTokData;
986}
987
988XclExpScToken XclExpFmlaCompImpl::AndTerm( XclExpScToken aTokData, bool bInParentheses )
989{
990 aTokData = CompareTerm( aTokData, bInParentheses );
991 sal_uInt8 nParamCount = 1;
992 while( mxData->mbOk && (aTokData.GetOpCode() == ocAnd) )
993 {
995 aTokData = CompareTerm( GetNextToken(), bInParentheses );
997 ++nParamCount;
998 if( mxData->mbOk ) mxData->mbOk = nParamCount <= EXC_FUNC_MAXPARAM;
999 }
1000 if( mxData->mbOk && (nParamCount > 1) )
1002 return aTokData;
1003}
1004
1005XclExpScToken XclExpFmlaCompImpl::CompareTerm( XclExpScToken aTokData, bool bInParentheses )
1006{
1007 aTokData = ConcatTerm( aTokData, bInParentheses );
1008 while( mxData->mbOk )
1009 {
1010 sal_uInt8 nOpTokenId = lclGetConcatTokenId( aTokData.GetOpCode() );
1011 if (nOpTokenId == EXC_TOKID_NONE)
1012 break;
1013 sal_uInt8 nSpaces = aTokData.mnSpaces;
1014 aTokData = ConcatTerm( GetNextToken(), bInParentheses );
1015 AppendBinaryOperatorToken( nOpTokenId, true, nSpaces );
1016 }
1017 return aTokData;
1018}
1019
1020XclExpScToken XclExpFmlaCompImpl::ConcatTerm( XclExpScToken aTokData, bool bInParentheses )
1021{
1022 aTokData = AddSubTerm( aTokData, bInParentheses );
1023 while( mxData->mbOk )
1024 {
1025 sal_uInt8 nOpTokenId = lclGetCompareTokenId( aTokData.GetOpCode() );
1026 if (nOpTokenId == EXC_TOKID_NONE)
1027 break;
1028 sal_uInt8 nSpaces = aTokData.mnSpaces;
1029 aTokData = AddSubTerm( GetNextToken(), bInParentheses );
1030 AppendBinaryOperatorToken( nOpTokenId, true, nSpaces );
1031 }
1032 return aTokData;
1033}
1034
1035XclExpScToken XclExpFmlaCompImpl::AddSubTerm( XclExpScToken aTokData, bool bInParentheses )
1036{
1037 aTokData = MulDivTerm( aTokData, bInParentheses );
1038 while( mxData->mbOk )
1039 {
1040 sal_uInt8 nOpTokenId = lclGetAddSubTokenId( aTokData.GetOpCode() );
1041 if (nOpTokenId == EXC_TOKID_NONE)
1042 break;
1043 sal_uInt8 nSpaces = aTokData.mnSpaces;
1044 aTokData = MulDivTerm( GetNextToken(), bInParentheses );
1045 AppendBinaryOperatorToken( nOpTokenId, true, nSpaces );
1046 }
1047 return aTokData;
1048}
1049
1050XclExpScToken XclExpFmlaCompImpl::MulDivTerm( XclExpScToken aTokData, bool bInParentheses )
1051{
1052 aTokData = PowTerm( aTokData, bInParentheses );
1053 while( mxData->mbOk )
1054 {
1055 sal_uInt8 nOpTokenId = lclGetMulDivTokenId( aTokData.GetOpCode() );
1056 if (nOpTokenId == EXC_TOKID_NONE)
1057 break;
1058 sal_uInt8 nSpaces = aTokData.mnSpaces;
1059 aTokData = PowTerm( GetNextToken(), bInParentheses );
1060 AppendBinaryOperatorToken( nOpTokenId, true, nSpaces );
1061 }
1062 return aTokData;
1063}
1064
1065XclExpScToken XclExpFmlaCompImpl::PowTerm( XclExpScToken aTokData, bool bInParentheses )
1066{
1067 aTokData = UnaryPostTerm( aTokData, bInParentheses );
1068 sal_uInt8 nOpTokenId = EXC_TOKID_NONE;
1069 while( mxData->mbOk )
1070 {
1071 nOpTokenId = lclGetPowTokenId( aTokData.GetOpCode() );
1072 if (nOpTokenId == EXC_TOKID_NONE)
1073 break;
1074 sal_uInt8 nSpaces = aTokData.mnSpaces;
1075 aTokData = UnaryPostTerm( GetNextToken(), bInParentheses );
1076 AppendBinaryOperatorToken( nOpTokenId, true, nSpaces );
1077 }
1078 return aTokData;
1079}
1080
1081XclExpScToken XclExpFmlaCompImpl::UnaryPostTerm( XclExpScToken aTokData, bool bInParentheses )
1082{
1083 aTokData = UnaryPreTerm( aTokData, bInParentheses );
1084 sal_uInt8 nOpTokenId = EXC_TOKID_NONE;
1085 while( mxData->mbOk )
1086 {
1087 nOpTokenId = lclGetUnaryPostTokenId( aTokData.GetOpCode() );
1088 if (nOpTokenId == EXC_TOKID_NONE)
1089 break;
1090 AppendUnaryOperatorToken( nOpTokenId, aTokData.mnSpaces );
1091 GetNextToken( aTokData );
1092 }
1093 return aTokData;
1094}
1095
1096XclExpScToken XclExpFmlaCompImpl::UnaryPreTerm( XclExpScToken aTokData, bool bInParentheses )
1097{
1098 sal_uInt8 nOpTokenId = mxData->mbOk ? lclGetUnaryPreTokenId( aTokData.GetOpCode() ) : EXC_TOKID_NONE;
1099 if( nOpTokenId != EXC_TOKID_NONE )
1100 {
1101 sal_uInt8 nSpaces = aTokData.mnSpaces;
1102 aTokData = UnaryPreTerm( GetNextToken(), bInParentheses );
1103 AppendUnaryOperatorToken( nOpTokenId, nSpaces );
1104 }
1105 else
1106 {
1107 aTokData = ListTerm( aTokData, bInParentheses );
1108 }
1109 return aTokData;
1110}
1111
1112XclExpScToken XclExpFmlaCompImpl::ListTerm( XclExpScToken aTokData, bool bInParentheses )
1113{
1114 sal_uInt16 nSubExprPos = GetSize();
1115 bool bHasAnyRefOp = false;
1116 bool bHasListOp = false;
1117 aTokData = IntersectTerm( aTokData, bHasAnyRefOp );
1118 while( mxData->mbOk )
1119 {
1120 sal_uInt8 nOpTokenId = lclGetListTokenId( aTokData.GetOpCode(), mxData->mbStopAtSep );
1121 if (nOpTokenId == EXC_TOKID_NONE)
1122 break;
1123 sal_uInt8 nSpaces = aTokData.mnSpaces;
1124 aTokData = IntersectTerm( GetNextToken(), bHasAnyRefOp );
1125 AppendBinaryOperatorToken( nOpTokenId, false, nSpaces );
1126 bHasAnyRefOp = bHasListOp = true;
1127 }
1128 if( bHasAnyRefOp )
1129 {
1130 // add a tMemFunc token enclosing the entire reference subexpression
1131 sal_uInt16 nSubExprSize = GetSize() - nSubExprPos;
1132 InsertZeros( nSubExprPos, 3 );
1133 mxData->maTokVec[ nSubExprPos ] = GetTokenId( EXC_TOKID_MEMFUNC, EXC_TOKCLASS_REF );
1134 Overwrite( nSubExprPos + 1, nSubExprSize );
1135 // update the operand/operator stack (set the list expression as operand of the tMemFunc)
1136 XclExpOperandListRef xOperands = std::make_shared<XclExpOperandList>();
1137 xOperands->AppendOperand( PopOperandPos(), EXC_PARAMCONV_VAL, false );
1138 PushOperatorPos( nSubExprPos, xOperands );
1139 }
1140 // #i86439# enclose list operator into parentheses, e.g. Calc's =AREAS(A1~A2) to Excel's =AREAS((A1;A2))
1141 if( bHasListOp && !bInParentheses )
1143 return aTokData;
1144}
1145
1146XclExpScToken XclExpFmlaCompImpl::IntersectTerm( XclExpScToken aTokData, bool& rbHasRefOp )
1147{
1148 aTokData = RangeTerm( aTokData, rbHasRefOp );
1149 while( mxData->mbOk )
1150 {
1151 sal_uInt8 nOpTokenId = lclGetIntersectTokenId( aTokData.GetOpCode() );
1152 if (nOpTokenId ==EXC_TOKID_NONE)
1153 break;
1154 sal_uInt8 nSpaces = aTokData.mnSpaces;
1155 aTokData = RangeTerm( GetNextToken(), rbHasRefOp );
1156 AppendBinaryOperatorToken( nOpTokenId, false, nSpaces );
1157 rbHasRefOp = true;
1158 }
1159 return aTokData;
1160}
1161
1162XclExpScToken XclExpFmlaCompImpl::RangeTerm( XclExpScToken aTokData, bool& rbHasRefOp )
1163{
1164 aTokData = Factor( aTokData );
1165 while( mxData->mbOk )
1166 {
1167 sal_uInt8 nOpTokenId = lclGetRangeTokenId( aTokData.GetOpCode() );
1168 if (nOpTokenId == EXC_TOKID_NONE)
1169 break;
1170 sal_uInt8 nSpaces = aTokData.mnSpaces;
1171 aTokData = Factor( GetNextToken() );
1172 AppendBinaryOperatorToken( nOpTokenId, false, nSpaces );
1173 rbHasRefOp = true;
1174 }
1175 return aTokData;
1176}
1177
1178XclExpScToken XclExpFmlaCompImpl::Factor( XclExpScToken aTokData )
1179{
1180 if( !mxData->mbOk || !aTokData.Is() ) return XclExpScToken();
1181
1182 switch( aTokData.GetType() )
1183 {
1184 case svUnknown: mxData->mbOk = false; break;
1185 case svDouble: ProcessDouble( aTokData ); break;
1186 case svString: ProcessString( aTokData ); break;
1187 case svSingleRef: ProcessCellRef( aTokData ); break;
1188 case svDoubleRef: ProcessRangeRef( aTokData ); break;
1189 case svExternalSingleRef: ProcessExternalCellRef( aTokData ); break;
1190 case svExternalDoubleRef: ProcessExternalRangeRef( aTokData ); break;
1191 case svExternalName: ProcessExternalName( aTokData ); break;
1192 case svMatrix: ProcessMatrix( aTokData ); break;
1193 case svExternal: ProcessExternal( aTokData ); break;
1194
1195 default: switch( aTokData.GetOpCode() )
1196 {
1197 case ocNone: /* do nothing */ break;
1198 case ocMissing: ProcessMissing( aTokData ); break;
1199 case ocBad: ProcessBad( aTokData ); break;
1200 case ocOpen: ProcessParentheses( aTokData ); break;
1201 case ocName: ProcessDefinedName( aTokData ); break;
1202 case ocFalse:
1203 case ocTrue: ProcessBoolean( aTokData ); break;
1204 case ocDde: ProcessDdeLink( aTokData ); break;
1205 default: ProcessFunction( aTokData );
1206 }
1207 }
1208
1209 return GetNextToken();
1210}
1211
1212// formula structure ----------------------------------------------------------
1213
1214void XclExpFmlaCompImpl::ProcessDouble( const XclExpScToken& rTokData )
1215{
1216 double fValue = rTokData.mpScToken->GetDouble();
1217 double fInt;
1218 double fFrac = modf( fValue, &fInt );
1219 if( (fFrac == 0.0) && (0.0 <= fInt) && (fInt <= 65535.0) )
1220 AppendIntToken( static_cast< sal_uInt16 >( fInt ), rTokData.mnSpaces );
1221 else
1222 AppendNumToken( fValue, rTokData.mnSpaces );
1223}
1224
1225void XclExpFmlaCompImpl::ProcessString( const XclExpScToken& rTokData )
1226{
1227 AppendOperandTokenId( EXC_TOKID_STR, rTokData.mnSpaces );
1228 Append( rTokData.mpScToken->GetString().getString() );
1229}
1230
1231void XclExpFmlaCompImpl::ProcessMissing( const XclExpScToken& rTokData )
1232{
1233 AppendMissingToken( rTokData.mnSpaces );
1234}
1235
1236void XclExpFmlaCompImpl::ProcessBad( const XclExpScToken& rTokData )
1237{
1238 AppendErrorToken( EXC_ERR_NA, rTokData.mnSpaces );
1239}
1240
1241void XclExpFmlaCompImpl::ProcessParentheses( const XclExpScToken& rTokData )
1242{
1243 XclExpScToken aTokData = Expression( GetNextToken(), true, false );
1244 mxData->mbOk = aTokData.GetOpCode() == ocClose;
1245 AppendParenToken( rTokData.mnSpaces, aTokData.mnSpaces );
1246}
1247
1248void XclExpFmlaCompImpl::ProcessBoolean( const XclExpScToken& rTokData )
1249{
1250 mxData->mbOk = GetNextToken().GetOpCode() == ocOpen;
1251 if( mxData->mbOk ) mxData->mbOk = GetNextToken().GetOpCode() == ocClose;
1252 if( mxData->mbOk )
1253 AppendBoolToken( rTokData.GetOpCode() == ocTrue, rTokData.mnSpaces );
1254}
1255
1256namespace {
1257
1258bool lclGetTokenString( OUString& rString, const XclExpScToken& rTokData )
1259{
1260 bool bIsStr = (rTokData.GetType() == svString) && (rTokData.GetOpCode() == ocPush);
1261 if( bIsStr )
1262 rString = rTokData.mpScToken->GetString().getString();
1263 return bIsStr;
1264}
1265
1266} // namespace
1267
1268void XclExpFmlaCompImpl::ProcessDdeLink( const XclExpScToken& rTokData )
1269{
1270 OUString aApplic, aTopic, aItem;
1271
1272 mxData->mbOk = GetNextToken().GetOpCode() == ocOpen;
1273 if( mxData->mbOk ) mxData->mbOk = lclGetTokenString( aApplic, GetNextToken() );
1274 if( mxData->mbOk ) mxData->mbOk = GetNextToken().GetOpCode() == ocSep;
1275 if( mxData->mbOk ) mxData->mbOk = lclGetTokenString( aTopic, GetNextToken() );
1276 if( mxData->mbOk ) mxData->mbOk = GetNextToken().GetOpCode() == ocSep;
1277 if( mxData->mbOk ) mxData->mbOk = lclGetTokenString( aItem, GetNextToken() );
1278 if( mxData->mbOk ) mxData->mbOk = GetNextToken().GetOpCode() == ocClose;
1279 if( mxData->mbOk ) mxData->mbOk = !aApplic.isEmpty() && !aTopic.isEmpty() && !aItem.isEmpty();
1280 if( mxData->mbOk )
1281 {
1282 sal_uInt16 nExtSheet(0), nExtName(0);
1283 if( mxData->mpLinkMgr && mxData->mpLinkMgr->InsertDde( nExtSheet, nExtName, aApplic, aTopic, aItem ) )
1284 AppendNameXToken( nExtSheet, nExtName, rTokData.mnSpaces );
1285 else
1286 AppendErrorToken( EXC_ERR_NA, rTokData.mnSpaces );
1287 }
1288}
1289
1290void XclExpFmlaCompImpl::ProcessExternal( const XclExpScToken& rTokData )
1291{
1292 /* #i47228# Excel import generates svExternal/ocMacro tokens for invalid
1293 names and for external/invalid function calls. This function looks for
1294 the next token in the token array. If it is an opening parenthesis, the
1295 token is processed as external function call, otherwise as undefined name. */
1296 const FormulaToken* pNextScToken = PeekNextRawToken();
1297 if( !pNextScToken || (pNextScToken->GetOpCode() != ocOpen) )
1298 AppendMissingNameToken( rTokData.mpScToken->GetExternal(), rTokData.mnSpaces );
1299 else
1300 ProcessFunction( rTokData );
1301}
1302
1303void XclExpFmlaCompImpl::ProcessMatrix( const XclExpScToken& rTokData )
1304{
1305 const ScMatrix* pMatrix = rTokData.mpScToken->GetMatrix();
1306 if( pMatrix && mxData->mrCfg.mbAllowArrays )
1307 {
1308 SCSIZE nScCols, nScRows;
1309 pMatrix->GetDimensions( nScCols, nScRows );
1310 OSL_ENSURE( (nScCols > 0) && (nScRows > 0), "XclExpFmlaCompImpl::ProcessMatrix - invalid matrix size" );
1311 sal_uInt16 nCols = ::limit_cast< sal_uInt16 >( nScCols, 0, 256 );
1312 sal_uInt16 nRows = ::limit_cast< sal_uInt16 >( nScRows, 0, 1024 );
1313
1314 // create the tArray token
1316 Append( static_cast< sal_uInt8 >( (meBiff == EXC_BIFF8) ? (nCols - 1) : nCols ) );
1317 Append( static_cast< sal_uInt16 >( (meBiff == EXC_BIFF8) ? (nRows - 1) : nRows ) );
1318 Append( static_cast< sal_uInt32 >( 0 ) );
1319
1320 // create the extended data containing the array values
1321 AppendExt( static_cast< sal_uInt8 >( (meBiff == EXC_BIFF8) ? (nCols - 1) : nCols ) );
1322 AppendExt( static_cast< sal_uInt16 >( (meBiff == EXC_BIFF8) ? (nRows - 1) : nRows ) );
1323 for( SCSIZE nScRow = 0; nScRow < nScRows; ++nScRow )
1324 {
1325 for( SCSIZE nScCol = 0; nScCol < nScCols; ++nScCol )
1326 {
1327 ScMatrixValue nMatVal = pMatrix->Get( nScCol, nScRow );
1328 if( ScMatrix::IsValueType( nMatVal.nType ) ) // value, boolean, or error
1329 {
1330 FormulaError nErr;
1331 if( ScMatrix::IsBooleanType( nMatVal.nType ) )
1332 {
1334 AppendExt( static_cast< sal_uInt8 >( nMatVal.GetBoolean() ? 1 : 0 ) );
1335 AppendExt( 0, 7 );
1336 }
1337 else if( (nErr = nMatVal.GetError()) != FormulaError::NONE )
1338 {
1341 AppendExt( 0, 7 );
1342 }
1343 else
1344 {
1346 AppendExt( nMatVal.fVal );
1347 }
1348 }
1349 else // string or empty
1350 {
1351 const OUString aStr( nMatVal.GetString().getString());
1352 if( aStr.isEmpty() )
1353 {
1355 AppendExt( 0, 8 );
1356 }
1357 else
1358 {
1360 AppendExt( aStr );
1361 }
1362 }
1363 }
1364 }
1365 }
1366 else
1367 {
1368 // array in places that do not allow it (cond fmts, data validation)
1369 AppendErrorToken( EXC_ERR_NA, rTokData.mnSpaces );
1370 }
1371}
1372
1373void XclExpFmlaCompImpl::ProcessFunction( const XclExpScToken& rTokData )
1374{
1375 OpCode eOpCode = rTokData.GetOpCode();
1376 const XclFunctionInfo* pFuncInfo = maFuncProv.GetFuncInfoFromOpCode( eOpCode );
1377
1378 XclExpExtFuncData aExtFuncData;
1379
1380 // no exportable function found - try to create an external macro call
1381 if( !pFuncInfo && (eOpCode >= SC_OPCODE_START_NO_PAR) )
1382 {
1383 const OUString& rFuncName = ScCompiler::GetNativeSymbol( eOpCode );
1384 if( !rFuncName.isEmpty() )
1385 {
1386 aExtFuncData.Set( rFuncName, true, false );
1388 }
1389 }
1390
1391 mxData->mbOk = pFuncInfo != nullptr;
1392 if( !mxData->mbOk ) return;
1393
1394 // internal functions equivalent to an existing add-in
1395 if( pFuncInfo->IsAddInEquivalent() )
1396 aExtFuncData.Set( pFuncInfo->GetAddInEquivalentFuncName(), true, false );
1397 // functions simulated by a macro call in file format
1398 else if( pFuncInfo->IsMacroFunc() )
1399 aExtFuncData.Set( pFuncInfo->GetMacroFuncName(), false, true );
1400
1401 XclExpFuncData aFuncData( rTokData, *pFuncInfo, std::move(aExtFuncData) );
1402 XclExpScToken aTokData;
1403
1404 // preparations for special functions, before function processing starts
1405 PrepareFunction( aFuncData );
1406
1407 enum { STATE_START, STATE_OPEN, STATE_PARAM, STATE_SEP, STATE_CLOSE, STATE_END }
1408 eState = STATE_START;
1409 while( eState != STATE_END ) switch( eState )
1410 {
1411 case STATE_START:
1412 mxData->mbOk = GetNextToken( aTokData ) && (aTokData.GetOpCode() == ocOpen);
1413 eState = mxData->mbOk ? STATE_OPEN : STATE_END;
1414 break;
1415 case STATE_OPEN:
1416 mxData->mbOk = GetNextToken( aTokData );
1417 eState = mxData->mbOk ? ((aTokData.GetOpCode() == ocClose) ? STATE_CLOSE : STATE_PARAM) : STATE_END;
1418 break;
1419 case STATE_PARAM:
1420 aTokData = ProcessParam( aTokData, aFuncData );
1421 switch( aTokData.GetOpCode() )
1422 {
1423 case ocSep: eState = STATE_SEP; break;
1424 case ocClose: eState = STATE_CLOSE; break;
1425 default: mxData->mbOk = false;
1426 }
1427 if( !mxData->mbOk ) eState = STATE_END;
1428 break;
1429 case STATE_SEP:
1430 mxData->mbOk = (aFuncData.GetParamCount() < EXC_FUNC_MAXPARAM) && GetNextToken( aTokData );
1431 eState = mxData->mbOk ? STATE_PARAM : STATE_END;
1432 break;
1433 case STATE_CLOSE:
1434 FinishFunction( aFuncData, aTokData.mnSpaces );
1435 eState = STATE_END;
1436 break;
1437 default:;
1438 }
1439}
1440
1441void XclExpFmlaCompImpl::PrepareFunction( const XclExpFuncData& rFuncData )
1442{
1443 // For OOXML these are not rewritten anymore.
1445 return;
1446
1447 switch( rFuncData.GetOpCode() )
1448 {
1449 case ocCosecant: // simulate CSC(x) by (1/SIN(x))
1450 case ocSecant: // simulate SEC(x) by (1/COS(x))
1451 case ocCot: // simulate COT(x) by (1/TAN(x))
1452 case ocCosecantHyp: // simulate CSCH(x) by (1/SINH(x))
1453 case ocSecantHyp: // simulate SECH(x) by (1/COSH(x))
1454 case ocCotHyp: // simulate COTH(x) by (1/TANH(x))
1455 AppendIntToken( 1 );
1456 break;
1457 case ocArcCot: // simulate ACOT(x) by (PI/2-ATAN(x))
1458 AppendNumToken( M_PI_2 );
1459 break;
1460 default:;
1461 }
1462}
1463
1464void XclExpFmlaCompImpl::FinishFunction( XclExpFuncData& rFuncData, sal_uInt8 nCloseSpaces )
1465{
1466 // append missing parameters required in Excel, may modify param count
1467 AppendTrailingParam( rFuncData );
1468
1469 // check if parameter count fits into the limits of the function
1470 sal_uInt8 nParamCount = rFuncData.GetParamCount();
1471 if( (rFuncData.GetMinParamCount() <= nParamCount) && (nParamCount <= rFuncData.GetMaxParamCount()) )
1472 {
1473 // first put the tAttrSpace tokens, they must not be included in tAttrGoto handling
1475 AppendSpaceToken( EXC_TOK_ATTR_SPACE_SP, rFuncData.GetSpaces() );
1476
1477 // add tAttrGoto tokens for IF or CHOOSE functions
1478 switch( rFuncData.GetOpCode() )
1479 {
1480 case ocIf:
1481 case ocChoose:
1482 AppendJumpToken( rFuncData, EXC_TOK_ATTR_GOTO );
1483 break;
1484 default:;
1485 }
1486
1487 // put the tFunc or tFuncVar token (or another special token, e.g. tAttrSum)
1488 AppendFuncToken( rFuncData );
1489
1490 // update volatile flag - is set if at least one used function is volatile
1491 mxData->mbVolatile |= rFuncData.IsVolatile();
1492
1493 // update jump tokens for specific functions, add additional tokens
1494 switch( rFuncData.GetOpCode() )
1495 {
1496 case ocIf:
1497 FinishIfFunction( rFuncData );
1498 break;
1499 case ocChoose:
1500 FinishChooseFunction( rFuncData );
1501 break;
1502
1503 case ocCosecant: // simulate CSC(x) by (1/SIN(x))
1504 case ocSecant: // simulate SEC(x) by (1/COS(x))
1505 case ocCot: // simulate COT(x) by (1/TAN(x))
1506 case ocCosecantHyp: // simulate CSCH(x) by (1/SINH(x))
1507 case ocSecantHyp: // simulate SECH(x) by (1/COSH(x))
1508 case ocCotHyp: // simulate COTH(x) by (1/TANH(x))
1509 // For OOXML not rewritten anymore.
1511 {
1514 }
1515 break;
1516 case ocArcCot: // simulate ACOT(x) by (PI/2-ATAN(x))
1517 // For OOXML not rewritten anymore.
1519 {
1522 }
1523 break;
1524
1525 default:;
1526 }
1527 }
1528 else
1529 mxData->mbOk = false;
1530}
1531
1532void XclExpFmlaCompImpl::FinishIfFunction( XclExpFuncData& rFuncData )
1533{
1534 sal_uInt16 nParamCount = rFuncData.GetParamCount();
1535 OSL_ENSURE( (nParamCount == 2) || (nParamCount == 3), "XclExpFmlaCompImpl::FinishIfFunction - wrong parameter count" );
1536 const ScfUInt16Vec& rAttrPos = rFuncData.GetAttrPosVec();
1537 OSL_ENSURE( nParamCount == rAttrPos.size(), "XclExpFmlaCompImpl::FinishIfFunction - wrong number of tAttr tokens" );
1538 // update tAttrIf token following the condition parameter
1539 Overwrite( rAttrPos[ 0 ] + 2, static_cast< sal_uInt16 >( rAttrPos[ 1 ] - rAttrPos[ 0 ] ) );
1540 // update the tAttrGoto tokens following true and false parameters
1541 UpdateAttrGoto( rAttrPos[ 1 ] );
1542 if( nParamCount == 3 )
1543 UpdateAttrGoto( rAttrPos[ 2 ] );
1544}
1545
1546void XclExpFmlaCompImpl::FinishChooseFunction( XclExpFuncData& rFuncData )
1547{
1548 sal_uInt16 nParamCount = rFuncData.GetParamCount();
1549 ScfUInt16Vec& rAttrPos = rFuncData.GetAttrPosVec();
1550 OSL_ENSURE( nParamCount == rAttrPos.size(), "XclExpFmlaCompImpl::FinishChooseFunction - wrong number of tAttr tokens" );
1551 // number of choices is parameter count minus 1
1552 sal_uInt16 nChoices = nParamCount - 1;
1553 // tAttrChoose token contains number of choices
1554 Overwrite( rAttrPos[ 0 ] + 2, nChoices );
1555 // cache position of the jump table (follows number of choices in tAttrChoose token)
1556 sal_uInt16 nJumpArrPos = rAttrPos[ 0 ] + 4;
1557 // size of jump table: number of choices, plus 1 for error position
1558 sal_uInt16 nJumpArrSize = 2 * (nChoices + 1);
1559 // insert the jump table into the tAttrChoose token
1560 InsertZeros( nJumpArrPos, nJumpArrSize );
1561 // update positions of tAttrGoto tokens after jump table insertion
1562 sal_uInt16 nIdx;
1563 for( nIdx = 1; nIdx < nParamCount; ++nIdx )
1564 rAttrPos[ nIdx ] = rAttrPos[ nIdx ] + nJumpArrSize;
1565 // update the tAttrGoto tokens (they contain a value one-less to real distance)
1566 for( nIdx = 1; nIdx < nParamCount; ++nIdx )
1567 UpdateAttrGoto( rAttrPos[ nIdx ] );
1568 // update the distances in the jump table
1569 Overwrite( nJumpArrPos, nJumpArrSize );
1570 for( nIdx = 1; nIdx < nParamCount; ++nIdx )
1571 Overwrite( nJumpArrPos + 2 * nIdx, static_cast< sal_uInt16 >( rAttrPos[ nIdx ] + 4 - nJumpArrPos ) );
1572}
1573
1574XclExpScToken XclExpFmlaCompImpl::ProcessParam( XclExpScToken aTokData, XclExpFuncData& rFuncData )
1575{
1576 if( rFuncData.IsCalcOnlyParam() )
1577 {
1578 // skip Calc-only parameter, stop at next ocClose or ocSep
1579 aTokData = SkipExpression( aTokData, true );
1580 rFuncData.IncParamInfoIdx();
1581 }
1582 else
1583 {
1584 // insert Excel-only parameters, modifies param count and class in rFuncData
1585 while( rFuncData.IsExcelOnlyParam() )
1586 AppendDefaultParam( rFuncData );
1587
1588 // process the parameter, stop at next ocClose or ocSep
1589 PrepareParam( rFuncData );
1590 /* #i37355# insert tMissArg token for missing parameters --
1591 Excel import filter adds ocMissing token (handled in Factor()),
1592 but Calc itself does not do this if a new formula is entered. */
1593 switch( aTokData.GetOpCode() )
1594 {
1595 case ocSep:
1596 case ocClose: AppendMissingToken(); break; // empty parameter
1597 default: aTokData = Expression( aTokData, false, true );
1598 }
1599 // finalize the parameter and add special tokens, e.g. for IF or CHOOSE parameters
1600 if( mxData->mbOk ) FinishParam( rFuncData );
1601 }
1602 return aTokData;
1603}
1604
1605void XclExpFmlaCompImpl::PrepareParam( XclExpFuncData& rFuncData )
1606{
1607 // index of this parameter is equal to number of already finished parameters
1608 sal_uInt8 nParamIdx = rFuncData.GetParamCount();
1609
1610 switch( rFuncData.GetOpCode() )
1611 {
1612 case ocIf:
1613 switch( nParamIdx )
1614 {
1615 // add a tAttrIf token before true-parameter (second parameter)
1616 case 1: AppendJumpToken( rFuncData, EXC_TOK_ATTR_IF ); break;
1617 // add a tAttrGoto token before false-parameter (third parameter)
1618 case 2: AppendJumpToken( rFuncData, EXC_TOK_ATTR_GOTO ); break;
1619 }
1620 break;
1621
1622 case ocChoose:
1623 switch( nParamIdx )
1624 {
1625 // do nothing for first parameter
1626 case 0: break;
1627 // add a tAttrChoose token before first value parameter (second parameter)
1628 case 1: AppendJumpToken( rFuncData, EXC_TOK_ATTR_CHOOSE ); break;
1629 // add a tAttrGoto token before other value parameters
1630 default: AppendJumpToken( rFuncData, EXC_TOK_ATTR_GOTO );
1631 }
1632 break;
1633
1634 case ocArcCotHyp: // simulate ACOTH(x) by ATANH(1/(x))
1635 if( nParamIdx == 0 )
1636 AppendIntToken( 1 );
1637 break;
1638 default:;
1639 }
1640}
1641
1642void XclExpFmlaCompImpl::FinishParam( XclExpFuncData& rFuncData )
1643{
1644 // increase parameter count, update operand stack
1645 rFuncData.FinishParam( PopOperandPos() );
1646
1647 // append more tokens for parameters of some special functions
1648 sal_uInt8 nParamIdx = rFuncData.GetParamCount() - 1;
1649 switch( rFuncData.GetOpCode() )
1650 {
1651 case ocArcCotHyp: // simulate ACOTH(x) by ATANH(1/(x))
1652 if( nParamIdx == 0 )
1653 {
1656 }
1657 break;
1658 default:;
1659 }
1660}
1661
1662void XclExpFmlaCompImpl::AppendDefaultParam( XclExpFuncData& rFuncData )
1663{
1664 // prepare parameters of some special functions
1665 PrepareParam( rFuncData );
1666
1667 switch( rFuncData.GetOpCode() )
1668 {
1669 case ocExternal:
1670 AppendAddInCallToken( rFuncData.GetExtFuncData() );
1671 break;
1672 case ocEuroConvert:
1673 AppendEuroToolCallToken( rFuncData.GetExtFuncData() );
1674 break;
1675 case ocMacro:
1676 // Do not write the OOXML <definedName> element.
1678 AppendNameToken( 0 ); // dummy to keep parameter count valid
1679 else
1680 AppendMacroCallToken( rFuncData.GetExtFuncData() );
1681 break;
1682 default:
1683 {
1684 if( rFuncData.IsAddInEquivalent() )
1685 {
1686 AppendAddInCallToken( rFuncData.GetExtFuncData() );
1687 }
1688 else if( rFuncData.IsMacroFunc() )
1689 {
1690 // Do not write the OOXML <definedName> element for new _xlfn.
1691 // prefixed functions.
1693 AppendNameToken( 0 ); // dummy to keep parameter count valid
1694 else
1695 AppendMacroCallToken( rFuncData.GetExtFuncData() );
1696 }
1697 else
1698 {
1699 SAL_WARN( "sc.filter", "XclExpFmlaCompImpl::AppendDefaultParam - unknown opcode" );
1700 AppendMissingToken(); // to keep parameter count valid
1701 }
1702 }
1703 }
1704
1705 // update parameter count, add special parameter tokens
1706 FinishParam( rFuncData );
1707}
1708
1709void XclExpFmlaCompImpl::AppendTrailingParam( XclExpFuncData& rFuncData )
1710{
1711 sal_uInt8 nParamCount = rFuncData.GetParamCount();
1712 switch( rFuncData.GetOpCode() )
1713 {
1714 case ocIf:
1715 if( nParamCount == 1 )
1716 {
1717 // Excel needs at least two parameters in IF function
1718 PrepareParam( rFuncData );
1719 AppendBoolToken( true );
1720 FinishParam( rFuncData );
1721 }
1722 break;
1723
1724 case ocRound:
1725 case ocRoundUp:
1726 case ocRoundDown:
1727 if( nParamCount == 1 )
1728 {
1729 // ROUND, ROUNDUP, ROUNDDOWN functions are fixed to 2 parameters in Excel
1730 PrepareParam( rFuncData );
1731 AppendIntToken( 0 );
1732 FinishParam( rFuncData );
1733 }
1734 break;
1735
1736 case ocIndex:
1737 if( nParamCount == 1 )
1738 {
1739 // INDEX function needs at least 2 parameters in Excel
1740 PrepareParam( rFuncData );
1742 FinishParam( rFuncData );
1743 }
1744 break;
1745
1746 case ocExternal:
1747 case ocMacro:
1748 // external or macro call without parameters needs the external name reference
1749 if( nParamCount == 0 )
1750 AppendDefaultParam( rFuncData );
1751 break;
1752
1753 case ocGammaDist:
1754 if( nParamCount == 3 )
1755 {
1756 // GAMMADIST function needs 4 parameters in Excel
1757 PrepareParam( rFuncData );
1758 AppendIntToken( 1 );
1759 FinishParam( rFuncData );
1760 }
1761 break;
1762
1763 case ocPoissonDist:
1764 if( nParamCount == 2 )
1765 {
1766 // POISSON function needs 3 parameters in Excel
1767 PrepareParam( rFuncData );
1768 AppendIntToken( 1 );
1769 FinishParam( rFuncData );
1770 }
1771 break;
1772
1773 case ocNormDist:
1774 if( nParamCount == 3 )
1775 {
1776 // NORMDIST function needs 4 parameters in Excel
1777 PrepareParam( rFuncData );
1778 AppendBoolToken( true );
1779 FinishParam( rFuncData );
1780 }
1781 break;
1782
1783 case ocLogNormDist:
1784 case ocLogInv:
1785 switch( nParamCount )
1786 {
1787 // LOGNORMDIST function needs 3 parameters in Excel
1788 case 1:
1789 PrepareParam( rFuncData );
1790 AppendIntToken( 0 );
1791 FinishParam( rFuncData );
1792 [[fallthrough]]; // add next default parameter
1793 case 2:
1794 PrepareParam( rFuncData );
1795 AppendIntToken( 1 );
1796 FinishParam( rFuncData );
1797 break;
1798 default:;
1799 }
1800
1801 break;
1802
1803 default:
1804 // #i108420# function without parameters stored as macro call needs the external name reference
1805 if( (nParamCount == 0) && rFuncData.IsMacroFunc() )
1806 AppendDefaultParam( rFuncData );
1807
1808 }
1809}
1810
1811// reference handling ---------------------------------------------------------
1812
1813namespace {
1814
1815bool lclIsRefRel2D( const ScSingleRefData& rRefData )
1816{
1817 return rRefData.IsColRel() || rRefData.IsRowRel();
1818}
1819
1820bool lclIsRefDel2D( const ScSingleRefData& rRefData )
1821{
1822 return rRefData.IsColDeleted() || rRefData.IsRowDeleted();
1823}
1824
1825bool lclIsRefRel2D( const ScComplexRefData& rRefData )
1826{
1827 return lclIsRefRel2D( rRefData.Ref1 ) || lclIsRefRel2D( rRefData.Ref2 );
1828}
1829
1830bool lclIsRefDel2D( const ScComplexRefData& rRefData )
1831{
1832 return lclIsRefDel2D( rRefData.Ref1 ) || lclIsRefDel2D( rRefData.Ref2 );
1833}
1834
1835} // namespace
1836
1838{
1839 if (rRefData.IsTabDeleted())
1840 return SCTAB_INVALID;
1841
1842 if (!rRefData.IsTabRel())
1843 // absolute address
1844 return rRefData.Tab();
1845
1846 if (!mxData->mpScBasePos)
1847 return SCTAB_INVALID;
1848
1849 return rRefData.toAbs(GetRoot().GetDoc(), *mxData->mpScBasePos).Tab();
1850}
1851
1852bool XclExpFmlaCompImpl::IsRef2D( const ScSingleRefData& rRefData, bool bCheck3DFlag ) const
1853{
1854 /* rRefData.IsFlag3D() determines if sheet name is always visible, even on
1855 the own sheet. If 3D references are allowed, the passed reference does
1856 not count as 2D reference. */
1857
1858 // conditional formatting does not allow 3D refs in xls
1859 if (mxData && mxData->mrCfg.meType == EXC_FMLATYPE_CONDFMT)
1860 return true;
1861
1862 if (bCheck3DFlag && rRefData.IsFlag3D())
1863 return false;
1864
1865 if (rRefData.IsTabDeleted())
1866 return false;
1867
1868 if (rRefData.IsTabRel())
1869 return rRefData.Tab() == 0;
1870 else
1871 return rRefData.Tab() == GetCurrScTab();
1872}
1873
1874bool XclExpFmlaCompImpl::IsRef2D( const ScComplexRefData& rRefData, bool bCheck3DFlag ) const
1875{
1876 return IsRef2D(rRefData.Ref1, bCheck3DFlag) && IsRef2D(rRefData.Ref2, bCheck3DFlag);
1877}
1878
1880 ScSingleRefData& rRefData, XclAddress& rXclPos,
1881 bool bNatLangRef, bool bTruncMaxCol, bool bTruncMaxRow ) const
1882{
1883 if( mxData->mpScBasePos )
1884 {
1885 // *** reference position exists (cell, matrix) - convert to absolute ***
1886 ScAddress aAbs = rRefData.toAbs(GetRoot().GetDoc(), *mxData->mpScBasePos);
1887
1888 // convert column index
1889 if (bTruncMaxCol && (aAbs.Col() == mnMaxScCol))
1890 aAbs.SetCol(mnMaxAbsCol);
1891 else if ((aAbs.Col() < 0) || (aAbs.Col() > mnMaxAbsCol))
1892 rRefData.SetColDeleted(true);
1893 rXclPos.mnCol = static_cast<sal_uInt16>(aAbs.Col()) & mnMaxColMask;
1894
1895 // convert row index
1896 if (bTruncMaxRow && (aAbs.Row() == mnMaxScRow))
1897 aAbs.SetRow(mnMaxAbsRow);
1898 else if ((aAbs.Row() < 0) || (aAbs.Row() > mnMaxAbsRow))
1899 rRefData.SetRowDeleted(true);
1900 rXclPos.mnRow = static_cast<sal_uInt32>(aAbs.Row()) & mnMaxRowMask;
1901
1902 // Update the reference.
1903 rRefData.SetAddress(GetRoot().GetDoc().GetSheetLimits(), aAbs, *mxData->mpScBasePos);
1904 }
1905 else
1906 {
1907 // *** no reference position (shared, names, condfmt) - use relative values ***
1908
1909 // convert column index (2-step-cast ScsCOL->sal_Int16->sal_uInt16 to get all bits correctly)
1910 sal_Int16 nXclRelCol = static_cast<sal_Int16>(rRefData.Col());
1911 rXclPos.mnCol = static_cast< sal_uInt16 >( nXclRelCol ) & mnMaxColMask;
1912
1913 // convert row index (2-step-cast ScsROW->sal_Int32->sal_uInt32 to get all bits correctly)
1914 sal_Int32 nXclRelRow = static_cast<sal_Int32>(rRefData.Row());
1915 rXclPos.mnRow = static_cast< sal_uInt32 >( nXclRelRow ) & mnMaxRowMask;
1916 }
1917
1918 // flags for relative column and row
1919 if( bNatLangRef )
1920 {
1921 OSL_ENSURE( meBiff == EXC_BIFF8, "XclExpFmlaCompImpl::ConvertRefData - NLRs only for BIFF8" );
1922 // Calc does not support absolute reference mode in natural language references
1923 ::set_flag( rXclPos.mnCol, EXC_TOK_NLR_REL );
1924 }
1925 else
1926 {
1927 sal_uInt16 rnRelRow = rXclPos.mnRow;
1928 sal_uInt16& rnRelField = (meBiff <= EXC_BIFF5) ? rnRelRow : rXclPos.mnCol;
1929 ::set_flag( rnRelField, EXC_TOK_REF_COLREL, rRefData.IsColRel() );
1930 ::set_flag( rnRelField, EXC_TOK_REF_ROWREL, rRefData.IsRowRel() );
1931 }
1932}
1933
1935 ScComplexRefData& rRefData, XclRange& rXclRange, bool bNatLangRef ) const
1936{
1937 // convert start and end of the range
1938 ConvertRefData( rRefData.Ref1, rXclRange.maFirst, bNatLangRef, false, false );
1939 bool bTruncMaxCol = !rRefData.Ref1.IsColDeleted() && (rXclRange.maFirst.mnCol == 0);
1940 bool bTruncMaxRow = !rRefData.Ref1.IsRowDeleted() && (rXclRange.maFirst.mnRow == 0);
1941 ConvertRefData( rRefData.Ref2, rXclRange.maLast, bNatLangRef, bTruncMaxCol, bTruncMaxRow );
1942}
1943
1945{
1946 if( mxData->mpRefLog )
1947 {
1948 mxData->mpRefLog->emplace_back();
1949 return &mxData->mpRefLog->back();
1950 }
1951 return nullptr;
1952}
1953
1954void XclExpFmlaCompImpl::ProcessCellRef( const XclExpScToken& rTokData )
1955{
1956 // get the Excel address components, adjust internal data in aRefData
1957 bool bNatLangRef = (meBiff == EXC_BIFF8) && mxData->mpScBasePos && (rTokData.GetOpCode() == ocColRowName);
1958 ScSingleRefData aRefData = *rTokData.mpScToken->GetSingleRef();
1960 ConvertRefData( aRefData, aXclPos, bNatLangRef, false, false );
1961
1962 if( bNatLangRef )
1963 {
1964 OSL_ENSURE( aRefData.IsColRel() != aRefData.IsRowRel(),
1965 "XclExpFmlaCompImpl::ProcessCellRef - broken natural language reference" );
1966 // create tNlr token for natural language reference
1967 sal_uInt8 nSubId = aRefData.IsColRel() ? EXC_TOK_NLR_COLV : EXC_TOK_NLR_ROWV;
1968 AppendOperandTokenId( EXC_TOKID_NLR, rTokData.mnSpaces );
1969 Append( nSubId );
1970 AppendAddress( aXclPos );
1971 }
1972 else
1973 {
1974 // store external cell contents in CRN records
1975 if( mxData->mrCfg.mbFromCell && mxData->mpLinkMgr && mxData->mpScBasePos )
1976 mxData->mpLinkMgr->StoreCell(aRefData, *mxData->mpScBasePos);
1977
1978 // create the tRef, tRefErr, tRefN, tRef3d, or tRefErr3d token
1979 if (!mxData->mrCfg.mb3DRefOnly && IsRef2D(aRefData, mxData->mpLinkMgr != nullptr))
1980 {
1981 // 2D reference (not in defined names, but allowed in range lists)
1982 sal_uInt8 nBaseId = (!mxData->mpScBasePos && lclIsRefRel2D( aRefData )) ? EXC_TOKID_REFN :
1983 (lclIsRefDel2D( aRefData ) ? EXC_TOKID_REFERR : EXC_TOKID_REF);
1984 AppendOperandTokenId( GetTokenId( nBaseId, EXC_TOKCLASS_REF ), rTokData.mnSpaces );
1985 AppendAddress( aXclPos );
1986 }
1987 else if( mxData->mpLinkMgr ) // 3D reference
1988 {
1989 // 1-based EXTERNSHEET index and 0-based Excel sheet index
1990 sal_uInt16 nExtSheet, nXclTab;
1991 mxData->mpLinkMgr->FindExtSheet( nExtSheet, nXclTab, GetScTab( aRefData ), GetNewRefLogEntry() );
1992 // write the token
1993 sal_uInt8 nBaseId = lclIsRefDel2D( aRefData ) ? EXC_TOKID_REFERR3D : EXC_TOKID_REF3D;
1994 AppendOperandTokenId( GetTokenId( nBaseId, EXC_TOKCLASS_REF ), rTokData.mnSpaces );
1995 Append( nExtSheet );
1996 if( meBiff <= EXC_BIFF5 )
1997 {
1998 Append( 0, 8 );
1999 Append( nXclTab );
2000 Append( nXclTab );
2001 }
2002 AppendAddress( aXclPos );
2003 }
2004 else
2005 {
2006 // 3D ref in cond. format, or 2D ref in name
2007 AppendErrorToken( EXC_ERR_REF, rTokData.mnSpaces );
2008 }
2009 }
2010}
2011
2012void XclExpFmlaCompImpl::ProcessRangeRef( const XclExpScToken& rTokData )
2013{
2014 // get the Excel address components, adjust internal data in aRefData
2015 ScComplexRefData aRefData = *rTokData.mpScToken->GetDoubleRef();
2017 ConvertRefData( aRefData, aXclRange, false );
2018
2019 // store external cell contents in CRN records
2020 if( mxData->mrCfg.mbFromCell && mxData->mpLinkMgr && mxData->mpScBasePos )
2021 mxData->mpLinkMgr->StoreCellRange(aRefData, *mxData->mpScBasePos);
2022
2023 // create the tArea, tAreaErr, tAreaN, tArea3d, or tAreaErr3d token
2024 if (!mxData->mrCfg.mb3DRefOnly && IsRef2D(aRefData, mxData->mpLinkMgr != nullptr))
2025 {
2026 // 2D reference (not in name formulas, but allowed in range lists)
2027 sal_uInt8 nBaseId = (!mxData->mpScBasePos && lclIsRefRel2D( aRefData )) ? EXC_TOKID_AREAN :
2028 (lclIsRefDel2D( aRefData ) ? EXC_TOKID_AREAERR : EXC_TOKID_AREA);
2029 AppendOperandTokenId( GetTokenId( nBaseId, EXC_TOKCLASS_REF ), rTokData.mnSpaces );
2030 AppendRange( aXclRange );
2031 }
2032 else if( mxData->mpLinkMgr ) // 3D reference
2033 {
2034 // 1-based EXTERNSHEET index and 0-based Excel sheet indexes
2035 sal_uInt16 nExtSheet, nFirstXclTab, nLastXclTab;
2036 mxData->mpLinkMgr->FindExtSheet( nExtSheet, nFirstXclTab, nLastXclTab,
2037 GetScTab( aRefData.Ref1 ), GetScTab( aRefData.Ref2 ), GetNewRefLogEntry() );
2038 // write the token
2039 sal_uInt8 nBaseId = lclIsRefDel2D( aRefData ) ? EXC_TOKID_AREAERR3D : EXC_TOKID_AREA3D;
2040 AppendOperandTokenId( GetTokenId( nBaseId, EXC_TOKCLASS_REF ), rTokData.mnSpaces );
2041 Append( nExtSheet );
2042 if( meBiff <= EXC_BIFF5 )
2043 {
2044 Append( 0, 8 );
2045 Append( nFirstXclTab );
2046 Append( nLastXclTab );
2047 }
2048 AppendRange( aXclRange );
2049 }
2050 else
2051 {
2052 // 3D ref in cond. format, or 2D ref in name
2053 AppendErrorToken( EXC_ERR_REF, rTokData.mnSpaces );
2054 }
2055}
2056
2057void XclExpFmlaCompImpl::ProcessExternalCellRef( const XclExpScToken& rTokData )
2058{
2059 if( mxData->mpLinkMgr )
2060 {
2061 // get the Excel address components, adjust internal data in aRefData
2062 ScSingleRefData aRefData = *rTokData.mpScToken->GetSingleRef();
2064 ConvertRefData( aRefData, aXclPos, false, false, false );
2065
2066 // store external cell contents in CRN records
2067 sal_uInt16 nFileId = rTokData.mpScToken->GetIndex();
2068 OUString aTabName = rTokData.mpScToken->GetString().getString();
2069 if( mxData->mrCfg.mbFromCell && mxData->mpScBasePos )
2070 mxData->mpLinkMgr->StoreCell(nFileId, aTabName, aRefData.toAbs(GetRoot().GetDoc(), *mxData->mpScBasePos));
2071
2072 // 1-based EXTERNSHEET index and 0-based Excel sheet indexes
2073 sal_uInt16 nExtSheet, nFirstSBTab, nLastSBTab;
2074 mxData->mpLinkMgr->FindExtSheet( nFileId, aTabName, 1, nExtSheet, nFirstSBTab, nLastSBTab, GetNewRefLogEntry() );
2075 // write the token
2076 sal_uInt8 nBaseId = lclIsRefDel2D( aRefData ) ? EXC_TOKID_REFERR3D : EXC_TOKID_REF3D;
2077 AppendOperandTokenId( GetTokenId( nBaseId, EXC_TOKCLASS_REF ), rTokData.mnSpaces );
2078 Append( nExtSheet );
2079 if( meBiff <= EXC_BIFF5 )
2080 {
2081 Append( 0, 8 );
2082 Append( nFirstSBTab );
2083 Append( nLastSBTab );
2084 }
2085 AppendAddress( aXclPos );
2086 }
2087 else
2088 {
2089 AppendErrorToken( EXC_ERR_REF, rTokData.mnSpaces );
2090 }
2091}
2092
2093void XclExpFmlaCompImpl::ProcessExternalRangeRef( const XclExpScToken& rTokData )
2094{
2095 if( mxData->mpLinkMgr )
2096 {
2097 // get the Excel address components, adjust internal data in aRefData
2098 ScComplexRefData aRefData = *rTokData.mpScToken->GetDoubleRef();
2100 ConvertRefData( aRefData, aXclRange, false );
2101
2102 // store external cell contents in CRN records
2103 sal_uInt16 nFileId = rTokData.mpScToken->GetIndex();
2104 OUString aTabName = rTokData.mpScToken->GetString().getString();
2105 if( mxData->mrCfg.mbFromCell && mxData->mpScBasePos )
2106 mxData->mpLinkMgr->StoreCellRange(nFileId, aTabName, aRefData.toAbs(GetRoot().GetDoc(), *mxData->mpScBasePos));
2107
2108 // 1-based EXTERNSHEET index and 0-based Excel sheet indexes
2109 sal_uInt16 nExtSheet, nFirstSBTab, nLastSBTab;
2110 sal_uInt16 nTabSpan = static_cast<sal_uInt16>(aRefData.Ref2.Tab() - aRefData.Ref1.Tab() + 1);
2111 mxData->mpLinkMgr->FindExtSheet(
2112 nFileId, aTabName, nTabSpan, nExtSheet, nFirstSBTab, nLastSBTab, GetNewRefLogEntry());
2113 // write the token
2114 sal_uInt8 nBaseId = lclIsRefDel2D( aRefData ) ? EXC_TOKID_AREAERR3D : EXC_TOKID_AREA3D;
2115 AppendOperandTokenId( GetTokenId( nBaseId, EXC_TOKCLASS_REF ), rTokData.mnSpaces );
2116 Append( nExtSheet );
2117 if( meBiff <= EXC_BIFF5 )
2118 {
2119 Append( 0, 8 );
2120 Append( nFirstSBTab );
2121 Append( nLastSBTab );
2122 }
2123 AppendRange( aXclRange );
2124 }
2125 else
2126 {
2127 AppendErrorToken( EXC_ERR_REF, rTokData.mnSpaces );
2128 }
2129}
2130
2131void XclExpFmlaCompImpl::ProcessDefinedName( const XclExpScToken& rTokData )
2132{
2133 sal_Int16 nSheet = rTokData.mpScToken->GetSheet();
2134 SCTAB nTab = (nSheet < 0 ? SCTAB_GLOBAL : nSheet);
2135
2136 XclExpNameManager& rNameMgr = GetNameManager();
2137 sal_uInt16 nNameIdx = rNameMgr.InsertName(nTab, rTokData.mpScToken->GetIndex(), GetCurrScTab());
2138 if( nNameIdx != 0 )
2139 {
2140 // global names always with tName token, local names dependent on config
2141 SCTAB nScTab = rNameMgr.GetScTab( nNameIdx );
2142 if( (nScTab == SCTAB_GLOBAL) || (!mxData->mrCfg.mb3DRefOnly && (nScTab == GetCurrScTab())) )
2143 {
2144 AppendNameToken( nNameIdx, rTokData.mnSpaces );
2145 }
2146 else if( mxData->mpLinkMgr )
2147 {
2148 // use the same special EXTERNNAME to refer to any local name
2149 sal_uInt16 nExtSheet = mxData->mpLinkMgr->FindExtSheet( EXC_EXTSH_OWNDOC );
2150 AppendNameXToken( nExtSheet, nNameIdx, rTokData.mnSpaces );
2151 }
2152 else
2153 AppendErrorToken( EXC_ERR_NAME, rTokData.mnSpaces );
2154 // volatile names (containing volatile functions)
2155 mxData->mbVolatile |= rNameMgr.IsVolatile( nNameIdx );
2156 }
2157 else
2158 AppendErrorToken( EXC_ERR_NAME, rTokData.mnSpaces );
2159}
2160
2161void XclExpFmlaCompImpl::ProcessExternalName( const XclExpScToken& rTokData )
2162{
2163 if( mxData->mpLinkMgr )
2164 {
2166 sal_uInt16 nFileId = rTokData.mpScToken->GetIndex();
2167 OUString aName = rTokData.mpScToken->GetString().getString();
2168 ScExternalRefCache::TokenArrayRef xArray = rExtRefMgr.getRangeNameTokens( nFileId, aName );
2169 if( xArray )
2170 {
2171 // store external cell contents in CRN records
2172 if( mxData->mpScBasePos )
2173 {
2174 FormulaTokenArrayPlainIterator aIter(*xArray);
2175 for( FormulaToken* pScToken = aIter.First(); pScToken; pScToken = aIter.Next() )
2176 {
2177 if( pScToken->IsExternalRef() )
2178 {
2179 switch( pScToken->GetType() )
2180 {
2182 {
2183 ScSingleRefData aRefData = *pScToken->GetSingleRef();
2184 mxData->mpLinkMgr->StoreCell(
2185 nFileId, pScToken->GetString().getString(), aRefData.toAbs(GetRoot().GetDoc(), *mxData->mpScBasePos));
2186 }
2187 break;
2189 {
2190 ScComplexRefData aRefData = *pScToken->GetDoubleRef();
2191 mxData->mpLinkMgr->StoreCellRange(
2192 nFileId, pScToken->GetString().getString(), aRefData.toAbs(GetRoot().GetDoc(), *mxData->mpScBasePos));
2193 }
2194 break;
2195 default:
2196 ; // nothing, avoid compiler warning
2197 }
2198 }
2199 }
2200 }
2201
2202 // insert the new external name and create the tNameX token
2203 sal_uInt16 nExtSheet = 0, nExtName = 0;
2204 const OUString* pFile = rExtRefMgr.getExternalFileName( nFileId );
2205 if( pFile && mxData->mpLinkMgr->InsertExtName( nExtSheet, nExtName, *pFile, aName, xArray ) )
2206 {
2207 AppendNameXToken( nExtSheet, nExtName, rTokData.mnSpaces );
2208 return;
2209 }
2210 }
2211 }
2212
2213 // on any error: create a #NAME? error
2214 AppendErrorToken( EXC_ERR_NAME, rTokData.mnSpaces );
2215}
2216
2217// token vector ---------------------------------------------------------------
2218
2219void XclExpFmlaCompImpl::PushOperandPos( sal_uInt16 nTokPos )
2220{
2221 mxData->maOpPosStack.push_back( nTokPos );
2222}
2223
2224void XclExpFmlaCompImpl::PushOperatorPos( sal_uInt16 nTokPos, const XclExpOperandListRef& rxOperands )
2225{
2226 PushOperandPos( nTokPos );
2227 OSL_ENSURE( rxOperands, "XclExpFmlaCompImpl::AppendOperatorTokenId - missing operand list" );
2228 if( mxData->maOpListVec.size() <= nTokPos )
2229 mxData->maOpListVec.resize( nTokPos + 1, XclExpOperandListRef() );
2230 mxData->maOpListVec[ nTokPos ] = rxOperands;
2231}
2232
2234{
2235 OSL_ENSURE( !mxData->mbOk || !mxData->maOpPosStack.empty(), "XclExpFmlaCompImpl::PopOperandPos - token stack broken" );
2236 mxData->mbOk &= !mxData->maOpPosStack.empty();
2237 if( mxData->mbOk )
2238 {
2239 sal_uInt16 nTokPos = mxData->maOpPosStack.back();
2240 mxData->maOpPosStack.pop_back();
2241 return nTokPos;
2242 }
2243 return 0;
2244}
2245
2246namespace {
2247
2248void lclAppend( ScfUInt8Vec& orVector, sal_uInt16 nData )
2249{
2250 orVector.resize( orVector.size() + 2 );
2251 ShortToSVBT16( nData, &*(orVector.end() - 2) );
2252}
2253
2254void lclAppend( ScfUInt8Vec& orVector, sal_uInt32 nData )
2255{
2256 orVector.resize( orVector.size() + 4 );
2257 UInt32ToSVBT32( nData, &*(orVector.end() - 4) );
2258}
2259
2260void lclAppend( ScfUInt8Vec& orVector, double fData )
2261{
2262 orVector.resize( orVector.size() + 8 );
2263 DoubleToSVBT64( fData, &*(orVector.end() - 8) );
2264}
2265
2266void lclAppend( ScfUInt8Vec& orVector, const XclExpRoot& rRoot, const OUString& rString, XclStrFlags nStrFlags )
2267{
2268 XclExpStringRef xXclStr = XclExpStringHelper::CreateString( rRoot, rString, nStrFlags, EXC_TOK_STR_MAXLEN );
2269 size_t nSize = orVector.size();
2270 orVector.resize( nSize + xXclStr->GetSize() );
2271 xXclStr->WriteToMem( &orVector[ nSize ] );
2272}
2273
2274} // namespace
2275
2277{
2278 mxData->maTokVec.push_back( nData );
2279}
2280
2281void XclExpFmlaCompImpl::Append( sal_uInt8 nData, size_t nCount )
2282{
2283 mxData->maTokVec.resize( mxData->maTokVec.size() + nCount, nData );
2284}
2285
2286void XclExpFmlaCompImpl::Append( sal_uInt16 nData )
2287{
2288 lclAppend( mxData->maTokVec, nData );
2289}
2290
2291void XclExpFmlaCompImpl::Append( sal_uInt32 nData )
2292{
2293 lclAppend( mxData->maTokVec, nData );
2294}
2295
2296void XclExpFmlaCompImpl::Append( double fData )
2297{
2298 lclAppend( mxData->maTokVec, fData );
2299}
2300
2301void XclExpFmlaCompImpl::Append( const OUString& rString )
2302{
2303 lclAppend( mxData->maTokVec, GetRoot(), rString, XclStrFlags::EightBitLength );
2304}
2305
2307{
2308 Append( static_cast<sal_uInt16>(rXclPos.mnRow) );
2309 if( meBiff <= EXC_BIFF5 )
2310 Append( static_cast< sal_uInt8 >( rXclPos.mnCol ) );
2311 else
2312 Append( rXclPos.mnCol );
2313}
2314
2316{
2317 Append( static_cast<sal_uInt16>(rXclRange.maFirst.mnRow) );
2318 Append( static_cast<sal_uInt16>(rXclRange.maLast.mnRow) );
2319 if( meBiff <= EXC_BIFF5 )
2320 {
2321 Append( static_cast< sal_uInt8 >( rXclRange.maFirst.mnCol ) );
2322 Append( static_cast< sal_uInt8 >( rXclRange.maLast.mnCol ) );
2323 }
2324 else
2325 {
2326 Append( rXclRange.maFirst.mnCol );
2327 Append( rXclRange.maLast.mnCol );
2328 }
2329}
2330
2332{
2333 if( nCount > 0 )
2334 {
2337 Append( nType );
2338 Append( nCount );
2339 }
2340}
2341
2343{
2346 Append( nTokenId );
2347}
2348
2349void XclExpFmlaCompImpl::AppendIntToken( sal_uInt16 nValue, sal_uInt8 nSpaces )
2350{
2352 Append( nValue );
2353}
2354
2355void XclExpFmlaCompImpl::AppendNumToken( double fValue, sal_uInt8 nSpaces )
2356{
2358 Append( fValue );
2359}
2360
2362{
2365}
2366
2368{
2370 Append( nErrCode );
2371}
2372
2374{
2376}
2377
2378void XclExpFmlaCompImpl::AppendNameToken( sal_uInt16 nNameIdx, sal_uInt8 nSpaces )
2379{
2380 if( nNameIdx > 0 )
2381 {
2383 Append( nNameIdx );
2384 Append( 0, (meBiff <= EXC_BIFF5) ? 12 : 2 );
2385 }
2386 else
2388}
2389
2390void XclExpFmlaCompImpl::AppendMissingNameToken( const OUString& rName, sal_uInt8 nSpaces )
2391{
2392 sal_uInt16 nNameIdx = GetNameManager().InsertRawName( rName );
2393 AppendNameToken( nNameIdx, nSpaces );
2394}
2395
2396void XclExpFmlaCompImpl::AppendNameXToken( sal_uInt16 nExtSheet, sal_uInt16 nExtName, sal_uInt8 nSpaces )
2397{
2399 Append( nExtSheet );
2400 if( meBiff <= EXC_BIFF5 )
2401 Append( 0, 8 );
2402 Append( nExtName );
2403 Append( 0, (meBiff <= EXC_BIFF5) ? 12 : 2 );
2404}
2405
2406void XclExpFmlaCompImpl::AppendMacroCallToken( const XclExpExtFuncData& rExtFuncData )
2407{
2408 sal_uInt16 nNameIdx = GetNameManager().InsertMacroCall( rExtFuncData.maFuncName, rExtFuncData.mbVBasic, true, rExtFuncData.mbHidden );
2409 AppendNameToken( nNameIdx );
2410}
2411
2412void XclExpFmlaCompImpl::AppendAddInCallToken( const XclExpExtFuncData& rExtFuncData )
2413{
2414 OUString aXclFuncName;
2415 if( mxData->mpLinkMgr && ScGlobal::GetAddInCollection()->GetExcelName( rExtFuncData.maFuncName, GetUILanguage(), aXclFuncName ) )
2416 {
2417 sal_uInt16 nExtSheet, nExtName;
2418 if( mxData->mpLinkMgr->InsertAddIn( nExtSheet, nExtName, aXclFuncName ) )
2419 {
2420 AppendNameXToken( nExtSheet, nExtName );
2421 return;
2422 }
2423 }
2424 AppendMacroCallToken( rExtFuncData );
2425}
2426
2427void XclExpFmlaCompImpl::AppendEuroToolCallToken( const XclExpExtFuncData& rExtFuncData )
2428{
2429 sal_uInt16 nExtSheet(0), nExtName(0);
2430 if( mxData->mpLinkMgr && mxData->mpLinkMgr->InsertEuroTool( nExtSheet, nExtName, rExtFuncData.maFuncName ) )
2431 AppendNameXToken( nExtSheet, nExtName );
2432 else
2433 AppendMacroCallToken( rExtFuncData );
2434}
2435
2436void XclExpFmlaCompImpl::AppendOperatorTokenId( sal_uInt8 nTokenId, const XclExpOperandListRef& rxOperands, sal_uInt8 nSpaces )
2437{
2439 PushOperatorPos( GetSize(), rxOperands );
2440 Append( nTokenId );
2441}
2442
2444{
2445 XclExpOperandListRef xOperands = std::make_shared<XclExpOperandList>();
2446 xOperands->AppendOperand( PopOperandPos(), EXC_PARAMCONV_RPO, true );
2447 AppendOperatorTokenId( nTokenId, xOperands, nSpaces );
2448}
2449
2451{
2452 XclExpOperandListRef xOperands = std::make_shared<XclExpOperandList>();
2453 xOperands->AppendOperand( PopOperandPos(), EXC_PARAMCONV_RPO, bValType );
2454 xOperands->AppendOperand( PopOperandPos(), EXC_PARAMCONV_RPO, bValType );
2455 AppendOperatorTokenId( nTokenId, xOperands, nSpaces );
2456}
2457
2458void XclExpFmlaCompImpl::AppendLogicalOperatorToken( sal_uInt16 nXclFuncIdx, sal_uInt8 nOpCount )
2459{
2460 XclExpOperandListRef xOperands = std::make_shared<XclExpOperandList>();
2461 for( sal_uInt8 nOpIdx = 0; nOpIdx < nOpCount; ++nOpIdx )
2462 xOperands->AppendOperand( PopOperandPos(), EXC_PARAMCONV_RPX, false );
2464 Append( nOpCount );
2465 Append( nXclFuncIdx );
2466}
2467
2468void XclExpFmlaCompImpl::AppendFuncToken( const XclExpFuncData& rFuncData )
2469{
2470 sal_uInt16 nXclFuncIdx = rFuncData.GetXclFuncIdx();
2471 sal_uInt8 nParamCount = rFuncData.GetParamCount();
2472 sal_uInt8 nRetClass = rFuncData.GetReturnClass();
2473
2474 if( (nXclFuncIdx == EXC_FUNCID_SUM) && (nParamCount == 1) )
2475 {
2476 // SUM with only one parameter
2477 AppendOperatorTokenId( EXC_TOKID_ATTR, rFuncData.GetOperandList() );
2479 Append( sal_uInt16( 0 ) );
2480 }
2481 else if( rFuncData.IsFixedParamCount() )
2482 {
2483 // fixed number of parameters
2484 AppendOperatorTokenId( GetTokenId( EXC_TOKID_FUNC, nRetClass ), rFuncData.GetOperandList() );
2485 Append( nXclFuncIdx );
2486 }
2487 else
2488 {
2489 // variable number of parameters
2490 AppendOperatorTokenId( GetTokenId( EXC_TOKID_FUNCVAR, nRetClass ), rFuncData.GetOperandList() );
2491 Append( nParamCount );
2492 Append( nXclFuncIdx );
2493 }
2494}
2495
2497{
2501}
2502
2503void XclExpFmlaCompImpl::AppendJumpToken( XclExpFuncData& rFuncData, sal_uInt8 nAttrType )
2504{
2505 // store the start position of the token
2506 rFuncData.AppendAttrPos( GetSize() );
2507 // create the tAttr token
2509 Append( nAttrType );
2510 Append( sal_uInt16( 0 ) ); // placeholder that will be updated later
2511}
2512
2513void XclExpFmlaCompImpl::InsertZeros( sal_uInt16 nInsertPos, sal_uInt16 nInsertSize )
2514{
2515 // insert zeros into the token array
2516 OSL_ENSURE( nInsertPos < mxData->maTokVec.size(), "XclExpFmlaCompImpl::Insert - invalid position" );
2517 mxData->maTokVec.insert( mxData->maTokVec.begin() + nInsertPos, nInsertSize, 0 );
2518
2519 // update positions of operands waiting for an operator
2520 for( auto& rOpPos : mxData->maOpPosStack )
2521 if( nInsertPos <= rOpPos )
2522 rOpPos += nInsertSize;
2523
2524 // update operand lists of all operator tokens
2525 if( nInsertPos < mxData->maOpListVec.size() )
2526 mxData->maOpListVec.insert( mxData->maOpListVec.begin() + nInsertPos, nInsertSize, XclExpOperandListRef() );
2527 for( auto& rxOpList : mxData->maOpListVec )
2528 if( rxOpList )
2529 for( auto& rOp : *rxOpList )
2530 if( nInsertPos <= rOp.mnTokPos )
2531 rOp.mnTokPos += nInsertSize;
2532}
2533
2534void XclExpFmlaCompImpl::Overwrite( sal_uInt16 nWriteToPos, sal_uInt16 nOffset )
2535{
2536 OSL_ENSURE( o3tl::make_unsigned( nWriteToPos + 1 ) < mxData->maTokVec.size(), "XclExpFmlaCompImpl::Overwrite - invalid position" );
2537 ShortToSVBT16( nOffset, &mxData->maTokVec[ nWriteToPos ] );
2538}
2539
2540void XclExpFmlaCompImpl::UpdateAttrGoto( sal_uInt16 nAttrPos )
2541{
2542 /* tAttrGoto contains distance from end of tAttr token to position behind
2543 the function token (for IF or CHOOSE function), which is currently at
2544 the end of the token array. Additionally this distance is decreased by
2545 one, for whatever reason. So we have to subtract 4 and 1 from the
2546 distance between the tAttr token start and the end of the token array. */
2547 Overwrite( nAttrPos + 2, static_cast< sal_uInt16 >( GetSize() - nAttrPos - 5 ) );
2548}
2549
2550bool XclExpFmlaCompImpl::IsSpaceToken( sal_uInt16 nPos ) const
2551{
2552 return
2553 (o3tl::make_unsigned( nPos + 4 ) <= mxData->maTokVec.size()) &&
2554 (mxData->maTokVec[ nPos ] == EXC_TOKID_ATTR) &&
2555 (mxData->maTokVec[ nPos + 1 ] == EXC_TOK_ATTR_SPACE);
2556}
2557
2559{
2560 // remove trailing tParen token
2561 if( !mxData->maTokVec.empty() && (mxData->maTokVec.back() == EXC_TOKID_PAREN) )
2562 mxData->maTokVec.pop_back();
2563 // remove remaining tAttrSpace tokens
2564 while( (mxData->maTokVec.size() >= 4) && IsSpaceToken( GetSize() - 4 ) )
2565 mxData->maTokVec.erase( mxData->maTokVec.end() - 4, mxData->maTokVec.end() );
2566}
2567
2569{
2570 mxData->maExtDataVec.push_back( nData );
2571}
2572
2573void XclExpFmlaCompImpl::AppendExt( sal_uInt8 nData, size_t nCount )
2574{
2575 mxData->maExtDataVec.resize( mxData->maExtDataVec.size() + nCount, nData );
2576}
2577
2578void XclExpFmlaCompImpl::AppendExt( sal_uInt16 nData )
2579{
2580 lclAppend( mxData->maExtDataVec, nData );
2581}
2582
2584{
2585 lclAppend( mxData->maExtDataVec, fData );
2586}
2587
2588void XclExpFmlaCompImpl::AppendExt( const OUString& rString )
2589{
2590 lclAppend( mxData->maExtDataVec, GetRoot(), rString, (meBiff == EXC_BIFF8) ? XclStrFlags::NONE : XclStrFlags::EightBitLength );
2591}
2592
2593namespace {
2594
2595void lclInitOwnTab( ScSingleRefData& rRef, const ScAddress& rScPos, SCTAB nCurrScTab, bool b3DRefOnly )
2596{
2597 if( b3DRefOnly )
2598 {
2599 // no reduction to 2D reference, if global link manager is used
2600 rRef.SetFlag3D(true);
2601 }
2602 else if( rScPos.Tab() == nCurrScTab )
2603 {
2604 rRef.SetRelTab(0);
2605 }
2606}
2607
2608void lclPutCellToTokenArray( ScTokenArray& rScTokArr, const ScAddress& rScPos, SCTAB nCurrScTab, bool b3DRefOnly )
2609{
2610 ScSingleRefData aRef;
2611 aRef.InitAddress( rScPos );
2612 lclInitOwnTab( aRef, rScPos, nCurrScTab, b3DRefOnly );
2613 rScTokArr.AddSingleReference( aRef );
2614}
2615
2616void lclPutRangeToTokenArray( ScTokenArray& rScTokArr, const ScRange& rScRange, SCTAB nCurrScTab, bool b3DRefOnly )
2617{
2618 if( rScRange.aStart == rScRange.aEnd )
2619 {
2620 lclPutCellToTokenArray( rScTokArr, rScRange.aStart, nCurrScTab, b3DRefOnly );
2621 }
2622 else
2623 {
2624 ScComplexRefData aRef;
2625 aRef.InitRange( rScRange );
2626 lclInitOwnTab( aRef.Ref1, rScRange.aStart, nCurrScTab, b3DRefOnly );
2627 lclInitOwnTab( aRef.Ref2, rScRange.aEnd, nCurrScTab, b3DRefOnly );
2628 rScTokArr.AddDoubleReference( aRef );
2629 }
2630}
2631
2632} // namespace
2633
2635 XclExpRoot( rRoot ),
2636 mxImpl( std::make_shared<XclExpFmlaCompImpl>( rRoot ) )
2637{
2638}
2639
2641{
2642}
2643
2645 XclFormulaType eType, const ScTokenArray& rScTokArr,
2646 const ScAddress* pScBasePos, XclExpRefLog* pRefLog )
2647{
2648 return mxImpl->CreateFormula( eType, rScTokArr, pScBasePos, pRefLog );
2649}
2650
2652{
2653 ScTokenArray aScTokArr(GetRoot().GetDoc());
2654 lclPutCellToTokenArray( aScTokArr, rScPos, GetCurrScTab(), mxImpl->Is3DRefOnly( eType ) );
2655 return mxImpl->CreateFormula( eType, aScTokArr );
2656}
2657
2659{
2660 ScTokenArray aScTokArr(GetRoot().GetDoc());
2661 lclPutRangeToTokenArray( aScTokArr, rScRange, GetCurrScTab(), mxImpl->Is3DRefOnly( eType ) );
2662 return mxImpl->CreateFormula( eType, aScTokArr );
2663}
2664
2666{
2667 size_t nCount = rScRanges.size();
2668 if( nCount == 0 )
2669 return XclTokenArrayRef();
2670
2671 ScTokenArray aScTokArr(GetRoot().GetDoc());
2672 SCTAB nCurrScTab = GetCurrScTab();
2673 bool b3DRefOnly = mxImpl->Is3DRefOnly( eType );
2674 for( size_t nIdx = 0; nIdx < nCount; ++nIdx )
2675 {
2676 if( nIdx > 0 )
2677 aScTokArr.AddOpCode( ocUnion );
2678 lclPutRangeToTokenArray( aScTokArr, rScRanges[ nIdx ], nCurrScTab, b3DRefOnly );
2679 }
2680 return mxImpl->CreateFormula( eType, aScTokArr );
2681}
2682
2684{
2685 return mxImpl->CreateErrorFormula( nErrCode );
2686}
2687
2689 sal_uInt8 nTokenId, const XclAddress& rXclPos )
2690{
2691 return mxImpl->CreateSpecialRefFormula( nTokenId, rXclPos );
2692}
2693
2695 sal_uInt16 nExtSheet, sal_uInt16 nExtName )
2696{
2697 return mxImpl->CreateNameXFormula( nExtSheet, nExtName );
2698}
2699
2701{
2702 return mxImpl->IsRef2D(rRefData, true);
2703}
2704
2706{
2707 return mxImpl->IsRef2D(rRefData, true);
2708}
2709
2710/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
size_t SCSIZE
size_t typedef to be able to find places where code was changed from USHORT to size_t and is used to ...
Definition: address.hxx:44
@ UNINITIALIZED
Definition: address.hxx:220
SCTAB Tab() const
Definition: address.hxx:283
void SetCol(SCCOL nColP)
Definition: address.hxx:291
SCROW Row() const
Definition: address.hxx:274
void SetRow(SCROW nRowP)
Definition: address.hxx:287
SCCOL Col() const
Definition: address.hxx:279
void MoveRelWrap()
Definition: compiler.cxx:5185
ScSheetLimits & GetSheetLimits() const
Definition: document.hxx:897
SC_DLLPUBLIC ScExternalRefManager * GetExternalRefManager() const
Definition: documen3.cxx:633
std::shared_ptr< ScTokenArray > TokenArrayRef
const OUString * getExternalFileName(sal_uInt16 nFileId, bool bForceOriginal=false)
It returns a pointer to the name of the URI associated with a given external file ID.
ScExternalRefCache::TokenArrayRef getRangeNameTokens(sal_uInt16 nFileId, const OUString &rName, const ScAddress *pCurPos=nullptr)
Get an array of tokens corresponding with a specified name in a specified file.
static SC_DLLPUBLIC ScUnoAddInCollection * GetAddInCollection()
Definition: global.cxx:283
Matrix data type that can store values of mixed types.
Definition: scmatrix.hxx:101
ScMatrixValue Get(SCSIZE nC, SCSIZE nR) const
@ATTENTION: If bString the ScMatrixValue->pS may still be NULL to indicate an empty string!
Definition: scmatrix.cxx:3041
static bool IsBooleanType(ScMatValType nType)
Boolean.
Definition: scmatrix.hxx:172
static bool IsValueType(ScMatValType nType)
Value or boolean.
Definition: scmatrix.hxx:166
void GetDimensions(SCSIZE &rC, SCSIZE &rR) const
Definition: scmatrix.cxx:2931
size_t size() const
Definition: rangelst.hxx:89
ScAddress aEnd
Definition: address.hxx:498
ScAddress aStart
Definition: address.hxx:497
virtual formula::FormulaToken * AddOpCode(OpCode eCode) override
Definition: token.cxx:2265
std::unique_ptr< ScTokenArray > Clone() const
Definition: token.cxx:1931
formula::FormulaToken * AddDoubleReference(const ScComplexRefData &rRef)
Definition: token.cxx:2282
formula::FormulaToken * AddSingleReference(const ScSingleRefData &rRef)
ScSingleRefToken with ocPush.
Definition: token.cxx:2272
bool GetExcelName(const OUString &rCalcName, LanguageType eDestLang, OUString &rRetExcelName)
leave rRetExcelName unchanged, if no matching name is found
Definition: addincol.cxx:596
Implementation class of the export formula compiler.
Definition: xeformula.cxx:298
void FinishFunction(XclExpFuncData &rFuncData, sal_uInt8 nCloseSpaces)
Definition: xeformula.cxx:1464
void AppendUnaryOperatorToken(sal_uInt8 nTokenId, sal_uInt8 nSpaces=0)
Definition: xeformula.cxx:2443
void Overwrite(sal_uInt16 nWriteToPos, sal_uInt16 nOffset)
Definition: xeformula.cxx:2534
void AppendBinaryOperatorToken(sal_uInt8 nTokenId, bool bValType, sal_uInt8 nSpaces=0)
Definition: xeformula.cxx:2450
void PushOperandPos(sal_uInt16 nTokPos)
Definition: xeformula.cxx:2219
XclExpScToken SkipExpression(XclExpScToken aTokData, bool bStopAtSep)
Definition: xeformula.cxx:957
void ProcessFunction(const XclExpScToken &rTokData)
Definition: xeformula.cxx:1373
void AppendMissingToken(sal_uInt8 nSpaces=0)
Definition: xeformula.cxx:2373
XclExpScToken AndTerm(XclExpScToken aTokData, bool bInParentheses)
Definition: xeformula.cxx:988
void ProcessExternalRangeRef(const XclExpScToken &rTokData)
Definition: xeformula.cxx:2093
void PrepareFunction(const XclExpFuncData &rFuncData)
Definition: xeformula.cxx:1441
void AppendRange(const XclRange &rXclRange)
Definition: xeformula.cxx:2315
void ProcessMissing(const XclExpScToken &rTokData)
Definition: xeformula.cxx:1231
void FinishParam(XclExpFuncData &rFuncData)
Definition: xeformula.cxx:1642
void ProcessExternalName(const XclExpScToken &rTokData)
Definition: xeformula.cxx:2161
void AppendAddInCallToken(const XclExpExtFuncData &rExtFuncData)
Definition: xeformula.cxx:2412
sal_uInt16 PopOperandPos()
Definition: xeformula.cxx:2233
std::vector< XclExpCompDataRef > maDataStack
Working data for current formula.
Definition: xeformula.cxx:462
void AppendAddress(const XclAddress &rXclPos)
Definition: xeformula.cxx:2306
void ProcessDouble(const XclExpScToken &rTokData)
Definition: xeformula.cxx:1214
std::map< XclFormulaType, XclExpCompConfig > XclExpCompConfigMap
Definition: xeformula.cxx:455
void ProcessDdeLink(const XclExpScToken &rTokData)
Definition: xeformula.cxx:1268
const sal_uInt16 mnMaxColMask
Maximum row index in Calc itself.
Definition: xeformula.cxx:468
void FinishIfFunction(XclExpFuncData &rFuncData)
Definition: xeformula.cxx:1532
const SCCOL mnMaxAbsCol
Cached BIFF version to save GetBiff() calls.
Definition: xeformula.cxx:464
XclExpScToken PowTerm(XclExpScToken aTokData, bool bInParentheses)
Definition: xeformula.cxx:1065
void PushOperatorPos(sal_uInt16 nTokPos, const XclExpOperandListRef &rxOperands)
Definition: xeformula.cxx:2224
std::shared_ptr< XclExpCompData > XclExpCompDataRef
Definition: xeformula.cxx:456
XclFunctionProvider maFuncProv
Compiler configuration map for all formula types.
Definition: xeformula.cxx:459
void FinishChooseFunction(XclExpFuncData &rFuncData)
Definition: xeformula.cxx:1546
void AppendEuroToolCallToken(const XclExpExtFuncData &rExtFuncData)
Definition: xeformula.cxx:2427
const XclExpCompConfig * GetConfigForType(XclFormulaType eType) const
Definition: xeformula.cxx:561
void AppendLogicalOperatorToken(sal_uInt16 nXclFuncIdx, sal_uInt8 nOpCount)
Definition: xeformula.cxx:2458
void AppendMissingNameToken(const OUString &rName, sal_uInt8 nSpaces=0)
Definition: xeformula.cxx:2390
void InsertZeros(sal_uInt16 nInsertPos, sal_uInt16 nInsertSize)
Definition: xeformula.cxx:2513
XclExpRefLogEntry * GetNewRefLogEntry()
Definition: xeformula.cxx:1944
XclTokenArrayRef CreateErrorFormula(sal_uInt8 nErrCode)
Creates a single error token containing the passed error code.
Definition: xeformula.cxx:530
XclExpScToken CompareTerm(XclExpScToken aTokData, bool bInParentheses)
Definition: xeformula.cxx:1005
void AppendOperatorTokenId(sal_uInt8 nTokenId, const XclExpOperandListRef &rxOperands, sal_uInt8 nSpaces=0)
Definition: xeformula.cxx:2436
XclExpFmlaCompImpl(const XclExpRoot &rRoot)
Definition: xeformula.cxx:472
const FormulaToken * PeekNextRawToken() const
Definition: xeformula.cxx:816
XclExpScToken OrTerm(XclExpScToken aTokData, bool bInParentheses)
Definition: xeformula.cxx:971
XclExpScToken MulDivTerm(XclExpScToken aTokData, bool bInParentheses)
Definition: xeformula.cxx:1050
void RemoveTrailingParen()
Definition: xeformula.cxx:2558
const SCCOL mnMaxScCol
Maximum row index.
Definition: xeformula.cxx:466
void ProcessParentheses(const XclExpScToken &rTokData)
Definition: xeformula.cxx:1241
XclTokenArrayRef CreateSpecialRefFormula(sal_uInt8 nTokenId, const XclAddress &rXclPos)
Creates a single token for a special cell reference.
Definition: xeformula.cxx:537
void ProcessBad(const XclExpScToken &rTokData)
Definition: xeformula.cxx:1236
void AppendIntToken(sal_uInt16 nValue, sal_uInt8 nSpaces=0)
Definition: xeformula.cxx:2349
void Append(sal_uInt8 nData)
Definition: xeformula.cxx:2276
sal_uInt16 GetSize() const
Definition: xeformula.cxx:321
void RecalcTokenClasses()
Definition: xeformula.cxx:621
XclExpScToken UnaryPostTerm(XclExpScToken aTokData, bool bInParentheses)
Definition: xeformula.cxx:1081
void ProcessExternalCellRef(const XclExpScToken &rTokData)
Definition: xeformula.cxx:2057
bool IsSpaceToken(sal_uInt16 nPos) const
Definition: xeformula.cxx:2550
void ProcessCellRef(const XclExpScToken &rTokData)
Definition: xeformula.cxx:1954
XclExpScToken Factor(XclExpScToken aTokData)
Definition: xeformula.cxx:1178
const SCROW mnMaxScRow
Maximum column index in Calc itself.
Definition: xeformula.cxx:467
void AppendErrorToken(sal_uInt8 nErrCode, sal_uInt8 nSpaces=0)
Definition: xeformula.cxx:2367
void AppendOperandTokenId(sal_uInt8 nTokenId, sal_uInt8 nSpaces=0)
Definition: xeformula.cxx:2342
void AppendDefaultParam(XclExpFuncData &rFuncData)
Definition: xeformula.cxx:1662
XclExpScToken UnaryPreTerm(XclExpScToken aTokData, bool bInParentheses)
Definition: xeformula.cxx:1096
void AppendMacroCallToken(const XclExpExtFuncData &rExtFuncData)
Definition: xeformula.cxx:2406
const SCROW mnMaxAbsRow
Maximum column index.
Definition: xeformula.cxx:465
XclExpCompConfigMap maCfgMap
Definition: xeformula.cxx:458
void UpdateAttrGoto(sal_uInt16 nAttrPos)
Definition: xeformula.cxx:2540
XclExpScToken ListTerm(XclExpScToken aTokData, bool bInParentheses)
Definition: xeformula.cxx:1112
const FormulaToken * GetNextRawToken()
Definition: xeformula.cxx:809
void ConvertRefData(ScSingleRefData &rRefData, XclAddress &rXclPos, bool bNatLangRef, bool bTruncMaxCol, bool bTruncMaxRow) const
Definition: xeformula.cxx:1879
void ProcessExternal(const XclExpScToken &rTokData)
Definition: xeformula.cxx:1290
bool IsRef2D(const ScSingleRefData &rRefData, bool bCheck3DFlag) const
Definition: xeformula.cxx:1852
void ProcessString(const XclExpScToken &rTokData)
Definition: xeformula.cxx:1225
XclTokenArrayRef CreateTokenArray()
Definition: xeformula.cxx:788
XclExpScToken IntersectTerm(XclExpScToken aTokData, bool &rbHasRefOp)
Definition: xeformula.cxx:1146
XclExpCompDataRef mxData
Excel function data provider.
Definition: xeformula.cxx:460
XclExpScToken AddSubTerm(XclExpScToken aTokData, bool bInParentheses)
Definition: xeformula.cxx:1035
void ProcessDefinedName(const XclExpScToken &rTokData)
Definition: xeformula.cxx:2131
SCTAB GetScTab(const ScSingleRefData &rRefData) const
Definition: xeformula.cxx:1837
void ProcessMatrix(const XclExpScToken &rTokData)
Definition: xeformula.cxx:1303
void AppendBoolToken(bool bValue, sal_uInt8 nSpaces=0)
Definition: xeformula.cxx:2361
XclExpScToken RangeTerm(XclExpScToken aTokData, bool &rbHasRefOp)
Definition: xeformula.cxx:1162
void AppendFuncToken(const XclExpFuncData &rFuncData)
Definition: xeformula.cxx:2468
void AppendTrailingParam(XclExpFuncData &rFuncData)
Definition: xeformula.cxx:1709
void RecalcTokenClass(const XclExpTokenConvInfo &rConvInfo, XclFuncParamConv ePrevConv, XclExpClassConv ePrevClassConv, bool bWasRefClass)
Definition: xeformula.cxx:645
void AppendParenToken(sal_uInt8 nOpenSpaces=0, sal_uInt8 nCloseSpaces=0)
Definition: xeformula.cxx:2496
void ProcessRangeRef(const XclExpScToken &rTokData)
Definition: xeformula.cxx:2012
void AppendNumToken(double fValue, sal_uInt8 nSpaces=0)
Definition: xeformula.cxx:2355
void ProcessBoolean(const XclExpScToken &rTokData)
Definition: xeformula.cxx:1248
XclExpScToken ConcatTerm(XclExpScToken aTokData, bool bInParentheses)
Definition: xeformula.cxx:1020
const XclBiff meBiff
Stack for working data, when compiler is called recursively.
Definition: xeformula.cxx:463
void AppendNameToken(sal_uInt16 nNameIdx, sal_uInt8 nSpaces=0)
Definition: xeformula.cxx:2378
XclExpScToken GetNextToken()
Definition: xeformula.cxx:842
void Init(XclFormulaType eType)
Definition: xeformula.cxx:568
XclExpScToken Expression(XclExpScToken aTokData, bool bInParentheses, bool bStopAtSep)
Definition: xeformula.cxx:942
XclExpScToken ProcessParam(XclExpScToken aTokData, XclExpFuncData &rFuncData)
Definition: xeformula.cxx:1574
bool Is3DRefOnly(XclFormulaType eType) const
Returns true, if the passed formula type allows 3D references only.
Definition: xeformula.cxx:553
void AppendExt(sal_uInt8 nData)
Definition: xeformula.cxx:2568
void AppendNameXToken(sal_uInt16 nExtSheet, sal_uInt16 nExtName, sal_uInt8 nSpaces=0)
Definition: xeformula.cxx:2396
XclTokenArrayRef CreateFormula(XclFormulaType eType, const ScTokenArray &rScTokArr, const ScAddress *pScBasePos=nullptr, XclExpRefLog *pRefLog=nullptr)
Creates an Excel token array from the passed Calc token array.
Definition: xeformula.cxx:488
void AppendSpaceToken(sal_uInt8 nType, sal_uInt8 nCount)
Definition: xeformula.cxx:2331
const sal_uInt32 mnMaxRowMask
Mask to delete invalid bits in column fields.
Definition: xeformula.cxx:469
void PrepareParam(XclExpFuncData &rFuncData)
Definition: xeformula.cxx:1605
void AppendJumpToken(XclExpFuncData &rFuncData, sal_uInt8 nAttrType)
Definition: xeformula.cxx:2503
XclTokenArrayRef CreateNameXFormula(sal_uInt16 nExtSheet, sal_uInt16 nExtName)
Creates a single tNameXR token for a reference to an external name.
Definition: xeformula.cxx:546
bool IsRef2D(const ScSingleRefData &rRefData) const
Definition: xeformula.cxx:2700
XclTokenArrayRef CreateErrorFormula(sal_uInt8 nErrCode)
Creates a single error token containing the passed error code.
Definition: xeformula.cxx:2683
XclExpFmlaCompImplRef mxImpl
Definition: xeformula.hxx:88
virtual ~XclExpFormulaCompiler() override
Definition: xeformula.cxx:2640
XclExpFormulaCompiler(const XclExpRoot &rRoot)
Definition: xeformula.cxx:2634
XclTokenArrayRef CreateNameXFormula(sal_uInt16 nExtSheet, sal_uInt16 nExtName)
Creates a single tNameXR token for a reference to an external name.
Definition: xeformula.cxx:2694
XclTokenArrayRef CreateFormula(XclFormulaType eType, const ScTokenArray &rScTokArr, const ScAddress *pScBasePos=nullptr, XclExpRefLog *pRefLog=nullptr)
Creates and returns the token array of a formula.
Definition: xeformula.cxx:2644
XclTokenArrayRef CreateSpecialRefFormula(sal_uInt8 nTokenId, const XclAddress &rXclPos)
Creates a single token for a special cell reference.
Definition: xeformula.cxx:2688
Stores all data for internal/external references (the link table).
Definition: xelink.hxx:146
Manager that stores all internal defined names (NAME records) of the document.
Definition: xename.hxx:32
sal_uInt16 InsertRawName(const OUString &rName)
Returns index of an existing name, or creates a name without definition.
Definition: xename.cxx:832
SCTAB GetScTab(sal_uInt16 nNameIdx) const
Returns the Calc sheet of a local defined name, or SCTAB_GLOBAL for global defined names.
Definition: xename.cxx:848
sal_uInt16 InsertName(SCTAB nTab, sal_uInt16 nScNameIdx, SCTAB nCurrTab)
Inserts the Calc name with the passed index and returns the Excel NAME index.
Definition: xename.cxx:804
bool IsVolatile(sal_uInt16 nNameIdx) const
Returns true, if the specified defined name is volatile.
Definition: xename.cxx:854
sal_uInt16 InsertMacroCall(const OUString &rMacroName, bool bVBasic, bool bFunc, bool bHidden=false)
Searches or inserts a defined name describing a macro name.
Definition: xename.cxx:837
Access to global data from other classes.
Definition: xeroot.hxx:113
XclExpLinkManager & GetGlobalLinkManager() const
Returns the global link manager for defined names.
Definition: xeroot.cxx:130
XclExpNameManager & GetNameManager() const
Returns the buffer that contains internal defined names.
Definition: xeroot.cxx:142
XclExpLinkManager & GetLocalLinkManager() const
Returns the local link manager for the current sheet.
Definition: xeroot.cxx:136
const XclExpRoot & GetRoot() const
Returns this root instance - for code readability in derived classes.
Definition: xeroot.hxx:118
static XclExpStringRef CreateString(const XclExpRoot &rRoot, const OUString &rString, XclStrFlags nFlags=XclStrFlags::NONE, sal_uInt16 nMaxLen=EXC_STR_MAXLEN)
Creates a new unformatted string from the passed string.
Definition: xehelper.cxx:531
Provides access to function info structs for all available functions.
Definition: xlformula.hxx:345
const XclFunctionInfo * GetFuncInfoFromOpCode(OpCode eOpCode) const
Returns the function data for a Calc opcode, or 0 on error.
Definition: xlformula.cxx:692
XclOutput GetOutput() const
Returns the current output format of the importer/exporter.
Definition: xlroot.hxx:143
LanguageType GetUILanguage() const
Returns the UI language.
Definition: xlroot.hxx:153
SCTAB GetCurrScTab() const
Returns the current Calc sheet index.
Definition: xlroot.hxx:162
ScDocument & GetDoc() const
Returns reference to the destination document (import) or source document (export).
Definition: xlroot.cxx:286
A helper with Excel specific token array functions.
Definition: xlformula.hxx:486
static sal_uInt8 GetTokenClass(sal_uInt8 nTokenId)
Returns the token class of the passed token ID.
Definition: xlformula.hxx:494
static sal_uInt8 GetTokenId(sal_uInt8 nBaseId, sal_uInt8 nTokenClass)
Returns the classified token ID from a base ID and the token class.
Definition: xlformula.hxx:537
static void ChangeTokenClass(sal_uInt8 &rnTokenId, sal_uInt8 nTokenClass)
Changes the token class in the passed classified token ID.
Definition: xlformula.hxx:544
Special token array iterator for the Excel filters.
Definition: xlformula.hxx:439
const ::formula::FormulaToken * Get() const
Definition: xlformula.hxx:450
static sal_uInt8 GetXclErrorCode(FormulaError nScError)
Converts a Calc error code to an Excel error code.
Definition: xltools.cxx:201
static const OUString & GetNativeSymbol(OpCode eOp)
FormulaError GetCodeError() const
const OUString & getString() const
#define SC_OPCODE_START_NO_PAR
int nCount
FormulaError
DocumentType eType
sal_Int16 nValue
FunctionParamInfo mpParamInfos[FUNCINFO_PARAMINFOCOUNT]
BIFF token class of the return value.
::std::vector< sal_uInt8 > ScfUInt8Vec
Definition: ftools.hxx:253
void set_flag(Type &rnBitField, Type nMask, bool bSet=true)
Sets or clears (according to bSet) all set bits of nMask in rnBitField.
Definition: ftools.hxx:95
::std::vector< sal_uInt16 > ScfUInt16Vec
Definition: ftools.hxx:255
OUString aName
sal_uInt16 nPos
#define SAL_WARN(area, stream)
aStr
size
StackVar
svExternalDoubleRef
svUnknown
svExternalName
svDouble
svDoubleRef
svExternal
svExternalSingleRef
svString
svMatrix
svSingleRef
constexpr std::enable_if_t< std::is_signed_v< T >, std::make_unsigned_t< T > > make_unsigned(T value)
std::shared_ptr< T > make_shared(Args &&... args)
OpCode
ocNegSub
ocDiv
ocCot
ocFalse
ocRoundUp
ocSecant
ocDde
ocIndex
ocLessEqual
ocCosecantHyp
ocNone
ocOr
ocNotEqual
ocClose
ocColRowName
ocNormDist
ocRound
ocMacro
ocAdd
ocStop
ocUnion
ocSecantHyp
ocEqual
ocCosecant
ocOpen
ocSub
ocGreater
ocTrue
ocArcCot
ocExternal
ocSpaces
ocAnd
ocSep
ocMissing
ocPush
ocCotHyp
ocGreaterEqual
ocBad
ocArcCotHyp
ocWhitespace
ocRoundDown
ocLess
ocPoissonDist
ocLogInv
ocEuroConvert
ocNeg
ocMul
ocChoose
ocIf
ocGammaDist
ocLogNormDist
ocName
QPRO_FUNC_TYPE nType
Definition: qproform.cxx:398
Complex reference (a range) into the sheet.
Definition: refdata.hxx:123
SC_DLLPUBLIC ScRange toAbs(const ScSheetLimits &rLimits, const ScAddress &rPos) const
Definition: refdata.cxx:493
void InitRange(const ScRange &rRange)
Definition: refdata.hxx:130
ScSingleRefData Ref2
Definition: refdata.hxx:125
ScSingleRefData Ref1
Definition: refdata.hxx:124
Try NOT to use this struct.
Definition: scmatrix.hxx:53
ScMatValType nType
Definition: scmatrix.hxx:56
FormulaError GetError() const
Only valid if ScMatrix methods indicate that this is no string!
Definition: scmatrix.hxx:62
double fVal
Definition: scmatrix.hxx:54
const svl::SharedString & GetString() const
Only valid if ScMatrix methods indicate so!
Definition: scmatrix.hxx:59
bool GetBoolean() const
Only valid if ScMatrix methods indicate that this is a boolean.
Definition: scmatrix.hxx:65
Single reference (one address) into the sheet.
Definition: refdata.hxx:30
SCCOL Col() const
Definition: refdata.cxx:247
void SetAddress(const ScSheetLimits &rLimits, const ScAddress &rAddr, const ScAddress &rPos)
Definition: refdata.cxx:213
void InitAddress(const ScAddress &rAdr)
InitAddress: InitFlags and set address.
Definition: refdata.cxx:27
bool IsRowDeleted() const
Definition: refdata.hxx:84
SCTAB Tab() const
Definition: refdata.cxx:254
bool IsTabRel() const
Definition: refdata.hxx:69
SCROW Row() const
Definition: refdata.cxx:240
void SetColDeleted(bool bVal)
Definition: refdata.cxx:110
bool IsRowRel() const
Definition: refdata.hxx:67
void SetRelTab(SCTAB nVal)
Definition: refdata.cxx:99
ScAddress toAbs(const ScSheetLimits &rLimits, const ScAddress &rPos) const
Definition: refdata.cxx:193
bool IsColRel() const
Definition: refdata.hxx:65
bool IsTabDeleted() const
Definition: refdata.hxx:86
void SetFlag3D(bool bVal)
Definition: refdata.hxx:89
bool IsFlag3D() const
Definition: refdata.hxx:90
void SetRowDeleted(bool bVal)
Definition: refdata.cxx:115
bool IsColDeleted() const
Definition: refdata.hxx:82
A 2D cell address struct with Excel column and row indexes.
Definition: xladdress.hxx:30
sal_uInt16 mnCol
Definition: xladdress.hxx:31
sal_uInt32 mnRow
Definition: xladdress.hxx:32
Log entry for external references in a formula, used i.e.
Definition: xeformula.hxx:32
XclExpRefLogEntry()
Calc index of the last sheet.
Definition: xeformula.cxx:43
Structure that contains all needed information for a parameter in a function.
Definition: xlformula.hxx:276
bool mbValType
Token class conversion type.
Definition: xlformula.hxx:279
XclFuncParamConv meConv
Parameter validity.
Definition: xlformula.hxx:278
Represents information for a spreadsheet function for import and export.
Definition: xlformula.hxx:311
OUString GetMacroFuncName() const
Returns the name of the external function as string.
Definition: xlformula.cxx:35
OUString GetAddInEquivalentFuncName() const
Returns the programmatical name of the Add-In function as string.
Definition: xlformula.cxx:42
bool IsMacroFunc() const
Returns true, if the function is simulated by a macro call.
Definition: xlformula.hxx:332
bool IsAddInEquivalent() const
Returns true, if the function is stored as an add-in call.
Definition: xlformula.hxx:334
A 2D cell range address struct with Excel column and row indexes.
Definition: xladdress.hxx:59
XclAddress maFirst
Definition: xladdress.hxx:60
XclAddress maLast
Definition: xladdress.hxx:61
unsigned char sal_uInt8
sal_Int16 SCTAB
Definition: types.hxx:22
sal_Int16 SCCOL
Definition: types.hxx:21
sal_Int32 SCROW
Definition: types.hxx:17
RedlineType meType
::std::vector< XclExpRefLogEntry > XclExpRefLog
Vector containing a log for all external references in a formula, used i.e.
Definition: xeformula.hxx:43
std::shared_ptr< XclExpString > XclExpStringRef
Definition: xeroot.hxx:35
const SCTAB SCTAB_INVALID
An invalid Excel sheet index, for common use.
Definition: xlconst.hxx:73
const sal_uInt8 EXC_ERR_NA
Definition: xlconst.hxx:110
const sal_uInt8 EXC_ERR_REF
Definition: xlconst.hxx:107
const SCTAB SCTAB_GLOBAL
An invalid Calc sheet index, for common use.
Definition: xlconst.hxx:74
const sal_uInt8 EXC_ERR_NAME
Definition: xlconst.hxx:108
const sal_uInt8 EXC_CACHEDVAL_ERROR
Definition: xlconst.hxx:118
const sal_uInt8 EXC_CACHEDVAL_STRING
Definition: xlconst.hxx:116
XclBiff
An enumeration for all Excel file format types (BIFF types).
Definition: xlconst.hxx:30
@ EXC_BIFF5
MS Excel 4.0.
Definition: xlconst.hxx:34
@ EXC_BIFF8
MS Excel 5.0, MS Excel 7.0 (95)
Definition: xlconst.hxx:35
@ EXC_OUTPUT_XML_2007
MS Excel binary .xls.
Definition: xlconst.hxx:43
const sal_uInt8 EXC_CACHEDVAL_EMPTY
Definition: xlconst.hxx:114
const sal_uInt8 EXC_CACHEDVAL_BOOL
Definition: xlconst.hxx:117
const sal_uInt8 EXC_CACHEDVAL_DOUBLE
Definition: xlconst.hxx:115
const sal_uInt8 EXC_TOKID_MEMFUNC
Constant reference subexpression without result.
Definition: xlformula.hxx:95
const sal_uInt8 EXC_TOKID_AREA
2D cell reference.
Definition: xlformula.hxx:91
const sal_uInt8 EXC_TOKID_LIST
Intersection operator.
Definition: xlformula.hxx:67
const sal_uInt8 EXC_TOKID_UMINUS
Unary plus.
Definition: xlformula.hxx:70
const sal_uInt8 EXC_TOKID_ISECT
Not equal operator.
Definition: xlformula.hxx:66
const sal_uInt8 EXC_TOKID_INT
Boolean constant.
Definition: xlformula.hxx:81
const sal_uInt8 EXC_TOKID_DIV
Multiplication operator.
Definition: xlformula.hxx:57
const sal_uInt8 EXC_TOKCLASS_VAL
20-3F: Reference class tokens.
Definition: xlformula.hxx:44
const sal_uInt8 EXC_TOKID_REF3D
External reference.
Definition: xlformula.hxx:104
const sal_uInt8 EXC_TOK_BOOL_TRUE
sal_False value of a tBool token.
Definition: xlformula.hxx:114
const sal_uInt8 EXC_TOKID_SUB
Addition operator.
Definition: xlformula.hxx:55
const sal_uInt16 EXC_FUNCID_SUM
Definition: xlformula.hxx:296
const sal_uInt8 EXC_TOKID_NAME
Function, variable number of arguments.
Definition: xlformula.hxx:89
const sal_uInt8 EXC_FUNC_MAXPARAM
Definition: xlformula.hxx:284
const sal_uInt16 EXC_FUNCID_OR
Definition: xlformula.hxx:298
const sal_uInt16 EXC_TOK_NLR_REL
NLR: Pivot table name.
Definition: xlformula.hxx:153
const sal_uInt8 EXC_TOKID_CONCAT
Power operator.
Definition: xlformula.hxx:59
const sal_uInt8 EXC_TOKID_REFERR
Variable reference subexpression.
Definition: xlformula.hxx:96
const sal_uInt8 EXC_TOK_ATTR_IF
Volatile function.
Definition: xlformula.hxx:117
const sal_uInt8 EXC_TOK_NLR_ROWV
NLR: Column index.
Definition: xlformula.hxx:143
const sal_uInt8 EXC_TOK_BOOL_FALSE
Maximum string length of a tStr token.
Definition: xlformula.hxx:113
const sal_uInt8 EXC_TOKCLASS_ARR
40-5F: Value class tokens.
Definition: xlformula.hxx:45
XclFuncParamConv
Enumerates different types of token class conversion in function parameters.
Definition: xlformula.hxx:186
@ EXC_PARAMCONV_VAL
Use original class of current token.
Definition: xlformula.hxx:188
@ EXC_PARAMCONV_ORG
Definition: xlformula.hxx:187
@ EXC_PARAMCONV_RPX
Repeat parent conversion in VALTYPE parameters.
Definition: xlformula.hxx:191
@ EXC_PARAMCONV_RPT
Convert tokens to ARR class.
Definition: xlformula.hxx:190
@ EXC_PARAMCONV_ARR
Convert tokens to VAL class.
Definition: xlformula.hxx:189
@ EXC_PARAMCONV_RPO
Repeat parent conversion in REFTYPE parameters.
Definition: xlformula.hxx:192
const sal_uInt8 EXC_TOKID_FUNC
Array constant.
Definition: xlformula.hxx:87
const sal_uInt8 EXC_TOKID_AREAERR3D
Deleted 3D cell reference.
Definition: xlformula.hxx:107
const sal_uInt8 EXC_TOKID_GT
Greater than or equal operator.
Definition: xlformula.hxx:64
const sal_uInt8 EXC_TOK_ATTR_SPACE_SP_OPEN
Line breaks before next token.
Definition: xlformula.hxx:126
const sal_uInt8 EXC_TOK_NLR_COLV
NLR: Value in row.
Definition: xlformula.hxx:144
const sal_uInt8 EXC_TOKID_MUL
Subtraction operator.
Definition: xlformula.hxx:56
const sal_uInt8 EXC_TOKID_NE
Greater than operator.
Definition: xlformula.hxx:65
@ EXC_PARAM_NONE
Definition: xlformula.hxx:178
@ EXC_PARAM_EXCELONLY
Parameter supported by Calc only.
Definition: xlformula.hxx:181
@ EXC_PARAM_CALCONLY
Parameter supported by Calc and Excel.
Definition: xlformula.hxx:180
const sal_uInt8 EXC_TOKID_NAMEX
Definition: xlformula.hxx:103
const sal_uInt8 EXC_TOKID_REFERR3D
3D area reference.
Definition: xlformula.hxx:106
const sal_uInt8 EXC_TOKID_REFN
Deleted 2D area reference.
Definition: xlformula.hxx:98
const sal_uInt8 EXC_TOKID_ARRAY
Floating-point constant.
Definition: xlformula.hxx:86
const sal_uInt8 EXC_TOKID_AREAERR
Deleted 2D cell reference.
Definition: xlformula.hxx:97
const sal_uInt8 EXC_TOKID_REF
Defined name.
Definition: xlformula.hxx:90
const sal_uInt8 EXC_TOK_ATTR_SPACE_SP
Spaces in formula representation.
Definition: xlformula.hxx:124
const sal_uInt8 EXC_TOKID_MISSARG
Parentheses.
Definition: xlformula.hxx:73
XclFormulaType
Mask for number of appended ranges.
Definition: xlformula.hxx:160
@ EXC_FMLATYPE_CHART
Defined name.
Definition: xlformula.hxx:167
@ EXC_FMLATYPE_MATRIX
Simple cell formula, also used in change tracking.
Definition: xlformula.hxx:162
@ EXC_FMLATYPE_NAME
Data validation.
Definition: xlformula.hxx:166
@ EXC_FMLATYPE_SHARED
Matrix (array) formula.
Definition: xlformula.hxx:163
@ EXC_FMLATYPE_CONTROL
Chart source ranges.
Definition: xlformula.hxx:168
@ EXC_FMLATYPE_DATAVAL
Conditional format.
Definition: xlformula.hxx:165
@ EXC_FMLATYPE_WQUERY
Spreadsheet links in form controls.
Definition: xlformula.hxx:169
@ EXC_FMLATYPE_LISTVAL
Web query source range.
Definition: xlformula.hxx:170
@ EXC_FMLATYPE_CONDFMT
Shared formula.
Definition: xlformula.hxx:164
@ EXC_FMLATYPE_CELL
Definition: xlformula.hxx:161
const sal_uInt8 EXC_TOKID_RANGE
List operator.
Definition: xlformula.hxx:68
const sal_uInt8 EXC_TOK_ATTR_SUM
Jump to token.
Definition: xlformula.hxx:120
std::shared_ptr< XclTokenArray > XclTokenArrayRef
Definition: xlformula.hxx:416
const sal_uInt8 EXC_TOK_ATTR_VOLATILE
sal_True value of a tBool token.
Definition: xlformula.hxx:116
const sal_uInt8 EXC_TOKID_GE
Equal operator.
Definition: xlformula.hxx:63
const sal_uInt8 EXC_TOKID_LE
Less than operator.
Definition: xlformula.hxx:61
const sal_uInt16 EXC_TOK_STR_MAXLEN
Deleted 3D area reference.
Definition: xlformula.hxx:111
const sal_uInt8 EXC_TOKCLASS_REF
00-1F: Base tokens.
Definition: xlformula.hxx:43
const sal_uInt16 EXC_TOK_REF_ROWREL
True = Column is relative.
Definition: xlformula.hxx:138
const sal_uInt8 EXC_TOKID_ERR
End of a sheet reference (BIFF2-BIFF4).
Definition: xlformula.hxx:79
const sal_uInt8 EXC_TOK_ATTR_SPACE_SP_CLOSE
Line breaks before opening parenthesis.
Definition: xlformula.hxx:128
const sal_uInt8 EXC_TOKID_NLR
String constant.
Definition: xlformula.hxx:75
const size_t EXC_TOKARR_MAXLEN
Definition: xlformula.hxx:37
const sal_uInt8 EXC_TOKID_AREA3D
3D cell reference.
Definition: xlformula.hxx:105
const sal_uInt8 EXC_TOK_ATTR_CHOOSE
Start of true condition in IF function.
Definition: xlformula.hxx:118
const sal_uInt8 EXC_TOKID_LT
String concatenation operator.
Definition: xlformula.hxx:60
const sal_uInt8 EXC_TOK_ATTR_GOTO
Jump array of CHOOSE function.
Definition: xlformula.hxx:119
const sal_uInt8 EXC_TOKID_EQ
Less than or equal operator.
Definition: xlformula.hxx:62
const sal_uInt8 EXC_TOKID_STR
Missing argument.
Definition: xlformula.hxx:74
const sal_uInt8 EXC_TOKID_NUM
Integer constant.
Definition: xlformula.hxx:82
const sal_uInt8 EXC_TOKID_ADD
Multiple operation reference.
Definition: xlformula.hxx:54
const sal_uInt8 EXC_TOKID_NONE
Definition: xlformula.hxx:51
const sal_uInt8 EXC_TOKID_ATTR
Natural language reference (NLR).
Definition: xlformula.hxx:76
const sal_uInt8 EXC_TOKID_POWER
Division operator.
Definition: xlformula.hxx:58
const sal_uInt8 EXC_TOKID_FUNCVAR
Function, fixed number of arguments.
Definition: xlformula.hxx:88
const sal_uInt8 EXC_TOKID_BOOL
Error constant.
Definition: xlformula.hxx:80
const sal_uInt16 EXC_FUNCID_AND
Definition: xlformula.hxx:297
const sal_uInt8 EXC_TOKID_PERCENT
Unary minus.
Definition: xlformula.hxx:71
const sal_uInt8 EXC_TOKID_PAREN
Percent sign.
Definition: xlformula.hxx:72
const size_t EXC_FUNCINFO_PARAMINFO_COUNT
Maximum parameter count.
Definition: xlformula.hxx:286
const sal_uInt8 EXC_TOKID_UPLUS
Range operator.
Definition: xlformula.hxx:69
const sal_uInt16 EXC_TOK_REF_COLREL
Mask for parameter count.
Definition: xlformula.hxx:137
const sal_uInt8 EXC_TOK_ATTR_SPACE
BASIC style assignment.
Definition: xlformula.hxx:122
const sal_uInt8 EXC_TOKID_AREAN
Relative 2D cell reference (in names).
Definition: xlformula.hxx:99
XclStrFlags
Flags used to specify import/export mode of strings.
Definition: xlstring.hxx:29
@ EightBitLength
Always use UCS-2 characters (default: try to compress). BIFF8 only.