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