22#include <compiler.hxx>
23#include <document.hxx>
26#include <tokenarray.hxx>
45 mpFirstTab( nullptr ),
60 const FormulaToken* mpScToken;
63 explicit XclExpScToken() : mpScToken( nullptr ), mnSpaces( 0 ) {}
64 bool Is()
const {
return mpScToken !=
nullptr; }
66 OpCode GetOpCode()
const {
return mpScToken ? mpScToken->GetOpCode() :
ocNone; }
78struct XclExpTokenConvInfo
87struct XclExpOperandList :
public std::vector< XclExpTokenConvInfo >
89 explicit XclExpOperandList() { reserve( 2 ); }
90 void AppendOperand( sal_uInt16 nTokPos,
XclFuncParamConv eConv,
bool bValType );
93void XclExpOperandList::AppendOperand( sal_uInt16 nTokPos,
XclFuncParamConv eConv,
bool bValType )
96 XclExpTokenConvInfo& rConvInfo = back();
97 rConvInfo.mnTokPos = nTokPos;
98 rConvInfo.meConv = eConv;
99 rConvInfo.mbValType = bValType;
102typedef std::shared_ptr< XclExpOperandList > XclExpOperandListRef;
105struct XclExpExtFuncData
111 explicit XclExpExtFuncData() : mbVBasic( false ), mbHidden( false ) {}
112 void Set(
const OUString& rFuncName,
bool bVBasic,
bool bHidden );
115void XclExpExtFuncData::Set(
const OUString& rFuncName,
bool bVBasic,
bool bHidden )
117 maFuncName = rFuncName;
126 explicit XclExpFuncData(
127 const XclExpScToken& rTokData,
129 XclExpExtFuncData aExtFuncData );
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; }
143 bool IsCalcOnlyParam()
const;
144 bool IsExcelOnlyParam()
const;
145 void IncParamInfoIdx();
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; }
154 void AppendAttrPos( sal_uInt16 nPos ) { maAttrPosVec.push_back( nPos ); }
158 const XclExpScToken& mrTokData;
160 XclExpExtFuncData maExtFuncData;
161 XclExpOperandListRef mxOperands;
165XclExpFuncData::XclExpFuncData(
const XclExpScToken& rTokData,
167 mrTokData( rTokData ),
168 mrFuncInfo( rFuncInfo ),
169 maExtFuncData(
std::move( aExtFuncData )),
173 OSL_ENSURE( mrTokData.mpScToken,
"XclExpFuncData::XclExpFuncData - missing core token" );
175 if( (maExtFuncData.maFuncName.isEmpty()) &&
dynamic_cast< const FormulaExternalToken*
>( mrTokData.mpScToken ) )
176 maExtFuncData.Set( GetScToken().GetExternal(),
true,
false );
182 return mpParamInfo ? *mpParamInfo : saInvalidInfo;
185bool XclExpFuncData::IsCalcOnlyParam()
const
190bool XclExpFuncData::IsExcelOnlyParam()
const
195void XclExpFuncData::IncParamInfoIdx()
204 else if( IsExcelOnlyParam() || IsCalcOnlyParam() )
205 mpParamInfo =
nullptr;
207 else if( mrFuncInfo.IsParamPairs() )
212void XclExpFuncData::FinishParam( sal_uInt16 nTokPos )
216 mxOperands->AppendOperand( nTokPos, rParamInfo.
meConv, rParamInfo.
mbValType );
224enum XclExpFmlaClassType
232struct XclExpCompConfig
235 XclExpFmlaClassType meClassType;
243const XclExpCompConfig spConfigTable[] =
261 typedef std::shared_ptr< ScTokenArray > ScTokenArrayRef;
263 const XclExpCompConfig& mrCfg;
264 ScTokenArrayRef mxOwnScTokArr;
272 std::vector< XclExpOperandListRef >
279 explicit XclExpCompData(
const XclExpCompConfig* pCfg );
282XclExpCompData::XclExpCompData(
const XclExpCompConfig* pCfg ) :
283 mrCfg( pCfg ? *pCfg : spConfigTable[ 0 ] ),
284 mpLinkMgr( nullptr ),
286 mpScBasePos( nullptr ),
287 mbStopAtSep( false ),
289 mbOk( pCfg != nullptr )
291 OSL_ENSURE( pCfg,
"XclExpFmlaCompImpl::Init - unknown formula type" );
321 sal_uInt16
GetSize()
const {
return static_cast< sal_uInt16
>(
mxData->maTokVec.size() ); }
343 XclExpScToken
Expression( XclExpScToken aTokData,
bool bInParentheses,
bool bStopAtSep );
344 XclExpScToken
SkipExpression( XclExpScToken aTokData,
bool bStopAtSep );
346 XclExpScToken
OrTerm( XclExpScToken aTokData,
bool bInParentheses );
347 XclExpScToken
AndTerm( XclExpScToken aTokData,
bool bInParentheses );
348 XclExpScToken
CompareTerm( XclExpScToken aTokData,
bool bInParentheses );
349 XclExpScToken
ConcatTerm( XclExpScToken aTokData,
bool bInParentheses );
350 XclExpScToken
AddSubTerm( XclExpScToken aTokData,
bool bInParentheses );
351 XclExpScToken
MulDivTerm( XclExpScToken aTokData,
bool bInParentheses );
352 XclExpScToken
PowTerm( XclExpScToken aTokData,
bool bInParentheses );
353 XclExpScToken
UnaryPostTerm( XclExpScToken aTokData,
bool bInParentheses );
354 XclExpScToken
UnaryPreTerm( XclExpScToken aTokData,
bool bInParentheses );
355 XclExpScToken
ListTerm( XclExpScToken aTokData,
bool bInParentheses );
356 XclExpScToken
IntersectTerm( XclExpScToken aTokData,
bool& rbHasRefOp );
357 XclExpScToken
RangeTerm( XclExpScToken aTokData,
bool& rbHasRefOp );
358 XclExpScToken
Factor( XclExpScToken aTokData );
365 void ProcessBad(
const XclExpScToken& rTokData );
378 XclExpScToken
ProcessParam( XclExpScToken aTokData, XclExpFuncData& rFuncData );
389 bool bNatLangRef,
bool bTruncMaxCol,
bool bTruncMaxRow )
const;
391 bool bNatLangRef )
const;
404 void PushOperatorPos( sal_uInt16 nTokPos,
const XclExpOperandListRef& rxOperands );
409 void Append( sal_uInt16 nData );
410 void Append( sal_uInt32 nData );
411 void Append(
double fData );
412 void Append(
const OUString& rString );
441 void InsertZeros( sal_uInt16 nInsertPos, sal_uInt16 nInsertSize );
442 void Overwrite( sal_uInt16 nWriteToPos, sal_uInt16 nOffset );
453 void AppendExt(
const OUString& rString );
462 std::vector< XclExpCompDataRef >
476 meBiff( rRoot.GetBiff() ),
477 mnMaxAbsCol( rRoot.GetXclMaxPos().
Col() ),
478 mnMaxAbsRow( rRoot.GetXclMaxPos().
Row() ),
479 mnMaxScCol( rRoot.GetScMaxPos().
Col() ),
480 mnMaxScRow( rRoot.GetScMaxPos().
Row() ),
481 mnMaxColMask( static_cast< sal_uInt16 >( rRoot.GetXclMaxPos().
Col() ) ),
482 mnMaxRowMask( static_cast< sal_uInt32 >( rRoot.GetXclMaxPos().
Row() ) )
485 for(
auto const &rEntry : spConfigTable)
493 Init(
eType, rScTokArr, pScBasePos, pRefLog );
500 if( (nScError != FormulaError::NONE) && (!aTokData.Is() || (aTokData.GetOpCode() ==
ocStop)) )
505 else if( aTokData.Is() )
507 aTokData =
Expression( aTokData,
false,
false );
511 OSL_FAIL(
"XclExpFmlaCompImpl::CreateFormula - empty token array" );
518 mxData->mbOk = !aTokData.Is() || (aTokData.GetOpCode() ==
ocStop);
519 OSL_ENSURE(
mxData->mbOk,
"XclExpFmlaCompImpl::CreateFormula - unknown garbage behind formula" );
557 return pCfg && pCfg->mb3DRefOnly;
564 XclExpCompConfigMap::const_iterator aIt =
maCfgMap.find(
eType );
565 OSL_ENSURE( aIt !=
maCfgMap.end(),
"XclExpFmlaCompImpl::GetConfigForType - unknown formula type" );
566 return (aIt ==
maCfgMap.end()) ? nullptr : &aIt->second;
590 mxData->mbOk = pScBasePos !=
nullptr;
591 OSL_ENSURE(
mxData->mbOk,
"XclExpFmlaCompImpl::Init - missing cell address" );
592 mxData->mpScBasePos = pScBasePos;
595 mxData->mbOk = pScBasePos !=
nullptr;
596 assert(
mxData->mbOk &&
"XclExpFmlaCompImpl::Init - missing cell address");
614 mxData->maTokArrIt.Init(
mxData->mxOwnScTokArr ? *
mxData->mxOwnScTokArr : rScTokArr,
false );
615 mxData->mpRefLog = pRefLog;
618 mxData->mpScBasePos = pScBasePos;
628 OSL_ENSURE(
mxData->mbOk,
"XclExpFmlaCompImpl::RecalcTokenClasses - position of root token expected on stack" );
634 bool bNameFmla =
mxData->mrCfg.meClassType == EXC_CLASSTYPE_NAME;
636 XclExpClassConv eClassConv = bNameFmla ? EXC_CLASSCONV_ARR : EXC_CLASSCONV_VAL;
637 XclExpTokenConvInfo aConvInfo = {
PopOperandPos(), eParamConv, !bNameFmla };
639 RecalcTokenClass(aConvInfo, eParamConv, eClassConv, bNameFmla, aSeenTokens);
643 mxData->maOpListVec.clear();
644 mxData->maOpPosStack.clear();
648 XclFuncParamConv ePrevConv, XclExpClassConv ePrevClassConv,
bool bWasRefClass,
651 OSL_ENSURE( rConvInfo.mnTokPos <
GetSize(),
"XclExpFmlaCompImpl::RecalcTokenClass - invalid token position" );
653 const bool bAlreadySeen = !rSeenTokens.
insert(&rConvInfo).second;
656 SAL_WARN(
"sc.filter",
"XclExpFmlaCompImpl::RecalcTokenClass: loop in nested operands");
659 rSeenTokens.
insert(&rConvInfo);
675 XclExpClassConv eClassConv = EXC_CLASSCONV_ORG;
680 eClassConv = EXC_CLASSCONV_ORG;
684 eClassConv = EXC_CLASSCONV_VAL;
688 eClassConv = EXC_CLASSCONV_ARR;
700 eClassConv = bWasRefClass ? EXC_CLASSCONV_VAL : ePrevClassConv;
704 eClassConv = ePrevClassConv;
711 eClassConv = bWasRefClass ? ePrevClassConv : EXC_CLASSCONV_ORG;
724 eClassConv = ((nTokClass ==
EXC_TOKCLASS_REF) || (ePrevClassConv == EXC_CLASSCONV_ARR)) ?
725 ePrevClassConv : EXC_CLASSCONV_ORG;
734 case EXC_CLASSCONV_ORG:
745 case EXC_CLASSCONV_VAL:
753 case EXC_CLASSCONV_ARR:
764 if( rConvInfo.mnTokPos <
mxData->maOpListVec.size() )
765 if(
const XclExpOperandList* pOperands =
mxData->maOpListVec[ rConvInfo.mnTokPos ].get() )
766 for(
const auto& rOperand : *pOperands )
794 mxData->maExtDataVec.clear();
795 mxData->mbVolatile =
false;
803 OSL_ENSURE(
mxData->mrCfg.mbAllowArrays ||
mxData->maExtDataVec.empty(),
"XclExpFmlaCompImpl::CreateTokenArray - unexpected extended data" );
804 if( !
mxData->mrCfg.mbAllowArrays )
805 mxData->maExtDataVec.clear();
823 const FormulaToken* pScToken =
mxData->maTokArrIt.Get();
838 return aTempIt.
Get();
844 rTokData.mnSpaces = 0;
848 rTokData.mnSpaces += rTokData.mpScToken->GetByte();
851 return rTokData.Is();
856 XclExpScToken aTokData;
956 if(
mxData->mbOk && aTokData.Is() )
959 bool bOldStopAtSep =
mxData->mbStopAtSep;
960 mxData->mbStopAtSep = bStopAtSep;
962 aTokData =
OrTerm( aTokData, bInParentheses );
964 mxData->mbStopAtSep = bOldStopAtSep;
971 while(
mxData->mbOk && aTokData.Is() && (aTokData.GetOpCode() !=
ocClose) && (!bStopAtSep || (aTokData.GetOpCode() !=
ocSep)) )
973 if( aTokData.GetOpCode() ==
ocOpen )
985 aTokData =
AndTerm( aTokData, bInParentheses );
987 while(
mxData->mbOk && (aTokData.GetOpCode() ==
ocOr) )
995 if(
mxData->mbOk && (nParamCount > 1) )
1002 aTokData =
CompareTerm( aTokData, bInParentheses );
1004 while(
mxData->mbOk && (aTokData.GetOpCode() ==
ocAnd) )
1012 if(
mxData->mbOk && (nParamCount > 1) )
1019 aTokData =
ConcatTerm( aTokData, bInParentheses );
1022 sal_uInt8 nOpTokenId = lclGetConcatTokenId( aTokData.GetOpCode() );
1034 aTokData =
AddSubTerm( aTokData, bInParentheses );
1037 sal_uInt8 nOpTokenId = lclGetCompareTokenId( aTokData.GetOpCode() );
1049 aTokData =
MulDivTerm( aTokData, bInParentheses );
1052 sal_uInt8 nOpTokenId = lclGetAddSubTokenId( aTokData.GetOpCode() );
1064 aTokData =
PowTerm( aTokData, bInParentheses );
1067 sal_uInt8 nOpTokenId = lclGetMulDivTokenId( aTokData.GetOpCode() );
1083 nOpTokenId = lclGetPowTokenId( aTokData.GetOpCode() );
1099 nOpTokenId = lclGetUnaryPostTokenId( aTokData.GetOpCode() );
1119 aTokData =
ListTerm( aTokData, bInParentheses );
1126 sal_uInt16 nSubExprPos =
GetSize();
1127 bool bHasAnyRefOp =
false;
1128 bool bHasListOp =
false;
1132 sal_uInt8 nOpTokenId = lclGetListTokenId( aTokData.GetOpCode(),
mxData->mbStopAtSep );
1138 bHasAnyRefOp = bHasListOp =
true;
1143 sal_uInt16 nSubExprSize =
GetSize() - nSubExprPos;
1146 Overwrite( nSubExprPos + 1, nSubExprSize );
1148 XclExpOperandListRef xOperands = std::make_shared<XclExpOperandList>();
1153 if( bHasListOp && !bInParentheses )
1160 aTokData =
RangeTerm( aTokData, rbHasRefOp );
1163 sal_uInt8 nOpTokenId = lclGetIntersectTokenId( aTokData.GetOpCode() );
1176 aTokData =
Factor( aTokData );
1179 sal_uInt8 nOpTokenId = lclGetRangeTokenId( aTokData.GetOpCode() );
1192 if( !
mxData->mbOk || !aTokData.Is() )
return XclExpScToken();
1194 switch( aTokData.GetType() )
1207 default:
switch( aTokData.GetOpCode() )
1228 double fValue = rTokData.mpScToken->GetDouble();
1230 double fFrac = modf( fValue, &fInt );
1231 if( (fFrac == 0.0) && (0.0 <= fInt) && (fInt <= 65535.0) )
1232 AppendIntToken(
static_cast< sal_uInt16
>( fInt ), rTokData.mnSpaces );
1240 Append( rTokData.mpScToken->GetString().getString() );
1270bool lclGetTokenString( OUString& rString,
const XclExpScToken& rTokData )
1272 bool bIsStr = (rTokData.GetType() ==
svString) && (rTokData.GetOpCode() ==
ocPush);
1274 rString = rTokData.mpScToken->GetString().getString();
1282 OUString aApplic, aTopic, aItem;
1291 if(
mxData->mbOk )
mxData->mbOk = !aApplic.isEmpty() && !aTopic.isEmpty() && !aItem.isEmpty();
1294 sal_uInt16 nExtSheet(0), nExtName(0);
1295 if(
mxData->mpLinkMgr &&
mxData->mpLinkMgr->InsertDde( nExtSheet, nExtName, aApplic, aTopic, aItem ) )
1309 if( !pNextScToken || (pNextScToken->GetOpCode() !=
ocOpen) )
1317 const ScMatrix* pMatrix = rTokData.mpScToken->GetMatrix();
1318 if( pMatrix &&
mxData->mrCfg.mbAllowArrays )
1322 OSL_ENSURE( (nScCols > 0) && (nScRows > 0),
"XclExpFmlaCompImpl::ProcessMatrix - invalid matrix size" );
1323 sal_uInt16 nCols = ::limit_cast< sal_uInt16 >( nScCols, 0, 256 );
1324 sal_uInt16 nRows = ::limit_cast< sal_uInt16 >( nScRows, 0, 1024 );
1330 Append(
static_cast< sal_uInt32
>( 0 ) );
1335 for(
SCSIZE nScRow = 0; nScRow < nScRows; ++nScRow )
1337 for(
SCSIZE nScCol = 0; nScCol < nScCols; ++nScCol )
1349 else if( (nErr = nMatVal.
GetError()) != FormulaError::NONE )
1364 if(
aStr.isEmpty() )
1387 OpCode eOpCode = rTokData.GetOpCode();
1390 XclExpExtFuncData aExtFuncData;
1396 if( !rFuncName.isEmpty() )
1398 aExtFuncData.Set( rFuncName,
true,
false );
1403 mxData->mbOk = pFuncInfo !=
nullptr;
1404 if( !
mxData->mbOk )
return;
1413 XclExpFuncData aFuncData( rTokData, *pFuncInfo, std::move(aExtFuncData) );
1414 XclExpScToken aTokData;
1419 enum { STATE_START, STATE_OPEN, STATE_PARAM, STATE_SEP, STATE_CLOSE, STATE_END }
1420 eState = STATE_START;
1421 while( eState != STATE_END )
switch( eState )
1425 eState =
mxData->mbOk ? STATE_OPEN : STATE_END;
1429 eState =
mxData->mbOk ? ((aTokData.GetOpCode() ==
ocClose) ? STATE_CLOSE : STATE_PARAM) : STATE_END;
1433 switch( aTokData.GetOpCode() )
1435 case ocSep: eState = STATE_SEP;
break;
1436 case ocClose: eState = STATE_CLOSE;
break;
1437 default:
mxData->mbOk =
false;
1439 if( !
mxData->mbOk ) eState = STATE_END;
1443 eState =
mxData->mbOk ? STATE_PARAM : STATE_END;
1459 switch( rFuncData.GetOpCode() )
1482 sal_uInt8 nParamCount = rFuncData.GetParamCount();
1483 if( (rFuncData.GetMinParamCount() <= nParamCount) && (nParamCount <= rFuncData.GetMaxParamCount()) )
1490 switch( rFuncData.GetOpCode() )
1503 mxData->mbVolatile |= rFuncData.IsVolatile();
1506 switch( rFuncData.GetOpCode() )
1546 sal_uInt16 nParamCount = rFuncData.GetParamCount();
1547 OSL_ENSURE( (nParamCount == 2) || (nParamCount == 3),
"XclExpFmlaCompImpl::FinishIfFunction - wrong parameter count" );
1548 const ScfUInt16Vec& rAttrPos = rFuncData.GetAttrPosVec();
1549 OSL_ENSURE( nParamCount == rAttrPos.size(),
"XclExpFmlaCompImpl::FinishIfFunction - wrong number of tAttr tokens" );
1551 Overwrite( rAttrPos[ 0 ] + 2,
static_cast< sal_uInt16
>( rAttrPos[ 1 ] - rAttrPos[ 0 ] ) );
1554 if( nParamCount == 3 )
1560 sal_uInt16 nParamCount = rFuncData.GetParamCount();
1562 OSL_ENSURE( nParamCount == rAttrPos.size(),
"XclExpFmlaCompImpl::FinishChooseFunction - wrong number of tAttr tokens" );
1564 sal_uInt16 nChoices = nParamCount - 1;
1566 Overwrite( rAttrPos[ 0 ] + 2, nChoices );
1568 sal_uInt16 nJumpArrPos = rAttrPos[ 0 ] + 4;
1570 sal_uInt16 nJumpArrSize = 2 * (nChoices + 1);
1575 for( nIdx = 1; nIdx < nParamCount; ++nIdx )
1576 rAttrPos[ nIdx ] = rAttrPos[ nIdx ] + nJumpArrSize;
1578 for( nIdx = 1; nIdx < nParamCount; ++nIdx )
1582 for( nIdx = 1; nIdx < nParamCount; ++nIdx )
1583 Overwrite( nJumpArrPos + 2 * nIdx,
static_cast< sal_uInt16
>( rAttrPos[ nIdx ] + 4 - nJumpArrPos ) );
1588 if( rFuncData.IsCalcOnlyParam() )
1592 rFuncData.IncParamInfoIdx();
1597 while( rFuncData.IsExcelOnlyParam() )
1605 switch( aTokData.GetOpCode() )
1609 default: aTokData =
Expression( aTokData,
false,
true );
1620 sal_uInt8 nParamIdx = rFuncData.GetParamCount();
1622 switch( rFuncData.GetOpCode() )
1647 if( nParamIdx == 0 )
1660 sal_uInt8 nParamIdx = rFuncData.GetParamCount() - 1;
1661 switch( rFuncData.GetOpCode() )
1664 if( nParamIdx == 0 )
1679 switch( rFuncData.GetOpCode() )
1696 if( rFuncData.IsAddInEquivalent() )
1700 else if( rFuncData.IsMacroFunc() )
1711 SAL_WARN(
"sc.filter",
"XclExpFmlaCompImpl::AppendDefaultParam - unknown opcode" );
1723 sal_uInt8 nParamCount = rFuncData.GetParamCount();
1724 switch( rFuncData.GetOpCode() )
1727 if( nParamCount == 1 )
1739 if( nParamCount == 1 )
1749 if( nParamCount == 1 )
1761 if( nParamCount == 0 )
1766 if( nParamCount == 3 )
1776 if( nParamCount == 2 )
1786 if( nParamCount == 3 )
1797 switch( nParamCount )
1817 if( (nParamCount == 0) && rFuncData.IsMacroFunc() )
1839 return lclIsRefRel2D( rRefData.
Ref1 ) || lclIsRefRel2D( rRefData.
Ref2 );
1844 return lclIsRefDel2D( rRefData.
Ref1 ) || lclIsRefDel2D( rRefData.
Ref2 );
1856 return rRefData.
Tab();
1858 if (!
mxData->mpScBasePos)
1874 if (bCheck3DFlag && rRefData.
IsFlag3D())
1881 return rRefData.
Tab() == 0;
1893 bool bNatLangRef,
bool bTruncMaxCol,
bool bTruncMaxRow )
const
1895 if(
mxData->mpScBasePos )
1922 sal_Int16 nXclRelCol =
static_cast<sal_Int16
>(rRefData.
Col());
1926 sal_Int32 nXclRelRow =
static_cast<sal_Int32
>(rRefData.
Row());
1933 OSL_ENSURE(
meBiff ==
EXC_BIFF8,
"XclExpFmlaCompImpl::ConvertRefData - NLRs only for BIFF8" );
1939 sal_uInt16 rnRelRow = rXclPos.
mnRow;
1960 mxData->mpRefLog->emplace_back();
1961 return &
mxData->mpRefLog->back();
1977 "XclExpFmlaCompImpl::ProcessCellRef - broken natural language reference" );
1988 mxData->mpLinkMgr->StoreCell(aRefData, *
mxData->mpScBasePos);
1999 else if(
mxData->mpLinkMgr )
2002 sal_uInt16 nExtSheet, nXclTab;
2033 mxData->mpLinkMgr->StoreCellRange(aRefData, *
mxData->mpScBasePos);
2044 else if(
mxData->mpLinkMgr )
2047 sal_uInt16 nExtSheet, nFirstXclTab, nLastXclTab;
2048 mxData->mpLinkMgr->FindExtSheet( nExtSheet, nFirstXclTab, nLastXclTab,
2079 sal_uInt16 nFileId = rTokData.mpScToken->GetIndex();
2080 OUString aTabName = rTokData.mpScToken->GetString().getString();
2085 sal_uInt16 nExtSheet, nFirstSBTab, nLastSBTab;
2086 mxData->mpLinkMgr->FindExtSheet( nFileId, aTabName, 1, nExtSheet, nFirstSBTab, nLastSBTab,
GetNewRefLogEntry() );
2115 sal_uInt16 nFileId = rTokData.mpScToken->GetIndex();
2116 OUString aTabName = rTokData.mpScToken->GetString().getString();
2121 sal_uInt16 nExtSheet, nFirstSBTab, nLastSBTab;
2122 sal_uInt16 nTabSpan =
static_cast<sal_uInt16
>(aRefData.
Ref2.
Tab() - aRefData.
Ref1.
Tab() + 1);
2123 mxData->mpLinkMgr->FindExtSheet(
2124 nFileId, aTabName, nTabSpan, nExtSheet, nFirstSBTab, nLastSBTab,
GetNewRefLogEntry());
2145 sal_Int16 nSheet = rTokData.mpScToken->GetSheet();
2158 else if(
mxData->mpLinkMgr )
2178 sal_uInt16 nFileId = rTokData.mpScToken->GetIndex();
2179 OUString
aName = rTokData.mpScToken->GetString().getString();
2184 if(
mxData->mpScBasePos )
2186 FormulaTokenArrayPlainIterator aIter(*xArray);
2187 for( FormulaToken* pScToken = aIter.First(); pScToken; pScToken = aIter.Next() )
2189 if( pScToken->IsExternalRef() )
2191 switch( pScToken->GetType() )
2196 mxData->mpLinkMgr->StoreCell(
2203 mxData->mpLinkMgr->StoreCellRange(
2215 sal_uInt16 nExtSheet = 0, nExtName = 0;
2217 if( pFile &&
mxData->mpLinkMgr->InsertExtName( nExtSheet, nExtName, *pFile,
aName, xArray ) )
2233 mxData->maOpPosStack.push_back( nTokPos );
2239 OSL_ENSURE( rxOperands,
"XclExpFmlaCompImpl::AppendOperatorTokenId - missing operand list" );
2240 if(
mxData->maOpListVec.size() <= nTokPos )
2241 mxData->maOpListVec.resize( nTokPos + 1, XclExpOperandListRef() );
2242 mxData->maOpListVec[ nTokPos ] = rxOperands;
2247 OSL_ENSURE( !
mxData->mbOk || !
mxData->maOpPosStack.empty(),
"XclExpFmlaCompImpl::PopOperandPos - token stack broken" );
2251 sal_uInt16 nTokPos =
mxData->maOpPosStack.back();
2252 mxData->maOpPosStack.pop_back();
2260void lclAppend(
ScfUInt8Vec& orVector, sal_uInt16 nData )
2262 orVector.resize( orVector.size() + 2 );
2263 ShortToSVBT16( nData, &*(orVector.end() - 2) );
2266void lclAppend(
ScfUInt8Vec& orVector, sal_uInt32 nData )
2268 orVector.resize( orVector.size() + 4 );
2269 UInt32ToSVBT32( nData, &*(orVector.end() - 4) );
2272void lclAppend(
ScfUInt8Vec& orVector,
double fData )
2274 orVector.resize( orVector.size() + 8 );
2275 DoubleToSVBT64( fData, &*(orVector.end() - 8) );
2281 size_t nSize = orVector.size();
2282 orVector.resize( nSize + xXclStr->GetSize() );
2283 xXclStr->WriteToMem( &orVector[ nSize ] );
2290 mxData->maTokVec.push_back( nData );
2300 lclAppend(
mxData->maTokVec, nData );
2305 lclAppend(
mxData->maTokVec, nData );
2310 lclAppend(
mxData->maTokVec, fData );
2426 OUString aXclFuncName;
2429 sal_uInt16 nExtSheet, nExtName;
2430 if(
mxData->mpLinkMgr->InsertAddIn( nExtSheet, nExtName, aXclFuncName ) )
2441 sal_uInt16 nExtSheet(0), nExtName(0);
2442 if(
mxData->mpLinkMgr &&
mxData->mpLinkMgr->InsertEuroTool( nExtSheet, nExtName, rExtFuncData.maFuncName ) )
2457 XclExpOperandListRef xOperands = std::make_shared<XclExpOperandList>();
2464 XclExpOperandListRef xOperands = std::make_shared<XclExpOperandList>();
2472 XclExpOperandListRef xOperands = std::make_shared<XclExpOperandList>();
2473 for(
sal_uInt8 nOpIdx = 0; nOpIdx < nOpCount; ++nOpIdx )
2482 sal_uInt16 nXclFuncIdx = rFuncData.GetXclFuncIdx();
2483 sal_uInt8 nParamCount = rFuncData.GetParamCount();
2484 sal_uInt8 nRetClass = rFuncData.GetReturnClass();
2491 Append( sal_uInt16( 0 ) );
2493 else if( rFuncData.IsFixedParamCount() )
2518 rFuncData.AppendAttrPos(
GetSize() );
2522 Append( sal_uInt16( 0 ) );
2528 OSL_ENSURE( nInsertPos < mxData->maTokVec.size(),
"XclExpFmlaCompImpl::Insert - invalid position" );
2529 mxData->maTokVec.insert(
mxData->maTokVec.begin() + nInsertPos, nInsertSize, 0 );
2532 for(
auto& rOpPos :
mxData->maOpPosStack )
2533 if( nInsertPos <= rOpPos )
2534 rOpPos += nInsertSize;
2537 if( nInsertPos < mxData->maOpListVec.size() )
2538 mxData->maOpListVec.insert(
mxData->maOpListVec.begin() + nInsertPos, nInsertSize, XclExpOperandListRef() );
2539 for(
auto& rxOpList :
mxData->maOpListVec )
2541 for(
auto& rOp : *rxOpList )
2542 if( nInsertPos <= rOp.mnTokPos )
2543 rOp.mnTokPos += nInsertSize;
2548 OSL_ENSURE(
o3tl::make_unsigned( nWriteToPos + 1 ) <
mxData->maTokVec.size(),
"XclExpFmlaCompImpl::Overwrite - invalid position" );
2549 ShortToSVBT16( nOffset, &
mxData->maTokVec[ nWriteToPos ] );
2559 Overwrite( nAttrPos + 2,
static_cast< sal_uInt16
>(
GetSize() - nAttrPos - 5 ) );
2574 mxData->maTokVec.pop_back();
2582 mxData->maExtDataVec.push_back( nData );
2592 lclAppend(
mxData->maExtDataVec, nData );
2597 lclAppend(
mxData->maExtDataVec, fData );
2614 else if( rScPos.
Tab() == nCurrScTab )
2624 lclInitOwnTab( aRef, rScPos, nCurrScTab, b3DRefOnly );
2632 lclPutCellToTokenArray( rScTokArr, rScRange.
aStart, nCurrScTab, b3DRefOnly );
2638 lclInitOwnTab( aRef.
Ref1, rScRange.
aStart, nCurrScTab, b3DRefOnly );
2639 lclInitOwnTab( aRef.
Ref2, rScRange.
aEnd, nCurrScTab, b3DRefOnly );
2660 return mxImpl->CreateFormula(
eType, rScTokArr, pScBasePos, pRefLog );
2686 for(
size_t nIdx = 0; nIdx <
nCount; ++nIdx )
2690 lclPutRangeToTokenArray( aScTokArr, rScRanges[ nIdx ], nCurrScTab, b3DRefOnly );
2697 return mxImpl->CreateErrorFormula( nErrCode );
2703 return mxImpl->CreateSpecialRefFormula( nTokenId, rXclPos );
2707 sal_uInt16 nExtSheet, sal_uInt16 nExtName )
2709 return mxImpl->CreateNameXFormula( nExtSheet, nExtName );
2714 return mxImpl->IsRef2D(rRefData,
true);
2719 return mxImpl->IsRef2D(rRefData,
true);
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 ...
ScSheetLimits & GetSheetLimits() const
SC_DLLPUBLIC ScExternalRefManager * GetExternalRefManager() const
std::shared_ptr< ScTokenArray > TokenArrayRef
const OUString * getExternalFileName(sal_uInt16 nFileId, bool bForceOriginal=false)
It returns a pointer to the name of the URI associated with a given external file ID.
ScExternalRefCache::TokenArrayRef getRangeNameTokens(sal_uInt16 nFileId, const OUString &rName, const ScAddress *pCurPos=nullptr)
Get an array of tokens corresponding with a specified name in a specified file.
static SC_DLLPUBLIC ScUnoAddInCollection * GetAddInCollection()
Matrix data type that can store values of mixed types.
ScMatrixValue Get(SCSIZE nC, SCSIZE nR) const
@ATTENTION: If bString the ScMatrixValue->pS may still be NULL to indicate an empty string!
static bool IsBooleanType(ScMatValType nType)
Boolean.
static bool IsValueType(ScMatValType nType)
Value or boolean.
void GetDimensions(SCSIZE &rC, SCSIZE &rR) const
virtual formula::FormulaToken * AddOpCode(OpCode eCode) override
std::unique_ptr< ScTokenArray > Clone() const
formula::FormulaToken * AddDoubleReference(const ScComplexRefData &rRef)
formula::FormulaToken * AddSingleReference(const ScSingleRefData &rRef)
ScSingleRefToken with ocPush.
bool GetExcelName(const OUString &rCalcName, LanguageType eDestLang, OUString &rRetExcelName)
leave rRetExcelName unchanged, if no matching name is found
Implementation class of the export formula compiler.
void FinishFunction(XclExpFuncData &rFuncData, sal_uInt8 nCloseSpaces)
void AppendUnaryOperatorToken(sal_uInt8 nTokenId, sal_uInt8 nSpaces=0)
void Overwrite(sal_uInt16 nWriteToPos, sal_uInt16 nOffset)
void AppendBinaryOperatorToken(sal_uInt8 nTokenId, bool bValType, sal_uInt8 nSpaces=0)
void PushOperandPos(sal_uInt16 nTokPos)
XclExpScToken SkipExpression(XclExpScToken aTokData, bool bStopAtSep)
void ProcessFunction(const XclExpScToken &rTokData)
void AppendMissingToken(sal_uInt8 nSpaces=0)
XclExpScToken AndTerm(XclExpScToken aTokData, bool bInParentheses)
void ProcessExternalRangeRef(const XclExpScToken &rTokData)
void PrepareFunction(const XclExpFuncData &rFuncData)
void AppendRange(const XclRange &rXclRange)
void ProcessMissing(const XclExpScToken &rTokData)
void FinishParam(XclExpFuncData &rFuncData)
void ProcessExternalName(const XclExpScToken &rTokData)
void AppendAddInCallToken(const XclExpExtFuncData &rExtFuncData)
sal_uInt16 PopOperandPos()
std::vector< XclExpCompDataRef > maDataStack
Working data for current formula.
void AppendAddress(const XclAddress &rXclPos)
void ProcessDouble(const XclExpScToken &rTokData)
std::map< XclFormulaType, XclExpCompConfig > XclExpCompConfigMap
void ProcessDdeLink(const XclExpScToken &rTokData)
const sal_uInt16 mnMaxColMask
Maximum row index in Calc itself.
void FinishIfFunction(XclExpFuncData &rFuncData)
const SCCOL mnMaxAbsCol
Cached BIFF version to save GetBiff() calls.
XclExpScToken PowTerm(XclExpScToken aTokData, bool bInParentheses)
void PushOperatorPos(sal_uInt16 nTokPos, const XclExpOperandListRef &rxOperands)
std::shared_ptr< XclExpCompData > XclExpCompDataRef
XclFunctionProvider maFuncProv
Compiler configuration map for all formula types.
void FinishChooseFunction(XclExpFuncData &rFuncData)
void AppendEuroToolCallToken(const XclExpExtFuncData &rExtFuncData)
const XclExpCompConfig * GetConfigForType(XclFormulaType eType) const
void AppendLogicalOperatorToken(sal_uInt16 nXclFuncIdx, sal_uInt8 nOpCount)
void AppendMissingNameToken(const OUString &rName, sal_uInt8 nSpaces=0)
void InsertZeros(sal_uInt16 nInsertPos, sal_uInt16 nInsertSize)
XclExpRefLogEntry * GetNewRefLogEntry()
XclTokenArrayRef CreateErrorFormula(sal_uInt8 nErrCode)
Creates a single error token containing the passed error code.
XclExpScToken CompareTerm(XclExpScToken aTokData, bool bInParentheses)
void AppendOperatorTokenId(sal_uInt8 nTokenId, const XclExpOperandListRef &rxOperands, sal_uInt8 nSpaces=0)
XclExpFmlaCompImpl(const XclExpRoot &rRoot)
const FormulaToken * PeekNextRawToken() const
XclExpScToken OrTerm(XclExpScToken aTokData, bool bInParentheses)
XclExpScToken MulDivTerm(XclExpScToken aTokData, bool bInParentheses)
void RemoveTrailingParen()
const SCCOL mnMaxScCol
Maximum row index.
void RecalcTokenClass(const XclExpTokenConvInfo &rConvInfo, XclFuncParamConv ePrevConv, XclExpClassConv ePrevClassConv, bool bWasRefClass, o3tl::sorted_vector< const XclExpTokenConvInfo * > &rSeenTokens)
void ProcessParentheses(const XclExpScToken &rTokData)
XclTokenArrayRef CreateSpecialRefFormula(sal_uInt8 nTokenId, const XclAddress &rXclPos)
Creates a single token for a special cell reference.
void ProcessBad(const XclExpScToken &rTokData)
void AppendIntToken(sal_uInt16 nValue, sal_uInt8 nSpaces=0)
void Append(sal_uInt8 nData)
sal_uInt16 GetSize() const
void RecalcTokenClasses()
XclExpScToken UnaryPostTerm(XclExpScToken aTokData, bool bInParentheses)
void ProcessExternalCellRef(const XclExpScToken &rTokData)
bool IsSpaceToken(sal_uInt16 nPos) const
void ProcessCellRef(const XclExpScToken &rTokData)
XclExpScToken Factor(XclExpScToken aTokData)
const SCROW mnMaxScRow
Maximum column index in Calc itself.
void AppendErrorToken(sal_uInt8 nErrCode, sal_uInt8 nSpaces=0)
void AppendOperandTokenId(sal_uInt8 nTokenId, sal_uInt8 nSpaces=0)
void AppendDefaultParam(XclExpFuncData &rFuncData)
XclExpScToken UnaryPreTerm(XclExpScToken aTokData, bool bInParentheses)
void AppendMacroCallToken(const XclExpExtFuncData &rExtFuncData)
const SCROW mnMaxAbsRow
Maximum column index.
XclExpCompConfigMap maCfgMap
void UpdateAttrGoto(sal_uInt16 nAttrPos)
XclExpScToken ListTerm(XclExpScToken aTokData, bool bInParentheses)
const FormulaToken * GetNextRawToken()
void ConvertRefData(ScSingleRefData &rRefData, XclAddress &rXclPos, bool bNatLangRef, bool bTruncMaxCol, bool bTruncMaxRow) const
void ProcessExternal(const XclExpScToken &rTokData)
bool IsRef2D(const ScSingleRefData &rRefData, bool bCheck3DFlag) const
void ProcessString(const XclExpScToken &rTokData)
XclTokenArrayRef CreateTokenArray()
XclExpScToken IntersectTerm(XclExpScToken aTokData, bool &rbHasRefOp)
XclExpCompDataRef mxData
Excel function data provider.
XclExpScToken AddSubTerm(XclExpScToken aTokData, bool bInParentheses)
void ProcessDefinedName(const XclExpScToken &rTokData)
SCTAB GetScTab(const ScSingleRefData &rRefData) const
void ProcessMatrix(const XclExpScToken &rTokData)
void AppendBoolToken(bool bValue, sal_uInt8 nSpaces=0)
XclExpScToken RangeTerm(XclExpScToken aTokData, bool &rbHasRefOp)
void AppendFuncToken(const XclExpFuncData &rFuncData)
void AppendTrailingParam(XclExpFuncData &rFuncData)
void AppendParenToken(sal_uInt8 nOpenSpaces=0, sal_uInt8 nCloseSpaces=0)
void ProcessRangeRef(const XclExpScToken &rTokData)
void AppendNumToken(double fValue, sal_uInt8 nSpaces=0)
void ProcessBoolean(const XclExpScToken &rTokData)
XclExpScToken ConcatTerm(XclExpScToken aTokData, bool bInParentheses)
const XclBiff meBiff
Stack for working data, when compiler is called recursively.
void AppendNameToken(sal_uInt16 nNameIdx, sal_uInt8 nSpaces=0)
XclExpScToken GetNextToken()
void Init(XclFormulaType eType)
XclExpScToken Expression(XclExpScToken aTokData, bool bInParentheses, bool bStopAtSep)
XclExpScToken ProcessParam(XclExpScToken aTokData, XclExpFuncData &rFuncData)
bool Is3DRefOnly(XclFormulaType eType) const
Returns true, if the passed formula type allows 3D references only.
void AppendExt(sal_uInt8 nData)
void AppendNameXToken(sal_uInt16 nExtSheet, sal_uInt16 nExtName, sal_uInt8 nSpaces=0)
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.
void AppendSpaceToken(sal_uInt8 nType, sal_uInt8 nCount)
const sal_uInt32 mnMaxRowMask
Mask to delete invalid bits in column fields.
void PrepareParam(XclExpFuncData &rFuncData)
void AppendJumpToken(XclExpFuncData &rFuncData, sal_uInt8 nAttrType)
XclTokenArrayRef CreateNameXFormula(sal_uInt16 nExtSheet, sal_uInt16 nExtName)
Creates a single tNameXR token for a reference to an external name.
Stores all data for internal/external references (the link table).
Manager that stores all internal defined names (NAME records) of the document.
sal_uInt16 InsertRawName(const OUString &rName)
Returns index of an existing name, or creates a name without definition.
SCTAB GetScTab(sal_uInt16 nNameIdx) const
Returns the Calc sheet of a local defined name, or SCTAB_GLOBAL for global defined names.
sal_uInt16 InsertName(SCTAB nTab, sal_uInt16 nScNameIdx, SCTAB nCurrTab)
Inserts the Calc name with the passed index and returns the Excel NAME index.
bool IsVolatile(sal_uInt16 nNameIdx) const
Returns true, if the specified defined name is volatile.
sal_uInt16 InsertMacroCall(const OUString &rMacroName, bool bVBasic, bool bFunc, bool bHidden=false)
Searches or inserts a defined name describing a macro name.
Access to global data from other classes.
XclExpLinkManager & GetGlobalLinkManager() const
Returns the global link manager for defined names.
XclExpNameManager & GetNameManager() const
Returns the buffer that contains internal defined names.
XclExpLinkManager & GetLocalLinkManager() const
Returns the local link manager for the current sheet.
const XclExpRoot & GetRoot() const
Returns this root instance - for code readability in derived classes.
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.
Provides access to function info structs for all available functions.
const XclFunctionInfo * GetFuncInfoFromOpCode(OpCode eOpCode) const
Returns the function data for a Calc opcode, or 0 on error.
XclOutput GetOutput() const
Returns the current output format of the importer/exporter.
LanguageType GetUILanguage() const
Returns the UI language.
SCTAB GetCurrScTab() const
Returns the current Calc sheet index.
ScDocument & GetDoc() const
Returns reference to the destination document (import) or source document (export).
A helper with Excel specific token array functions.
static sal_uInt8 GetTokenClass(sal_uInt8 nTokenId)
Returns the token class of the passed token ID.
static sal_uInt8 GetTokenId(sal_uInt8 nBaseId, sal_uInt8 nTokenClass)
Returns the classified token ID from a base ID and the token class.
static void ChangeTokenClass(sal_uInt8 &rnTokenId, sal_uInt8 nTokenClass)
Changes the token class in the passed classified token ID.
Special token array iterator for the Excel filters.
const ::formula::FormulaToken * Get() const
std::pair< const_iterator, bool > insert(Value &&x)
const OUString & getString() const
#define SC_OPCODE_START_NO_PAR
#define SAL_WARN(area, stream)
constexpr std::enable_if_t< std::is_signed_v< T >, std::make_unsigned_t< T > > make_unsigned(T value)
std::shared_ptr< T > make_shared(Args &&... args)
Complex reference (a range) into the sheet.
SC_DLLPUBLIC ScRange toAbs(const ScSheetLimits &rLimits, const ScAddress &rPos) const
void InitRange(const ScRange &rRange)
Try NOT to use this struct.
FormulaError GetError() const
Only valid if ScMatrix methods indicate that this is no string!
const svl::SharedString & GetString() const
Only valid if ScMatrix methods indicate so!
bool GetBoolean() const
Only valid if ScMatrix methods indicate that this is a boolean.
Single reference (one address) into the sheet.
void SetAddress(const ScSheetLimits &rLimits, const ScAddress &rAddr, const ScAddress &rPos)
void InitAddress(const ScAddress &rAdr)
InitAddress: InitFlags and set address.
bool IsRowDeleted() const
void SetColDeleted(bool bVal)
void SetRelTab(SCTAB nVal)
ScAddress toAbs(const ScSheetLimits &rLimits, const ScAddress &rPos) const
bool IsTabDeleted() const
void SetFlag3D(bool bVal)
void SetRowDeleted(bool bVal)
bool IsColDeleted() const
A 2D cell address struct with Excel column and row indexes.
Log entry for external references in a formula, used i.e.
XclExpRefLogEntry()
Calc index of the last sheet.
Structure that contains all needed information for a parameter in a function.
bool mbValType
Token class conversion type.
XclFuncParamConv meConv
Parameter validity.
Represents information for a spreadsheet function for import and export.
OUString GetMacroFuncName() const
Returns the name of the external function as string.
OUString GetAddInEquivalentFuncName() const
Returns the programmatical name of the Add-In function as string.
bool IsMacroFunc() const
Returns true, if the function is simulated by a macro call.
bool IsAddInEquivalent() const
Returns true, if the function is stored as an add-in call.
A 2D cell range address struct with Excel column and row indexes.
std::shared_ptr< XclExpString > XclExpStringRef
const SCTAB SCTAB_INVALID
An invalid Excel sheet index, for common use.
const sal_uInt8 EXC_ERR_NA
const sal_uInt8 EXC_ERR_REF
const SCTAB SCTAB_GLOBAL
An invalid Calc sheet index, for common use.
const sal_uInt8 EXC_ERR_NAME
const sal_uInt8 EXC_CACHEDVAL_ERROR
const sal_uInt8 EXC_CACHEDVAL_STRING
XclBiff
An enumeration for all Excel file format types (BIFF types).
@ EXC_BIFF8
MS Excel 5.0, MS Excel 7.0 (95)
@ EXC_OUTPUT_XML_2007
MS Excel binary .xls.
const sal_uInt8 EXC_CACHEDVAL_EMPTY
const sal_uInt8 EXC_CACHEDVAL_BOOL
const sal_uInt8 EXC_CACHEDVAL_DOUBLE
const sal_Unicode EXC_EXTSH_OWNDOC
const sal_uInt16 EXC_TAB_DELETED
Special sheet index for external links.
XclStrFlags
Flags used to specify import/export mode of strings.
@ EightBitLength
Always use UCS-2 characters (default: try to compress). BIFF8 only.