20#include <config_features.h>
22#include <compiler.hxx>
37#include <osl/diagnose.h>
38#include <rtl/character.hxx>
41#include <com/sun/star/lang/Locale.hpp>
42#include <com/sun/star/sheet/FormulaOpCodeMapEntry.hpp>
43#include <com/sun/star/sheet/FormulaLanguage.hpp>
44#include <com/sun/star/i18n/KParseTokens.hpp>
45#include <com/sun/star/i18n/KParseType.hpp>
50#include <rtl/math.hxx>
51#include <rtl/ustring.hxx>
55#include <document.hxx>
72#include <tokenarray.hxx>
75#include <officecfg/Office/Common.hxx>
105static const char*
pInternal[2] = {
"TTT",
"__DEBUG_VAR" };
111 size_t nSymbolOffset;
116 case FormulaGrammar::GRAM_API:
117 case FormulaGrammar::GRAM_PODF:
118 nSymbolOffset = offsetof(
AddInMap, pUpper);
121 case FormulaGrammar::GRAM_ODFF:
122 nSymbolOffset = offsetof(
AddInMap, pODFF);
124 case FormulaGrammar::GRAM_ENGLISH:
125 nSymbolOffset = offsetof(
AddInMap, pEnglish);
131 char const *
const * ppSymbol =
132 reinterpret_cast< char const *
const *
>(
133 reinterpret_cast< char const *
>(pMap) + nSymbolOffset);
134 xMap->putExternal( OUString::createFromAscii( *ppSymbol),
135 OUString::createFromAscii( pMap->pOriginal));
137 if (_eGrammar == FormulaGrammar::GRAM_API)
143 nSymbolOffset = offsetof(
AddInMap, pEnglish);
146 char const *
const * ppSymbol =
147 reinterpret_cast< char const *
const *
>(
148 reinterpret_cast< char const *
>(pMap) + nSymbolOffset);
149 xMap->putExternal( OUString::createFromAscii( *ppSymbol),
150 OUString::createFromAscii( pMap->pOriginal));
178 if (!
aName.isEmpty())
221 return !aIntName.isEmpty();
262 assert( eGrammar != FormulaGrammar::GRAM_UNSPECIFIED &&
"ScCompiler::SetGrammar: don't pass FormulaGrammar::GRAM_UNSPECIFIED");
266 if( eGrammar == FormulaGrammar::GRAM_EXTERNAL )
274 const sal_Int32 nFormulaLanguage = FormulaGrammar::extractFormulaLanguage( eMyGrammar);
276 OSL_ENSURE( xMap,
"ScCompiler::SetGrammar: unknown formula language");
280 eMyGrammar = xMap->getGrammar();
301 if (rTabNames.empty())
304 for (
auto& rTabName : rTabNames)
344 if (eConv == FormulaGrammar::CONV_UNSPECIFIED && eOldGrammar == FormulaGrammar::GRAM_UNSPECIFIED)
369 for (
i = 0;
i < 128;
i++)
380 if (FormulaGrammar::CONV_ODF ==
meConv)
385 if (FormulaGrammar::CONV_ODF ==
meConv)
399 for (
i = 48;
i < 58;
i++)
410 for (
i = 65;
i < 91;
i++)
413 if (FormulaGrammar::CONV_ODF ==
meConv)
419 else if (FormulaGrammar::CONV_OOO ==
meConv)
425 else if (FormulaGrammar::CONV_XL_OOX ==
meConv)
431 else if (FormulaGrammar::CONV_XL_A1 ==
meConv)
437 else if( FormulaGrammar::CONV_XL_R1C1 ==
meConv )
454 for (
i = 97;
i < 123;
i++)
463 if( !(FormulaGrammar::CONV_XL_A1 ==
meConv || FormulaGrammar::CONV_XL_R1C1 ==
meConv || FormulaGrammar::CONV_XL_OOX ==
meConv) )
508 while (
nPos < rFormula.size())
510 if (rFormula[
nPos] ==
'\'')
512 if ( (
nPos+1 == rFormula.size()) || (rFormula[
nPos+1] !=
'\'') )
514 rRes.TokenType = KParseType::SINGLE_QUOTE_NAME;
515 rRes.EndPos =
nPos+1;
528 const OUString& rSymbol,
533 const uno::Sequence<sheet::ExternalLinkInfo>* pExternalLinks )
537 const sal_Unicode*
const pStart = rSymbol.getStr();
539 sal_Int32 nLen = rSymbol.getLength();
541 OUStringBuffer aTmpName;
543 bool bInName =
false;
549 OUString aStartTabName, aEndTabName;
552 aEndTabName, nFlags,
true, pExternalLinks );
553 if (!
p ||
p == pStart)
555 i = sal_Int32(
p - pStart);
557 for ( ;
i < nLen; ++
i, ++
p)
562 if (c ==
'.' || c == cSep)
571 for (sal_Int32 j =
i; j < nLen; ++j, ++
p)
586 aTmpFile += OUStringChar(c);
595 if (cPrev ==
'\'' && j !=
i)
607 aTmpFile += OUStringChar(c);
647 if (rtl::isAsciiAlphanumeric(c))
671 aTmpFile += OUStringChar(c);
682 sal_Int32 nNameLen = aTmpName.getLength();
689 if (aTmpName[0] != cSep)
695 if (aTmpName[nNameLen-1] ==
'!')
703 rName = aTmpName.makeStringAndClear().copy(1);
710 OUString aEscQuote(
"''");
711 OUString aFile(rFile.replaceAll(
"'", aEscQuote));
712 OUString
aName(rName);
715 OUStringBuffer
aBuf(aFile.getLength() +
aName.getLength() + 9);
718 aBuf.append(
"'" + aFile +
"'" + OUStringChar(cSep) );
720 aBuf.append(
"$$'" );
724 return aBuf.makeStringAndClear();
728 const vector<OUString>& rTabNames,
const ScRange& rRef )
733 size_t nCount = rTabNames.size();
734 vector<OUString>::const_iterator itrBeg = rTabNames.begin(), itrEnd = rTabNames.end();
735 vector<OUString>::const_iterator itr = ::std::find(itrBeg, itrEnd, rTabName1);
736 if (itr == rTabNames.end())
738 rTabName2 =
ScResId(STR_NO_REF_TABLE);
742 size_t nDist = ::std::distance(itrBeg, itr);
743 if (nDist +
static_cast<size_t>(nTabSpan) >=
nCount)
745 rTabName2 =
ScResId(STR_NO_REF_TABLE);
749 rTabName2 = rTabNames[nDist+nTabSpan];
752 rTabName2 = rTabName1;
762 static void MakeColStr(
const ScSheetLimits& rLimits, OUStringBuffer& rBuffer,
SCCOL nCol );
763 static void MakeRowStr(
const ScSheetLimits& rLimits, OUStringBuffer& rBuffer,
SCROW nRow );
765 ParseResult parseAnyToken(
const OUString& rFormula,
768 bool bGroupSeparator)
const override
774 constexpr sal_Int32 nStartFlags = KParseTokens::ANY_LETTER_OR_NUMBER |
775 KParseTokens::ASC_UNDERSCORE | KParseTokens::ASC_DOLLAR;
776 constexpr sal_Int32 nContFlags = nStartFlags | KParseTokens::ASC_DOT;
778 static constexpr OUStringLiteral aAddAllowed(u
"?#");
780 nSrcPos, nStartFlags, aAddAllowed,
781 (bGroupSeparator ? nContFlags | KParseTokens::GROUP_SEPARATOR_IN_NUMBER : nContFlags),
787 return mpCharTable[
static_cast<sal_uInt8>(c)];
793void Convention_A1::MakeColStr(
const ScSheetLimits& rLimits, OUStringBuffer& rBuffer,
SCCOL nCol )
796 rBuffer.append(
ScResId(STR_NO_REF_TABLE));
801void Convention_A1::MakeRowStr(
const ScSheetLimits& rLimits, OUStringBuffer& rBuffer,
SCROW nRow )
804 rBuffer.append(
ScResId(STR_NO_REF_TABLE));
806 rBuffer.append(sal_Int32(nRow + 1));
811struct ConventionOOO_A1 :
public Convention_A1
816 static void MakeTabStr( OUStringBuffer &rBuf,
const std::vector<OUString>& rTabNames,
SCTAB nTab )
819 rBuf.append(
ScResId(STR_NO_REF_TABLE));
821 rBuf.append(rTabNames[nTab]);
825 enum SingletonDisplay
832 static void MakeOneRefStrImpl(
834 std::u16string_view rErrRef,
const std::vector<OUString>& rTabNames,
836 bool bForceTab,
bool bODF, SingletonDisplay eSingletonDisplay )
844 rBuffer.append(rErrRef);
851 MakeTabStr(rBuffer, rTabNames, rAbsRef.
Tab());
857 if (eSingletonDisplay != SINGLETON_ROW)
862 rBuffer.append(rErrRef);
864 MakeColStr(rLimits, rBuffer, rAbsRef.
Col());
867 if (eSingletonDisplay != SINGLETON_COL)
872 rBuffer.append(rErrRef);
874 MakeRowStr(rLimits, rBuffer, rAbsRef.
Row());
884 return SINGLETON_NONE;
888 return SINGLETON_COL;
892 if (!bFromRangeName && rAbs1.
Row() == 0 && rAbs2.
Row() == rLimits.
mnMaxRow &&
894 return SINGLETON_COL;
898 return SINGLETON_ROW;
902 if (!bFromRangeName && rAbs1.
Col() == 0 && rAbs2.
Col() == rLimits.
mnMaxCol &&
904 return SINGLETON_ROW;
906 return SINGLETON_NONE;
909 virtual void makeRefStr(
911 OUStringBuffer& rBuffer,
914 const OUString& rErrRef,
const std::vector<OUString>& rTabNames,
917 bool bFromRangeName )
const override
925 SingletonDisplay eSingleton = bSingleRef ? SINGLETON_NONE :
926 getSingletonDisplay( rLimits, aAbs1, aAbs2, rRef, bFromRangeName);
927 MakeOneRefStrImpl(rLimits, rBuffer, rErrRef, rTabNames, rRef.
Ref1, aAbs1,
false,
false, eSingleton);
931 MakeOneRefStrImpl(rLimits, rBuffer, rErrRef, rTabNames, rRef.
Ref2, aAbs2, aAbs1.
Tab() != aAbs2.Tab(),
false,
936 virtual sal_Unicode getSpecialSymbol( SpecialSymbolType eSymType )
const override
949 virtual bool parseExternalName(
const OUString& rSymbol, OUString& rFile, OUString& rName,
951 const uno::Sequence<sheet::ExternalLinkInfo>* pExternalLinks )
const override
956 virtual OUString makeExternalNameStr( sal_uInt16 ,
const OUString& rFile,
957 const OUString& rName )
const override
962 static bool makeExternalSingleRefStr(
964 OUStringBuffer& rBuffer,
const OUString& rFileName,
const OUString& rTabName,
976 rBuffer.append(
"'" + aFile.replaceAll(
"'",
"''") +
"'#");
987 MakeColStr( rLimits, rBuffer, aAbsRef.
Col());
990 MakeRowStr( rLimits, rBuffer, aAbsRef.
Row());
995 static void makeExternalRefStrImpl(
997 OUStringBuffer& rBuffer,
const ScAddress& rPos,
const OUString& rFileName,
1001 rBuffer.append(
'[');
1003 bool bEncodeUrl = bODF;
1004 makeExternalSingleRefStr(rLimits, rBuffer, rFileName, rTabName, rRef, rPos,
true, bEncodeUrl);
1006 rBuffer.append(
']');
1009 virtual void makeExternalRefStr(
1011 OUStringBuffer& rBuffer,
const ScAddress& rPos, sal_uInt16 ,
const OUString& rFileName,
1012 const OUString& rTabName,
const ScSingleRefData& rRef )
const override
1014 makeExternalRefStrImpl(rLimits, rBuffer, rPos, rFileName, rTabName, rRef,
false);
1017 static void makeExternalRefStrImpl(
1019 OUStringBuffer& rBuffer,
const ScAddress& rPos,
const OUString& rFileName,
1020 const std::vector<OUString>& rTabNames,
const OUString& rTabName,
1026 rBuffer.append(
'[');
1028 bool bEncodeUrl = bODF;
1032 if (!makeExternalSingleRefStr(rLimits, rBuffer, rFileName, rTabName, rRef.
Ref1, rPos,
true, bEncodeUrl))
1035 rBuffer.append(
':');
1037 OUString aLastTabName;
1039 if (bDisplayTabName)
1044 OSL_FAIL(
"ConventionOOO_A1::makeExternalRefStrImpl: sheet name not found");
1049 rBuffer.append(
'.');
1050 makeExternalSingleRefStr(rLimits,
1051 rBuffer, rFileName, aLastTabName, rRef.
Ref2, rPos, bDisplayTabName, bEncodeUrl);
1055 rBuffer.append(
']');
1058 virtual void makeExternalRefStr(
1060 OUStringBuffer& rBuffer,
const ScAddress& rPos, sal_uInt16 ,
const OUString& rFileName,
1061 const std::vector<OUString>& rTabNames,
const OUString& rTabName,
1064 makeExternalRefStrImpl(rLimits, rBuffer, rPos, rFileName, rTabNames, rTabName, rRef,
false);
1068struct ConventionOOO_A1_ODF :
public ConventionOOO_A1
1070 ConventionOOO_A1_ODF() : ConventionOOO_A1 (
FormulaGrammar::CONV_ODF) { }
1072 virtual void makeRefStr(
1074 OUStringBuffer& rBuffer,
1077 const OUString& rErrRef,
const std::vector<OUString>& rTabNames,
1080 bool bFromRangeName )
const override
1082 rBuffer.append(
'[');
1092 rBuffer.append(rErrRef);
1099 SingletonDisplay eSingleton = bSingleRef ? SINGLETON_NONE :
1100 getSingletonDisplay( rLimits, aAbs1, aAbs2, rRef, bFromRangeName);
1101 MakeOneRefStrImpl(rLimits, rBuffer, rErrRef, rTabNames, rRef.
Ref1, aAbs1,
false,
true, eSingleton);
1104 rBuffer.append(
':');
1105 MakeOneRefStrImpl(rLimits, rBuffer, rErrRef, rTabNames, rRef.
Ref2, aAbs2, aAbs1.
Tab() != aAbs2.Tab(),
true,
1109 rBuffer.append(
']');
1112 virtual OUString makeExternalNameStr( sal_uInt16 ,
const OUString& rFile,
1113 const OUString& rName )
const override
1118 virtual void makeExternalRefStr(
1120 OUStringBuffer& rBuffer,
const ScAddress& rPos, sal_uInt16 ,
const OUString& rFileName,
1121 const OUString& rTabName,
const ScSingleRefData& rRef )
const override
1123 makeExternalRefStrImpl(rLimits, rBuffer, rPos, rFileName, rTabName, rRef,
true);
1126 virtual void makeExternalRefStr(
1128 OUStringBuffer& rBuffer,
const ScAddress& rPos, sal_uInt16 ,
const OUString& rFileName,
1129 const std::vector<OUString>& rTabNames,
1132 makeExternalRefStrImpl(rLimits, rBuffer, rPos, rFileName, rTabNames, rTabName, rRef,
true);
1138 virtual ~ConventionXL()
1144 const ScAddress& rPos,
const std::vector<OUString>& rTabNames,
1150 rTabName =
ScResId( STR_NO_REF_TABLE );
1153 rTabName = rTabNames[aAbs.
Tab()];
1156 static void MakeTabStr(
const ScSheetLimits& rLimits, OUStringBuffer& rBuf,
1158 const std::vector<OUString>& rTabNames,
1165 OUString aStartTabName, aEndTabName;
1167 GetTab(rLimits, rPos, rTabNames, rRef.
Ref1, aStartTabName);
1171 GetTab(rLimits, rPos, rTabNames, rRef.
Ref2, aEndTabName);
1174 rBuf.append( aStartTabName );
1175 if( !bSingleRef && rRef.
Ref2.
IsFlag3D() && aStartTabName != aEndTabName )
1178 rBuf.append( aEndTabName );
1196 static bool parseExternalName(
const OUString& rSymbol, OUString& rFile, OUString& rName,
1198 const uno::Sequence<sheet::ExternalLinkInfo>* pExternalLinks )
1203 static OUString makeExternalNameStr(
const OUString& rFile,
const OUString& rName )
1208 static void makeExternalDocStr( OUStringBuffer& rBuffer, std::u16string_view rFullName )
1217 rBuffer.append(
'[');
1218 rBuffer.append(
'\'');
1222 sal_Int32 nLen = aFullName.getLength();
1223 for (sal_Int32 i = 0;
i < nLen; ++
i)
1230 rBuffer.append(
'\'');
1231 rBuffer.append(
']');
1234 static void makeExternalTabNameRange( OUStringBuffer& rBuf,
const OUString& rTabName,
1235 const vector<OUString>& rTabNames,
1238 OUString aLastTabName;
1246 if (rTabName != aLastTabName)
1253 virtual void parseExternalDocName(
const OUString& rFormula, sal_Int32& rSrcPos )
const
1255 sal_Int32 nLen = rFormula.getLength();
1258 for (sal_Int32 i = rSrcPos;
i < nLen; ++
i)
1267 else if (i == rSrcPos + 1)
1287 if (rSrcPos >= nLen)
1297 if (i > rSrcPos + 2 && cPrev ==
'\'')
1307struct ConventionXL_A1 :
public Convention_A1,
public ConventionXL
1309 ConventionXL_A1() : Convention_A1(
FormulaGrammar::CONV_XL_A1 ) { }
1316 MakeColStr(rLimits, rBuf, rAbs.
Col());
1319 MakeRowStr(rLimits, rBuf, rAbs.
Row());
1322 virtual void makeRefStr(
1324 OUStringBuffer& rBuf,
1327 const OUString& rErrRef,
const std::vector<OUString>& rTabNames,
1330 bool )
const override
1336 ScAddress aAbs1 = aRef.Ref1.toAbs(rLimits, rPos), aAbs2;
1338 MakeTabStr(rLimits, rBuf, rPos, rTabNames, aRef, bSingleRef);
1342 rBuf.append(rErrRef);
1348 aAbs2 = aRef.Ref2.toAbs(rLimits, rPos);
1351 rBuf.append(rErrRef);
1355 if (aAbs1.
Col() == 0 && aAbs2.Col() >= rLimits.
mnMaxCol)
1357 if (!aRef.Ref1.IsRowRel())
1359 MakeRowStr(rLimits, rBuf, aAbs1.
Row());
1361 if (!aRef.Ref2.IsRowRel())
1363 MakeRowStr(rLimits, rBuf, aAbs2.Row());
1367 if (aAbs1.
Row() == 0 && aAbs2.Row() >= rLimits.
mnMaxRow)
1369 if (!aRef.Ref1.IsColRel())
1371 MakeColStr(rLimits, rBuf, aAbs1.
Col());
1373 if (!aRef.Ref2.IsColRel())
1375 MakeColStr(rLimits, rBuf, aAbs2.Col());
1380 makeSingleCellStr(rLimits, rBuf, aRef.Ref1, aAbs1);
1384 makeSingleCellStr(rLimits, rBuf, aRef.Ref2, aAbs2);
1388 virtual ParseResult parseAnyToken(
const OUString& rFormula,
1391 bool bGroupSeparator)
const override
1393 parseExternalDocName(rFormula,
nSrcPos);
1399 constexpr sal_Int32 nStartFlags = KParseTokens::ANY_LETTER_OR_NUMBER |
1400 KParseTokens::ASC_UNDERSCORE | KParseTokens::ASC_DOLLAR;
1401 constexpr sal_Int32 nContFlags = nStartFlags | KParseTokens::ASC_DOT;
1403 static constexpr OUStringLiteral aAddAllowed(u
"?!");
1405 nSrcPos, nStartFlags, aAddAllowed,
1406 (bGroupSeparator ? nContFlags | KParseTokens::GROUP_SEPARATOR_IN_NUMBER : nContFlags),
1410 virtual sal_Unicode getSpecialSymbol( SpecialSymbolType eSymType )
const override
1412 return ConventionXL::getSpecialSymbol(eSymType);
1415 virtual bool parseExternalName(
const OUString& rSymbol, OUString& rFile, OUString& rName,
1417 const uno::Sequence<sheet::ExternalLinkInfo>* pExternalLinks )
const override
1419 return ConventionXL::parseExternalName( rSymbol, rFile, rName,
rDoc, pExternalLinks);
1422 virtual OUString makeExternalNameStr( sal_uInt16 ,
const OUString& rFile,
1423 const OUString& rName )
const override
1425 return ConventionXL::makeExternalNameStr(rFile, rName);
1428 virtual void makeExternalRefStr(
1430 OUStringBuffer& rBuffer,
const ScAddress& rPos, sal_uInt16 ,
const OUString& rFileName,
1431 const OUString& rTabName,
const ScSingleRefData& rRef )
const override
1439 ConventionXL::makeExternalDocStr(rBuffer, rFileName);
1441 rBuffer.append(
'!');
1443 makeSingleCellStr(rLimits, rBuffer, rRef, rRef.
toAbs(rLimits, rPos));
1446 virtual void makeExternalRefStr(
1448 OUStringBuffer& rBuffer,
const ScAddress& rPos, sal_uInt16 ,
const OUString& rFileName,
1449 const std::vector<OUString>& rTabNames,
const OUString& rTabName,
1454 ConventionXL::makeExternalDocStr(rBuffer, rFileName);
1455 ConventionXL::makeExternalTabNameRange(rBuffer, rTabName, rTabNames, aAbsRef);
1456 rBuffer.append(
'!');
1458 makeSingleCellStr(rLimits, rBuffer, rRef.
Ref1, aAbsRef.
aStart);
1461 rBuffer.append(
':');
1462 makeSingleCellStr(rLimits, rBuffer, rRef.
Ref2, aAbsRef.
aEnd);
1467struct ConventionXL_OOX :
public ConventionXL_A1
1469 ConventionXL_OOX() : ConventionXL_A1(
FormulaGrammar::CONV_XL_OOX ) { }
1472 OUStringBuffer& rBuf,
1475 const OUString& rErrRef,
const std::vector<OUString>& rTabNames,
1478 bool bFromRangeName )
const override
1499 rBuf.append(rErrRef);
1508 rBuf.append(rErrRef);
1519 rBuf.append(rErrRef);
1524 ConventionXL_A1::makeRefStr( rLimits, rBuf, eGram,
aPos, rErrRef, rTabNames, rRef, bSingleRef, bFromRangeName);
1527 virtual OUString makeExternalNameStr( sal_uInt16 nFileId,
const OUString& ,
1528 const OUString& rName )
const override
1531 return OUString(
"[" + OUString::number(nFileId+1) +
"]!" + rName );
1539 virtual void parseExternalDocName(
const OUString& rFormula, sal_Int32& rSrcPos)
const override
1541 sal_Int32 nLen = rFormula.getLength();
1543 for (sal_Int32 i = rSrcPos;
i < nLen; ++
i)
1560 virtual void makeExternalRefStr(
1562 OUStringBuffer& rBuffer,
const ScAddress& rPos, sal_uInt16 nFileId,
const OUString& ,
1563 const OUString& rTabName,
const ScSingleRefData& rRef )
const override
1569 OUString aQuotedTab( rTabName);
1571 if (!aQuotedTab.isEmpty() && aQuotedTab[0] ==
'\'')
1573 rBuffer.append(
'\'');
1574 ConventionXL_OOX::makeExternalDocStr( rBuffer, nFileId);
1575 rBuffer.append( aQuotedTab.subView(1));
1579 ConventionXL_OOX::makeExternalDocStr( rBuffer, nFileId);
1580 rBuffer.append( aQuotedTab);
1582 rBuffer.append(
'!');
1584 makeSingleCellStr(rLimits, rBuffer, rRef, rRef.
toAbs(rLimits, rPos));
1587 virtual void makeExternalRefStr(
1589 OUStringBuffer& rBuffer,
const ScAddress& rPos, sal_uInt16 nFileId,
const OUString& ,
1590 const std::vector<OUString>& rTabNames,
const OUString& rTabName,
1601 OUStringBuffer
aBuf;
1602 ConventionXL::makeExternalTabNameRange( aBuf, rTabName, rTabNames, aAbsRef);
1603 if (!
aBuf.isEmpty() && aBuf[0] ==
'\'')
1605 rBuffer.append(
'\'');
1606 ConventionXL_OOX::makeExternalDocStr( rBuffer, nFileId);
1607 rBuffer.append(
aBuf.subView(1));
1611 ConventionXL_OOX::makeExternalDocStr( rBuffer, nFileId);
1612 rBuffer.append( aBuf);
1614 rBuffer.append(
'!');
1616 makeSingleCellStr(rLimits, rBuffer, rRef.
Ref1, aAbsRef.
aStart);
1619 rBuffer.append(
':');
1620 makeSingleCellStr(rLimits, rBuffer, rRef.
Ref2, aAbsRef.
aEnd);
1624 static void makeExternalDocStr( OUStringBuffer& rBuffer, sal_uInt16 nFileId )
1626 rBuffer.append(
"[" + OUString::number(
static_cast<sal_Int32
>(nFileId+1) ) +
"]");
1640 rBuf.append(
"[" + OUString::number(nCol) +
"]");
1643 rBuf.append(
static_cast<sal_Int32
>(rAbsRef.
Col() + 1) );
1651 if (rRef.
Row() != 0)
1653 rBuf.append(
"[" + OUString::number(rRef.
Row()) +
"]");
1657 rBuf.append( rAbsRef.
Row() + 1 );
1667 OUStringBuffer& rBuf,
1670 const OUString& rErrRef,
const std::vector<OUString>& rTabNames,
1673 bool )
const override
1678 MakeTabStr(rLimits, rBuf, rPos, rTabNames, aRef, bSingleRef);
1684 rBuf.append(rErrRef);
1692 rBuf.append(rErrRef);
1732 ParseResult parseAnyToken(
const OUString& rFormula,
1735 bool bGroupSeparator)
const override
1737 parseExternalDocName(rFormula,
nSrcPos);
1743 constexpr sal_Int32 nStartFlags = KParseTokens::ANY_LETTER_OR_NUMBER |
1744 KParseTokens::ASC_UNDERSCORE ;
1745 constexpr sal_Int32 nContFlags = nStartFlags | KParseTokens::ASC_DOT;
1747 static constexpr OUStringLiteral aAddAllowed(u
"?-[]!");
1750 nSrcPos, nStartFlags, aAddAllowed,
1751 (bGroupSeparator ? nContFlags | KParseTokens::GROUP_SEPARATOR_IN_NUMBER : nContFlags),
1755 virtual sal_Unicode getSpecialSymbol( SpecialSymbolType eSymType )
const override
1757 return ConventionXL::getSpecialSymbol(eSymType);
1760 virtual bool parseExternalName(
const OUString& rSymbol, OUString& rFile, OUString& rName,
1762 const uno::Sequence<sheet::ExternalLinkInfo>* pExternalLinks )
const override
1764 return ConventionXL::parseExternalName( rSymbol, rFile, rName,
rDoc, pExternalLinks);
1767 virtual OUString makeExternalNameStr( sal_uInt16 ,
const OUString& rFile,
1768 const OUString& rName )
const override
1770 return ConventionXL::makeExternalNameStr(rFile, rName);
1773 virtual void makeExternalRefStr(
1775 OUStringBuffer& rBuffer,
const ScAddress& rPos, sal_uInt16 ,
const OUString& rFileName,
1776 const OUString& rTabName,
const ScSingleRefData& rRef )
const override
1785 ConventionXL::makeExternalDocStr(rBuffer, rFileName);
1787 rBuffer.append(
'!');
1793 virtual void makeExternalRefStr(
1795 OUStringBuffer& rBuffer,
const ScAddress& rPos, sal_uInt16 ,
const OUString& rFileName,
1796 const std::vector<OUString>& rTabNames,
const OUString& rTabName,
1801 ConventionXL::makeExternalDocStr(rBuffer, rFileName);
1802 ConventionXL::makeExternalTabNameRange(rBuffer, rTabName, rTabNames, aAbsRef);
1803 rBuffer.append(
'!');
1807 rBuffer.append(
ScResId(STR_NO_REF_TABLE));
1816 rBuffer.append(
':');
1827 rBuffer.append(
':');
1835 rBuffer.append(
':');
1843 if (c ==
'-' && cLast ==
'[')
1855 rDoc(rCxt.getDoc()),
1857 mpFormatter(pContext ? pContext->GetFormatTable() :
rDoc.GetFormatTable()),
1881 mpFormatter(pContext ? pContext->GetFormatTable() : rDoc.GetFormatTable()),
1882 mpInterpreterContext(pContext),
1883 mnCurrentSheetTab(-1),
1884 mnCurrentSheetEndPos(0),
1887 mbCharClassesDiffer(false),
1888 mnPredetectedReference(0),
1889 mnRangeOpPosInSymbol(-1),
1891 meExtendedErrorDetection( EXTENDED_ERROR_DETECTION_NONE ),
1892 mbCloseBrackets( true ),
1894 mbRefConventionChartOOXML( false )
1904 rDoc(rCxt.getDoc()),
1906 mpFormatter(pContext ? pContext->GetFormatTable() : rDoc.GetFormatTable()),
1907 mpInterpreterContext(pContext),
1908 mnCurrentSheetTab(-1),
1909 mnCurrentSheetEndPos(0),
1911 mbCharClassesDiffer(false),
1912 mnPredetectedReference(0),
1913 mnRangeOpPosInSymbol(-1),
1915 meExtendedErrorDetection(EXTENDED_ERROR_DETECTION_NONE),
1916 mbCloseBrackets(true),
1918 mbRefConventionChartOOXML(false),
1919 maTabNames(rCxt.getTabNames())
1930 mpFormatter(pContext ? pContext->GetFormatTable() : rDoc.GetFormatTable()),
1931 mpInterpreterContext(pContext),
1932 mnCurrentSheetTab(-1),
1933 mnCurrentSheetEndPos(0),
1936 mbCharClassesDiffer(false),
1937 mnPredetectedReference(0),
1938 mnRangeOpPosInSymbol(-1),
1940 meExtendedErrorDetection( EXTENDED_ERROR_DETECTION_NONE ),
1941 mbCloseBrackets( true ),
1943 mbRefConventionChartOOXML( false )
1957 sal_Int32 nStartFlags = KParseTokens::ANY_LETTER_OR_NUMBER | KParseTokens::ASC_UNDERSCORE;
1958 sal_Int32 nContFlags = nStartFlags;
1960 KParseType::IDENTNAME, rString, 0, nStartFlags, OUString(), nContFlags, OUString());
1961 bool bNeedsQuote = !((aRes.TokenType & KParseType::IDENTNAME) && aRes.EndPos == rString.getLength());
1966 case FormulaGrammar::CONV_UNSPECIFIED :
1968 case FormulaGrammar::CONV_OOO :
1969 case FormulaGrammar::CONV_XL_A1 :
1970 case FormulaGrammar::CONV_XL_R1C1 :
1971 case FormulaGrammar::CONV_XL_OOX :
1972 case FormulaGrammar::CONV_ODF :
1976 rString = rString.replaceAll(
"'",
"''" );
1989 rString =
"'" + rString +
"'";
1995 if (rString[0] !=
'\'')
1999 if (
nPos != -1 && rString[
nPos-1] !=
'\'')
2016 case FormulaGrammar::CONV_OOO:
2018 static const ConventionOOO_A1 ConvOOO_A1;
2021 case FormulaGrammar::CONV_ODF:
2023 static const ConventionOOO_A1_ODF ConvOOO_A1_ODF;
2024 return &ConvOOO_A1_ODF;
2026 case FormulaGrammar::CONV_XL_A1:
2028 static const ConventionXL_A1 ConvXL_A1;
2031 case FormulaGrammar::CONV_XL_R1C1:
2033 static const ConventionXL_R1C1 ConvXL_R1C1;
2034 return &ConvXL_R1C1;
2036 case FormulaGrammar::CONV_XL_OOX:
2038 static const ConventionXL_OOX ConvXL_OOX;
2041 case FormulaGrammar::CONV_UNSPECIFIED:
2053 assert( FormulaGrammar::isSupported(
meGrammar));
2065 while ( pDst < pStop )
2078 for (
size_t i=0;
i<
n; ++
i)
2084 if (p1[
i] <
'a' ||
'z' < p1[
i])
2086 if (p2[
i] <
'A' ||
'Z' < p2[
i])
2088 if (p1[
i] != p2[
i] + 0x20)
2099 if (rSpace.
cChar != c)
2102 rvSpaces.emplace_back(rSpace);
2147 std::vector<Whitespace> vSpaces;
2155 bool bQuote =
false;
2157 ScanState eState = ssGetChar;
2170 bool bAutoIntersection =
false;
2171 size_t nAutoIntersectionSpacesPos = 0;
2173 bool bErrorConstantHadSlash =
false;
2176 while ((c != 0) && (eState != ssStop) )
2183 if (c == cSep || (bInArray && (c == cArrayColSep || c == cArrayRowSep)))
2190 case ssGetReference:
2191 case ssSkipReference:
2192 case ssGetTableRefItem:
2193 case ssGetTableRefColumn:
2196 if (eState == ssGetChar)
2203Label_MaskStateMachine:
2212 eState = ssGetTableRefColumn;
2227 if (!bAutoIntersection)
2235 nAutoIntersectionSpacesPos = vSpaces.size();
2236 bAutoIntersection =
true;
2247 goto Label_MaskStateMachine;
2261 goto Label_MaskStateMachine;
2272 if (c ==
'[' && FormulaGrammar::isExcelSyntax(
meGrammar)
2279 if (FormulaGrammar::isRefConventionOOXML(
meGrammar) &&
2280 pSrc[0] ==
'0' && pSrc[1] ==
']' && pSrc[2] ==
'!')
2288 goto Label_MaskStateMachine;
2299 eState = ssGetReference;
2310 eState = ssGetValue;
2315 eState = ssGetString;
2321 eState = ssGetTableRefItem;
2323 eState = ssGetErrorConstant;
2333 eState = ssGetIdent;
2348 SetError(FormulaError::StringOverflow);
2368 SetError(FormulaError::StringOverflow);
2387 SetError(FormulaError::StringOverflow);
2396 else if ( 128 <= c ||
'\'' == c )
2428 SetError(FormulaError::StringOverflow);
2431 else if (c == cDecSep || (cDecSepAlt && c == cDecSepAlt))
2449 else if (c ==
'E' || c ==
'e')
2462 if (((cLast ==
'E') || (cLast ==
'e')) &&
2499 SetError(FormulaError::StringOverflow);
2500 eState = ssSkipString;
2511 case ssGetErrorConstant:
2531 eState = ssGetIdent;
2537 if (!bErrorConstantHadSlash)
2538 bErrorConstantHadSlash =
true;
2546 (c < 128 && !rtl::isAsciiAlphanumeric( c)))
2557 SetError( FormulaError::StringOverflow);
2565 case ssGetTableRefItem:
2572 SetError( FormulaError::StringOverflow);
2585 case ssGetTableRefColumn:
2588 if (c !=
']' || cLast ==
'\'')
2592 SetError( FormulaError::StringOverflow);
2605 case ssGetReference:
2608 SetError( FormulaError::StringOverflow);
2609 eState = ssSkipReference;
2612 case ssSkipReference:
2631 constexpr int kDollar = (1 << 1);
2634 constexpr int kOpen = (1 << 2);
2636 constexpr int kName = (1 << 3);
2640 constexpr int kQuote = (1 << 4);
2642 constexpr int kClose = (1 << 5);
2644 constexpr int kFileSep = (1 << 6);
2646 constexpr int kPast = (1 << 7);
2650 constexpr int kMarkAhead = (1 << 8);
2652 constexpr int kDefName = (1 << 9);
2654 constexpr int kRefErr = (1 << 10);
2656 bool bAddToSymbol =
true;
2659 OSL_ENSURE( nRefInName & (kPast | kDefName | kRefErr),
2660 "ScCompiler::NextSymbol: reference: "
2661 "closing bracket ']' without prior sheet name separator '.' violates ODF spec");
2663 bAddToSymbol =
false;
2666 else if (cSheetSep == c && nRefInName == 0)
2669 bAddToSymbol =
false;
2670 nRefInName |= kPast;
2671 if (
'$' == pSrc[0] &&
'$' == pSrc[1])
2672 nRefInName |= kMarkAhead;
2674 else if (!(nRefInName & kPast) || (nRefInName & (kMarkAhead | kDefName)))
2680 else if (
'$' == c &&
'$' == pSrc[0] && !(nRefInName & kOpen))
2682 nRefInName &= ~kMarkAhead;
2683 if (!(nRefInName & kDefName))
2686 bAddToSymbol =
false;
2688 nRefInName &= kPast;
2689 nRefInName |= kDefName;
2695 if (eState != ssSkipReference)
2701 SetError( FormulaError::StringOverflow);
2707 bAddToSymbol =
false;
2710 else if (cSheetPrefix == c && nRefInName == 0)
2711 nRefInName |= kDollar;
2717 if (!(nRefInName & kName))
2719 nRefInName |= (kOpen | kName);
2720 bAddToSymbol = !(nRefInName & kDefName);
2722 else if (!(nRefInName & kOpen))
2724 OSL_FAIL(
"ScCompiler::NextSymbol: reference: "
2725 "a ''' without the name being enclosed in '...' violates ODF spec");
2727 else if (nRefInName & kQuote)
2730 nRefInName &= ~kQuote;
2738 nRefInName |= kQuote;
2742 nRefInName |= kFileSep;
2746 nRefInName |= kClose;
2747 nRefInName &= ~kOpen;
2749 bAddToSymbol = !(nRefInName & kDefName);
2752 else if (
'#' == c && nRefInName == 0)
2753 nRefInName |= kRefErr;
2754 else if (cSheetSep == c && !(nRefInName & kOpen))
2757 nRefInName |= kPast;
2758 if (
'$' == pSrc[0] &&
'$' == pSrc[1])
2759 nRefInName |= kMarkAhead;
2761 else if (
':' == c && !(nRefInName & kOpen))
2763 OSL_FAIL(
"ScCompiler::NextSymbol: reference: "
2764 "range operator ':' without prior sheet name separator '.' violates ODF spec");
2768 else if (!(nRefInName & kName))
2771 nRefInName |= kName;
2780 if (bAddToSymbol && eState != ssSkipReference)
2793 vSpaces.emplace_back(aSpace);
2797 const sal_Int32 nOldSrcPos =
nSrcPos;
2798 for (
const auto& r : vSpaces)
2807 const bool bGroupSeparator = (128 <= cGroupSep && cGroupSep != cSep &&
2808 cGroupSep != cArrayColSep && cGroupSep != cArrayRowSep &&
2809 cGroupSep != cDecSep && cGroupSep != cDecSepAlt &&
2810 cGroupSep != cSheetPrefix && cGroupSep != cSheetSep);
2815 OUStringBuffer aSymbol;
2822 if ( pStart[
nSrcPos] == cSheetPrefix && pStart[
nSrcPos+1] ==
'\'' )
2823 aSymbol.append(pStart[
nSrcPos++]);
2827 if ( !aRes.TokenType )
2829 nErr = FormulaError::IllegalChar;
2835 assert(!aRes.TokenType);
2836 nErr = FormulaError::IllegalChar;
2841 aSymbol.setLength(0);
2851 for (sal_Int32
i =
nSrcPos;
i < aRes.EndPos; ++
i)
2853 if (pStart[
i] == cSep)
2860 if ( aRes.TokenType & KParseType::SINGLE_QUOTE_NAME )
2871 aSymbol.append(pStart[
nSrcPos++]);
2873 }
while ( bi18n && nErr == FormulaError::NONE );
2874 sal_Int32 nLen = aSymbol.getLength();
2877 SetError( FormulaError::StringOverflow );
2900 if (bAutoIntersection && vSpaces[nAutoIntersectionSpacesPos].
nCount > 1)
2901 --vSpaces[nAutoIntersectionSpacesPos].nCount;
2909 OpCodeHashMap::const_iterator iLook(
mxSymbols->getHashMap().find( rName));
2910 bool bFound = (iLook !=
mxSymbols->getHashMap().end());
2913 OpCode eOp = iLook->second;
2925 else if (rName ==
";")
2927 switch (FormulaGrammar::extractFormulaLanguage(
meGrammar))
2931 case css::sheet::FormulaLanguage::NATIVE:
2932 case css::sheet::FormulaLanguage::ENGLISH:
2933 case css::sheet::FormulaLanguage::ODFF:
2934 case css::sheet::FormulaLanguage::ODF_11:
2965 static const FunctionName aOdffAliases[] = {
2978 for (
const FunctionName& rOdffAlias : aOdffAliases)
2980 if (rName.equalsIgnoreAsciiCaseAscii( rOdffAlias.pName))
2997 static const FunctionName aOoxmlAliases[] = {
3006 for (
const FunctionName& rOoxmlAlias : aOoxmlAliases)
3008 if (rName.equalsIgnoreAsciiCaseAscii( rOoxmlAlias.pName))
3028 static const FunctionName aPodfAliases[] = {
3031 for (
const FunctionName& rPodfAlias : aPodfAliases)
3033 if (rName.equalsIgnoreAsciiCaseAscii( rPodfAlias.pName))
3048 ExternalHashMap::const_iterator iExt(
3049 mxSymbols->getExternalHashMap().find( rName));
3050 if (iExt !=
mxSymbols->getExternalHashMap().end())
3053 aIntName = (*iExt).second;
3069 if (!aIntName.isEmpty())
3080 bool bShouldBeNegSub =
3085 if (bShouldBeNegSub && eOp ==
ocSub)
3088 else if (!bShouldBeNegSub && eOp ==
ocNegSub)
3117 const sal_Int32 nFormulaLanguage = FormulaGrammar::extractFormulaLanguage(
GetGrammar());
3118 if (nFormulaLanguage == css::sheet::FormulaLanguage::ODFF || nFormulaLanguage == css::sheet::FormulaLanguage::OOXML)
3122 rtl_math_ConversionStatus eStatus;
3123 sal_Int32 nParseEnd;
3124 double fVal = rtl::math::stringToDouble( rSym,
'.', 0, &eStatus, &nParseEnd);
3125 if (nParseEnd != rSym.getLength())
3137 if (rSym.equalsIgnoreAsciiCase(
"TRUE"))
3139 else if (rSym.equalsIgnoreAsciiCase(
"FALSE"))
3151 if (eStatus == rtl_math_ConversionStatus_OutOfRange)
3157 if (!std::isfinite(fVal) && rSym ==
"INF")
3168 SetError( FormulaError::IllegalArgument );
3187 if (
nType & (SvNumFormatType::TIME | SvNumFormatType::DATE))
3190 if (
nType == SvNumFormatType::LOGICAL)
3196 if(
nType == SvNumFormatType::TEXT )
3198 SetError( FormulaError::IllegalArgument );
3210 sal_Int32 nLen = sal::static_int_cast<sal_Int32>(
p -
cSymbol - 1 );
3211 if (!nLen ||
cSymbol[nLen] !=
'"')
3237 const OUString aErrRef(
"#REF!");
3238 sal_Int32
nPos = rName.indexOf( aErrRef);
3252 if (rName.getLength() == 5)
3271 if (
'$' == c2 ||
'#' == c2 || (
'0' <= c2 && c2 <=
'9'))
3279 (
'.' == c2 ||
'$' == c2 ||
'#' == c2 ||
3280 (
'0' <= c2 && c2 <=
'9')))
3287 if (rtl::isAsciiAlpha(c) &&
3433 if ( ch1 == cDecSep )
3440 if ( ch1 == cDecSep )
3461 if ( !(ch2 ==
'$' || rtl::isAsciiAlpha( ch2 )) )
3463 if ( cDecSep ==
'.' && (ch2 ==
'E' || ch2 ==
'e')
3476 OUString aTabName( rName.copy( 0,
nPos ) );
3514 case FormulaGrammar::CONV_XL_A1:
3515 case FormulaGrammar::CONV_XL_OOX:
3519 if (rName[0] !=
'\'')
3522 case FormulaGrammar::CONV_XL_R1C1:
3536#if !HAVE_FEATURE_SCRIPTING
3551 SAL_WARN(
"sc.core",
"ScCompiler::ParseMacro - SolarMutex would deadlock, not obtaining Basic");
3555 OUString
aName( rName);
3578 if (FormulaGrammar::isODFF(
GetGrammar()) &&
aName.startsWithIgnoreAsciiCase(
"USER."))
3589 ||
dynamic_cast<const SbMethod*
>( pMeth) == nullptr )
3670 rbInvalidExternalNameRange =
false;
3675 OUString aFile,
aName;
3683 OUString aTmp = aFile;
3689 rbInvalidExternalNameRange =
true;
3714 bool bInList =
false;
3715 bool bFound =
false;
3717 OUString
aName( rName );
3720 for (
short jThisTab = 1; jThisTab >= 0 && !bInList; jThisTab-- )
3722 for (
short jRow=0; jRow<2 && !bInList; jRow++ )
3729 for (
size_t iPair = 0, nPairs = pRL->
size(); iPair < nPairs && !bInList; ++iPair )
3733 if ( jThisTab && (rNameRange.
aStart.
Tab() > nThisTab ||
3734 nThisTab > rNameRange.
aEnd.
Tab()) )
3737 for (
bool bHas = aIter.
first(); bHas && !bInList; bHas = aIter.
next())
3765 bInList = bFound =
true;
3792 for (
const ScAddress& aAddress : rAddresses )
3796 if ( nMax <
static_cast<tools::Long>(aAddress.Col()) )
3799 if ( aAddress !=
aPos )
3803 SCCOL nCol = aAddress.Col();
3804 SCROW nRow = aAddress.Row();
3810 if ( nD < nDistance )
3812 if ( nC < 0 || nR < 0 )
3815 aTwo.
Set( nCol, nRow, aAddress.Tab() );
3816 nMax = std::max( nMyCol + std::abs( nC ), nMyRow + std::abs( nR ) );
3825 aOne.
Set( nCol, nRow, aAddress.Tab() );
3826 nMax = std::max( nMyCol + nC, nMyRow + nR );
3833 aOne.
Set( nCol, nRow, aAddress.Tab() );
3834 nDistance = nC * nC + nR * nR;
3835 nMax = std::max( nMyCol + std::abs( nC ), nMyRow + std::abs( nR ) );
3845 for (
bool bHas = aIter.
first(); bHas; bHas = aIter.
next())
3874 if ( nD < nDistance )
3876 if ( nC < 0 || nR < 0 )
3880 nMax = std::max( nMyCol + std::abs( nC ), nMyRow + std::abs( nR ) );
3890 nMax = std::max( nMyCol + nC, nMyRow + nR );
3898 nDistance = nC * nC + nR * nR;
3899 nMax = std::max( nMyCol + std::abs( nC ), nMyRow + std::abs( nR ) );
3929 if ( nC1 * nC1 + nR1 * nR1 <= nC2 * nC2 + nR2 * nR2 )
3944 aAdr.
Col(), aAdr.
Row() + 1, aAdr.
Tab()))
3946 aAdr.
Col(), aAdr.
Row() - 1, aAdr.
Tab()))
3969 OpCodeHashMap::const_iterator iLook(
mxSymbols->getHashMap().find( rName ) );
3970 if( iLook !=
mxSymbols->getHashMap().end() &&
3971 ((*iLook).second ==
ocTrue ||
3984 if (nError != FormulaError::NONE)
3996 OpCodeHashMap::const_iterator iLook(
mxSymbols->getHashMap().find( rName));
3997 if (iLook !=
mxSymbols->getHashMap().end())
4004 switch ((*iLook).second)
4036OUString unescapeTableRefColumnSpecifier(
const OUString& rStr )
4040 if (rStr.indexOf(
'\'' ) < 0)
4043 const sal_Int32
n = rStr.getLength();
4044 OUStringBuffer
aBuf( n );
4047 bool bEscaped =
false;
4048 for ( ;
p < pStop; ++
p)
4061 return aBuf.makeStringAndClear();
4076 OUString
aName( unescapeTableRefColumnSpecifier( rName));
4108 for (
bool bHas = aIter.
first(); bHas; bHas = aIter.
next())
4127 SAL_WARN(
"sc.core",
"ScCompiler::IsTableRefColumn - falling back to cell lookup");
4167 if ( c1 == cQuote && c2 != cQuote )
4181 else if ( c1 != cQuote && c2 == cQuote )
4186 else if (
nPos == 0 && (c1 == cx || c1 == cX) )
4211 if ( aSymbol[0] ==
'\'' )
4213 sal_Int32 nPosition = aSymbol.indexOf(
"'#" );
4214 if (nPosition != -1)
4216 aDoc = aSymbol.copy(0, nPosition + 2);
4217 aSymbol = aSymbol.copy(nPosition + 2);
4226 OUString aTmp1( aSymbol.getToken( 0,
':',
nIndex ) );
4227 sal_Int32 nLen1 = aTmp1.getLength();
4228 OUStringBuffer aSym;
4230 bool bLastAlp =
true;
4231 sal_Int32 nStrip = 0;
4232 sal_Int32
nCount = nRefs;
4233 for ( sal_Int32 j=1; j<
nCount; j++ )
4235 aTmp2 = aSymbol.getToken( 0,
':',
nIndex );
4236 sal_Int32 nLen2 = aTmp2.getLength();
4237 if ( nLen1 || nLen2 )
4247 if ( bLastAlp == bNextNum && nStrip < 1 )
4256 if ( !aSym.isEmpty() && aSym[aSym.getLength()-1] !=
':')
4260 bLastAlp = !bNextNum;
4277 aSymbol = aSym + aTmp1;
4282 if ( nRefs && nRefs <= 2 )
4284 OUString aTab[2], aRef[2];
4288 sal_Int32 nIdx{ 0 };
4289 aRef[0] = aSymbol.getToken( 0,
':', nIdx );
4290 aRef[1] = aSymbol.getToken( 0,
':', nIdx );
4295 bool bChanged =
false;
4298 for (
int j=0; j<nRefs; j++ )
4301 sal_Int32 nDotPos = -1;
4302 while ( (nTmp = aRef[j].indexOf(
'.', nTmp )) != -1 )
4304 if ( nDotPos != -1 )
4306 aTab[j] = aRef[j].copy( 0, nDotPos + 1 );
4307 aRef[j] = aRef[j].copy( nDotPos + 1 );
4309 OUString aOld( aRef[j] );
4310 OUStringBuffer aStr2;
4312 while ( *
p && rtl::isAsciiDigit( *
p ) )
4314 aRef[j] = OUString(
p );
4316 if ( bColons || aRef[j] != aOld )
4320 bOk &= ((aAdr.
Parse( aRef[j],
rDoc, aDetails ) & nMask) == nMask);
4323 if ( bChanged && bOk )
4346 rUpper = rOrg.toAsciiUpperCase();
4366 bool bAllowBooleans = bInArray;
4367 const std::vector<Whitespace> & vSpaces =
NextSymbol(bInArray);
4387 if (!vSpaces.empty())
4390 for (
const auto& rSpace : vSpaces)
4392 if (rSpace.cChar == 0x20)
4409 SetError(FormulaError::CodeOverflow);
4419 bool bInvalidExternalNameRange;
4447 bool bMayBeFuncName;
4448 bool bAsciiNonAlnum;
4451 bMayBeFuncName = rtl::isAsciiAlpha(
cSymbol[0] );
4454 bMayBeFuncName = officecfg::Office::Common::Misc::ExperimentalMode::get();
4457 bAsciiNonAlnum = !bMayBeFuncName && !rtl::isAsciiDigit(
cSymbol[0] );
4461 OUString aTmpStr(
cSymbol[0] );
4463 bAsciiNonAlnum =
false;
4479 if ( bMayBeFuncName )
4485 bMayBeFuncName = ( *
p ==
'(' );
4492 bool bAsciiUpper =
false;
4498 const OUString aOrg(
cSymbol );
4512 bAsciiUpper =
false;
4541 if (aUpper.isEmpty())
4565 if (aUpper.isEmpty())
4600 bool bInvalidExternalNameRange;
4605 if (bInvalidExternalNameRange)
4630 if (aUpper.indexOf( aErrRef) >= 0 &&
ParseReference( aUpper, &aErrRef))
4660 bool bExternal =
GetGrammar() == FormulaGrammar::GRAM_EXTERNAL;
4661 sal_uInt16 nExpectedCount = bExternal ? 2 : 1;
4662 OSL_ENSURE(
pArr->
GetLen() == nExpectedCount,
"ScCompiler::CreateStringFromXMLTokenArray - wrong number of tokens" );
4675class ExternalFileInserter
4681 maPos(rPos), mrRefMgr(rRefMgr) {}
4683 void operator() (sal_uInt16 nFileId)
const
4693 OSL_ENSURE(
meGrammar != FormulaGrammar::GRAM_EXTERNAL,
"ScCompiler::CompileString - unexpected grammar GRAM_EXTERNAL" );
4694 if(
meGrammar == FormulaGrammar::GRAM_EXTERNAL )
4724 struct FunctionStack
4730 bool bPODF = FormulaGrammar::isPODF(
meGrammar);
4731 bool bOOXML = FormulaGrammar::isOOXML(
meGrammar);
4732 bool bUseFunctionStack = (bPODF || bOOXML);
4733 const size_t nAlloc = 512;
4734 FunctionStack aFuncs[ nAlloc ];
4735 FunctionStack* pFunctionStack = (bUseFunctionStack &&
o3tl::make_unsigned(rFormula.getLength()) > nAlloc ?
4736 new FunctionStack[rFormula.getLength()] : &aFuncs[0]);
4737 pFunctionStack[0].eOp =
ocNone;
4738 pFunctionStack[0].nSep = 0;
4739 size_t nFunction = 0;
4740 short nBrackets = 0;
4741 bool bInArray =
false;
4754 if (bUseFunctionStack)
4757 pFunctionStack[ nFunction ].eOp =
eLastOp;
4758 pFunctionStack[ nFunction ].nSep = 0;
4766 SetError( FormulaError::PairExpected );
4775 if (bUseFunctionStack && nFunction)
4781 if (bUseFunctionStack)
4782 ++pFunctionStack[ nFunction ].nSep;
4788 SetError( FormulaError::NestedArray );
4792 if (bUseFunctionStack)
4795 pFunctionStack[ nFunction ].eOp = eOp;
4796 pFunctionStack[ nFunction ].nSep = 0;
4808 SetError( FormulaError::PairExpected );
4815 if (bUseFunctionStack && nFunction)
4822 if (bUseFunctionStack)
4825 pFunctionStack[ nFunction ].eOp = eOp;
4826 pFunctionStack[ nFunction ].nSep = 0;
4832 if (bUseFunctionStack && nFunction)
4840 aArr.SetShareable(
false);
4861 SetError(FormulaError::CodeOverflow);
break;
4868 size_t nFunc = nFunction + 1;
4870 (pFunctionStack[ nFunc ].eOp ==
ocWeek &&
4871 pFunctionStack[ nFunc ].nSep == 0))
4876 SetError(FormulaError::CodeOverflow);
break;
4886 pFunctionStack[ nFunction ].eOp ==
ocAddress &&
4887 pFunctionStack[ nFunction ].nSep == 3)
4892 SetError(FormulaError::CodeOverflow);
break;
4894 ++pFunctionStack[ nFunction ].nSep;
4903 SetError( FormulaError::BadArrayContent);
4905 else if (!pNewToken)
4907 SetError(FormulaError::CodeOverflow);
4924 FormulaTokenArray::ReplaceMode::CODE_ONLY);
4960 SetError(FormulaError::CodeOverflow);
4969 while( nBrackets-- )
4973 SetError(FormulaError::CodeOverflow);
4984 if (pFunctionStack != &aFuncs[0])
4985 delete [] pFunctionStack;
5008 OSL_ENSURE( (
GetGrammar() == FormulaGrammar::GRAM_EXTERNAL) || rFormulaNmsp.isEmpty(),
5009 "ScCompiler::CompileString - unexpected formula namespace for internal grammar" );
5010 if(
GetGrammar() == FormulaGrammar::GRAM_EXTERNAL )
try
5013 uno::Reference< sheet::XFormulaParser > xParser( rParserPool.
getFormulaParser( rFormulaNmsp ), uno::UNO_SET_THROW );
5014 table::CellAddress aReferencePos;
5016 uno::Sequence< sheet::FormulaToken > aTokenSeq = xParser->parseFormula( rFormula, aReferencePos );
5021 std::unique_ptr<ScTokenArray> pNew(
new ScTokenArray( aTokenArray ));
5028 catch( uno::Exception& )
5047 if( nErr != FormulaError::NONE )
5061 bool bBorder1 = (eOp1 ==
ocSep || eOp1 ==
ocOpen);
5063 bool bAddPair = !(bBorder1 && bBorder2);
5080 if (nSheetTab >= 0 && nSheetTab !=
aPos.
Tab())
5147 OSL_FAIL(
"Wrong type for external reference!");
5215 OUString
const & rStr, sal_Int32 nPos,
ScCharFlags nFlags )
5225 ((
pConventions[nConv]->getCharTableFlags(c, cLast) & nFlags) != nFlags))
5238 sal_uInt16 nFileId =
t->GetIndex();
5245 switch (
t->GetType())
5252 rBuffer,
GetPos(), nUsedFileId, *pFileName,
t->GetString().getString(),
5253 *
t->GetSingleRef());
5257 vector<OUString> aTabNames;
5262 SAL_WARN_IF( aTabNames.empty(),
"sc.core",
"wrecked cache of external document? '" <<
5263 *pFileName <<
"' '" <<
t->GetString().getString() <<
"'");
5267 *
t->GetDoubleRef());
5273 OSL_FAIL(
"ScCompiler::CreateStringFromToken: unknown type of ocExternalRef");
5280 SCSIZE nC, nMaxC, nR, nMaxR;
5285 for( nR = 0 ; nR < nMaxR ; nR++)
5292 for( nC = 0 ; nC < nMaxC ; nC++)
5299 if( pMatrix->
IsValue( nC, nR ) )
5306 if (nErr != FormulaError::NONE)
5312 else if( pMatrix->
IsEmpty( nC, nR ) )
5322void escapeTableRefColumnSpecifier( OUString& rStr )
5324 const sal_Int32
n = rStr.getLength();
5325 OUStringBuffer
aBuf( n * 2 );
5328 for ( ;
p < pStop; ++
p)
5337 aBuf.append(
'\'' );
5344 rStr =
aBuf.makeStringAndClear();
5364 rBuffer.append(
'\'');
5365 rBuffer.append(
aStr);
5366 rBuffer.append(
'\'');
5380 SAL_WARN_IF( !
pData,
"sc.core",
"ScCompiler::CreateStringFromSingleRef - TableRef without ScDBData: " <<
5388 SAL_WARN(
"sc.core",
"ScCompiler::CreateStringFromSingleRef - TableRef falling back to cell: " <<
5394 SAL_WARN(
"sc.core",
"ScCompiler::CreateStringFromSingleRef - TableRef of empty header-less: " <<
5399 escapeTableRefColumnSpecifier(
aStr);
5400 rBuffer.append(
aStr);
5517 sheet::FormulaOpCodeMapEntry aEntry;
5536 aEntry.Name =
aName;
5543 _rVec.push_back( aEntry);
5564 bool bInList =
false;
5565 bool bValidName =
false;
5569 for (
size_t i = 0, nPairs = pRL->
size();
i < nPairs; ++
i )
5574 bInList = bValidName =
true;
5593 if (!bString && aCell.
isEmpty())
5600 SCROW nStartRow = nRow + 1;
5604 if ( nMyCol == nCol )
5606 if ( nMyRow == nStartRow )
5612 else if ( nMyRow > nStartRow )
5614 nMaxRow = nMyRow - 1;
5617 for (
size_t i = 0, nPairs = pRL->
size();
i < nPairs; ++
i )
5624 if ( nStartRow < nTmp && nTmp <= nMaxRow )
5628 aRange.
aStart.
Set( nCol, nStartRow, nTab );
5629 aRange.
aEnd.
Set( nCol, nMaxRow, nTab );
5633 SCCOL nStartCol = nCol + 1;
5637 if ( nMyRow == nRow )
5639 if ( nMyCol == nStartCol )
5645 else if ( nMyCol > nStartCol )
5647 nMaxCol = nMyCol - 1;
5650 for (
size_t i = 0, nPairs = pRL->
size();
i < nPairs; ++
i )
5657 if ( nStartCol < nTmp && nTmp <= nMaxCol )
5661 aRange.
aStart.
Set( nStartCol, nRow, nTab );
5662 aRange.
aEnd.
Set( nMaxCol, nRow, nTab );
5675 bool bSingle = (aRange.
aStart == aRange.
aEnd);
5698 && nMyRow <= aRange.
aEnd.
Row());
5705 && nMyCol <= aRange.
aEnd.
Col());
5784 if (
p &&
p->GetOpCode() == eOp)
5802 SetError(FormulaError::UnknownToken);
5816 bool bForwardToClose =
false;
5829 nError = FormulaError::NoRef;
5830 bForwardToClose =
true;
5835 bForwardToClose =
true;
5843 nError = FormulaError::NoRef;
5844 bForwardToClose =
true;
5858 nError = FormulaError::NoRef;
5859 bForwardToClose =
true;
5867 nError = FormulaError::NoRef;
5868 bForwardToClose =
true;
5876 nError = FormulaError::NoRef;
5877 bForwardToClose =
true;
5889 nError = FormulaError::NoValue;
5894 bForwardToClose =
true;
5898 bool bColumnRange =
false;
5899 bool bCol1Rel =
false;
5900 bool bCol1RelName =
false;
5921 switch (
p->GetOpCode())
5924 eState = ((eState == sOpen || eState == sSep) ? sOpen : sStop);
5936 eState = ((eState == sOpen) ? sItem : sStop);
5939 eState = ((eState == sItem || eState == sClose) ? sClose : sStop);
5940 if (eState != sStop && --nLevel == 0)
5944 eState = ((eState == sClose) ? sSep : sStop);
5949 bColumnRange =
true;
5950 bCol1Rel =
p->GetSingleRef()->IsColRel();
5951 bCol1RelName =
p->GetSingleRef()->IsRelName();
5961 if (nError == FormulaError::NONE)
5962 nError = FormulaError::NoName;
5967 if (eState != sStop)
5969 if (eState == sLast)
5972 }
while (eState != sStop);
5975 if (nError == FormulaError::NONE || nError == FormulaError::NoValue)
5977 bool bCol2Rel =
false;
5978 bool bCol2RelName =
false;
6001 bCol2Rel =
mpToken->GetSingleRef()->IsColRel();
6002 bCol2RelName =
mpToken->GetSingleRef()->IsRelName();
6034 if (nError != FormulaError::NONE)
6052 bool bRelName = bCol1RelName || bCol2RelName;
6063 if (nError != FormulaError::NONE)
6085 while (nLevel-- > 0)
6138 if (nNumParams > 0 && *pppToken[0] ==
nullptr)
6151 if (nNumParams != 3)
6154 if (!(pppToken[0] && pppToken[2] && *pppToken[0] && *pppToken[2]))
6160 const StackVar eSumRangeType = (*pppToken[2])->GetType();
6170 aSumRange.
Ref1 = *(*pppToken[2])->GetSingleRef();
6174 aSumRange = *(*pppToken[2])->GetDoubleRef();
6182 if (nNumParams != 1)
6200 if (nNumParams != 2)
6218 if (nNumParams != 1)
6232 if (nNumParams != 3 && nNumParams != 4)
6246 if (nNumParams == 4 && (*pppToken[3])->GetType() ==
svDoubleRef)
6254 bool possibleII =
false;
6255 for(
int i = 0;
i < nNumParams; ++
i )
6267 for(
int i = 0;
i < nNumParams; ++
i )
6280 if( *item.parameterLocation != item.parameter )
6282 if( item.parameterLocation >=
pCode )
6285 if( item.operation->IsInForceArray())
6332 (*ppDoubleRefTok)->DecRef();
6333 *ppDoubleRefTok = pNewSingleRefTok;
6334 pNewSingleRefTok->
IncRef();
6352 if ( nRow == rRange.
aEnd.
Row() )
6357 else if ( nTab != nMyTab && nTab == rRange.
aEnd.
Tab()
6368 if ( nCol == rRange.
aEnd.
Col() )
6373 else if ( nTab != nMyTab && nTab == rRange.
aEnd.
Tab()
6383 if ( nTab == rRange.
aEnd.
Tab() )
6385 else if ( nTab <= nMyTab && nMyTab <= rRange.
aEnd.
Tab() )
6390 rAdr.
Set( nCol, nRow, nTab );
6416 SCCOL nXDeltaSum = 0;
6417 SCROW nYDeltaSum = 0;
6427 if (nXDelta == nXDeltaSum &&
6428 nYDelta == nYDeltaSum)
6435 SCCOL nXInc = nXDelta - nXDeltaSum;
6436 SCROW nYInc = nYDelta - nYDeltaSum;
6463 (*ppSumRangeToken)->DecRef();
6464 *ppSumRangeToken = pNewSumRangeTok;
6465 pNewSumRangeTok->
IncRef();
6476 if (eOpCode ==
ocSum)
6488 bool bTillClose =
true;
6489 bool bCloseTillIf =
false;
6490 sal_Int16 nToksTillIf = 0;
6491 constexpr sal_Int16 MAXDIST_IF = 15;
6500 if (nToksTillIf > MAXDIST_IF)
6517 bCloseTillIf =
true;
6530 const short nJumpCount = pTok->
GetJump()[0];
6531 if (nJumpCount != 2)
6534 OpCode eCompOp = (*(ppTok - 1))->GetOpCode();
6567 bool bTillClose =
true;
6568 bool bCloseTillIf =
false;
6569 sal_Int16 nToksTillIf = 0;
6570 constexpr sal_Int16 MAXDIST_IF = 15;
6579 if (nToksTillIf > MAXDIST_IF)
6606 bCloseTillIf =
true;
6619 const short nJumpCount = pTok->
GetJump()[0];
6620 if (nJumpCount != 2)
6623 OpCode eCompOp = (*(ppTok - 1))->GetOpCode();
void ScColToAlpha(OUStringBuffer &rBuf, SCCOL nCol)
append alpha representation of column to buffer
bool ValidTab(SCTAB nTab)
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 ...
std::vector< ScAddress > ScAutoNameAddresses
static const AllSettings & GetSettings()
static bool isAsciiNumeric(std::u16string_view rStr)
static bool isAsciiAlpha(std::u16string_view rStr)
OUString uppercase(const OUString &rStr, sal_Int32 nPos, sal_Int32 nCount) const
css::i18n::ParseResult parseAnyToken(const OUString &rStr, sal_Int32 nPos, sal_Int32 nStartCharFlags, const OUString &userDefinedCharactersStart, sal_Int32 nContCharFlags, const OUString &userDefinedCharactersCont) const
const LanguageTag & getLanguageTag() const
bool isLetter(const OUString &rStr, sal_Int32 nPos) const
bool isLetterNumeric(const OUString &rStr, sal_Int32 nPos) const
css::i18n::ParseResult parsePredefinedToken(sal_Int32 nTokenType, const OUString &rStr, sal_Int32 nPos, sal_Int32 nStartCharFlags, const OUString &userDefinedCharactersStart, sal_Int32 nContCharFlags, const OUString &userDefinedCharactersCont) const
bool isDigit(const OUString &rStr, sal_Int32 nPos) const
static OUString decode(std::u16string_view rText, DecodeMechanism eMechanism, rtl_TextEncoding eCharset=RTL_TEXTENCODING_UTF8)
OUString getLanguage() const
const OUString & getNumThousandSep() const
const OUString & getNumDecimalSepAlt() const
const OUString & getNumDecimalSep() const
virtual bool IsFixed() const override
virtual SbxDataType GetType() const override
void Set(SCCOL nCol, SCROW nRow, SCTAB nTab)
SC_DLLPUBLIC void Format(OStringBuffer &r, ScRefFlags nFlags, const ScDocument *pDocument=nullptr, const Details &rDetails=detailsOOOa1) const
void IncCol(SCCOL nDelta=1)
SC_DLLPUBLIC ScRefFlags Parse(const OUString &, const ScDocument &, const Details &rDetails=detailsOOOa1, ExternalInfo *pExtInfo=nullptr, const css::uno::Sequence< css::sheet::ExternalLinkInfo > *pExternalLinks=nullptr, sal_Int32 *pSheetEndPos=nullptr, const OUString *pErrRef=nullptr)
void IncRow(SCROW nDelta=1)
Cache for faster lookup of automatic names during CompileXML (during CompileXML, no document content ...
const ScAutoNameAddresses & GetNameOccurrences(const OUString &rName, SCTAB nTab)
Walk through all cells in an area.
ScFormulaCell * getFormulaCell()
const ScAddress & GetPos() const
OUString getString() const
virtual void CreateStringFromDoubleRef(OUStringBuffer &rBuffer, const formula::FormulaToken *pToken) const override
static sal_Int32 GetDocTabPos(const OUString &rString)
Analyzes a string for a 'Doc'Tab construct, or 'Do''c'Tab etc...
css::uno::Sequence< css::sheet::ExternalLinkInfo > maExternalLinks
static bool DoubleRefToPosSingleRefScalarCase(const ScRange &rRange, ScAddress &rAdr, const ScAddress &rFormulaPos)
TODO : Move this to somewhere appropriate.
const ScRangeData * GetRangeData(SCTAB &rSheet, const OUString &rUpperName) const
bool ParseDBRange(const OUString &)
static const struct ScCompiler::AddInMap g_aAddInMap[]
virtual void HandleIIOpCode(formula::FormulaToken *token, formula::FormulaToken ***pppToken, sal_uInt8 nNumParams) override
const ScAddress & GetPos() const
void AutoCorrectParsedSymbol()
virtual void AnnotateOperands() override
bool HasPossibleNamedRangeConflict(SCTAB nTab) const
void SetFormulaLanguage(const OpCodeMapPtr &xMap)
Set symbol map if not empty.
virtual void CreateStringFromExternal(OUStringBuffer &rBuffer, const formula::FormulaToken *pToken) const override
bool ParseOpCode(const OUString &, bool bInArray)
virtual void fillFromAddInMap(const NonConstOpCodeMapPtr &xMap, formula::FormulaGrammar::Grammar _eGrammar) const override
void SetGrammarAndRefConvention(const formula::FormulaGrammar::Grammar eNewGrammar, const formula::FormulaGrammar::Grammar eOldGrammar)
Set grammar and reference convention from within SetFormulaLanguage() or SetGrammar().
std::unordered_set< formula::FormulaTokenRef > mUnhandledPossibleImplicitIntersections
static bool IsEnglishSymbol(const OUString &rName)
bool ParseSingleReference(const OUString &rSymbol, const OUString *pErrRef=nullptr)
void CreateStringFromXMLTokenArray(OUString &rFormula, OUString &rFormulaNmsp)
bool ParseOpCode2(std::u16string_view)
const ScInterpreterContext * mpInterpreterContext
static const Convention * pConventions[formula::FormulaGrammar::CONV_LAST]
virtual bool HandleRange() override
bool SkipImplicitIntersectionOptimization(const formula::FormulaToken *token) const
std::vector< TableRefEntry > maTableRefs
virtual void SetError(FormulaError nError) override
std::vector< PendingImplicitIntersectionOptimization > mPendingImplicitIntersectionOptimizations
ExtendedErrorDetection meExtendedErrorDetection
bool ToUpperAsciiOrI18nIsAscii(OUString &rUpper, const OUString &rOrg) const
std::vector< Whitespace > NextSymbol(bool bInArray)
const CharClass * pCharClass
static const CharClass * pCharClassEnglish
virtual void fillAddInToken(::std::vector< css::sheet::FormulaOpCodeMapEntry > &_rVec, bool _bIsEnglish) const override
void AnnotateTrimOnDoubleRefs()
sal_Int32 mnRangeOpPosInSymbol
void SetAutoCorrection(bool bVal)
When auto correction is set, the jump command reorder must be enabled.
virtual void LocalizeString(OUString &rName) const override
virtual bool HandleExternalReference(const formula::FormulaToken &_aToken) override
bool AdjustSumRangeShape(const ScComplexRefData &rBaseRange, ScComplexRefData &rSumRange)
bool ParseBoolean(const OUString &)
static const CharClass * pCharClassLocalized
void SetNumberFormatter(SvNumberFormatter *pFormatter)
bool mbRefConventionChartOOXML
virtual ~ScCompiler() override
std::vector< OUString > maTabNames
virtual bool HandleTableRef() override
virtual formula::ParamClass GetForceArrayParameter(const formula::FormulaToken *pToken, sal_uInt16 nParam) const override
bool ParseNamedRange(const OUString &, bool onlyCheck=false)
static bool ParameterMayBeImplicitIntersection(const formula::FormulaToken *token, int parameter)
static const CharClass * GetCharClassEnglish()
@ EXTENDED_ERROR_DETECTION_NAME_BREAK
@ EXTENDED_ERROR_DETECTION_NONE
@ EXTENDED_ERROR_DETECTION_NAME_NO_BREAK
virtual bool HandleDbData() override
bool ParseErrorConstant(const OUString &)
static bool IsCharFlagAllConventions(OUString const &rStr, sal_Int32 nPos, ScCharFlags nFlags)
If the character is allowed as tested by nFlags (SC_COMPILER_C_... bits) for all known address conven...
sal_Int32 mnCurrentSheetEndPos
std::set< OpCode > mUnhandledPossibleImplicitIntersectionsOpCodes
std::vector< sal_uInt16 > maExternalFiles
sal_uInt16 mnPredetectedReference
static void addWhitespace(std::vector< ScCompiler::Whitespace > &rvSpaces, ScCompiler::Whitespace &rSpace, sal_Unicode c, sal_Int32 n=1)
std::vector< OUString > & GetSetupTabNames() const
sheet names mangled for the current grammar for output
ScCompiler(sc::CompileFormulaContext &rCxt, const ScAddress &rPos, bool bComputeII=false, bool bMatrixFlag=false, const ScInterpreterContext *pContext=nullptr)
virtual formula::FormulaTokenRef ExtendRangeReference(formula::FormulaToken &rTok1, formula::FormulaToken &rTok2) override
virtual void fillFromAddInCollectionUpperName(const NonConstOpCodeMapPtr &xMap) const override
static size_t GetAddInMapCount()
bool ParseTableRefColumn(const OUString &)
bool ParseTableRefItem(const OUString &)
void SetRelNameReference()
ScCharFlags GetCharTableFlags(sal_Unicode c, sal_Unicode cLast)
Access the CharTable flags.
bool GetTokenIfOpCode(OpCode eOp)
Calls GetToken() if PeekNextNoSpaces() is of given OpCode.
static void CheckTabQuotes(OUString &aTabName, const formula::FormulaGrammar::AddressConvention eConv=formula::FormulaGrammar::CONV_OOO)
all
bool ParseColRowName(const OUString &)
bool ParseExternalNamedRange(const OUString &rSymbol, bool &rbInvalidExternalNameRange)
virtual void CreateStringFromMatrix(OUStringBuffer &rBuffer, const formula::FormulaToken *pToken) const override
virtual void CreateStringFromIndex(OUStringBuffer &rBuffer, const formula::FormulaToken *pToken) const override
bool ParsePredetectedErrRefReference(const OUString &rName, const OUString *pErrRef)
bool ParseValue(const OUString &)
void SetGrammar(const formula::FormulaGrammar::Grammar eGrammar)
virtual OUString FindAddInFunction(const OUString &rUpperName, bool bLocalFirst) const override
static const CharClass * GetCharClassLocalized()
virtual void CreateStringFromSingleRef(OUStringBuffer &rBuffer, const formula::FormulaToken *pToken) const override
static const Convention * GetRefConvention(formula::FormulaGrammar::AddressConvention eConv)
void SetRefConvention(const Convention *pConvP)
bool ParseDoubleReference(const OUString &rSymbol, const OUString *pErrRef=nullptr)
bool ParsePredetectedReference(const OUString &rSymbol)
bool NextNewToken(bool bInArray)
std::queue< OpCode > maPendingOpCodes
bool ParseReference(const OUString &rSymbol, const OUString *pErrRef=nullptr)
virtual void fillFromAddInCollectionEnglishName(const NonConstOpCodeMapPtr &xMap) const override
void ReplaceDoubleRefII(formula::FormulaToken **ppDoubleRefTok)
void AdjustSheetLocalNameRelReferences(SCTAB nDelta)
bool HandleIIOpCodeInternal(formula::FormulaToken *token, formula::FormulaToken ***pppToken, sal_uInt8 nNumParams)
sal_Unicode cSymbol[MAXSTRLEN+1]
bool ParseMacro(const OUString &)
virtual void PostProcessCode() override
SvNumberFormatter * mpFormatter
void CorrectSumRange(const ScComplexRefData &rBaseRange, ScComplexRefData &rSumRange, formula::FormulaToken **ppSumRangeToken)
virtual bool HandleColRowName() override
std::unique_ptr< ScTokenArray > CompileString(const OUString &rFormula)
Tokenize formula expression string into an array of tokens.
Stores global named database ranges.
ScDBData * findByIndex(sal_uInt16 nIndex)
ScDBData * findByUpperName(const OUString &rName)
const OUString & GetName() const
sal_Int32 GetColumnNameOffset(const OUString &rName) const
Finds the column named rName and returns the corresponding offset within the table.
void GetArea(SCTAB &rTab, SCCOL &rCol1, SCROW &rRow1, SCCOL &rCol2, SCROW &rRow2) const
bool IsLookUpColRowNames() const
ScSheetLimits & GetSheetLimits() const
bool ValidRow(SCROW nRow) const
ScFormulaParserPool & GetFormulaParserPool() const
Returns the pool containing external formula parsers.
SC_DLLPUBLIC bool GetTable(const OUString &rName, SCTAB &rTab) const
ScRangePairList * GetRowNameRanges()
SC_DLLPUBLIC SCCOL MaxCol() const
const ScDBData * GetDBAtCursor(SCCOL nCol, SCROW nRow, SCTAB nTab, ScDBDataPortion ePortion) const
bool ValidAddress(const ScAddress &rAddress) const
SC_DLLPUBLIC formula::FormulaGrammar::AddressConvention GetAddressConvention() const
ScRangeData * FindRangeNameBySheetAndIndex(SCTAB nTab, sal_uInt16 nIndex) const
Find a named expression / range name in either global or a local scope.
SC_DLLPUBLIC SCROW MaxRow() const
SC_DLLPUBLIC std::vector< OUString > GetAllTableNames() const
ScAutoNameCache * GetAutoNameCache()
SC_DLLPUBLIC ScExternalRefManager * GetExternalRefManager() const
SC_DLLPUBLIC bool HasStringData(SCCOL nCol, SCROW nRow, SCTAB nTab) const
ScRangePairList * GetColNameRanges()
SC_DLLPUBLIC formula::FormulaGrammar::Grammar GetGrammar() const
SC_DLLPUBLIC ScDBCollection * GetDBCollection() const
SfxObjectShell * GetDocumentShell() const
bool ValidCol(SCCOL nCol) const
SC_DLLPUBLIC svl::SharedStringPool & GetSharedStringPool()
SC_DLLPUBLIC ScRangeName * GetRangeName(SCTAB nTab) const
SC_DLLPUBLIC OUString GetString(SCCOL nCol, SCROW nRow, SCTAB nTab, const ScInterpreterContext *pContext=nullptr) const
SC_DLLPUBLIC bool GetName(SCTAB nTab, OUString &rName) const
SC_DLLPUBLIC const ScDocOptions & GetDocOptions() const
ScRefCellValue GetRefCellValue(const ScAddress &rPos)
bool IsImportingXML() const
std::shared_ptr< ScTokenArray > TokenArrayRef
sal_uInt16 getExternalFileId(const OUString &rFile)
const OUString * getRealTableName(sal_uInt16 nFileId, const OUString &rTabName) const
bool isValidRangeName(sal_uInt16 nFileId, const OUString &rName)
sal_uInt16 convertFileIdToUsedFileId(sal_uInt16 nFileId)
Reindex external file references to skip unused files, if skipping is enabled.
const OUString * getRealRangeName(sal_uInt16 nFileId, const OUString &rRangeName) const
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 convertToAbsName(OUString &rFile) const
Takes a flat file name, and convert it to an absolute URL path.
void insertRefCell(sal_uInt16 nFileId, const ScAddress &rCell)
void getAllCachedTableNames(sal_uInt16 nFileId, ::std::vector< OUString > &rTabNames) const
Returns a vector containing all (real) table names and cache tables of the specified file.
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 LegacyFuncCollection * GetLegacyFuncCollection()
static SC_DLLPUBLIC ::utl::TransliterationWrapper & GetTransliteration()
static SC_DLLPUBLIC ScUnoAddInCollection * GetAddInCollection()
static SC_DLLPUBLIC sal_Int32 FindUnquoted(const OUString &rString, sal_Unicode cChar, sal_Int32 nStart=0)
Finds an unquoted instance of cChar in rString, starting at offset nStart.
static SC_DLLPUBLIC const LocaleDataWrapper & getLocaleData()
static OUString GetErrorString(FormulaError nErrNumber)
static SC_DLLPUBLIC const CharClass & getCharClass()
Matrix data type that can store values of mixed types.
svl::SharedString GetString(SCSIZE nC, SCSIZE nR) const
bool IsStringOrEmpty(SCSIZE nIndex) const
bool IsEmpty(SCSIZE nC, SCSIZE nR) const
bool IsBoolean(SCSIZE nC, SCSIZE nR) const
double GetDouble(SCSIZE nC, SCSIZE nR) const
FormulaError GetError(SCSIZE nC, SCSIZE nR) const
May be used before obtaining the double value of an element to avoid passing its NAN around.
void GetDimensions(SCSIZE &rC, SCSIZE &rR) const
bool IsValue(SCSIZE nIndex) const
static formula::ParamClass GetParameterType(const formula::FormulaToken *pToken, sal_uInt16 nParameter)
Get one parameter type for function eOp.
SC_DLLPUBLIC FormulaError GetErrCode() const
bool HasReferences() const
SC_DLLPUBLIC ScRangeData * findByUpperName(const OUString &rName)
bool hasPossibleAddressConflict() const
const ScRange & GetRange(sal_uInt16 n) const
static void AppendTableName(OUStringBuffer &rBuf, const OUString &rTabName)
ScRange Intersection(const ScRange &rOther) const
const sal_Unicode * Parse_XL_Header(const sal_Unicode *pString, const ScDocument &rDocument, OUString &rExternDocName, OUString &rStartTabName, OUString &rEndTabName, ScRefFlags &nFlags, bool bOnlyAcceptSingle, const css::uno::Sequence< css::sheet::ExternalLinkInfo > *pExternalLinks=nullptr, const OUString *pErrRef=nullptr)
Parse an Excel style reference up to and including the sheet name separator '!', including detection ...
bool Contains(const ScAddress &) const
is Address& fully in Range?
ScRefFlags Parse(const OUString &, const ScDocument &, const ScAddress::Details &rDetails=ScAddress::detailsOOOa1, ScAddress::ExternalInfo *pExtInfo=nullptr, const css::uno::Sequence< css::sheet::ExternalLinkInfo > *pExternalLinks=nullptr, const OUString *pErrRef=nullptr)
static void MoveRelWrap(const ScDocument &rDoc, const ScAddress &rPos, SCCOL nMaxCol, SCROW nMaxRow, ScComplexRefData &rRef)
Special token to remember details of ocTableRef "structured references".
virtual sal_uInt16 GetIndex() const override
void SetAreaRefRPN(formula::FormulaToken *pToken)
formula::FormulaToken * GetAreaRefRPN() const
virtual formula::FormulaToken * AddOpCode(OpCode eCode) override
std::unique_ptr< ScTokenArray > Clone() const
formula::FormulaToken * AddRawToken(const ScRawToken &)
formula::FormulaToken * AddDoubleReference(const ScComplexRefData &rRef)
formula::FormulaToken * AddSingleReference(const ScSingleRefData &rRef)
ScSingleRefToken with ocPush.
static SC_DLLPUBLIC bool ConvertToTokenArray(ScDocument &rDoc, ScTokenArray &rTokenArray, const css::uno::Sequence< css::sheet::FormulaToken > &rSequence)
void LocalizeString(OUString &rName)
modify rName - input: exact name
const ScUnoAddInFuncData * GetFuncData(const OUString &rName, bool bComplete=false)
Only if bComplete is set, the function reference and argument types are initialized (component may ha...
tools::Long GetFuncCount()
OUString FindFunction(const OUString &rUpperName, bool bLocalFirst)
User entered name. rUpperName MUST already be upper case!
const OUString & GetUpperLocal() const
const OUString & GetUpperEnglish() const
bool GetExcelName(const LanguageTag &rDestLang, OUString &rRetExcelName, bool bFallbackToAny=true) const
const OUString & GetUpperName() const
const OUString & GetOriginalName() const
static void FillApiAddress(css::table::CellAddress &rApiAddress, const ScAddress &rScAddress)
static StarBASIC * GetBasic()
StarBASIC * GetBasic() const
virtual SbxVariable * Find(const OUString &, SbxClassType) override
formula::FormulaGrammar::Grammar getGrammar() const
SharedString intern(const OUString &rStr)
const OUString & getString() const
rtl_uString * getDataIgnoreCase()
bool isEqual(const OUString &rStr1, const OUString &rStr2) const
static sal_Unicode * lcl_UnicodeStrNCpy(sal_Unicode *pDst, const sal_Unicode *pSrc, sal_Int32 nMax)
static void r1c1_add_col(OUStringBuffer &rBuf, const ScSingleRefData &rRef, const ScAddress &rAbsRef)
static bool lcl_ParenthesisFollows(const sal_Unicode *p)
static std::mutex & getCharClassMutex()
static OUString lcl_makeExternalNameStr(const OUString &rFile, const OUString &rName, const sal_Unicode cSep, bool bODF)
static void r1c1_add_row(OUStringBuffer &rBuf, const ScSingleRefData &rRef, const ScAddress &rAbsRef)
static bool lcl_isValidQuotedText(std::u16string_view rFormula, size_t nSrcPos, ParseResult &rRes)
static bool lcl_getLastTabName(OUString &rTabName2, const OUString &rTabName1, const vector< OUString > &rTabNames, const ScRange &rRef)
static bool lcl_isUnicodeIgnoreAscii(const sal_Unicode *p1, const char *p2, size_t n)
static const char * pInternal[2]
static void lcl_GetColRowDeltas(const ScRange &rRange, SCCOL &rXDelta, SCROW &rYDelta)
static bool lcl_parseExternalName(const OUString &rSymbol, OUString &rFile, OUString &rName, const sal_Unicode cSep, const ScDocument &rDoc, const uno::Sequence< sheet::ExternalLinkInfo > *pExternalLinks)
#define SC_OPCODE_STOP_BIN_OP
#define SC_OPCODE_STOP_1_PAR
#define SC_OPCODE_STOP_UN_OP
#define SC_OPCODE_START_UN_OP
#define SC_COMPILER_FILE_TAB_SEP
#define SC_OPCODE_START_1_PAR
#define SC_OPCODE_START_BIN_OP
#define LANGUAGE_ENGLISH_US
#define SAL_WARN_IF(condition, area, stream)
#define SAL_WARN(area, stream)
std::unique_ptr< sal_Int32[]> pData
OString strip(const OString &rIn, char c)
sal_Int32 getTokenCount(std::string_view rIn, char cTok)
constexpr std::enable_if_t< std::is_signed_v< T >, std::make_unsigned_t< T > > make_unsigned(T value)
bool equalsIgnoreAsciiCase(std::u16string_view s1, std::u16string_view s2)
bool equalsAscii(std::u16string_view s1, std::string_view s2)
PyRef getCharClass(const Runtime &)
OUString ScResId(TranslateId aId)
virtual css::i18n::ParseResult parseAnyToken(const OUString &rFormula, sal_Int32 nSrcPos, const CharClass *pCharClass, bool bGroupSeparator) const =0
@ ABS_SHEET_PREFIX
In OOO A1, a sheet name may be prefixed with '$' to indicate an absolute sheet position.
@ SHEET_SEPARATOR
Character between sheet name and address.
const formula::FormulaGrammar::AddressConvention meConv
virtual sal_Unicode getSpecialSymbol(SpecialSymbolType eSymType) const =0
std::unique_ptr< ScCharFlags[]> mpCharTable
virtual OUString makeExternalNameStr(sal_uInt16 nFileId, const OUString &rFile, const OUString &rName) const =0
virtual bool parseExternalName(const OUString &rSymbol, OUString &rFile, OUString &rName, const ScDocument &rDoc, const css::uno::Sequence< css::sheet::ExternalLinkInfo > *pExternalLinks) const =0
Parse the symbol string and pick up the file name and the external range name.
virtual void makeExternalRefStr(ScSheetLimits &rLimits, OUStringBuffer &rBuffer, const ScAddress &rPos, sal_uInt16 nFileId, const OUString &rFileName, const OUString &rTabName, const ScSingleRefData &rRef) const =0
virtual void makeRefStr(ScSheetLimits &rLimits, OUStringBuffer &rBuffer, formula::FormulaGrammar::Grammar eGram, const ScAddress &rPos, const OUString &rErrRef, const std::vector< OUString > &rTabNames, const ScComplexRefData &rRef, bool bSingleRef, bool bFromRangeName) const =0
Convention(formula::FormulaGrammar::AddressConvention eConvP)
"stack" of currently active ocTableRef tokens
void reset(sal_Unicode c)
Complex reference (a range) into the sheet.
SC_DLLPUBLIC ScRange toAbs(const ScSheetLimits &rLimits, const ScAddress &rPos) const
void InitRange(const ScRange &rRange)
bool IsEntireRow(const ScSheetLimits &rLimits) const
Whether this references entire rows, 1:1.
void SetRange(const ScSheetLimits &rLimits, const ScRange &rRange, const ScAddress &rPos)
Set a new range, assuming that the ordering of the range matches the ordering of the reference data f...
void SetTrimToData(bool bSet)
bool IsEntireCol(const ScSheetLimits &rLimits) const
Whether this references entire columns, A:A.
void SetExternalDoubleRef(sal_uInt16 nFileId, const OUString &rTabName, const ScComplexRefData &rRef)
void SetDouble(double fVal)
void SetString(rtl_uString *pData, rtl_uString *pDataIgnoreCase)
void SetDoubleReference(const ScComplexRefData &rRef)
void SetExternalSingleRef(sal_uInt16 nFileId, const OUString &rTabName, const ScSingleRefData &rRef)
void SetOpCode(OpCode eCode)
struct ScRawToken::@17::@19 whitespace
struct ScRawToken::@17::@20 sbyte
void SetName(sal_Int16 nSheet, sal_uInt16 nIndex)
bool IsValidReference(const ScDocument &rDoc) const
If the token is a non-external reference, determine if the reference is valid.
void SetSingleReference(const ScSingleRefData &rRef)
void SetErrorConstant(FormulaError nErr)
void SetExternalName(sal_uInt16 nFileId, const OUString &rName)
void SetExternal(const OUString &rStr)
formula::FormulaToken * CreateToken(ScSheetLimits &rLimits) const
This is very similar to ScCellValue, except that it references the original value instead of copying ...
bool ValidAddress(const ScAddress &rAddress) const
bool ValidRow(SCROW nRow) const
const SCROW mnMaxRow
Maximum addressable column.
bool ValidCol(SCCOL nCol) const
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 SetRowRel(bool bVal)
void SetTabRel(bool bVal)
void SetColDeleted(bool bVal)
ScAddress toAbs(const ScSheetLimits &rLimits, const ScAddress &rPos) const
bool IsTabDeleted() const
void SetFlag3D(bool bVal)
void InitFlags()
No default ctor, because used in ScRawToken union, set InitFlags!
void SetRelName(bool bVal)
void SetRowDeleted(bool bVal)
bool IsColDeleted() const
void SetColRel(bool bVal)
void SetTabDeleted(bool bVal)
FormulaTokenRef extendRangeReference(ScSheetLimits &rLimits, FormulaToken &rTok1, FormulaToken &rTok2, const ScAddress &rPos, bool bReuseDoubleRef)
If rTok1 and rTok2 both are SingleRef or DoubleRef tokens, extend/merge ranges as needed for ocRange.
std::unique_ptr< char[]> aBuffer