22 #include <compiler.hxx>
23 #include <document.hxx>
26 #include <tokenarray.hxx>
44 mpFirstTab( nullptr ),
59 const FormulaToken* mpScToken;
62 explicit XclExpScToken() : mpScToken( nullptr ), mnSpaces( 0 ) {}
63 bool Is()
const {
return mpScToken !=
nullptr; }
65 OpCode GetOpCode()
const {
return mpScToken ? mpScToken->GetOpCode() :
ocNone; }
77 struct XclExpTokenConvInfo
86 struct XclExpOperandList :
public std::vector< XclExpTokenConvInfo >
88 explicit XclExpOperandList() { reserve( 2 ); }
89 void AppendOperand( sal_uInt16 nTokPos,
XclFuncParamConv eConv,
bool bValType );
92 void XclExpOperandList::AppendOperand( sal_uInt16 nTokPos,
XclFuncParamConv eConv,
bool bValType )
95 XclExpTokenConvInfo& rConvInfo = back();
96 rConvInfo.mnTokPos = nTokPos;
97 rConvInfo.meConv = eConv;
98 rConvInfo.mbValType = bValType;
101 typedef std::shared_ptr< XclExpOperandList > XclExpOperandListRef;
104 struct XclExpExtFuncData
110 explicit XclExpExtFuncData() : mbVBasic(
false ), mbHidden(
false ) {}
111 void Set(
const OUString& rFuncName,
bool bVBasic,
bool bHidden );
114 void XclExpExtFuncData::Set(
const OUString& rFuncName,
bool bVBasic,
bool bHidden )
116 maFuncName = rFuncName;
125 explicit XclExpFuncData(
126 const XclExpScToken& rTokData,
128 const XclExpExtFuncData& rExtFuncData );
130 const FormulaToken& GetScToken()
const {
return *mrTokData.mpScToken; }
131 OpCode GetOpCode()
const {
return mrFuncInfo.meOpCode; }
132 sal_uInt16 GetXclFuncIdx()
const {
return mrFuncInfo.mnXclFunc; }
133 bool IsVolatile()
const {
return mrFuncInfo.IsVolatile(); }
134 bool IsFixedParamCount()
const {
return mrFuncInfo.IsFixedParamCount(); }
135 bool IsAddInEquivalent()
const {
return mrFuncInfo.IsAddInEquivalent(); }
136 bool IsMacroFunc()
const {
return mrFuncInfo.IsMacroFunc(); }
137 sal_uInt8 GetSpaces()
const {
return mrTokData.mnSpaces; }
138 const XclExpExtFuncData& GetExtFuncData()
const {
return maExtFuncData; }
139 sal_uInt8 GetReturnClass()
const {
return mrFuncInfo.mnRetClass; }
142 bool IsCalcOnlyParam()
const;
143 bool IsExcelOnlyParam()
const;
144 void IncParamInfoIdx();
146 sal_uInt8 GetMinParamCount()
const {
return mrFuncInfo.mnMinParamCount; }
147 sal_uInt8 GetMaxParamCount()
const {
return mrFuncInfo.mnMaxParamCount; }
148 sal_uInt8 GetParamCount()
const {
return static_cast< sal_uInt8 >( mxOperands->size() ); }
149 void FinishParam( sal_uInt16 nTokPos );
150 const XclExpOperandListRef& GetOperandList()
const {
return mxOperands; }
153 void AppendAttrPos( sal_uInt16 nPos ) { maAttrPosVec.push_back( nPos ); }
157 const XclExpScToken& mrTokData;
159 XclExpExtFuncData maExtFuncData;
160 XclExpOperandListRef mxOperands;
164 XclExpFuncData::XclExpFuncData(
const XclExpScToken& rTokData,
165 const XclFunctionInfo& rFuncInfo,
const XclExpExtFuncData& rExtFuncData ) :
166 mrTokData( rTokData ),
167 mrFuncInfo( rFuncInfo ),
168 maExtFuncData( rExtFuncData ),
172 OSL_ENSURE( mrTokData.mpScToken,
"XclExpFuncData::XclExpFuncData - missing core token" );
174 if( (maExtFuncData.maFuncName.isEmpty()) && dynamic_cast< const FormulaExternalToken* >( mrTokData.mpScToken ) )
175 maExtFuncData.Set( GetScToken().GetExternal(),
true,
false );
181 return mpParamInfo ? *mpParamInfo : saInvalidInfo;
184 bool XclExpFuncData::IsCalcOnlyParam()
const
189 bool XclExpFuncData::IsExcelOnlyParam()
const
194 void XclExpFuncData::IncParamInfoIdx()
203 else if( IsExcelOnlyParam() || IsCalcOnlyParam() )
204 mpParamInfo =
nullptr;
206 else if( mrFuncInfo.IsParamPairs() )
211 void XclExpFuncData::FinishParam( sal_uInt16 nTokPos )
215 mxOperands->AppendOperand( nTokPos, rParamInfo.
meConv, rParamInfo.
mbValType );
231 struct XclExpCompConfig
242 const XclExpCompConfig spConfigTable[] =
258 struct XclExpCompData
260 typedef std::shared_ptr< ScTokenArray > ScTokenArrayRef;
262 const XclExpCompConfig& mrCfg;
263 ScTokenArrayRef mxOwnScTokArr;
271 std::vector< XclExpOperandListRef >
278 explicit XclExpCompData(
const XclExpCompConfig* pCfg );
281 XclExpCompData::XclExpCompData(
const XclExpCompConfig* pCfg ) :
282 mrCfg( pCfg ? *pCfg : spConfigTable[ 0 ] ),
283 mpLinkMgr( nullptr ),
285 mpScBasePos( nullptr ),
286 mbStopAtSep(
false ),
288 mbOk( pCfg != nullptr )
290 OSL_ENSURE( pCfg,
"XclExpFmlaCompImpl::Init - unknown formula type" );
320 sal_uInt16
GetSize()
const {
return static_cast< sal_uInt16
>(
mxData->maTokVec.size() ); }
341 XclExpScToken
Expression( XclExpScToken aTokData,
bool bInParentheses,
bool bStopAtSep );
342 XclExpScToken
SkipExpression( XclExpScToken aTokData,
bool bStopAtSep );
344 XclExpScToken
OrTerm( XclExpScToken aTokData,
bool bInParentheses );
345 XclExpScToken
AndTerm( XclExpScToken aTokData,
bool bInParentheses );
346 XclExpScToken
CompareTerm( XclExpScToken aTokData,
bool bInParentheses );
347 XclExpScToken
ConcatTerm( XclExpScToken aTokData,
bool bInParentheses );
348 XclExpScToken
AddSubTerm( XclExpScToken aTokData,
bool bInParentheses );
349 XclExpScToken
MulDivTerm( XclExpScToken aTokData,
bool bInParentheses );
350 XclExpScToken
PowTerm( XclExpScToken aTokData,
bool bInParentheses );
351 XclExpScToken
UnaryPostTerm( XclExpScToken aTokData,
bool bInParentheses );
352 XclExpScToken
UnaryPreTerm( XclExpScToken aTokData,
bool bInParentheses );
353 XclExpScToken
ListTerm( XclExpScToken aTokData,
bool bInParentheses );
354 XclExpScToken
IntersectTerm( XclExpScToken aTokData,
bool& rbHasRefOp );
355 XclExpScToken
RangeTerm( XclExpScToken aTokData,
bool& rbHasRefOp );
356 XclExpScToken
Factor( XclExpScToken aTokData );
363 void ProcessBad(
const XclExpScToken& rTokData );
376 XclExpScToken
ProcessParam( XclExpScToken aTokData, XclExpFuncData& rFuncData );
387 bool bNatLangRef,
bool bTruncMaxCol,
bool bTruncMaxRow )
const;
389 bool bNatLangRef )
const;
402 void PushOperatorPos( sal_uInt16 nTokPos,
const XclExpOperandListRef& rxOperands );
407 void Append( sal_uInt16 nData );
408 void Append( sal_uInt32 nData );
409 void Append(
double fData );
410 void Append(
const OUString& rString );
439 void InsertZeros( sal_uInt16 nInsertPos, sal_uInt16 nInsertSize );
440 void Overwrite( sal_uInt16 nWriteToPos, sal_uInt16 nOffset );
451 void AppendExt(
const OUString& rString );
460 std::vector< XclExpCompDataRef >
474 meBiff( rRoot.GetBiff() ),
475 mnMaxAbsCol( rRoot.GetXclMaxPos().
Col() ),
476 mnMaxAbsRow( rRoot.GetXclMaxPos().
Row() ),
477 mnMaxScCol( rRoot.GetScMaxPos().
Col() ),
478 mnMaxScRow( rRoot.GetScMaxPos().
Row() ),
479 mnMaxColMask( static_cast< sal_uInt16 >( rRoot.GetXclMaxPos().
Col() ) ),
480 mnMaxRowMask( static_cast< sal_uInt32 >( rRoot.GetXclMaxPos().
Row() ) )
483 for(
auto const &rEntry : spConfigTable)
491 Init( eType, rScTokArr, pScBasePos, pRefLog );
498 if( (nScError != FormulaError::NONE) && (!aTokData.Is() || (aTokData.GetOpCode() ==
ocStop)) )
503 else if( aTokData.Is() )
505 aTokData =
Expression( aTokData,
false,
false );
509 OSL_FAIL(
"XclExpFmlaCompImpl::CreateFormula - empty token array" );
516 mxData->mbOk = !aTokData.Is() || (aTokData.GetOpCode() ==
ocStop);
517 OSL_ENSURE(
mxData->mbOk,
"XclExpFmlaCompImpl::CreateFormula - unknown garbage behind formula" );
555 return pCfg && pCfg->mb3DRefOnly;
562 XclExpCompConfigMap::const_iterator aIt =
maCfgMap.find( eType );
563 OSL_ENSURE( aIt !=
maCfgMap.end(),
"XclExpFmlaCompImpl::GetConfigForType - unknown formula type" );
564 return (aIt ==
maCfgMap.end()) ?
nullptr : &aIt->second;
588 mxData->mbOk = pScBasePos !=
nullptr;
589 OSL_ENSURE(
mxData->mbOk,
"XclExpFmlaCompImpl::Init - missing cell address" );
590 mxData->mpScBasePos = pScBasePos;
593 mxData->mbOk = pScBasePos !=
nullptr;
594 assert(
mxData->mbOk &&
"XclExpFmlaCompImpl::Init - missing cell address");
612 mxData->maTokArrIt.Init(
mxData->mxOwnScTokArr ? *
mxData->mxOwnScTokArr : rScTokArr,
false );
613 mxData->mpRefLog = pRefLog;
616 mxData->mpScBasePos = pScBasePos;
626 OSL_ENSURE(
mxData->mbOk,
"XclExpFmlaCompImpl::RecalcTokenClasses - position of root token expected on stack" );
632 bool bNameFmla =
mxData->mrCfg.meClassType == EXC_CLASSTYPE_NAME;
634 XclExpClassConv eClassConv = bNameFmla ? EXC_CLASSCONV_ARR : EXC_CLASSCONV_VAL;
635 XclExpTokenConvInfo aConvInfo = {
PopOperandPos(), eParamConv, !bNameFmla };
640 mxData->maOpListVec.clear();
641 mxData->maOpPosStack.clear();
647 OSL_ENSURE( rConvInfo.mnTokPos <
GetSize(),
"XclExpFmlaCompImpl::RecalcTokenClass - invalid token position" );
667 eClassConv = EXC_CLASSCONV_ORG;
671 eClassConv = EXC_CLASSCONV_VAL;
675 eClassConv = EXC_CLASSCONV_ARR;
687 eClassConv = bWasRefClass ? EXC_CLASSCONV_VAL : ePrevClassConv;
691 eClassConv = ePrevClassConv;
698 eClassConv = bWasRefClass ? ePrevClassConv : EXC_CLASSCONV_ORG;
711 eClassConv = ((nTokClass ==
EXC_TOKCLASS_REF) || (ePrevClassConv == EXC_CLASSCONV_ARR)) ?
712 ePrevClassConv : EXC_CLASSCONV_ORG;
721 case EXC_CLASSCONV_ORG:
732 case EXC_CLASSCONV_VAL:
740 case EXC_CLASSCONV_ARR:
751 if( rConvInfo.mnTokPos <
mxData->maOpListVec.size() )
752 if(
const XclExpOperandList* pOperands =
mxData->maOpListVec[ rConvInfo.mnTokPos ].get() )
753 for(
const auto& rOperand : *pOperands )
781 mxData->maExtDataVec.clear();
782 mxData->mbVolatile =
false;
790 OSL_ENSURE(
mxData->mrCfg.mbAllowArrays ||
mxData->maExtDataVec.empty(),
"XclExpFmlaCompImpl::CreateTokenArray - unexpected extended data" );
791 if( !
mxData->mrCfg.mbAllowArrays )
792 mxData->maExtDataVec.clear();
810 const FormulaToken* pScToken =
mxData->maTokArrIt.Get();
825 return aTempIt.
Get();
831 rTokData.mnSpaces = 0;
835 rTokData.mnSpaces += rTokData.mpScToken->GetByte();
838 return rTokData.Is();
843 XclExpScToken aTokData;
943 if(
mxData->mbOk && aTokData.Is() )
946 bool bOldStopAtSep =
mxData->mbStopAtSep;
947 mxData->mbStopAtSep = bStopAtSep;
949 aTokData =
OrTerm( aTokData, bInParentheses );
951 mxData->mbStopAtSep = bOldStopAtSep;
958 while(
mxData->mbOk && aTokData.Is() && (aTokData.GetOpCode() !=
ocClose) && (!bStopAtSep || (aTokData.GetOpCode() !=
ocSep)) )
960 if( aTokData.GetOpCode() ==
ocOpen )
972 aTokData =
AndTerm( aTokData, bInParentheses );
974 while(
mxData->mbOk && (aTokData.GetOpCode() ==
ocOr) )
982 if(
mxData->mbOk && (nParamCount > 1) )
989 aTokData =
CompareTerm( aTokData, bInParentheses );
991 while(
mxData->mbOk && (aTokData.GetOpCode() ==
ocAnd) )
999 if(
mxData->mbOk && (nParamCount > 1) )
1006 aTokData =
ConcatTerm( aTokData, bInParentheses );
1009 sal_uInt8 nOpTokenId = lclGetConcatTokenId( aTokData.GetOpCode() );
1021 aTokData =
AddSubTerm( aTokData, bInParentheses );
1024 sal_uInt8 nOpTokenId = lclGetCompareTokenId( aTokData.GetOpCode() );
1036 aTokData =
MulDivTerm( aTokData, bInParentheses );
1039 sal_uInt8 nOpTokenId = lclGetAddSubTokenId( aTokData.GetOpCode() );
1051 aTokData =
PowTerm( aTokData, bInParentheses );
1054 sal_uInt8 nOpTokenId = lclGetMulDivTokenId( aTokData.GetOpCode() );
1070 nOpTokenId = lclGetPowTokenId( aTokData.GetOpCode() );
1086 nOpTokenId = lclGetUnaryPostTokenId( aTokData.GetOpCode() );
1106 aTokData =
ListTerm( aTokData, bInParentheses );
1113 sal_uInt16 nSubExprPos =
GetSize();
1114 bool bHasAnyRefOp =
false;
1115 bool bHasListOp =
false;
1119 sal_uInt8 nOpTokenId = lclGetListTokenId( aTokData.GetOpCode(),
mxData->mbStopAtSep );
1125 bHasAnyRefOp = bHasListOp =
true;
1130 sal_uInt16 nSubExprSize =
GetSize() - nSubExprPos;
1133 Overwrite( nSubExprPos + 1, nSubExprSize );
1135 XclExpOperandListRef xOperands = std::make_shared<XclExpOperandList>();
1140 if( bHasListOp && !bInParentheses )
1147 aTokData =
RangeTerm( aTokData, rbHasRefOp );
1150 sal_uInt8 nOpTokenId = lclGetIntersectTokenId( aTokData.GetOpCode() );
1163 aTokData =
Factor( aTokData );
1166 sal_uInt8 nOpTokenId = lclGetRangeTokenId( aTokData.GetOpCode() );
1179 if( !
mxData->mbOk || !aTokData.Is() )
return XclExpScToken();
1181 switch( aTokData.GetType() )
1194 default:
switch( aTokData.GetOpCode() )
1215 double fValue = rTokData.mpScToken->GetDouble();
1217 double fFrac = modf( fValue, &fInt );
1218 if( (fFrac == 0.0) && (0.0 <= fInt) && (fInt <= 65535.0) )
1219 AppendIntToken( static_cast< sal_uInt16 >( fInt ), rTokData.mnSpaces );
1227 Append( rTokData.mpScToken->GetString().getString() );
1257 bool lclGetTokenString( OUString& rString,
const XclExpScToken& rTokData )
1259 bool bIsStr = (rTokData.GetType() ==
svString) && (rTokData.GetOpCode() ==
ocPush);
1261 rString = rTokData.mpScToken->GetString().getString();
1269 OUString aApplic, aTopic, aItem;
1278 if(
mxData->mbOk )
mxData->mbOk = !aApplic.isEmpty() && !aTopic.isEmpty() && !aItem.isEmpty();
1281 sal_uInt16 nExtSheet(0), nExtName(0);
1282 if(
mxData->mpLinkMgr &&
mxData->mpLinkMgr->InsertDde( nExtSheet, nExtName, aApplic, aTopic, aItem ) )
1296 if( !pNextScToken || (pNextScToken->GetOpCode() !=
ocOpen) )
1304 const ScMatrix* pMatrix = rTokData.mpScToken->GetMatrix();
1305 if( pMatrix &&
mxData->mrCfg.mbAllowArrays )
1309 OSL_ENSURE( (nScCols > 0) && (nScRows > 0),
"XclExpFmlaCompImpl::ProcessMatrix - invalid matrix size" );
1310 sal_uInt16 nCols =
::limit_cast< sal_uInt16 >( nScCols, 0, 256 );
1311 sal_uInt16 nRows =
::limit_cast< sal_uInt16 >( nScRows, 0, 1024 );
1317 Append( static_cast< sal_uInt32 >( 0 ) );
1322 for(
SCSIZE nScRow = 0; nScRow < nScRows; ++nScRow )
1324 for(
SCSIZE nScCol = 0; nScCol < nScCols; ++nScCol )
1336 else if( (nErr = nMatVal.
GetError()) != FormulaError::NONE )
1351 if(
aStr.isEmpty() )
1374 OpCode eOpCode = rTokData.GetOpCode();
1377 XclExpExtFuncData aExtFuncData;
1383 if( !rFuncName.isEmpty() )
1385 aExtFuncData.Set( rFuncName,
true,
false );
1390 mxData->mbOk = pFuncInfo !=
nullptr;
1391 if( !
mxData->mbOk )
return;
1400 XclExpFuncData aFuncData( rTokData, *pFuncInfo, aExtFuncData );
1401 XclExpScToken aTokData;
1406 enum { STATE_START, STATE_OPEN, STATE_PARAM, STATE_SEP, STATE_CLOSE, STATE_END }
1407 eState = STATE_START;
1408 while( eState != STATE_END )
switch( eState )
1412 eState =
mxData->mbOk ? STATE_OPEN : STATE_END;
1416 eState =
mxData->mbOk ? ((aTokData.GetOpCode() ==
ocClose) ? STATE_CLOSE : STATE_PARAM) : STATE_END;
1420 switch( aTokData.GetOpCode() )
1422 case ocSep: eState = STATE_SEP;
break;
1423 case ocClose: eState = STATE_CLOSE;
break;
1424 default:
mxData->mbOk =
false;
1426 if( !
mxData->mbOk ) eState = STATE_END;
1430 eState =
mxData->mbOk ? STATE_PARAM : STATE_END;
1446 switch( rFuncData.GetOpCode() )
1470 if( (rFuncData.GetMinParamCount() <=
nParamCount) && (nParamCount <= rFuncData.GetMaxParamCount()) )
1477 switch( rFuncData.GetOpCode() )
1490 mxData->mbVolatile |= rFuncData.IsVolatile();
1493 switch( rFuncData.GetOpCode() )
1533 sal_uInt16
nParamCount = rFuncData.GetParamCount();
1534 OSL_ENSURE( (nParamCount == 2) || (nParamCount == 3),
"XclExpFmlaCompImpl::FinishIfFunction - wrong parameter count" );
1535 const ScfUInt16Vec& rAttrPos = rFuncData.GetAttrPosVec();
1536 OSL_ENSURE( nParamCount == rAttrPos.size(),
"XclExpFmlaCompImpl::FinishIfFunction - wrong number of tAttr tokens" );
1538 Overwrite( rAttrPos[ 0 ] + 2, static_cast< sal_uInt16 >( rAttrPos[ 1 ] - rAttrPos[ 0 ] ) );
1541 if( nParamCount == 3 )
1547 sal_uInt16
nParamCount = rFuncData.GetParamCount();
1549 OSL_ENSURE( nParamCount == rAttrPos.size(),
"XclExpFmlaCompImpl::FinishChooseFunction - wrong number of tAttr tokens" );
1551 sal_uInt16 nChoices = nParamCount - 1;
1553 Overwrite( rAttrPos[ 0 ] + 2, nChoices );
1555 sal_uInt16 nJumpArrPos = rAttrPos[ 0 ] + 4;
1557 sal_uInt16 nJumpArrSize = 2 * (nChoices + 1);
1563 rAttrPos[ nIdx ] = rAttrPos[ nIdx ] + nJumpArrSize;
1570 Overwrite( nJumpArrPos + 2 * nIdx, static_cast< sal_uInt16 >( rAttrPos[ nIdx ] + 4 - nJumpArrPos ) );
1575 if( rFuncData.IsCalcOnlyParam() )
1579 rFuncData.IncParamInfoIdx();
1584 while( rFuncData.IsExcelOnlyParam() )
1592 switch( aTokData.GetOpCode() )
1596 default: aTokData =
Expression( aTokData,
false,
true );
1607 sal_uInt8 nParamIdx = rFuncData.GetParamCount();
1609 switch( rFuncData.GetOpCode() )
1634 if( nParamIdx == 0 )
1647 sal_uInt8 nParamIdx = rFuncData.GetParamCount() - 1;
1648 switch( rFuncData.GetOpCode() )
1651 if( nParamIdx == 0 )
1666 switch( rFuncData.GetOpCode() )
1683 if( rFuncData.IsAddInEquivalent() )
1687 else if( rFuncData.IsMacroFunc() )
1698 SAL_WARN(
"sc.filter",
"XclExpFmlaCompImpl::AppendDefaultParam - unknown opcode" );
1711 switch( rFuncData.GetOpCode() )
1714 if( nParamCount == 1 )
1726 if( nParamCount == 1 )
1736 if( nParamCount == 1 )
1748 if( nParamCount == 0 )
1753 if( nParamCount == 3 )
1763 if( nParamCount == 2 )
1773 if( nParamCount == 3 )
1784 switch( nParamCount )
1804 if( (nParamCount == 0) && rFuncData.IsMacroFunc() )
1826 return lclIsRefRel2D( rRefData.
Ref1 ) || lclIsRefRel2D( rRefData.
Ref2 );
1831 return lclIsRefDel2D( rRefData.
Ref1 ) || lclIsRefDel2D( rRefData.
Ref2 );
1843 return rRefData.
Tab();
1845 if (!
mxData->mpScBasePos)
1861 if (bCheck3DFlag && rRefData.
IsFlag3D())
1868 return rRefData.
Tab() == 0;
1880 bool bNatLangRef,
bool bTruncMaxCol,
bool bTruncMaxRow )
const
1882 if(
mxData->mpScBasePos )
1909 sal_Int16 nXclRelCol =
static_cast<sal_Int16
>(rRefData.
Col());
1913 sal_Int32 nXclRelRow =
static_cast<sal_Int32
>(rRefData.
Row());
1920 OSL_ENSURE(
meBiff ==
EXC_BIFF8,
"XclExpFmlaCompImpl::ConvertRefData - NLRs only for BIFF8" );
1926 sal_uInt16 rnRelRow = rXclPos.
mnRow;
1947 mxData->mpRefLog->emplace_back();
1948 return &
mxData->mpRefLog->back();
1964 "XclExpFmlaCompImpl::ProcessCellRef - broken natural language reference" );
1975 mxData->mpLinkMgr->StoreCell(aRefData, *
mxData->mpScBasePos);
1986 else if(
mxData->mpLinkMgr )
1989 sal_uInt16 nExtSheet, nXclTab;
2020 mxData->mpLinkMgr->StoreCellRange(aRefData, *
mxData->mpScBasePos);
2031 else if(
mxData->mpLinkMgr )
2034 sal_uInt16 nExtSheet, nFirstXclTab, nLastXclTab;
2035 mxData->mpLinkMgr->FindExtSheet( nExtSheet, nFirstXclTab, nLastXclTab,
2066 sal_uInt16 nFileId = rTokData.mpScToken->GetIndex();
2067 OUString aTabName = rTokData.mpScToken->GetString().getString();
2072 sal_uInt16 nExtSheet, nFirstSBTab, nLastSBTab;
2073 mxData->mpLinkMgr->FindExtSheet( nFileId, aTabName, 1, nExtSheet, nFirstSBTab, nLastSBTab,
GetNewRefLogEntry() );
2102 sal_uInt16 nFileId = rTokData.mpScToken->GetIndex();
2103 OUString aTabName = rTokData.mpScToken->GetString().getString();
2108 sal_uInt16 nExtSheet, nFirstSBTab, nLastSBTab;
2109 sal_uInt16 nTabSpan =
static_cast<sal_uInt16
>(aRefData.
Ref2.
Tab() - aRefData.
Ref1.
Tab() + 1);
2110 mxData->mpLinkMgr->FindExtSheet(
2111 nFileId, aTabName, nTabSpan, nExtSheet, nFirstSBTab, nLastSBTab,
GetNewRefLogEntry());
2132 sal_Int16 nSheet = rTokData.mpScToken->GetSheet();
2145 else if(
mxData->mpLinkMgr )
2165 sal_uInt16 nFileId = rTokData.mpScToken->GetIndex();
2166 OUString
aName = rTokData.mpScToken->GetString().getString();
2171 if(
mxData->mpScBasePos )
2173 FormulaTokenArrayPlainIterator aIter(*xArray);
2174 for( FormulaToken* pScToken = aIter.First(); pScToken; pScToken = aIter.Next() )
2176 if( pScToken->IsExternalRef() )
2178 switch( pScToken->GetType() )
2183 mxData->mpLinkMgr->StoreCell(
2190 mxData->mpLinkMgr->StoreCellRange(
2202 sal_uInt16 nExtSheet = 0, nExtName = 0;
2204 if( pFile &&
mxData->mpLinkMgr->InsertExtName( nExtSheet, nExtName, *pFile, aName, xArray ) )
2220 mxData->maOpPosStack.push_back( nTokPos );
2226 OSL_ENSURE( rxOperands,
"XclExpFmlaCompImpl::AppendOperatorTokenId - missing operand list" );
2227 if(
mxData->maOpListVec.size() <= nTokPos )
2228 mxData->maOpListVec.resize( nTokPos + 1, XclExpOperandListRef() );
2229 mxData->maOpListVec[ nTokPos ] = rxOperands;
2234 OSL_ENSURE( !
mxData->mbOk || !
mxData->maOpPosStack.empty(),
"XclExpFmlaCompImpl::PopOperandPos - token stack broken" );
2238 sal_uInt16 nTokPos =
mxData->maOpPosStack.back();
2239 mxData->maOpPosStack.pop_back();
2247 void lclAppend(
ScfUInt8Vec& orVector, sal_uInt16 nData )
2249 orVector.resize( orVector.size() + 2 );
2250 ShortToSVBT16( nData, &*(orVector.end() - 2) );
2253 void lclAppend(
ScfUInt8Vec& orVector, sal_uInt32 nData )
2255 orVector.resize( orVector.size() + 4 );
2256 UInt32ToSVBT32( nData, &*(orVector.end() - 4) );
2259 void lclAppend(
ScfUInt8Vec& orVector,
double fData )
2261 orVector.resize( orVector.size() + 8 );
2262 DoubleToSVBT64( fData, &*(orVector.end() - 8) );
2268 size_t nSize = orVector.size();
2269 orVector.resize( nSize + xXclStr->GetSize() );
2270 xXclStr->WriteToMem( &orVector[ nSize ] );
2277 mxData->maTokVec.push_back( nData );
2282 mxData->maTokVec.resize(
mxData->maTokVec.size() + nCount, nData );
2287 lclAppend(
mxData->maTokVec, nData );
2292 lclAppend(
mxData->maTokVec, nData );
2297 lclAppend(
mxData->maTokVec, fData );
2309 Append( static_cast< sal_uInt8 >( rXclPos.
mnCol ) );
2413 OUString aXclFuncName;
2416 sal_uInt16 nExtSheet, nExtName;
2417 if(
mxData->mpLinkMgr->InsertAddIn( nExtSheet, nExtName, aXclFuncName ) )
2428 sal_uInt16 nExtSheet(0), nExtName(0);
2429 if(
mxData->mpLinkMgr &&
mxData->mpLinkMgr->InsertEuroTool( nExtSheet, nExtName, rExtFuncData.maFuncName ) )
2444 XclExpOperandListRef xOperands = std::make_shared<XclExpOperandList>();
2451 XclExpOperandListRef xOperands = std::make_shared<XclExpOperandList>();
2459 XclExpOperandListRef xOperands = std::make_shared<XclExpOperandList>();
2460 for(
sal_uInt8 nOpIdx = 0; nOpIdx < nOpCount; ++nOpIdx )
2469 sal_uInt16 nXclFuncIdx = rFuncData.GetXclFuncIdx();
2471 sal_uInt8 nRetClass = rFuncData.GetReturnClass();
2478 Append( sal_uInt16( 0 ) );
2480 else if( rFuncData.IsFixedParamCount() )
2505 rFuncData.AppendAttrPos(
GetSize() );
2509 Append( sal_uInt16( 0 ) );
2515 OSL_ENSURE( nInsertPos < mxData->maTokVec.size(),
"XclExpFmlaCompImpl::Insert - invalid position" );
2516 mxData->maTokVec.insert(
mxData->maTokVec.begin() + nInsertPos, nInsertSize, 0 );
2519 for(
auto& rOpPos :
mxData->maOpPosStack )
2520 if( nInsertPos <= rOpPos )
2521 rOpPos += nInsertSize;
2524 if( nInsertPos < mxData->maOpListVec.size() )
2525 mxData->maOpListVec.insert(
mxData->maOpListVec.begin() + nInsertPos, nInsertSize, XclExpOperandListRef() );
2526 for(
auto& rxOpList :
mxData->maOpListVec )
2528 for(
auto& rOp : *rxOpList )
2529 if( nInsertPos <= rOp.mnTokPos )
2530 rOp.mnTokPos += nInsertSize;
2535 OSL_ENSURE(
o3tl::make_unsigned( nWriteToPos + 1 ) <
mxData->maTokVec.size(),
"XclExpFmlaCompImpl::Overwrite - invalid position" );
2536 ShortToSVBT16( nOffset, &
mxData->maTokVec[ nWriteToPos ] );
2546 Overwrite( nAttrPos + 2, static_cast< sal_uInt16 >(
GetSize() - nAttrPos - 5 ) );
2561 mxData->maTokVec.pop_back();
2569 mxData->maExtDataVec.push_back( nData );
2574 mxData->maExtDataVec.resize(
mxData->maExtDataVec.size() + nCount, nData );
2579 lclAppend(
mxData->maExtDataVec, nData );
2584 lclAppend(
mxData->maExtDataVec, fData );
2601 else if( rScPos.
Tab() == nCurrScTab )
2611 lclInitOwnTab( aRef, rScPos, nCurrScTab, b3DRefOnly );
2615 void lclPutRangeToTokenArray(
ScTokenArray& rScTokArr,
const ScRange& rScRange,
SCTAB nCurrScTab,
bool b3DRefOnly )
2619 lclPutCellToTokenArray( rScTokArr, rScRange.
aStart, nCurrScTab, b3DRefOnly );
2625 lclInitOwnTab( aRef.
Ref1, rScRange.
aStart, nCurrScTab, b3DRefOnly );
2626 lclInitOwnTab( aRef.
Ref2, rScRange.
aEnd, nCurrScTab, b3DRefOnly );
2647 return mxImpl->CreateFormula( eType, rScTokArr, pScBasePos, pRefLog );
2653 lclPutCellToTokenArray( aScTokArr, rScPos,
GetCurrScTab(),
mxImpl->Is3DRefOnly( eType ) );
2654 return mxImpl->CreateFormula( eType, aScTokArr );
2660 lclPutRangeToTokenArray( aScTokArr, rScRange,
GetCurrScTab(),
mxImpl->Is3DRefOnly( eType ) );
2661 return mxImpl->CreateFormula( eType, aScTokArr );
2672 bool b3DRefOnly =
mxImpl->Is3DRefOnly( eType );
2673 for(
size_t nIdx = 0; nIdx < nCount; ++nIdx )
2677 lclPutRangeToTokenArray( aScTokArr, rScRanges[ nIdx ], nCurrScTab, b3DRefOnly );
2679 return mxImpl->CreateFormula( eType, aScTokArr );
2684 return mxImpl->CreateErrorFormula( nErrCode );
2690 return mxImpl->CreateSpecialRefFormula( nTokenId, rXclPos );
2694 sal_uInt16 nExtSheet, sal_uInt16 nExtName )
2696 return mxImpl->CreateNameXFormula( nExtSheet, nExtName );
2701 return mxImpl->IsRef2D(rRefData,
true);
2706 return mxImpl->IsRef2D(rRefData,
true);
void AppendNumToken(double fValue, sal_uInt8 nSpaces=0)
Matrix data type that can store values of mixed types.
const SCCOL mnMaxScCol
Maximum row index.
formula::FormulaToken * AddDoubleReference(const ScComplexRefData &rRef)
void PushOperandPos(sal_uInt16 nTokPos)
static void ChangeTokenClass(sal_uInt8 &rnTokenId, sal_uInt8 nTokenClass)
Changes the token class in the passed classified token ID.
static SC_DLLPUBLIC ScUnoAddInCollection * GetAddInCollection()
void ProcessDdeLink(const XclExpScToken &rTokData)
XclExpScToken MulDivTerm(XclExpScToken aTokData, bool bInParentheses)
void ProcessDefinedName(const XclExpScToken &rTokData)
bool IsTabDeleted() const
OUString getString() const
XclBiff
An enumeration for all Excel file format types (BIFF types).
const sal_uInt8 EXC_ERR_NA
void AppendNameXToken(sal_uInt16 nExtSheet, sal_uInt16 nExtName, sal_uInt8 nSpaces=0)
XclExpRefLogEntry()
Calc index of the last sheet.
void AppendLogicalOperatorToken(sal_uInt16 nXclFuncIdx, sal_uInt8 nOpCount)
void ProcessExternalRangeRef(const XclExpScToken &rTokData)
const FormulaToken * PeekNextRawToken() const
bool IsVolatile(sal_uInt16 nNameIdx) const
Returns true, if the specified defined name is volatile.
SC_DLLPUBLIC ScRange toAbs(const ScSheetLimits &rLimits, const ScAddress &rPos) const
Single reference (one address) into the sheet.
XclStrFlags
Flags used to specify import/export mode of strings.
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 AppendNameToken(sal_uInt16 nNameIdx, sal_uInt8 nSpaces=0)
void PushOperatorPos(sal_uInt16 nTokPos, const XclExpOperandListRef &rxOperands)
bool mbValType
Token class conversion type.
const sal_uInt16 mnMaxColMask
Maximum row index in Calc itself.
void AppendOperandTokenId(sal_uInt8 nTokenId, sal_uInt8 nSpaces=0)
XclExpLinkManager & GetLocalLinkManager() const
Returns the local link manager for the current sheet.
ScAddress toAbs(const ScSheetLimits &rLimits, const ScAddress &rPos) const
void AppendFuncToken(const XclExpFuncData &rFuncData)
XclExpScToken OrTerm(XclExpScToken aTokData, bool bInParentheses)
void ProcessBad(const XclExpScToken &rTokData)
XclExpScToken AddSubTerm(XclExpScToken aTokData, bool bInParentheses)
void AppendIntToken(sal_uInt16 nValue, sal_uInt8 nSpaces=0)
ScMatrixValue Get(SCSIZE nC, SCSIZE nR) const
: If bString the ScMatrixValue->pS may still be NULL to indicate an empty string! ...
void SetRelTab(SCTAB nVal)
bool IsMacroFunc() const
Returns true, if the function is simulated by a macro call.
formula::FormulaToken * AddSingleReference(const ScSingleRefData &rRef)
ScSingleRefToken with ocPush.
void UpdateAttrGoto(sal_uInt16 nAttrPos)
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)
void AppendDefaultParam(XclExpFuncData &rFuncData)
XclExpScToken UnaryPreTerm(XclExpScToken aTokData, bool bInParentheses)
const SCROW mnMaxAbsRow
Maximum column index.
void ProcessExternalCellRef(const XclExpScToken &rTokData)
XclExpScToken ConcatTerm(XclExpScToken aTokData, bool bInParentheses)
SCTAB GetScTab(sal_uInt16 nNameIdx) const
Returns the Calc sheet of a local defined name, or SCTAB_GLOBAL for global defined names...
XclTokenArrayRef CreateNameXFormula(sal_uInt16 nExtSheet, sal_uInt16 nExtName)
Creates a single tNameXR token for a reference to an external name.
XclExpRefLogEntry * GetNewRefLogEntry()
std::shared_ptr< T > make_shared(Args &&...args)
void Init(XclFormulaType eType)
const sal_uInt8 EXC_CACHEDVAL_ERROR
ScDocument & GetDoc() const
Returns reference to the destination document (import) or source document (export).
XclExpScToken Expression(XclExpScToken aTokData, bool bInParentheses, bool bStopAtSep)
void RecalcTokenClass(const XclExpTokenConvInfo &rConvInfo, XclFuncParamConv ePrevConv, XclExpClassConv ePrevClassConv, bool bWasRefClass)
Try NOT to use this struct.
void FinishIfFunction(XclExpFuncData &rFuncData)
void ProcessFunction(const XclExpScToken &rTokData)
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)
Implementation class of the export formula compiler.
bool GetExcelName(const OUString &rCalcName, LanguageType eDestLang, OUString &rRetExcelName)
leave rRetExcelName unchanged, if no matching name is found
XclExpCompDataRef mxData
Excel function data provider.
Access to global data from other classes.
void ProcessExternal(const XclExpScToken &rTokData)
bool GetBoolean() const
Only valid if ScMatrix methods indicate that this is a boolean.
void AppendBinaryOperatorToken(sal_uInt8 nTokenId, bool bValType, sal_uInt8 nSpaces=0)
XclTokenArrayRef CreateTokenArray()
void AppendOperatorTokenId(sal_uInt8 nTokenId, const XclExpOperandListRef &rxOperands, sal_uInt8 nSpaces=0)
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 ...
void RecalcTokenClasses()
void ProcessCellRef(const XclExpScToken &rTokData)
static sal_uInt8 GetTokenId(sal_uInt8 nBaseId, sal_uInt8 nTokenClass)
Returns the classified token ID from a base ID and the token class.
const FormulaToken * GetNextRawToken()
void AppendMissingToken(sal_uInt8 nSpaces=0)
const SCTAB SCTAB_INVALID
An invalid Excel sheet index, for common use.
void ProcessParentheses(const XclExpScToken &rTokData)
void AppendBoolToken(bool bValue, sal_uInt8 nSpaces=0)
SC_DLLPUBLIC ScExternalRefManager * GetExternalRefManager() const
XclExpCompConfigMap maCfgMap
void FinishFunction(XclExpFuncData &rFuncData, sal_uInt8 nCloseSpaces)
void AppendRange(const XclRange &rXclRange)
void SetColDeleted(bool bVal)
XclExpScToken Factor(XclExpScToken aTokData)
LanguageType GetUILanguage() const
Returns the UI language.
const SCTAB SCTAB_GLOBAL
An invalid Calc sheet index, for common use.
const sal_uInt8 EXC_ERR_REF
void AppendEuroToolCallToken(const XclExpExtFuncData &rExtFuncData)
XclTokenArrayRef CreateSpecialRefFormula(sal_uInt8 nTokenId, const XclAddress &rXclPos)
Creates a single token for a special cell reference.
void AppendMissingNameToken(const OUString &rName, sal_uInt8 nSpaces=0)
FormulaError GetError() const
Only valid if ScMatrix methods indicate that this is no string!
void ConvertRefData(ScSingleRefData &rRefData, XclAddress &rXclPos, bool bNatLangRef, bool bTruncMaxCol, bool bTruncMaxRow) const
XclExpLinkManager & GetGlobalLinkManager() const
Returns the global link manager for defined names.
XclExpScToken GetNextToken()
MS Excel 5.0, MS Excel 7.0 (95)
Represents information for a spreadsheet function for import and export.
XclOutput GetOutput() const
Returns the current output format of the importer/exporter.
void ProcessExternalName(const XclExpScToken &rTokData)
const sal_uInt32 mnMaxRowMask
Mask to delete invalid bits in column fields.
OUString GetAddInEquivalentFuncName() const
Returns the programmatical name of the Add-In function as string.
std::shared_ptr< XclExpCompData > XclExpCompDataRef
void PrepareParam(XclExpFuncData &rFuncData)
void AppendUnaryOperatorToken(sal_uInt8 nTokenId, sal_uInt8 nSpaces=0)
Manager that stores all internal defined names (NAME records) of the document.
void SetFlag3D(bool bVal)
void GetDimensions(SCSIZE &rC, SCSIZE &rR) const
void ProcessMatrix(const XclExpScToken &rTokData)
sal_uInt16 PopOperandPos()
void InitAddress(const ScAddress &rAdr)
InitAddress: InitFlags and set address.
sal_uInt16 InsertRawName(const OUString &rName)
Returns index of an existing name, or creates a name without definition.
void ProcessRangeRef(const XclExpScToken &rTokData)
const XclFunctionInfo * GetFuncInfoFromOpCode(OpCode eOpCode) const
Returns the function data for a Calc opcode, or 0 on error.
XclFunctionProvider maFuncProv
Compiler configuration map for all formula types.
static bool IsValueType(ScMatValType nType)
Value or boolean.
sal_uInt16 GetSize() const
constexpr std::enable_if_t< std::is_signed_v< T >, std::make_unsigned_t< T > > make_unsigned(T value)
void ProcessMissing(const XclExpScToken &rTokData)
bool IsSpaceToken(sal_uInt16 nPos) const
XclExpScToken ProcessParam(XclExpScToken aTokData, XclExpFuncData &rFuncData)
const sal_uInt8 EXC_CACHEDVAL_BOOL
const XclBiff meBiff
Stack for working data, when compiler is called recursively.
XclExpNameManager & GetNameManager() const
Returns the buffer that contains internal defined names.
static bool IsBooleanType(ScMatValType nType)
Boolean.
XclExpScToken IntersectTerm(XclExpScToken aTokData, bool &rbHasRefOp)
A 2D cell address struct with Excel column and row indexes.
const ::formula::FormulaToken * Get() const
void AppendExt(sal_uInt8 nData)
std::map< XclFormulaType, XclExpCompConfig > XclExpCompConfigMap
const sal_uInt8 EXC_CACHEDVAL_EMPTY
void Overwrite(sal_uInt16 nWriteToPos, sal_uInt16 nOffset)
Provides access to function info structs for all available functions.
const XclExpRoot & GetRoot() const
Returns this root instance - for code readability in derived classes.
SCTAB GetCurrScTab() const
Returns the current Calc sheet index.
void AppendAddress(const XclAddress &rXclPos)
void AppendMacroCallToken(const XclExpExtFuncData &rExtFuncData)
XclExpScToken UnaryPostTerm(XclExpScToken aTokData, bool bInParentheses)
const svl::SharedString & GetString() const
Only valid if ScMatrix methods indicate so!
const sal_uInt8 EXC_CACHEDVAL_DOUBLE
virtual formula::FormulaToken * AddOpCode(OpCode eCode) override
void ProcessBoolean(const XclExpScToken &rTokData)
static sal_uInt8 GetTokenClass(sal_uInt8 nTokenId)
Returns the token class of the passed token ID.
void ProcessString(const XclExpScToken &rTokData)
XclExpScToken PowTerm(XclExpScToken aTokData, bool bInParentheses)
void PrepareFunction(const XclExpFuncData &rFuncData)
const sal_Unicode EXC_EXTSH_OWNDOC
const SCROW mnMaxScRow
Maximum column index in Calc itself.
void ProcessDouble(const XclExpScToken &rTokData)
XclExpScToken AndTerm(XclExpScToken aTokData, bool bInParentheses)
void AppendSpaceToken(sal_uInt8 nType, sal_uInt8 nCount)
Stores all data for internal/external references (the link table).
std::vector< XclExpCompDataRef > maDataStack
Working data for current formula.
sal_uInt16 InsertMacroCall(const OUString &rMacroName, bool bVBasic, bool bFunc, bool bHidden=false)
Searches or inserts a defined name describing a macro name.
const sal_uInt8 EXC_CACHEDVAL_STRING
const sal_uInt8 EXC_ERR_NAME
void InsertZeros(sal_uInt16 nInsertPos, sal_uInt16 nInsertSize)
bool IsRef2D(const ScSingleRefData &rRefData, bool bCheck3DFlag) const
void AppendErrorToken(sal_uInt8 nErrCode, sal_uInt8 nSpaces=0)
std::shared_ptr< ScTokenArray > TokenArrayRef
Always use UCS-2 characters (default: try to compress). BIFF8 only.
void InitRange(const ScRange &rRange)
SCTAB GetScTab(const ScSingleRefData &rRefData) const
XclFuncParamConv meConv
Parameter validity.
void SetAddress(const ScSheetLimits &rLimits, const ScAddress &rAddr, const ScAddress &rPos)
void FinishChooseFunction(XclExpFuncData &rFuncData)
Log entry for external references in a formula, used i.e.
XclTokenArrayRef CreateErrorFormula(sal_uInt8 nErrCode)
Creates a single error token containing the passed error code.
const sal_uInt16 EXC_TAB_DELETED
Special sheet index for external links.
#define SC_OPCODE_START_NO_PAR
bool Is3DRefOnly(XclFormulaType eType) const
Returns true, if the passed formula type allows 3D references only.
Complex reference (a range) into the sheet.
const XclExpCompConfig * GetConfigForType(XclFormulaType eType) const
XclExpScToken RangeTerm(XclExpScToken aTokData, bool &rbHasRefOp)
void Append(sal_uInt8 nData)
sal_uInt16 InsertName(SCTAB nTab, sal_uInt16 nScNameIdx, SCTAB nCurrTab)
Inserts the Calc name with the passed index and returns the Excel NAME index.
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.
#define SAL_WARN(area, stream)
XclExpScToken SkipExpression(XclExpScToken aTokData, bool bStopAtSep)
std::shared_ptr< XclExpString > XclExpStringRef
void AppendTrailingParam(XclExpFuncData &rFuncData)
A helper with Excel specific token array functions.
bool IsAddInEquivalent() const
Returns true, if the function is stored as an add-in call.
void AppendJumpToken(XclExpFuncData &rFuncData, sal_uInt8 nAttrType)
bool IsRowDeleted() const
const SCCOL mnMaxAbsCol
Cached BIFF version to save GetBiff() calls.
Special token array iterator for the Excel filters.
void AppendParenToken(sal_uInt8 nOpenSpaces=0, sal_uInt8 nCloseSpaces=0)
void RemoveTrailingParen()
std::unique_ptr< ScTokenArray > Clone() const
A 2D cell range address struct with Excel column and row indexes.
XclExpFmlaCompImpl(const XclExpRoot &rRoot)
Structure that contains all needed information for a parameter in a function.
bool IsColDeleted() const
OUString GetMacroFuncName() const
Returns the name of the external function as string.
XclExpScToken CompareTerm(XclExpScToken aTokData, bool bInParentheses)
void FinishParam(XclExpFuncData &rFuncData)
bool m_bDetectedRangeSegmentation false
XclExpScToken ListTerm(XclExpScToken aTokData, bool bInParentheses)