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