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