22 #include <com/sun/star/sheet/ComplexReference.hpp>
23 #include <com/sun/star/sheet/ExternalReference.hpp>
24 #include <com/sun/star/sheet/ReferenceFlags.hpp>
25 #include <com/sun/star/sheet/SingleReference.hpp>
26 #include <com/sun/star/table/CellAddress.hpp>
27 #include <osl/diagnose.h>
30 #include <oox/token/properties.hxx>
41 using namespace ::com::sun::star::sheet::ReferenceFlags;
57 if( rTokens.hasElements() )
59 const ApiToken* pToken = rTokens.getConstArray();
82 if( (orFuncToken.OpCode ==
OPCODE_BAD) && orFuncToken.Data.has< OUString >() )
90 if( (orFuncToken.OpCode ==
OPCODE_EXTERNAL) && (!pLibFuncInfo->maExtProgName.isEmpty()) )
91 orFuncToken.Data <<= pLibFuncInfo->maExtProgName;
93 orFuncToken.Data.clear();
109 if( (pFuncInfo->mnApiOpCode ==
OPCODE_EXTERNAL) && !pFuncInfo->maExtProgName.isEmpty() )
110 orFuncToken.Data <<= pFuncInfo->maExtProgName;
112 else if( (pFuncInfo->mnApiOpCode ==
OPCODE_BAD) && !pFuncInfo->maOoxFuncName.isEmpty() )
113 orFuncToken.Data <<= pFuncInfo->maOoxFuncName;
119 orFuncToken = rECToken;
122 if( (rECToken.OpCode ==
OPCODE_NAME) && rECToken.Data.has< sal_Int32 >() )
125 if( !aDefName.isEmpty() )
128 orFuncToken.Data <<= aDefName;
137 while( pToken < pTokenEnd )
157 OSL_ENSURE( (pToken < pTokenEnd) && (pToken->OpCode ==
OPCODE_OPEN),
"FormulaFinalizer::processParameters - OPCODE_OPEN expected" );
158 if( (pToken < pTokenEnd) && (pToken->OpCode ==
OPCODE_OPEN) )
166 OSL_ENSURE( aParams.size() >= 2,
"FormulaFinalizer::processParameters - missing tokens" );
169 if( (nParamCount == 1) &&
isEmptyParameter( aParams[ 0 ] + 1, aParams[ 1 ] ) )
178 ParameterPosVector::const_iterator aPosIt = aParams.begin();
191 pRealFuncInfo = pECFuncInfo;
205 size_t nLastValidCount = 0;
215 const ApiToken* pParamBegin = *aPosIt + 1;
216 const ApiToken* pParamEnd = *(aPosIt + 1);
225 while( (pParamBegin < pParamEnd) && (pParamBegin->OpCode ==
OPCODE_SPACES) )
232 OSL_ENSURE( (pParamBegin == pParamEnd) || (pParamBegin->OpCode ==
OPCODE_MISSING),
"FormulaFinalizer::processParameters - OPCODE_MISSING expected" );
233 if( pParamBegin < pParamEnd ) ++pParamBegin;
235 while( (pParamBegin < pParamEnd) && (pParamBegin->OpCode ==
OPCODE_SPACES) )
253 nLastValidCount =
nParam + 1;
282 if( (rFuncNameToken.OpCode ==
OPCODE_EXTERNAL) && !rFuncNameToken.Data.hasValue() )
290 while( (pToken < pTokenEnd) && (pToken->OpCode ==
OPCODE_SPACES) ) ++pToken;
291 if( (pToken < pTokenEnd) && (pToken->OpCode ==
OPCODE_MISSING) ) ++pToken;
292 while( (pToken < pTokenEnd) && (pToken->OpCode ==
OPCODE_SPACES) ) ++pToken;
293 return pToken == pTokenEnd;
298 const ApiToken* pSingleToken =
nullptr;
300 while( (pToken < pTokenEnd) && (pToken->OpCode ==
OPCODE_SPACES) ) ++pToken;
302 if( pToken < pTokenEnd ) pSingleToken = pToken++;
304 while( (pToken < pTokenEnd) && (pToken->OpCode ==
OPCODE_SPACES) ) ++pToken;
306 return (pToken == pTokenEnd) ? pSingleToken :
nullptr;
312 OSL_ENSURE( (pToken < pTokenEnd) && (pToken->OpCode ==
OPCODE_OPEN),
"skipParentheses - OPCODE_OPEN expected" );
314 while( (pToken < pTokenEnd) && (pToken->OpCode !=
OPCODE_CLOSE) )
322 OSL_ENSURE( ((pToken < pTokenEnd) && (pToken->OpCode ==
OPCODE_CLOSE)) || ((pTokenEnd - 1)->OpCode ==
OPCODE_BAD),
"skipParentheses - OPCODE_CLOSE expected" );
323 return (pToken < pTokenEnd) ? (pToken + 1) : pTokenEnd;
330 OSL_ENSURE( (pToken < pTokenEnd) && (pToken->OpCode ==
OPCODE_OPEN),
"FormulaFinalizer::findParameters - OPCODE_OPEN expected" );
331 rParams.push_back( pToken++ );
334 while( (pToken < pTokenEnd) && (pToken->OpCode !=
OPCODE_CLOSE) )
339 rParams.push_back( pToken++ );
345 OSL_ENSURE( ((pToken < pTokenEnd) && (pToken->OpCode ==
OPCODE_CLOSE)) || ((pTokenEnd - 1)->OpCode ==
OPCODE_BAD),
"FormulaFinalizer::findParameters - OPCODE_CLOSE expected" );
346 rParams.push_back( pToken );
347 return (pToken < pTokenEnd) ? (pToken + 1) : pTokenEnd;
358 if( (nParam == 1) || (nParam == 2) )
375 if (nParam == 2 && nParamCount < 3)
389 if( nParamCount == 1 )
401 bool bValid = (rToken.OpCode !=
OPCODE_MACRO) || rToken.Data.hasValue();
425 const OUString& rFormulaString );
448 static void appendSpaces( WhiteSpaceVec& orSpaces, sal_Int32 nCount,
bool bLineFeed );
465 bool pushOperandToken( sal_Int32 nOpCode,
const WhiteSpaceVec* pSpaces =
nullptr );
466 template<
typename Type >
468 template<
typename Type >
480 template<
typename Type >
482 template<
typename Type >
491 template<
typename Type >
498 bool pushDdeLinkOperand(
const OUString& rDdeServer,
const OUString& rDdeTopic,
const OUString& rDdeItem );
513 static void initReference3d( SingleReference& orApiRef, sal_Int32 nSheet,
bool bSameSheet );
518 void convertReference3d( SingleReference& orApiRef, sal_Int32 nSheet,
bool bSameSheet,
const BinSingleRef2d& rRef,
bool bDeleted,
bool bRelativeAsOffset )
const;
550 mnMaxApiCol( rParent.getAddressConverter().getMaxApiAddress().
Col() ),
551 mnMaxApiRow( rParent.getAddressConverter().getMaxApiAddress().
Row() ),
552 mnMaxXlsCol( rParent.getAddressConverter().getMaxXlsAddress().
Col() ),
553 mnMaxXlsRow( rParent.getAddressConverter().getMaxXlsAddress().
Row() ),
554 mbRelativeAsOffset( false ),
555 mb2dRefsAs3dRefs( false ),
556 mbSpecialTokens( false )
569 OSL_FAIL(
"FormulaParserImpl::importOoxFormula - not implemented" );
575 SAL_WARN(
"sc.filter",
"FormulaParserImpl::importBiff12Formula - not implemented" );
618 if( aTokens.hasElements() )
620 ApiToken* pToken = aTokens.getArray();
642 OSL_ENSURE( nCount >= 0,
"FormulaParserImpl::appendSpaces - negative count" );
644 orSpaces.emplace_back( nCount, bLineFeed );
682 for(
const auto& rSpace : *pSpaces )
684 return pSpaces ? pSpaces->size() : 0;
690 for(
const auto& rSpace : *pSpaces )
692 return pSpaces ? pSpaces->size() : 0;
698 "FormulaParserImpl::getOperandSize - invalid parameters" );
709 OSL_ENSURE( !
maOperandSizeStack.empty(),
"FormulaParserImpl::popOperandSize - invalid call" );
718 "FormulaParserImpl::getOperandToken - invalid parameters" );
720 for(
auto aEnd =
maOperandSizeStack.cend(), aIt = aEnd - 1 + nOpIndex; aIt != aEnd; ++aIt )
733 template<
typename Type >
844 template<
typename Type >
854 return pushValueOperand< double >( bValue ? 1.0 : 0.0 );
884 SingleReference aApiRef;
891 ComplexReference aApiRef;
896 template<
typename Type >
901 ExternalReference aApiExtRef;
903 aApiExtRef.Reference <<= rApiRef;
914 ComplexReference aApiRef;
918 SingleReference aApiRef;
925 ComplexReference aApiRef;
939 if( !rxDefName || rxDefName->getModelName().isEmpty() )
941 if( rxDefName->isMacroFunction() )
943 if( rxDefName->getTokenIndex() >= 0 )
980 OUString aDdeServer, aDdeTopic, aDdeItem;
981 if( rxExtName->getDdeLinkData( aDdeServer, aDdeTopic, aDdeItem ) )
1039 orApiRef.Flags = SHEET_RELATIVE;
1042 orApiRef.RelativeSheet = 0;
1048 orApiRef.Flags = SHEET_3D;
1052 orApiRef.Flags |= SHEET_DELETED;
1054 else if( bSameSheet )
1056 OSL_ENSURE( nSheet == 0,
"FormulaParserImpl::initReference3d - invalid sheet index" );
1057 orApiRef.Flags |= SHEET_RELATIVE;
1058 orApiRef.RelativeSheet = 0;
1062 orApiRef.Sheet = nSheet;
1070 orApiRef.Column = 0;
1073 orApiRef.Flags |= COLUMN_DELETED | ROW_DELETED;
1080 (rRef.
mbColRel ? orApiRef.RelativeColumn : orApiRef.Column) = rRef.
mnCol;
1081 (rRef.
mbRowRel ? orApiRef.RelativeRow : orApiRef.Row) = rRef.
mnRow;
1083 if( !bRelativeAsOffset )
1095 convertReference( orApiRef.Reference1, rRef1, bDeleted, bRelativeAsOffset );
1096 convertReference( orApiRef.Reference2, rRef2, bDeleted, bRelativeAsOffset );
1099 if( !bDeleted && !rRef1.
mbColRel && !rRef2.
mbColRel && (orApiRef.Reference1.Column == 0) && (orApiRef.Reference2.Column ==
mnMaxXlsCol) )
1101 if( !bDeleted && !rRef1.
mbRowRel && !rRef2.
mbRowRel && (orApiRef.Reference1.Row == 0) && (orApiRef.Reference2.Row ==
mnMaxXlsRow) )
1117 setFlag( orApiRef.Reference2.Flags, SHEET_3D,
false );
1143 sal_Int32 nBracketOpen = rTokenData.indexOf(
'[' );
1144 sal_Int32 nBracketClose = rTokenData.indexOf(
']' );
1145 sal_Int32 nExclamation = rTokenData.indexOf(
'!' );
1146 if( (0 == nBracketOpen) && (nBracketOpen + 1 < nBracketClose) && (nBracketClose + 1 == nExclamation) && (nExclamation + 1 < rTokenData.getLength()) )
1148 sal_Int32 nRefId = rTokenData.copy( nBracketOpen + 1, nBracketClose - nBracketOpen - 1 ).toInt32();
1152 OUString aFuncName = rTokenData.copy( nExclamation + 1 ).toAsciiUpperCase();
1164 return pDefName->getCalcName();
1175 explicit OoxFormulaParserImpl(
const FormulaParser& rParent );
1179 const OUString& rFormulaString )
override;
1194 bool importAreaToken(
SequenceInputStream& rStrm,
bool bDeleted,
bool bRelativeAsOffset );
1195 bool importRef3dToken(
SequenceInputStream& rStrm,
bool bDeleted,
bool bRelativeAsOffset );
1196 bool importArea3dToken(
SequenceInputStream& rStrm,
bool bDeleted,
bool bRelativeAsOffset );
1212 bool pushBiff12Name( sal_Int32 nNameId );
1213 bool pushBiff12ExtName( sal_Int32 nRefId, sal_Int32 nNameId );
1214 bool pushBiff12Function( sal_uInt16 nFuncId );
1225 OoxFormulaParserImpl::OoxFormulaParserImpl(
const FormulaParser& rParent ) :
1226 FormulaParserImpl( rParent ),
1227 maApiParser( rParent.getBaseFilter().getModelFactory(), rParent ),
1237 maApiParser.getParserProperties().setProperty( PROP_ExternalLinks, getExternalLinks().getLinkInfos() );
1240 return finalizeTokenArray(
maApiParser.parseFormula( rFormulaString, rBaseAddr ) );
1245 initializeImport( rBaseAddr, eType );
1247 sal_Int32 nFmlaSize = rStrm.readInt32();
1248 sal_Int64 nFmlaPos = rStrm.tell();
1249 sal_Int64 nFmlaEndPos = nFmlaPos + nFmlaSize;
1251 rStrm.seek( nFmlaEndPos );
1252 sal_Int32 nAddDataSize = rStrm.readInt32();
1254 sal_Int64 nAddDataEndPos =
mnAddDataPos + nAddDataSize;
1255 rStrm.seek( nFmlaPos );
1257 bool bOk = (nFmlaSize >= 0) && (nAddDataSize >= 0);
1258 bool bRelativeAsOffset = mbRelativeAsOffset;
1260 while( bOk && !rStrm.isEof() && (rStrm.tell() < nFmlaEndPos) )
1263 nTokenId = rStrm.readuChar();
1273 case BIFF_TOKID_ADD: bOk = pushBinaryOperator( OPCODE_ADD );
break;
1274 case BIFF_TOKID_SUB: bOk = pushBinaryOperator( OPCODE_SUB );
break;
1275 case BIFF_TOKID_MUL: bOk = pushBinaryOperator( OPCODE_MULT );
break;
1276 case BIFF_TOKID_DIV: bOk = pushBinaryOperator( OPCODE_DIV );
break;
1279 case BIFF_TOKID_LT: bOk = pushBinaryOperator( OPCODE_LESS );
break;
1280 case BIFF_TOKID_LE: bOk = pushBinaryOperator( OPCODE_LESS_EQUAL );
break;
1281 case BIFF_TOKID_EQ: bOk = pushBinaryOperator( OPCODE_EQUAL );
break;
1282 case BIFF_TOKID_GE: bOk = pushBinaryOperator( OPCODE_GREATER_EQUAL );
break;
1283 case BIFF_TOKID_GT: bOk = pushBinaryOperator( OPCODE_GREATER );
break;
1284 case BIFF_TOKID_NE: bOk = pushBinaryOperator( OPCODE_NOT_EQUAL );
break;
1285 case BIFF_TOKID_ISECT: bOk = pushBinaryOperator( OPCODE_INTERSECT );
break;
1288 case BIFF_TOKID_UPLUS: bOk = pushUnaryPreOperator( OPCODE_PLUS_SIGN );
break;
1293 case BIFF_TOKID_STR: bOk = pushValueOperand( BiffHelper::readString( rStrm,
false ) );
break;
1296 case BIFF_TOKID_ERR: bOk = pushBiffErrorOperand( rStrm.readuInt8() );
break;
1297 case BIFF_TOKID_BOOL: bOk = pushBiffBoolOperand( rStrm.readuInt8() );
break;
1298 case BIFF_TOKID_INT: bOk = pushValueOperand< double >( rStrm.readuInt16() );
break;
1299 case BIFF_TOKID_NUM: bOk = pushValueOperand( rStrm.readDouble() );
break;
1300 default: bOk =
false;
1312 case BIFF_TOKID_REF: bOk = importRefToken( rStrm,
false,
false );
break;
1313 case BIFF_TOKID_AREA: bOk = importAreaToken( rStrm,
false,
false );
break;
1320 case BIFF_TOKID_REFN: bOk = importRefToken( rStrm,
false,
true );
break;
1325 case BIFF_TOKID_REF3D: bOk = importRef3dToken( rStrm,
false, bRelativeAsOffset );
break;
1326 case BIFF_TOKID_AREA3D: bOk = importArea3dToken( rStrm,
false, bRelativeAsOffset );
break;
1327 case BIFF_TOKID_REFERR3D: bOk = importRef3dToken( rStrm,
true, bRelativeAsOffset );
break;
1329 default: bOk =
false;
1336 if( bOk && (rStrm.tell() == nFmlaEndPos) && (
mnAddDataPos == nAddDataEndPos) )
1337 aFinalTokens = finalizeImport();
1340 if( (nFmlaSize >= 0) && (nAddDataSize >= 0) )
1341 rStrm.seek( nAddDataEndPos );
1344 return aFinalTokens;
1349 bool OoxFormulaParserImpl::importAttrToken( SequenceInputStream& rStrm )
1353 nType = rStrm.readuChar();
1366 rStrm.skip( 2 * rStrm.readuInt16() + 2 );
1374 bOk = importSpaceToken( rStrm );
1382 bool OoxFormulaParserImpl::importSpaceToken( SequenceInputStream& rStrm )
1386 nType = rStrm.readuChar();
1387 nCount = rStrm.readuChar();
1391 appendLeadingSpaces( nCount,
false );
1394 appendLeadingSpaces( nCount,
true );
1397 appendOpeningSpaces( nCount,
false );
1400 appendOpeningSpaces( nCount,
true );
1403 appendClosingSpaces( nCount,
false );
1406 appendClosingSpaces( nCount,
true );
1412 bool OoxFormulaParserImpl::importTableToken( SequenceInputStream& rStrm )
1414 sal_uInt16 nFlags, nTableId, nCol1, nCol2;
1416 nFlags = rStrm.readuInt16();
1417 nTableId = rStrm.readuInt16();
1419 nCol1 = rStrm.readuInt16();
1420 nCol2 = rStrm.readuInt16();
1421 TableRef xTable = getTables().getTable( nTableId );
1422 sal_Int32 nTokenIndex = xTable ? xTable->getTokenIndex() : -1;
1423 if( nTokenIndex >= 0 )
1425 sal_Int32 nWidth = xTable->getWidth();
1426 sal_Int32 nHeight = xTable->getHeight();
1427 sal_Int32 nStartCol = 0;
1428 sal_Int32 nEndCol = nWidth - 1;
1429 sal_Int32 nStartRow = 0;
1430 sal_Int32 nEndRow = nHeight - 1;
1431 bool bFixedStartRow =
true;
1432 bool bFixedHeight =
false;
1436 bool bValidRef = !bSingleCol || !bColRange;
1437 OSL_ENSURE( bValidRef,
"OoxFormulaParserImpl::importTableToken - illegal combination of single column and column range" );
1441 nStartCol = nEndCol = nCol1;
1442 else if( bColRange )
1443 { nStartCol = nCol1; nEndCol = nCol2; }
1444 bValidRef = (nStartCol <= nEndCol) && (nEndCol < nWidth);
1445 OSL_ENSURE( bValidRef,
"OoxFormulaParserImpl::importTableToken - invalid column range" );
1456 sal_Int32 nStartDataRow = xTable->getHeaderRows();
1457 sal_Int32 nEndDataRow = nEndRow - xTable->getTotalsRows();
1458 bValidRef = (nStartRow <= nStartDataRow) && (nStartDataRow <= nEndDataRow) && (nEndDataRow <= nEndRow);
1459 OSL_ENSURE( bValidRef,
"OoxFormulaParserImpl::importTableToken - invalid data row range" );
1464 bValidRef = !bHeaderRows && !bDataRows && !bTotalsRows && !bThisRow;
1465 OSL_ENSURE( bValidRef,
"OoxFormulaParserImpl::importTableToken - unexpected flags in [#All] table token" );
1467 else if( bHeaderRows )
1469 bValidRef = !bTotalsRows && !bThisRow;
1470 OSL_ENSURE( bValidRef,
"OoxFormulaParserImpl::importTableToken - unexpected flags in [#Headers] table token" );
1471 nEndRow = bDataRows ? nEndDataRow : (nStartDataRow - 1);
1472 bFixedHeight = !bDataRows;
1474 else if( bDataRows )
1476 bValidRef = !bThisRow;
1477 OSL_ENSURE( bValidRef,
"OoxFormulaParserImpl::importTableToken - unexpected flags in [#Data] table token" );
1478 nStartRow = nStartDataRow;
1479 if( !bTotalsRows ) nEndRow = nEndDataRow;
1481 else if( bTotalsRows )
1483 bValidRef = !bThisRow;
1484 OSL_ENSURE( bValidRef,
"OoxFormulaParserImpl::importTableToken - unexpected flags in [#Totals] table token" );
1485 nStartRow = nEndDataRow + 1;
1486 bFixedStartRow =
false;
1487 bFixedHeight = !bDataRows;
1491 nStartRow = nEndRow = maBaseAddr.Row() - xTable->getRange().aStart.Row();
1492 bFixedHeight =
true;
1497 nStartRow = nStartDataRow;
1498 nEndRow = nEndDataRow;
1502 bValidRef = (0 <= nStartRow) && (nStartRow <= nEndRow) && (nEndRow < nHeight);
1507 if( (nStartCol == 0) && (nEndCol + 1 == nWidth) && (nStartRow == 0) && (nEndRow + 1 == nHeight) )
1508 return pushValueOperand( nTokenIndex, OPCODE_DBAREA );
1510 const FunctionInfo* pRowsInfo = getFuncInfoFromBiff12FuncId(
BIFF_FUNC_ROWS );
1511 const FunctionInfo* pColumnsInfo = getFuncInfoFromBiff12FuncId(
BIFF_FUNC_COLUMNS );
1513 pRowsInfo && pColumnsInfo &&
1514 pushValueOperandToken( nTokenIndex, OPCODE_DBAREA ) &&
1516 pushValueOperandToken< double >( nStartRow ) :
1517 (pushValueOperandToken( nTokenIndex, OPCODE_DBAREA ) &&
1518 pushFunctionOperatorToken( *pRowsInfo, 1 ) &&
1519 pushValueOperandToken< double >( nHeight - nStartRow ) &&
1520 pushBinaryOperatorToken( OPCODE_SUB ))) &&
1521 pushValueOperandToken< double >( nStartCol ) &&
1523 pushValueOperandToken< double >( nEndRow - nStartRow + 1 ) :
1524 (pushValueOperandToken( nTokenIndex, OPCODE_DBAREA ) &&
1525 pushFunctionOperatorToken( *pRowsInfo, 1 ) &&
1526 (((nStartRow == 0) && (nEndRow + 1 == nHeight)) ||
1527 (pushValueOperandToken< double >( nHeight - (nEndRow - nStartRow + 1) ) &&
1528 pushBinaryOperatorToken( OPCODE_SUB ))))) &&
1529 (((nStartCol == 0) && (nEndCol + 1 == nWidth)) ?
1530 (pushValueOperandToken( nTokenIndex, OPCODE_DBAREA ) &&
1531 pushFunctionOperatorToken( *pColumnsInfo, 1 )) :
1532 pushValueOperandToken< double >( nEndCol - nStartCol + 1 )) &&
1539 bool OoxFormulaParserImpl::importArrayToken( SequenceInputStream& rStrm )
1544 pushOperand( OPCODE_ARRAY_OPEN );
1545 size_t nOpSize = popOperandSize();
1546 size_t nOldArraySize = getFormulaSize();
1549 swapStreamPosition( rStrm );
1550 sal_Int32 nRows = rStrm.readInt32();
1551 sal_Int32 nCols = rStrm.readInt32();
1552 OSL_ENSURE( (nCols > 0) && (nRows > 0),
"OoxFormulaParserImpl::importArrayToken - empty array" );
1555 for( sal_Int32 nRow = 0; !rStrm.isEof() && (nRow < nRows); ++nRow )
1558 appendRawToken( OPCODE_ARRAY_ROWSEP );
1559 for( sal_Int32 nCol = 0; !rStrm.isEof() && (nCol < nCols); ++nCol )
1562 appendRawToken( OPCODE_ARRAY_COLSEP );
1563 switch( rStrm.readuInt8() )
1566 appendRawToken( OPCODE_PUSH ) <<= rStrm.readDouble();
1569 appendRawToken( OPCODE_PUSH ) <<= BiffHelper::readString( rStrm,
false );
1572 appendRawToken( OPCODE_PUSH ) <<=
static_cast< double >( (rStrm.readuInt8() ==
BIFF_TOK_BOOL_FALSE) ? 0.0 : 1.0 );
1575 appendRawToken( OPCODE_PUSH ) <<= BiffHelper::calcDoubleFromError( rStrm.readuInt8() );
1579 OSL_FAIL(
"OoxFormulaParserImpl::importArrayToken - unknown data type" );
1580 appendRawToken( OPCODE_PUSH ) <<= BiffHelper::calcDoubleFromError(
BIFF_ERR_NA );
1584 swapStreamPosition( rStrm );
1587 appendRawToken( OPCODE_ARRAY_CLOSE );
1588 pushOperandSize( nOpSize + getFormulaSize() - nOldArraySize );
1592 bool OoxFormulaParserImpl::importRefToken( SequenceInputStream& rStrm,
bool bDeleted,
bool bRelativeAsOffset )
1594 BinSingleRef2d aRef;
1595 aRef.readBiff12Data( rStrm, bRelativeAsOffset );
1596 return pushReferenceOperand( aRef, bDeleted, bRelativeAsOffset );
1599 bool OoxFormulaParserImpl::importAreaToken( SequenceInputStream& rStrm,
bool bDeleted,
bool bRelativeAsOffset )
1601 BinComplexRef2d aRef;
1602 aRef.readBiff12Data( rStrm, bRelativeAsOffset );
1603 return pushReferenceOperand( aRef, bDeleted, bRelativeAsOffset );
1606 bool OoxFormulaParserImpl::importRef3dToken( SequenceInputStream& rStrm,
bool bDeleted,
bool bRelativeAsOffset )
1608 LinkSheetRange aSheetRange = readSheetRange( rStrm );
1609 BinSingleRef2d aRef;
1610 aRef.readBiff12Data( rStrm, bRelativeAsOffset );
1611 return pushReferenceOperand( aSheetRange, aRef, bDeleted, bRelativeAsOffset );
1614 bool OoxFormulaParserImpl::importArea3dToken( SequenceInputStream& rStrm,
bool bDeleted,
bool bRelativeAsOffset )
1616 LinkSheetRange aSheetRange = readSheetRange( rStrm );
1617 BinComplexRef2d aRef;
1618 aRef.readBiff12Data( rStrm, bRelativeAsOffset );
1619 return pushReferenceOperand( aSheetRange, aRef, bDeleted, bRelativeAsOffset );
1622 bool OoxFormulaParserImpl::importMemAreaToken( SequenceInputStream& rStrm,
bool bAddData )
1626 skipMemAreaAddData( rStrm );
1630 bool OoxFormulaParserImpl::importMemFuncToken( SequenceInputStream& rStrm )
1636 bool OoxFormulaParserImpl::importNameToken( SequenceInputStream& rStrm )
1638 return pushBiff12Name( rStrm.readInt32() );
1641 bool OoxFormulaParserImpl::importNameXToken( SequenceInputStream& rStrm )
1643 sal_Int32 nRefId = rStrm.readInt16();
1644 sal_Int32 nNameId = rStrm.readInt32();
1645 return pushBiff12ExtName( nRefId, nNameId );
1648 bool OoxFormulaParserImpl::importFuncToken( SequenceInputStream& rStrm )
1651 nFuncId = rStrm.readuInt16();
1652 return pushBiff12Function( nFuncId );
1655 bool OoxFormulaParserImpl::importFuncVarToken( SequenceInputStream& rStrm )
1659 nParamCount = rStrm.readuChar();
1660 nFuncId = rStrm.readuInt16();
1661 return pushBiff12Function( nFuncId, nParamCount );
1664 bool OoxFormulaParserImpl::importExpToken( SequenceInputStream& rStrm )
1666 BinAddress aBaseAddr;
1667 aBaseAddr.mnRow = rStrm.readInt32();
1668 swapStreamPosition( rStrm );
1669 aBaseAddr.mnCol = rStrm.readInt32();
1670 swapStreamPosition( rStrm );
1671 return pushSpecialTokenOperand( aBaseAddr );
1674 LinkSheetRange OoxFormulaParserImpl::readSheetRange( SequenceInputStream& rStrm )
1676 return getExternalLinks().getSheetRange( rStrm.readInt16() );
1679 void OoxFormulaParserImpl::swapStreamPosition( SequenceInputStream& rStrm )
1681 sal_Int64 nRecPos = rStrm.tell();
1686 void OoxFormulaParserImpl::skipMemAreaAddData( SequenceInputStream& rStrm )
1688 swapStreamPosition( rStrm );
1689 rStrm.skip( 16 * rStrm.readInt32() );
1690 swapStreamPosition( rStrm );
1695 bool OoxFormulaParserImpl::pushBiff12Name( sal_Int32 nNameId )
1698 return pushDefinedNameOperand( getDefinedNames().getByIndex( nNameId - 1 ) );
1701 bool OoxFormulaParserImpl::pushBiff12ExtName( sal_Int32 nRefId, sal_Int32 nNameId )
1703 if(
const ExternalLink* pExtLink = getExternalLinks().getExternalLink( nRefId ).
get() )
1705 if( pExtLink->getLinkType() == ExternalLinkType::Self )
1706 return pushBiff12Name( nNameId );
1709 return pushExternalNameOperand( xExtName, *pExtLink );
1714 bool OoxFormulaParserImpl::pushBiff12Function( sal_uInt16 nFuncId )
1716 if(
const FunctionInfo* pFuncInfo = getFuncInfoFromBiff12FuncId( nFuncId ) )
1717 if( pFuncInfo->mnMinParamCount == pFuncInfo->mnMaxParamCount )
1718 return pushFunctionOperator( *pFuncInfo, pFuncInfo->mnMinParamCount );
1719 return pushFunctionOperator( OPCODE_NONAME, 0 );
1722 bool OoxFormulaParserImpl::pushBiff12Function( sal_uInt16 nFuncId,
sal_uInt8 nParamCount )
1726 if(
const FunctionInfo* pFuncInfo = getFuncInfoFromBiff12FuncId( nFuncId ) )
1727 return pushFunctionOperator( *pFuncInfo, nParamCount );
1728 return pushFunctionOperator( OPCODE_NONAME, nParamCount );
1735 bool lclExtractRefId( sal_Int32& rnRefId, OUString& rRemainder,
const OUString& rFormulaString )
1737 if( (rFormulaString.getLength() >= 4) && (rFormulaString[ 0 ] ==
'[') )
1739 sal_Int32 nBracketClose = rFormulaString.indexOf(
']', 1 );
1740 if( nBracketClose >= 2 )
1742 rnRefId = rFormulaString.copy( 1, nBracketClose - 1 ).toInt32();
1743 rRemainder = rFormulaString.copy( nBracketClose + 1 );
1744 return !rRemainder.isEmpty();
1755 mxImpl.reset(
new OoxFormulaParserImpl( *
this ) );
1764 return mxImpl->importOoxFormula( rBaseAddress, rFormulaString );
1769 return mxImpl->importBiff12Formula( rBaseAddress, eType, rStrm );
1774 sal_Int32 nRefId = -1;
1775 OUString aRemainder;
1776 if( lclExtractRefId( nRefId, aRemainder, rFormulaString ) && (aRemainder.getLength() >= 3) &&
1777 (aRemainder[ 0 ] ==
'!') && (aRemainder[ 1 ] ==
'\'') && (aRemainder[ aRemainder.getLength() - 1 ] ==
'\'') )
1778 return mxImpl->resolveOleTarget( nRefId,
false );
1784 OUString aTargetLink;
1785 sal_Int32 nFmlaSize = rStrm.
readInt32();
1786 sal_Int64 nFmlaEndPos = rStrm.
tell() + ::std::max< sal_Int32 >( nFmlaSize, 0 );
1793 aTargetLink =
mxImpl->resolveOleTarget( nRefId,
true );
1795 rStrm.
seek( nFmlaEndPos );
1823 sal_Int32 nRefId = -1;
1824 OUString aRemainder;
1825 if( lclExtractRefId( nRefId, aRemainder, rFormulaString ) && (aRemainder.getLength() > 1) && (aRemainder[ 0 ] ==
'!') )
1838 OSL_ENSURE( pExtLink,
"FormulaParser::importMacroName - missing link" );
1843 OUString aMacroName = aRemainder.copy( 1 );
1845 if( !pDefName || pDefName->
isVBName() )
Helper class to provide access to global workbook data.
sal_Int32 OPCODE_EXTERNAL
Internal: function name unknown to mapper.
const sal_uInt8 BIFF_TOKID_MEMNOMEM
Deleted reference subexpression.
const sal_uInt8 BIFF_TOKID_AREA
2D cell reference.
sal_Int32 OPCODE_OPEN
Function style #NAME? error.
Iterator working on the mpParamInfos member of the FunctionInfo struct.
const sal_uInt8 BIFF_TOKID_UPLUS
Range operator.
BinSingleRef2d maRef2
Start (top-left) cell address.
const sal_uInt8 BIFF_TOKID_AREAN
Relative 2D cell reference (in names).
ExternalLinkRef getExternalLink(sal_Int32 nRefId, bool bUseRefSheets=true) const
Returns the external link for the passed reference identifier.
const sal_uInt8 BIFF_ERR_NA
sal_Int32 OPCODE_CLOSE
Opening parenthesis.
Condition of a conditional format rule.
const sal_uInt8 BIFF_TOKID_ARRAY
Floating-point constant.
const sal_uInt8 BIFF_TOK_ATTR_SKIP
Jump array of CHOOSE function.
void push_back(const ApiToken &rToken)
A 2D cell address struct for binary filters.
const sal_uInt8 BIFF_TOK_ATTR_SPACE_SP_CLOSE
Line breaks before opening parenthesis.
const sal_uInt8 BIFF_TOKID_REF3D
External reference.
sal_Int32 OPCODE_MACRO
DDE link function.
Simple cell formula, or reference to a shared formula name.
const sal_uInt8 BIFF_TOKID_LIST
Intersection operator.
const sal_uInt8 BIFF_TOKID_LT
String concatenation operator.
Link refers to the current sheet.
static double calcDoubleFromError(sal_uInt8 nErrorCode)
Converts the passed BIFF error to a double containing the respective Calc error code.
Contains all API op-codes needed to build formulas with tokens.
sal_Int32 getLastSheet() const
const sal_uInt8 BIFF_ERR_REF
const FunctionInfo * getFuncInfoFromApiToken(const ApiToken &rToken) const
Returns the function info for an API token, or 0 on error.
const sal_uInt8 BIFF_TOKID_MEMFUNC
Constant reference subexpression without result.
const sal_uInt8 BIFF_TOK_ATTR_SPACE_BR
Spaces before next token.
const sal_uInt8 BIFF_TOKID_NE
Greater than operator.
OUString maExtProgName
Expected macro name in EXTERN.CALL function.
DefinedNameRef getByModelName(const OUString &rModelName, sal_Int16 nCalcSheet=-1) const
Returns a defined name by its model name.
const sal_uInt16 BIFF_FUNC_ROWS
Function identifier of the FALSE function.
Link refers to an external add-in.
const sal_uInt8 BIFF_ERR_NAME
const sal_uInt8 BIFF_TOKCLASS_VAL
20-3F: Reference class tokens.
css::sheet::FormulaToken ApiToken
const sal_uInt8 BIFF_TOKID_REF
Defined name.
const sal_uInt8 BIFF_TOKID_EXP
Placeholder for invalid token id.
const sal_uInt8 BIFF_TOKID_FUNCVAR
Function, fixed number of arguments.
const sal_uInt8 BIFF_TOKID_REFERR3D
3D area reference.
const sal_uInt8 BIFF_TOK_ATTR_SPACE_BR_CLOSE
Spaces before closing parenthesis.
sal_Int32 OPCODE_PUSH
External function call (e.g. add-ins).
sal_Int32 OPCODE_MISSING
Op-code for common value operands.
css::uno::Any & append(sal_Int32 nOpCode)
Appends a new token with the passed op-code, returns its data field.
const sal_uInt16 BIFF12_TOK_TABLE_DATA
Table reference: Special [#Headers] range.
const sal_uInt16 BIFF_FUNC_EXTERNCALL
Function identifier of the OFFSET function.
ExternalLinkType getLinkType() const
Returns the type of this external link.
Base class for defined names and external names.
const sal_uInt8 BIFF_TOKID_MEMERR
Constant reference subexpression.
Represents information for a spreadsheet function.
const sal_uInt8 BIFF_TOKID_PERCENT
Unary minus.
std::shared_ptr< Table > TableRef
const FunctionInfo * getFuncInfoFromOoxFuncName(const OUString &rFuncName) const
Returns the function info for an OOXML function name, or 0 on error.
const sal_uInt16 BIFF_FUNC_TRUE
Function identifier of the SUM function.
::oox::core::FilterBase & getBaseFilter() const
Returns the base filter object (base class of all filters).
const sal_uInt8 BIFF_TOK_ARRAY_BOOL
String value in an array.
const OUString & getModelName() const
Returns the original name as imported from or exported to the file.
const sal_uInt8 BIFF_TOKID_NAMEX
const sal_uInt16 BIFF_FUNC_WEEKNUM
Function identifier of the HYPERLINK function.
Just for round-tripping (FIXME: Functionality not actually implemented after all.) ...
const sal_uInt8 BIFF_TOKID_SUB
Addition operator.
sal_uInt16 mnBiff12FuncId
API function opcode.
bool isVBName() const
Returns true, if this defined name is a reference to a VBA macro.
const sal_uInt16 BIFF12_TOK_TABLE_COLUMN
True = row is relative.
bool getFlag(Type nBitField, Type nMask)
const sal_uInt8 BIFF_TOKID_FUNC
Array constant.
sal_Int32 OPCODE_SEP
Closing parenthesis.
virtual sal_Int64 tell() const override
const sal_uInt8 BIFF_TOK_ATTR_CHOOSE
Start of true condition in IF function.
Provides access to API op-codes for all available formula tokens and to function info structs for all...
void setFlag(Type &ornBitField, Type nMask, bool bSet=true)
sal_Int32 OPCODE_ARRAY_OPEN
Function parameter separator.
const sal_uInt8 BIFF_TOKID_REFN
Deleted 2D area reference.
sal_Int32 OPCODE_NAME
Spaces between other formula tokens.
A 2D formula cell range reference struct with relative flags.
const sal_uInt8 BIFF_TOKID_CONCAT
Power operator.
css::beans::Pair< css::table::CellAddress, sal_Bool > ApiSpecialTokenInfo
Contains the base address and type of a special token representing an array formula or a shared formu...
const sal_uInt8 BIFF_TOKID_DIV
Multiplication operator.
ExternalLinkBuffer & getExternalLinks() const
Returns the external links read from the external links substream.
const sal_uInt8 BIFF_TOKID_AREAERR3D
Deleted 3D cell reference.
const sal_uInt16 BIFF_FUNC_FLOOR
BIFF function id of the EXTERN.CALL function.
const sal_uInt8 BIFF_TOKID_ERR
End of a sheet reference (BIFF2-BIFF4).
Shared formula definition.
sal_Int32 OPCODE_ARRAY_CLOSE
Opening brace for constant arrays.
const sal_uInt8 BIFF_TOKID_ISECT
Not equal operator.
const sal_uInt8 BIFF_TOKID_MEMAREA
2D area reference.
sal_Int32 OPCODE_SPACES
Placeholder for a missing function parameter.
sal_Int32 OPCODE_NONAME
Bad token (unknown name, formula error).
const sal_uInt8 BIFF_TOK_BOOL_FALSE
Error code in an array.
const sal_uInt8 BIFF_TOKID_GE
Equal operator.
const sal_uInt8 BIFF_TOK_ARRAY_STRING
Double value in an array.
const sal_uInt8 BIFF_TOKID_MEMAREAN
Relative 2D area reference (in names).
const sal_uInt8 BIFF_TOKID_LE
Less than operator.
bool is3dRange() const
Returns true, if the sheet indexes are valid and different.
const OUString & getTargetUrl() const
Returns the target URL of this external link.
const sal_uInt8 BIFF_TOKID_AREA3D
3D cell reference.
const sal_uInt8 BIFF_TOK_ATTR_IFERROR
Leading spaces and volatile formula.
const sal_uInt8 BIFF_TOKID_MISSARG
Parentheses.
sal_Int32 OPCODE_DDE
Natural language reference.
sal_Int32 getDocLinkIndex() const
const sal_uInt8 BIFF_TOKID_NAME
Function, variable number of arguments.
sal_Int32 mnApiOpCode
The external library this function is part of.
const sal_uInt8 BIFF_TOKID_NUM
Integer constant.
sal_Int32 mnRow
Column index.
ApiTokenSequence toSequence() const
Converts to a sequence.
const sal_uInt8 BIFF_TOK_FUNCVAR_COUNTMASK
User prompt for macro commands.
css::uno::Sequence< ApiToken > ApiTokenSequence
const sal_uInt16 BIFF12_TOK_TABLE_HEADERS
Table reference: Special [#All] range.
const sal_uInt8 BIFF_TOKID_MEMNOMEMN
Reference subexpression (in names).
const sal_uInt8 BIFF_TOKCLASS_NONE
sal_Int32 getFirstSheet() const
const sal_uInt16 BIFF12_TOK_TABLE_COLRANGE
Table reference: Single column.
const sal_uInt8 BIFF_TOKID_UMINUS
Unary plus.
const sal_uInt16 BIFF_TOK_FUNCVAR_CMD
Spaces before formula (BIFF3).
sal_Int64 getRemaining() const
const sal_uInt8 BIFF_TOKID_INT
Boolean constant.
const sal_uInt16 BIFF12_TOK_TABLE_TOTALS
Table reference: Special [#Data] range.
sal_uInt16 mnBiffFuncId
BIFF12 function identifier.
const sal_uInt8 BIFF_TOK_ARRAY_DOUBLE
Deleted 3D area reference.
const sal_uInt16 BIFF_FUNC_FALSE
Function identifier of the TRUE function.
virtual void seek(sal_Int64 nPos) override
#define SAL_WARN_IF(condition, area, stream)
std::shared_ptr< DefinedName > DefinedNameRef
const sal_uInt8 BIFF_TOKID_STR
Missing argument.
sal_Int32 OPCODE_BAD
Macro function call.
const sal_uInt8 BIFF_TOK_ATTR_SPACE
BASIC style assignment.
const sal_uInt8 BIFF_TOK_ATTR_SPACE_SP_OPEN
Line breaks before next token.
const sal_uInt16 BIFF_FUNC_SUM
Function identifier of the IF function.
const sal_uInt8 BIFF_TOKID_MASK
This bit must be null for a valid token identifier.
const sal_uInt8 BIFF_TOK_ATTR_VOLATILE
TRUE value of a tBool token.
const FunctionInfo * getFuncInfoFromBiff12FuncId(sal_uInt16 nFuncId) const
Returns the function info for a BIFF12 function index, or 0 on error.
const sal_uInt8 BIFF_TOK_ARRAY_ERROR
Boolean value in an array.
const sal_uInt8 BIFF_TOKID_PAREN
Percent sign.
OUString maOoxFuncName
ODF function name.
const sal_uInt16 BIFF_FUNC_IF
Maximum parameter count for BIFF2-BIFF8 files.
bool mbRowRel
True = relative column reference.
const sal_uInt8 BIFF_TOK_ATTR_SPACE_BR_OPEN
Spaces before opening parenthesis.
const sal_uInt8 BIFF_TOK_ATTR_IF
Volatile function.
const sal_uInt8 BIFF_TOKID_ATTR
Natural language reference (NLR).
bool isExternal() const
Returns true, if the sheet range points to an external document.
const sal_uInt16 BIFF_FUNC_CEILING
Function identifier of the FLOOR function.
const sal_uInt8 BIFF_TOKID_RANGE
List operator.
const sal_uInt8 BIFF_TOKID_MUL
Subtraction operator.
const sal_uInt16 BIFF_FUNC_OFFSET
Function identifier of the COLUMNS function.
const sal_uInt16 BIFF_FUNC_COLUMNS
Function identifier of the ROWS function.
Contains indexes for a range of sheets in the spreadsheet document.
bool isCalcOnlyParam() const
const sal_uInt16 BIFF12_TOK_TABLE_THISROW
Table reference: Special [#Totals] range.
const sal_uInt8 BIFF_TOKID_REFERR
Variable reference subexpression.
OUString getAbsoluteUrl(const OUString &rUrl) const
#define SAL_WARN(area, stream)
const sal_uInt8 BIFF_TOK_ATTR_SUM
Skip tokens.
const sal_uInt8 BIFF_TOKID_AREAERR
Deleted 2D cell reference.
bool isSameSheet() const
Returns true, if the sheet indexes are valid and different.
const sal_uInt8 BIFF_TOK_ATTR_SPACE_VOLATILE
Spaces in formula representation.
const sal_uInt8 BIFF_TOKID_BOOL
Error constant.
const sal_uInt8 BIFF_TOK_ATTR_SPACE_SP
Start of condition in IFERROR function (BIFF12 only).
const sal_uInt8 BIFF_TOKID_POWER
Division operator.
const sal_uInt8 BIFF_TOKCLASS_MASK
Maximum size of a token array.
FunctionLibraryType getFuncLibraryType() const
Returns the type of the external library if this is a library link.
std::shared_ptr< ExternalName > ExternalNameRef
const sal_uInt16 BIFF12_TOK_TABLE_ALL
Table reference: Range of columns.
const sal_uInt8 BIFF_TOKID_NLR
String constant.
const sal_uInt8 BIFF_TOKID_EQ
Less than or equal operator.
FormulaType
Function identifier of the WEEKNUM function.
bool isExcelOnlyParam() const
DefinedNamesBuffer & getDefinedNames() const
Returns the defined names read from the workbook globals.
A vector of formula tokens with additional convenience functions.
const sal_uInt8 BIFF_TOK_ATTR_ASSIGN
SUM function with one parameter.
const sal_uInt8 BIFF_TOKID_GT
Greater than or equal operator.
A 2D formula cell reference struct with relative flags.
const sal_uInt8 BIFF_TOKID_ADD
Multiple operation reference.