25#include <osl/diagnose.h>
28#include <com/sun/star/sheet/FormulaToken.hpp>
58 eOp(e),
eType( eTypeP ), mnRefCnt(0)
170 assert( !
"virtual dummy called" );
181 assert( !
"virtual dummy called" );
187 assert( !
"virtual dummy called" );
194 assert( !
"virtual dummy called" );
195 static double fVal = 0.0;
201 SAL_WARN(
"formula.core",
"FormulaToken::GetDoubleType: virtual dummy called" );
207 assert( !
"virtual dummy called" );
214 SAL_WARN(
"formula.core",
"FormulaToken::GetString: virtual dummy called" );
220 assert( !
"virtual dummy called" );
225 SAL_WARN(
"formula.core",
"FormulaToken::GetIndex: virtual dummy called" );
231 assert( !
"virtual dummy called" );
236 SAL_WARN(
"formula.core",
"FormulaToken::GetSheet: virtual dummy called" );
242 assert( !
"virtual dummy called" );
248 assert( !
"virtual dummy called" );
254 SAL_WARN(
"formula.core",
"FormulaToken::GetJump: virtual dummy called" );
261 SAL_WARN(
"formula.core",
"FormulaToken::GetExternal: virtual dummy called" );
262 static OUString aDummyString;
268 SAL_WARN(
"formula.core",
"FormulaToken::GetFAPOrigToken: virtual dummy called" );
274 SAL_WARN(
"formula.core",
"FormulaToken::GetError: virtual dummy called" );
280 assert( !
"virtual dummy called" );
285 OSL_FAIL(
"FormulaToken::GetSingleRef: virtual dummy called" );
291 OSL_FAIL(
"FormulaToken::GetSingleRef: virtual dummy called" );
297 OSL_FAIL(
"FormulaToken::GetDoubleRef: virtual dummy called" );
303 OSL_FAIL(
"FormulaToken::GetDoubleRef: virtual dummy called" );
309 OSL_FAIL(
"FormulaToken::GetSingleRef2: virtual dummy called" );
315 OSL_FAIL(
"FormulaToken::GetSingleRef2: virtual dummy called" );
321 OSL_FAIL(
"FormulaToken::GetMatrix: virtual dummy called" );
327 OSL_FAIL(
"FormulaToken::GetMatrix: virtual dummy called" );
333 OSL_FAIL(
"FormulaToken::GetJumpMatrix: virtual dummy called" );
338 OSL_FAIL(
"FormulaToken::GetRefList: virtual dummy called" );
344 OSL_FAIL(
"FormulaToken::GetRefList: virtual dummy called" );
350 return *
this == rToken;
401 const OpCode eOpCode =
static_cast<OpCode>(rToken.OpCode);
403 const uno::TypeClass eClass = rToken.Data.getValueTypeClass();
406 case uno::TypeClass_VOID:
410 case uno::TypeClass_DOUBLE:
417 case uno::TypeClass_LONG:
420 sal_Int32
nValue = rToken.Data.get<sal_Int32>();
431 case uno::TypeClass_STRING:
433 OUString aStrVal( rToken.Data.get<OUString>() );
436 else if ( eOpCode ==
ocBad )
446 if (!aStrVal.isEmpty())
464 const sal_Int32
nCount = rSequence.getLength();
482 for( sal_uInt16
i = 0;
i <
nRPN;
i++ )
501 if (0 < nIdx && nIdx <=
nLen)
502 return pCode[--nIdx];
541 if (
i->IsExternalRef())
551 if (
i->GetOpCode() == eOp)
561 if (
i->GetOpCode() == eOp)
581 if (rOpCodes.count(
i->GetOpCode()) > 0)
595 mbFromRangeName(false),
608 Move( std::move(rArr) );
623 pCode = std::move( newCode );
646 for( sal_uInt16
i = 0;
i <
nLen;
i++ )
654 for( sal_uInt16
i = 0;
i <
nRPN;
i++ )
661 pCode = std::move(r.pCode);
680 assert(
pCode ==
nullptr );
686 for( sal_uInt16
i = 0;
i <
nLen;
i++ )
708 Move( std::move(rArr) );
718 for( sal_uInt16
i = 0;
i <
nLen;
i++ )
744 for( sal_uInt16
i = 0;
i <
nRPN;
i++ )
772 for (sal_uInt16
i=0;
i <
nRPN; ++
i)
779 if (
p->GetRef() == 1)
789 t->DeleteIfZeroRef();
799 "FormulaTokenArray::RemoveToken - nOffset " << nOffset <<
" + nCount " <<
nCount <<
" > nLen " <<
nLen);
800 const sal_uInt16 nStop = ::std::min(
static_cast<sal_uInt16
>(nOffset +
nCount),
nLen);
802 for (sal_uInt16 j = nOffset; j < nStop; ++j)
807 for (sal_uInt16
i=0;
i <
nRPN; ++
i)
812 for (sal_uInt16
x=
i+1;
x <
nRPN; ++
x)
819 if (
p->GetRef() == 1)
828 for (sal_uInt16
x = nStop;
x <
nLen; ++
x)
838 SAL_WARN(
"formula.core",
"FormulaTokenArray::RemoveToken - nOffset " << nOffset <<
" >= nLen " <<
nLen);
848 t->DeleteIfZeroRef();
857 const size_t MAX_FAST_TOKENS = 32;
860 if(
nLen == MAX_FAST_TOKENS )
863 std::copy(&
pCode[0], &
pCode[MAX_FAST_TOKENS], tmp);
877 t->DeleteIfZeroRef();
926 if (nExclusive & (nExclusive - 1))
931 if (nExclusive & nExBit)
980 if ( sp >= k && pStack[sp-k]->GetType() ==
svDoubleRef )
1002 sp = sal::static_int_cast<short>( sp - nParams );
1005 SAL_WARN(
"formula.core",
"FormulaTokenArray::HasMatrixDoubleRefOps: sp < 0" );
1008 pStack[sp++] = pResult;
1085class FormulaMissingContext
1092 inline bool AddDefaultArg( FormulaTokenArray* pNewArr,
int nArg,
double f )
const;
1093 bool AddMissingExternal( FormulaTokenArray* pNewArr )
const;
1094 bool AddMissing( FormulaTokenArray *pNewArr,
const MissingConvention & rConv )
const;
1095 void AddMoreArgs( FormulaTokenArray *pNewArr,
const MissingConvention & rConv )
const;
1100void FormulaMissingContext::AddMoreArgs( FormulaTokenArray *pNewArr,
const MissingConvention & rConv )
const
1105 switch (rConv.getConvention())
1115 pNewArr->AddOpCode(
ocSep );
1116 pNewArr->AddDouble( 1.0 );
1122 pNewArr->AddOpCode(
ocSep );
1123 pNewArr->AddDouble( 1.0 );
1129 pNewArr->AddOpCode(
ocSep );
1130 pNewArr->AddDouble( 1.0 );
1137 pNewArr->AddOpCode(
ocSep );
1138 pNewArr->AddDouble( 0.0 );
1142 pNewArr->AddOpCode(
ocSep );
1143 pNewArr->AddDouble( 1.0 );
1147 if ( rConv.isPODF() &&
mnCurArg == 0 )
1149 pNewArr->AddOpCode(
ocSep );
1150 pNewArr->AddDouble( 10.0 );
1166 pNewArr->AddOpCode(
ocSep );
1167 pNewArr->AddOpCode(
ocTrue );
1168 pNewArr->AddOpCode(
ocOpen );
1169 pNewArr->AddOpCode(
ocClose );
1176 pNewArr->AddOpCode(
ocSep );
1177 pNewArr->AddDouble( 0.0 );
1184 pNewArr->AddOpCode(
ocSep );
1185 pNewArr->AddDouble( 1.0 );
1194 pNewArr->AddOpCode(
ocSep );
1195 pNewArr->AddDouble( 1.0 );
1203 pNewArr->AddOpCode(
ocSep );
1204 pNewArr->AddDouble( 0.0 );
1208 pNewArr->AddOpCode(
ocSep );
1209 pNewArr->AddDouble( 1.0 );
1216 pNewArr->AddOpCode(
ocSep );
1217 pNewArr->AddDouble( 0.0 );
1227 pNewArr->AddOpCode(
ocSep );
1228 pNewArr->AddDouble( 0.0 );
1241inline bool FormulaMissingContext::AddDefaultArg( FormulaTokenArray* pNewArr,
int nArg,
double f )
const
1245 pNewArr->AddDouble( f );
1251bool FormulaMissingContext::AddMissingExternal( FormulaTokenArray *pNewArr )
const
1258 sal_Int32
nLength = rName.getLength();
1263 if ( nLastChar !=
't' && nLastChar !=
'm' )
1266 if (rName.equalsIgnoreAsciiCase(
1267 "com.sun.star.sheet.addin.Analysis.getAccrint" ))
1269 return AddDefaultArg( pNewArr, 4, 1000.0 );
1271 if (rName.equalsIgnoreAsciiCase(
1272 "com.sun.star.sheet.addin.Analysis.getAccrintm" ))
1274 return AddDefaultArg( pNewArr, 3, 1000.0 );
1279bool FormulaMissingContext::AddMissing( FormulaTokenArray *pNewArr,
const MissingConvention & rConv )
const
1287 switch (rConv.getConvention())
1295 return AddDefaultArg( pNewArr, 2, 1.0 );
1307 return AddDefaultArg( pNewArr, 2, 1.0 );
1309 return AddDefaultArg( pNewArr, 1, 2.0 );
1313 return AddDefaultArg( pNewArr, 3, 0.0 );
1316 return AddDefaultArg( pNewArr, 4, 0.0 );
1319 bRet |= AddDefaultArg( pNewArr, 2, 0.0 );
1320 bRet |= AddDefaultArg( pNewArr, 3, 0.0 );
1323 bRet |= AddDefaultArg( pNewArr, 1, 0.0 );
1324 bRet |= AddDefaultArg( pNewArr, 3, 0.0 );
1325 bRet |= AddDefaultArg( pNewArr, 4, 0.0 );
1328 return AddMissingExternal( pNewArr );
1346 return AddMissingExternal( pNewArr );
1380 const size_t nAlloc = 256;
1381 FormulaMissingContext aCtx[ nAlloc ];
1387 int aOpCodeAddressStack[ nAlloc ];
1388 const int nOmitAddressArg = 3;
1390 int aOpCodeDcountStack[ nAlloc ];
1391 const int nOmitDcountArg = 1;
1393 sal_uInt16 nTokens =
GetLen() + 1;
1394 FormulaMissingContext* pCtx = (nAlloc < nTokens ?
new FormulaMissingContext[nTokens] : &aCtx[0]);
1395 int* pOcas = (nAlloc < nTokens ?
new int[nTokens] : &aOpCodeAddressStack[0]);
1396 int* pOcds = (nAlloc < nTokens ?
new int[nTokens] : &aOpCodeDcountStack[0]);
1416 for (
int i = nOcas;
i-- > 0 && bAdd; )
1418 if (pCtx[ pOcas[
i ] ].
mnCurArg == nOmitAddressArg)
1423 if (pOcas[
i ] != nFn || pCur->GetOpCode() !=
ocSep)
1429 for (
int i = nOcds;
i-- > 0 && bAdd; )
1431 if (pCtx[ pOcds[
i ] ].
mnCurArg == nOmitDcountArg)
1434 if (pOcds[
i ] == nFn && pCur->GetOpCode() ==
ocPush && pCur->GetType() ==
svDouble &&
1435 pCur->GetDouble() == 0.0)
1439 if (
p &&
p->GetOpCode() ==
ocSep)
1442 if (
p &&
p->GetOpCode() ==
ocSep)
1448 switch ( pCur->GetOpCode() )
1454 pCtx[ nFn ].mnCurArg = 0;
1455 if (rConv.
isPODF() && pCtx[ nFn ].mpFunc && pCtx[ nFn ].mpFunc->GetOpCode() ==
ocAddress)
1456 pOcas[ nOcas++ ] = nFn;
1457 else if ((rConv.
isODFF() || rConv.
isOOXML()) && pCtx[ nFn ].mpFunc)
1461 pOcds[ nOcds++ ] = nFn;
1466 pCtx[ nFn ].AddMoreArgs( pNewArr, rConv );
1467 SAL_WARN_IF(nFn <= 0,
"formula.core",
"FormulaTokenArray::RewriteMissing: underflow");
1468 if (nOcas > 0 && pOcas[ nOcas-1 ] == nFn)
1470 else if (nOcds > 0 && pOcds[ nOcds-1 ] == nFn)
1476 pCtx[ nFn ].mnCurArg++;
1478 if (nOcas && pOcas[ nOcas-1 ] == nFn && pCtx[ nFn ].
mnCurArg == nOmitAddressArg)
1485 bAdd = !pCtx[ nFn ].AddMissing( pNewArr, rConv );
1492 OpCode eOp = pCur->GetOpCode();
1513 pNewArr->
Add( pToken );
1519 pNewArr->
Add( pToken );
1526 if (pOcds != &aOpCodeDcountStack[0])
1528 if (pOcas != &aOpCodeAddressStack[0])
1530 if (pCtx != &aCtx[0])
1546 sal_uInt16
i =
nLen - 1;
1603 switch (
i->GetType())
1606 i->SetString( rPool.
intern(
i->GetString().getString()));
1618 pArr(pArray), nPC(
pc), nStop(
stop)
1655 while ( mnIndex < mpFTA->
GetLen() )
1679 short nIdx =
maStack.back().nPC;
1683 if (
t ==
nullptr ||
t->GetOpCode() !=
ocPush)
1701 if( nStart != nNext )
1719 if (nIdx < cur.pArr->GetCodeLen() && nIdx < cur.
nStop)
1723 return (
t->GetOpCode() ==
ocSep ||
t->GetOpCode() ==
ocClose) ? nullptr :
t;
1735 while( mnIndex < mpFTA->
GetLen() )
1738 switch(
t->GetType() )
1756 while( mnIndex < mpFTA->
GetLen() )
1767 while( mnIndex < mpFTA->GetCodeLen() )
1770 switch(
t->GetType() )
1791 while ( mnIndex < mpFTA->
GetLen() )
1794 switch(
t->GetType() )
1826 if( mnIndex < mpFTA->
GetLen() )
1834 if(
mpFTA->
GetCode() && mnIndex < mpFTA->GetCodeLen() )
1863 if ( j < mpFTA->
GetLen() )
1890 const sal_uInt16 nStop = std::min(
static_cast<sal_uInt16
>(nOffset +
nCount),
mpFTA->
GetLen());
SharedString intern(const OUString &rStr)
static const SharedString & getEmptyString()
#define SC_OPCODE_STOP_BIN_OP
#define SC_OPCODE_STOP_1_PAR
#define SC_OPCODE_START_2_PAR
#define SC_OPCODE_STOP_UN_OP
#define SC_OPCODE_START_UN_OP
#define SC_OPCODE_STOP_2_PAR
#define SC_OPCODE_STOP_NO_PAR
#define SC_OPCODE_STOP_DIV
#define SC_OPCODE_START_1_PAR
#define SC_OPCODE_START_NO_PAR
#define SC_OPCODE_START_BIN_OP
#define SAL_WARN_IF(condition, area, stream)
#define SAL_WARN(area, stream)
bool isWhitespace(sal_Unicode c)
void Clear(EHistoryType eHistory)
tools::Long GetLen(const Point &rPnt)
const FormulaToken * mpFunc