20 #include <config_features.h>
22 #include <compiler.hxx>
34 #include <osl/diagnose.h>
35 #include <rtl/character.hxx>
38 #include <com/sun/star/lang/Locale.hpp>
39 #include <com/sun/star/sheet/FormulaOpCodeMapEntry.hpp>
40 #include <com/sun/star/sheet/FormulaLanguage.hpp>
41 #include <com/sun/star/i18n/KParseTokens.hpp>
42 #include <com/sun/star/i18n/KParseType.hpp>
47 #include <rtl/math.hxx>
48 #include <rtl/ustring.hxx>
53 #include <document.hxx>
57 #include <globstr.hrc>
70 #include <tokenarray.hxx>
73 #include <officecfg/Office/Common.hxx>
103 static const char*
pInternal[2] = {
"TTT",
"__DEBUG_VAR" };
109 size_t nSymbolOffset;
113 nSymbolOffset = offsetof(
AddInMap, pUpper);
117 nSymbolOffset = offsetof(
AddInMap, pODFF);
120 nSymbolOffset = offsetof(
AddInMap, pEnglish);
124 const AddInMap*
const pStop = pMap + GetAddInMapCount();
125 for ( ; pMap < pStop; ++pMap)
127 char const *
const * ppSymbol =
128 reinterpret_cast< char const *
const *
>(
129 reinterpret_cast< char const *
>(pMap) + nSymbolOffset);
130 xMap->putExternal( OUString::createFromAscii( *ppSymbol),
131 OUString::createFromAscii( pMap->
pOriginal));
169 if (pCharClassEnglish)
171 delete pCharClassEnglish;
172 pCharClassEnglish =
nullptr;
174 if (pCharClassLocalized)
176 delete pCharClassLocalized;
177 pCharClassLocalized =
nullptr;
184 OUString aUpper = GetCharClassEnglish()->uppercase(rName);
201 return !aIntName.isEmpty();
206 if (!pCharClassEnglish)
208 css::lang::Locale aLocale(
"en",
"US",
"");
212 return pCharClassEnglish;
217 if (!pCharClassLocalized)
224 return pCharClassLocalized;
230 if (eGrammar == GetGrammar())
235 meGrammar = eGrammar;
236 mxSymbols = GetOpCodeMap( css::sheet::FormulaLanguage::NATIVE);
243 OSL_ENSURE( xMap,
"ScCompiler::SetGrammar: unknown formula language");
246 xMap = GetOpCodeMap( css::sheet::FormulaLanguage::NATIVE);
247 eMyGrammar = xMap->getGrammar();
253 SetFormulaLanguage( xMap);
256 if (eMyGrammar != GetGrammar())
257 SetGrammarAndRefConvention( eMyGrammar, eOldGrammar);
266 std::vector<OUString> &rTabNames =
const_cast<ScCompiler *
>(
this)->maTabNames;
268 if (rTabNames.empty())
270 rTabNames = rDoc.GetAllTableNames();
271 for (
auto& rTabName : rTabNames)
280 mpFormatter = pFormatter;
289 if (mxSymbols->isEnglish())
290 pCharClass = GetCharClassEnglish();
292 pCharClass = GetCharClassLocalized();
300 const LanguageTag& rLT2 = pCharClass->getLanguageTag();
303 SetGrammarAndRefConvention( mxSymbols->getGrammar(), GetGrammar());
309 meGrammar = eNewGrammar;
312 SetRefConvention( rDoc.GetAddressConvention());
314 SetRefConvention( eConv );
333 ScCompiler::pConventions[
meConv ] =
this;
336 for (i = 0; i < 128; i++)
350 if (FormulaGrammar::CONV_ODF ==
meConv)
355 if (FormulaGrammar::CONV_ODF ==
meConv)
369 for (i = 48; i < 58; i++)
380 for (i = 65; i < 91; i++)
383 if (FormulaGrammar::CONV_ODF ==
meConv)
389 else if (FormulaGrammar::CONV_OOO ==
meConv)
395 else if (FormulaGrammar::CONV_XL_OOX ==
meConv)
401 else if (FormulaGrammar::CONV_XL_A1 ==
meConv)
407 else if( FormulaGrammar::CONV_XL_R1C1 ==
meConv )
424 for (i = 97; i < 123; i++)
433 if( !(FormulaGrammar::CONV_XL_A1 ==
meConv || FormulaGrammar::CONV_XL_R1C1 ==
meConv || FormulaGrammar::CONV_XL_OOX ==
meConv) )
478 if (nSrcPos < rFormula.getLength() && rFormula[
nSrcPos] ==
'\'')
480 sal_Int32
nPos = nSrcPos+1;
481 while (nPos < rFormula.getLength())
483 if (rFormula[nPos] ==
'\'')
485 if ( (nPos+1 == rFormula.getLength()) || (rFormula[nPos+1] !=
'\'') )
487 rRes.TokenType = KParseType::SINGLE_QUOTE_NAME;
488 rRes.EndPos = nPos+1;
501 const OUString& rSymbol,
506 const uno::Sequence<sheet::ExternalLinkInfo>* pExternalLinks )
510 const sal_Unicode*
const pStart = rSymbol.getStr();
512 sal_Int32 nLen = rSymbol.getLength();
514 OUStringBuffer aTmpName;
516 bool bInName =
false;
522 OUString aStartTabName, aEndTabName;
525 aEndTabName, nFlags,
true, pExternalLinks );
526 if (!p || p == pStart)
528 i = sal_Int32(p - pStart);
530 for ( ; i < nLen; ++i, ++p)
535 if (c ==
'.' || c == cSep)
544 for (sal_Int32 j = i; j < nLen; ++j, ++p)
559 aTmpFile += OUStringChar(c);
568 if (cPrev ==
'\'' && j != i)
580 aTmpFile += OUStringChar(c);
620 if (rtl::isAsciiAlphanumeric(c))
644 aTmpFile += OUStringChar(c);
655 sal_Int32 nNameLen = aTmpName.getLength();
662 if (aTmpName[0] != cSep)
668 if (aTmpName[nNameLen-1] ==
'!')
671 if (aTmpName.toString().equalsIgnoreAsciiCase(
"#REF!"))
676 rName = aTmpName.makeStringAndClear().copy(1);
683 OUString aEscQuote(
"''");
684 OUString aFile(rFile.replaceAll(
"'", aEscQuote));
685 OUString
aName(rName);
687 aName = aName.replaceAll(
"'", aEscQuote);
688 OUStringBuffer
aBuf(aFile.getLength() + aName.getLength() + 9);
691 aBuf.append(
"'" ).append( aFile ).append(
"'" ).append( OUStringChar(cSep) );
693 aBuf.append(
"$$'" );
697 return aBuf.makeStringAndClear();
701 const vector<OUString>& rTabNames,
const ScRange& rRef )
706 size_t nCount = rTabNames.size();
707 vector<OUString>::const_iterator itrBeg = rTabNames.begin(), itrEnd = rTabNames.end();
708 vector<OUString>::const_iterator itr = ::std::find(itrBeg, itrEnd, rTabName1);
709 if (itr == rTabNames.end())
711 rTabName2 =
ScResId(STR_NO_REF_TABLE);
715 size_t nDist = ::std::distance(itrBeg, itr);
716 if (nDist + static_cast<size_t>(nTabSpan) >= nCount)
718 rTabName2 =
ScResId(STR_NO_REF_TABLE);
722 rTabName2 = rTabNames[nDist+nTabSpan];
725 rTabName2 = rTabName1;
735 static void MakeColStr(
const ScSheetLimits& rLimits, OUStringBuffer& rBuffer,
SCCOL nCol );
736 static void MakeRowStr(
const ScSheetLimits& rLimits, OUStringBuffer& rBuffer,
SCROW nRow );
738 ParseResult parseAnyToken(
const OUString& rFormula,
741 bool bGroupSeparator)
const override
747 constexpr sal_Int32 nStartFlags = KParseTokens::ANY_LETTER_OR_NUMBER |
748 KParseTokens::ASC_UNDERSCORE | KParseTokens::ASC_DOLLAR;
749 constexpr sal_Int32 nContFlags = nStartFlags | KParseTokens::ASC_DOT;
751 static constexpr OUStringLiteral aAddAllowed(u
"?#");
753 nSrcPos, nStartFlags, aAddAllowed,
754 (bGroupSeparator ? nContFlags | KParseTokens::GROUP_SEPARATOR_IN_NUMBER : nContFlags),
760 return mpCharTable[
static_cast<sal_uInt8>(c)];
766 void Convention_A1::MakeColStr(
const ScSheetLimits& rLimits, OUStringBuffer& rBuffer,
SCCOL nCol )
769 rBuffer.append(
ScResId(STR_NO_REF_TABLE));
774 void Convention_A1::MakeRowStr(
const ScSheetLimits& rLimits, OUStringBuffer& rBuffer,
SCROW nRow )
777 rBuffer.append(
ScResId(STR_NO_REF_TABLE));
779 rBuffer.append(sal_Int32(nRow + 1));
784 struct ConventionOOO_A1 :
public Convention_A1
789 static void MakeTabStr( OUStringBuffer &rBuf,
const std::vector<OUString>& rTabNames,
SCTAB nTab )
792 rBuf.append(
ScResId(STR_NO_REF_TABLE));
794 rBuf.append(rTabNames[nTab]);
798 enum SingletonDisplay
805 static void MakeOneRefStrImpl(
807 const OUString& rErrRef,
const std::vector<OUString>& rTabNames,
809 bool bForceTab,
bool bODF, SingletonDisplay eSingletonDisplay )
815 eSingletonDisplay = SINGLETON_NONE;
823 rBuffer.append(rErrRef);
830 MakeTabStr(rBuffer, rTabNames, rAbsRef.
Tab());
836 if (eSingletonDisplay != SINGLETON_ROW)
841 rBuffer.append(rErrRef);
843 MakeColStr(rLimits, rBuffer, rAbsRef.
Col());
846 if (eSingletonDisplay != SINGLETON_COL)
851 rBuffer.append(rErrRef);
853 MakeRowStr(rLimits, rBuffer, rAbsRef.
Row());
863 return SINGLETON_NONE;
867 return SINGLETON_COL;
871 if (!bFromRangeName && rAbs1.
Row() == 0 && rAbs2.
Row() == rLimits.
mnMaxRow &&
873 return SINGLETON_COL;
877 return SINGLETON_ROW;
881 if (!bFromRangeName && rAbs1.
Col() == 0 && rAbs2.
Col() == rLimits.
mnMaxCol &&
883 return SINGLETON_ROW;
885 return SINGLETON_NONE;
888 virtual void makeRefStr(
890 OUStringBuffer& rBuffer,
893 const OUString& rErrRef,
const std::vector<OUString>& rTabNames,
896 bool bFromRangeName )
const override
904 SingletonDisplay eSingleton = bSingleRef ? SINGLETON_NONE :
905 getSingletonDisplay( rLimits, aAbs1, aAbs2, rRef, bFromRangeName);
906 MakeOneRefStrImpl(rLimits, rBuffer, rErrRef, rTabNames, rRef.
Ref1, aAbs1,
false,
false, eSingleton);
910 MakeOneRefStrImpl(rLimits, rBuffer, rErrRef, rTabNames, rRef.
Ref2, aAbs2, aAbs1.
Tab() != aAbs2.Tab(),
false,
915 virtual sal_Unicode getSpecialSymbol( SpecialSymbolType eSymType )
const override
928 virtual bool parseExternalName(
const OUString& rSymbol, OUString& rFile, OUString& rName,
930 const uno::Sequence<sheet::ExternalLinkInfo>* pExternalLinks )
const override
935 virtual OUString makeExternalNameStr( sal_uInt16 ,
const OUString& rFile,
936 const OUString& rName )
const override
941 static bool makeExternalSingleRefStr(
943 OUStringBuffer& rBuffer,
const OUString& rFileName,
const OUString& rTabName,
955 rBuffer.append(
"'").append(aFile.replaceAll(
"'",
"''")).append(
"'#");
966 MakeColStr( rLimits, rBuffer, aAbsRef.
Col());
969 MakeRowStr( rLimits, rBuffer, aAbsRef.
Row());
974 static void makeExternalRefStrImpl(
976 OUStringBuffer& rBuffer,
const ScAddress& rPos,
const OUString& rFileName,
980 rBuffer.append(
'[');
982 bool bEncodeUrl = bODF;
983 makeExternalSingleRefStr(rLimits, rBuffer, rFileName, rTabName, rRef, rPos,
true, bEncodeUrl);
985 rBuffer.append(
']');
988 virtual void makeExternalRefStr(
990 OUStringBuffer& rBuffer,
const ScAddress& rPos, sal_uInt16 ,
const OUString& rFileName,
993 makeExternalRefStrImpl(rLimits, rBuffer, rPos, rFileName, rTabName, rRef,
false);
996 static void makeExternalRefStrImpl(
998 OUStringBuffer& rBuffer,
const ScAddress& rPos,
const OUString& rFileName,
999 const std::vector<OUString>& rTabNames,
const OUString& rTabName,
1005 rBuffer.append(
'[');
1007 bool bEncodeUrl = bODF;
1011 if (!makeExternalSingleRefStr(rLimits, rBuffer, rFileName, rTabName, rRef.
Ref1, rPos,
true, bEncodeUrl))
1014 rBuffer.append(
':');
1016 OUString aLastTabName;
1018 if (bDisplayTabName)
1023 OSL_FAIL(
"ConventionOOO_A1::makeExternalRefStrImpl: sheet name not found");
1028 rBuffer.append(
'.');
1029 makeExternalSingleRefStr(rLimits,
1030 rBuffer, rFileName, aLastTabName, rRef.
Ref2, rPos, bDisplayTabName, bEncodeUrl);
1034 rBuffer.append(
']');
1037 virtual void makeExternalRefStr(
1039 OUStringBuffer& rBuffer,
const ScAddress& rPos, sal_uInt16 ,
const OUString& rFileName,
1040 const std::vector<OUString>& rTabNames,
const OUString& rTabName,
1043 makeExternalRefStrImpl(rLimits, rBuffer, rPos, rFileName, rTabNames, rTabName, rRef,
false);
1047 struct ConventionOOO_A1_ODF :
public ConventionOOO_A1
1049 ConventionOOO_A1_ODF() : ConventionOOO_A1 (
FormulaGrammar::CONV_ODF) { }
1051 virtual void makeRefStr(
1053 OUStringBuffer& rBuffer,
1056 const OUString& rErrRef,
const std::vector<OUString>& rTabNames,
1059 bool bFromRangeName )
const override
1061 rBuffer.append(
'[');
1071 rBuffer.append(rErrRef);
1078 SingletonDisplay eSingleton = bSingleRef ? SINGLETON_NONE :
1079 getSingletonDisplay( rLimits, aAbs1, aAbs2, rRef, bFromRangeName);
1080 MakeOneRefStrImpl(rLimits, rBuffer, rErrRef, rTabNames, rRef.
Ref1, aAbs1,
false,
true, eSingleton);
1083 rBuffer.append(
':');
1084 MakeOneRefStrImpl(rLimits, rBuffer, rErrRef, rTabNames, rRef.
Ref2, aAbs2, aAbs1.
Tab() != aAbs2.Tab(),
true,
1088 rBuffer.append(
']');
1091 virtual OUString makeExternalNameStr( sal_uInt16 ,
const OUString& rFile,
1092 const OUString& rName )
const override
1097 virtual void makeExternalRefStr(
1099 OUStringBuffer& rBuffer,
const ScAddress& rPos, sal_uInt16 ,
const OUString& rFileName,
1100 const OUString& rTabName,
const ScSingleRefData& rRef )
const override
1102 makeExternalRefStrImpl(rLimits, rBuffer, rPos, rFileName, rTabName, rRef,
true);
1105 virtual void makeExternalRefStr(
1107 OUStringBuffer& rBuffer,
const ScAddress& rPos, sal_uInt16 ,
const OUString& rFileName,
1108 const std::vector<OUString>& rTabNames,
1111 makeExternalRefStrImpl(rLimits, rBuffer, rPos, rFileName, rTabNames, rTabName, rRef,
true);
1117 virtual ~ConventionXL()
1123 const ScAddress& rPos,
const std::vector<OUString>& rTabNames,
1129 rTabName =
ScResId( STR_NO_REF_TABLE );
1132 rTabName = rTabNames[aAbs.
Tab()];
1135 static void MakeTabStr(
const ScSheetLimits& rLimits, OUStringBuffer& rBuf,
1137 const std::vector<OUString>& rTabNames,
1144 OUString aStartTabName, aEndTabName;
1146 GetTab(rLimits, rPos, rTabNames, rRef.
Ref1, aStartTabName);
1150 GetTab(rLimits, rPos, rTabNames, rRef.
Ref2, aEndTabName);
1153 rBuf.append( aStartTabName );
1154 if( !bSingleRef && rRef.
Ref2.
IsFlag3D() && aStartTabName != aEndTabName )
1157 rBuf.append( aEndTabName );
1175 static bool parseExternalName(
const OUString& rSymbol, OUString& rFile, OUString& rName,
1177 const uno::Sequence<sheet::ExternalLinkInfo>* pExternalLinks )
1182 static OUString makeExternalNameStr(
const OUString& rFile,
const OUString& rName )
1187 static void makeExternalDocStr( OUStringBuffer& rBuffer,
const OUString& rFullName )
1196 rBuffer.append(
'[');
1197 rBuffer.append(
'\'');
1201 sal_Int32 nLen = aFullName.getLength();
1202 for (sal_Int32 i = 0;
i < nLen; ++
i)
1209 rBuffer.append(
'\'');
1210 rBuffer.append(
']');
1213 static void makeExternalTabNameRange( OUStringBuffer& rBuf,
const OUString& rTabName,
1214 const vector<OUString>& rTabNames,
1217 OUString aLastTabName;
1225 if (rTabName != aLastTabName)
1232 virtual void parseExternalDocName(
const OUString& rFormula, sal_Int32& rSrcPos )
const
1234 sal_Int32 nLen = rFormula.getLength();
1237 for (sal_Int32 i = rSrcPos;
i < nLen; ++
i)
1246 else if (i == rSrcPos + 1)
1266 if (rSrcPos >= nLen)
1276 if (i > rSrcPos + 2 && cPrev ==
'\'')
1286 struct ConventionXL_A1 :
public Convention_A1,
public ConventionXL
1288 ConventionXL_A1() : Convention_A1(
FormulaGrammar::CONV_XL_A1 ) { }
1295 MakeColStr(rLimits, rBuf, rAbs.
Col());
1298 MakeRowStr(rLimits, rBuf, rAbs.
Row());
1301 virtual void makeRefStr(
1303 OUStringBuffer& rBuf,
1306 const OUString& rErrRef,
const std::vector<OUString>& rTabNames,
1309 bool )
const override
1315 ScAddress aAbs1 = aRef.Ref1.toAbs(rLimits, rPos), aAbs2;
1317 MakeTabStr(rLimits, rBuf, rPos, rTabNames, aRef, bSingleRef);
1321 rBuf.append(rErrRef);
1327 aAbs2 = aRef.Ref2.toAbs(rLimits, rPos);
1330 rBuf.append(rErrRef);
1334 if (aAbs1.
Col() == 0 && aAbs2.Col() >= rLimits.
mnMaxCol)
1336 if (!aRef.Ref1.IsRowRel())
1338 MakeRowStr(rLimits, rBuf, aAbs1.
Row());
1340 if (!aRef.Ref2.IsRowRel())
1342 MakeRowStr(rLimits, rBuf, aAbs2.Row());
1346 if (aAbs1.
Row() == 0 && aAbs2.Row() >= rLimits.
mnMaxRow)
1348 if (!aRef.Ref1.IsColRel())
1350 MakeColStr(rLimits, rBuf, aAbs1.
Col());
1352 if (!aRef.Ref2.IsColRel())
1354 MakeColStr(rLimits, rBuf, aAbs2.Col());
1359 makeSingleCellStr(rLimits, rBuf, aRef.Ref1, aAbs1);
1363 makeSingleCellStr(rLimits, rBuf, aRef.Ref2, aAbs2);
1367 virtual ParseResult parseAnyToken(
const OUString& rFormula,
1370 bool bGroupSeparator)
const override
1372 parseExternalDocName(rFormula, nSrcPos);
1378 constexpr sal_Int32 nStartFlags = KParseTokens::ANY_LETTER_OR_NUMBER |
1379 KParseTokens::ASC_UNDERSCORE | KParseTokens::ASC_DOLLAR;
1380 constexpr sal_Int32 nContFlags = nStartFlags | KParseTokens::ASC_DOT;
1382 static constexpr OUStringLiteral aAddAllowed(u
"?!");
1384 nSrcPos, nStartFlags, aAddAllowed,
1385 (bGroupSeparator ? nContFlags | KParseTokens::GROUP_SEPARATOR_IN_NUMBER : nContFlags),
1389 virtual sal_Unicode getSpecialSymbol( SpecialSymbolType eSymType )
const override
1391 return ConventionXL::getSpecialSymbol(eSymType);
1394 virtual bool parseExternalName(
const OUString& rSymbol, OUString& rFile, OUString& rName,
1396 const uno::Sequence<sheet::ExternalLinkInfo>* pExternalLinks )
const override
1398 return ConventionXL::parseExternalName( rSymbol, rFile, rName, rDoc, pExternalLinks);
1401 virtual OUString makeExternalNameStr( sal_uInt16 ,
const OUString& rFile,
1402 const OUString& rName )
const override
1404 return ConventionXL::makeExternalNameStr(rFile, rName);
1407 virtual void makeExternalRefStr(
1409 OUStringBuffer& rBuffer,
const ScAddress& rPos, sal_uInt16 ,
const OUString& rFileName,
1410 const OUString& rTabName,
const ScSingleRefData& rRef )
const override
1418 ConventionXL::makeExternalDocStr(rBuffer, rFileName);
1420 rBuffer.append(
'!');
1422 makeSingleCellStr(rLimits, rBuffer, rRef, rRef.
toAbs(rLimits, rPos));
1425 virtual void makeExternalRefStr(
1427 OUStringBuffer& rBuffer,
const ScAddress& rPos, sal_uInt16 ,
const OUString& rFileName,
1428 const std::vector<OUString>& rTabNames,
const OUString& rTabName,
1433 ConventionXL::makeExternalDocStr(rBuffer, rFileName);
1434 ConventionXL::makeExternalTabNameRange(rBuffer, rTabName, rTabNames, aAbsRef);
1435 rBuffer.append(
'!');
1437 makeSingleCellStr(rLimits, rBuffer, rRef.
Ref1, aAbsRef.
aStart);
1440 rBuffer.append(
':');
1441 makeSingleCellStr(rLimits, rBuffer, rRef.
Ref2, aAbsRef.
aEnd);
1446 struct ConventionXL_OOX :
public ConventionXL_A1
1448 ConventionXL_OOX() : ConventionXL_A1(
FormulaGrammar::CONV_XL_OOX ) { }
1451 OUStringBuffer& rBuf,
1454 const OUString& rErrRef,
const std::vector<OUString>& rTabNames,
1457 bool bFromRangeName )
const override
1478 rBuf.append(rErrRef);
1487 rBuf.append(rErrRef);
1498 rBuf.append(rErrRef);
1503 ConventionXL_A1::makeRefStr( rLimits, rBuf, eGram,
aPos, rErrRef, rTabNames, rRef, bSingleRef, bFromRangeName);
1506 virtual OUString makeExternalNameStr( sal_uInt16 nFileId,
const OUString& ,
1507 const OUString& rName )
const override
1510 return OUString(
"[" + OUString::number(nFileId+1) +
"]!" + rName );
1518 virtual void parseExternalDocName(
const OUString& rFormula, sal_Int32& rSrcPos)
const override
1520 sal_Int32 nLen = rFormula.getLength();
1522 for (sal_Int32 i = rSrcPos;
i < nLen; ++
i)
1539 virtual void makeExternalRefStr(
1541 OUStringBuffer& rBuffer,
const ScAddress& rPos, sal_uInt16 nFileId,
const OUString& ,
1542 const OUString& rTabName,
const ScSingleRefData& rRef )
const override
1548 OUString aQuotedTab( rTabName);
1550 if (!aQuotedTab.isEmpty() && aQuotedTab[0] ==
'\'')
1552 rBuffer.append(
'\'');
1553 ConventionXL_OOX::makeExternalDocStr( rBuffer, nFileId);
1554 rBuffer.append( aQuotedTab.copy(1));
1558 ConventionXL_OOX::makeExternalDocStr( rBuffer, nFileId);
1559 rBuffer.append( aQuotedTab);
1561 rBuffer.append(
'!');
1563 makeSingleCellStr(rLimits, rBuffer, rRef, rRef.
toAbs(rLimits, rPos));
1566 virtual void makeExternalRefStr(
1568 OUStringBuffer& rBuffer,
const ScAddress& rPos, sal_uInt16 nFileId,
const OUString& ,
1569 const std::vector<OUString>& rTabNames,
const OUString& rTabName,
1580 OUStringBuffer
aBuf;
1581 ConventionXL::makeExternalTabNameRange( aBuf, rTabName, rTabNames, aAbsRef);
1582 if (!aBuf.isEmpty() && aBuf[0] ==
'\'')
1584 rBuffer.append(
'\'');
1585 ConventionXL_OOX::makeExternalDocStr( rBuffer, nFileId);
1586 rBuffer.append( aBuf.copy(1));
1590 ConventionXL_OOX::makeExternalDocStr( rBuffer, nFileId);
1591 rBuffer.append( aBuf);
1593 rBuffer.append(
'!');
1595 makeSingleCellStr(rLimits, rBuffer, rRef.
Ref1, aAbsRef.
aStart);
1598 rBuffer.append(
':');
1599 makeSingleCellStr(rLimits, rBuffer, rRef.
Ref2, aAbsRef.
aEnd);
1603 static void makeExternalDocStr( OUStringBuffer& rBuffer, sal_uInt16 nFileId )
1605 rBuffer.append(
'[').append( OUString::number( nFileId+1)).append(
']');
1619 rBuf.append(
"[").append(OUString::number(nCol)).append(
"]");
1622 rBuf.append( OUString::number( rAbsRef.
Col() + 1 ) );
1630 if (rRef.
Row() != 0)
1632 rBuf.append(
"[").append( OUString::number(rRef.
Row()) ).append(
"]");
1636 rBuf.append( OUString::number( rAbsRef.
Row() + 1 ) );
1646 OUStringBuffer& rBuf,
1649 const OUString& rErrRef,
const std::vector<OUString>& rTabNames,
1652 bool )
const override
1657 MakeTabStr(rLimits, rBuf, rPos, rTabNames, aRef, bSingleRef);
1663 rBuf.append(rErrRef);
1671 rBuf.append(rErrRef);
1711 ParseResult parseAnyToken(
const OUString& rFormula,
1714 bool bGroupSeparator)
const override
1716 parseExternalDocName(rFormula, nSrcPos);
1722 constexpr sal_Int32 nStartFlags = KParseTokens::ANY_LETTER_OR_NUMBER |
1723 KParseTokens::ASC_UNDERSCORE ;
1724 constexpr sal_Int32 nContFlags = nStartFlags | KParseTokens::ASC_DOT;
1726 static constexpr OUStringLiteral aAddAllowed(u
"?-[]!");
1729 nSrcPos, nStartFlags, aAddAllowed,
1730 (bGroupSeparator ? nContFlags | KParseTokens::GROUP_SEPARATOR_IN_NUMBER : nContFlags),
1734 virtual sal_Unicode getSpecialSymbol( SpecialSymbolType eSymType )
const override
1736 return ConventionXL::getSpecialSymbol(eSymType);
1739 virtual bool parseExternalName(
const OUString& rSymbol, OUString& rFile, OUString& rName,
1741 const uno::Sequence<sheet::ExternalLinkInfo>* pExternalLinks )
const override
1743 return ConventionXL::parseExternalName( rSymbol, rFile, rName, rDoc, pExternalLinks);
1746 virtual OUString makeExternalNameStr( sal_uInt16 ,
const OUString& rFile,
1747 const OUString& rName )
const override
1749 return ConventionXL::makeExternalNameStr(rFile, rName);
1752 virtual void makeExternalRefStr(
1754 OUStringBuffer& rBuffer,
const ScAddress& rPos, sal_uInt16 ,
const OUString& rFileName,
1755 const OUString& rTabName,
const ScSingleRefData& rRef )
const override
1764 ConventionXL::makeExternalDocStr(rBuffer, rFileName);
1766 rBuffer.append(
'!');
1772 virtual void makeExternalRefStr(
1774 OUStringBuffer& rBuffer,
const ScAddress& rPos, sal_uInt16 ,
const OUString& rFileName,
1775 const std::vector<OUString>& rTabNames,
const OUString& rTabName,
1780 ConventionXL::makeExternalDocStr(rBuffer, rFileName);
1781 ConventionXL::makeExternalTabNameRange(rBuffer, rTabName, rTabNames, aAbsRef);
1782 rBuffer.append(
'!');
1786 rBuffer.append(
ScResId(STR_NO_REF_TABLE));
1795 rBuffer.append(
':');
1806 rBuffer.append(
':');
1814 rBuffer.append(
':');
1822 if (c ==
'-' && cLast ==
'[')
1834 rDoc(rCxt.getDoc()),
1836 mpFormatter(pContext ? pContext->GetFormatTable() :
rDoc.GetFormatTable()),
1840 pCharClass(
ScGlobal::getCharClassPtr()),
1859 mpFormatter(pContext ? pContext->GetFormatTable() : rDoc.GetFormatTable()),
1860 mpInterpreterContext(pContext),
1861 mnCurrentSheetTab(-1),
1862 mnCurrentSheetEndPos(0),
1864 pCharClass(
ScGlobal::getCharClassPtr() ),
1865 mbCharClassesDiffer(false),
1866 mnPredetectedReference(0),
1867 mnRangeOpPosInSymbol(-1),
1869 meExtendedErrorDetection( EXTENDED_ERROR_DETECTION_NONE ),
1870 mbCloseBrackets( true ),
1881 rDoc(rCxt.getDoc()),
1883 mpFormatter(pContext ? pContext->GetFormatTable() : rDoc.GetFormatTable()),
1884 mpInterpreterContext(pContext),
1885 mnCurrentSheetTab(-1),
1886 mnCurrentSheetEndPos(0),
1887 pCharClass(
ScGlobal::getCharClassPtr()),
1888 mbCharClassesDiffer(false),
1889 mnPredetectedReference(0),
1890 mnRangeOpPosInSymbol(-1),
1892 meExtendedErrorDetection(EXTENDED_ERROR_DETECTION_NONE),
1893 mbCloseBrackets(true),
1895 maTabNames(rCxt.getTabNames())
1906 mpFormatter(pContext ? pContext->GetFormatTable() : rDoc.GetFormatTable()),
1907 mpInterpreterContext(pContext),
1908 mnCurrentSheetTab(-1),
1909 mnCurrentSheetEndPos(0),
1911 pCharClass(
ScGlobal::getCharClassPtr() ),
1912 mbCharClassesDiffer(false),
1913 mnPredetectedReference(0),
1914 mnRangeOpPosInSymbol(-1),
1916 meExtendedErrorDetection( EXTENDED_ERROR_DETECTION_NONE ),
1917 mbCloseBrackets( true ),
1932 sal_Int32 nStartFlags = KParseTokens::ANY_LETTER_OR_NUMBER | KParseTokens::ASC_UNDERSCORE;
1933 sal_Int32 nContFlags = nStartFlags;
1936 bool bNeedsQuote = !((aRes.TokenType & KParseType::IDENTNAME) && aRes.EndPos == rString.getLength());
1941 case FormulaGrammar::CONV_UNSPECIFIED :
1943 case FormulaGrammar::CONV_OOO :
1944 case FormulaGrammar::CONV_XL_A1 :
1945 case FormulaGrammar::CONV_XL_R1C1 :
1946 case FormulaGrammar::CONV_XL_OOX :
1947 case FormulaGrammar::CONV_ODF :
1951 rString = rString.replaceAll(
"'",
"''" );
1964 rString =
"'" + rString +
"'";
1970 if (rString[0] !=
'\'')
1974 if (nPos != -1 && rString[nPos-1] !=
'\'')
1991 case FormulaGrammar::CONV_OOO:
1993 static const ConventionOOO_A1 ConvOOO_A1;
1996 case FormulaGrammar::CONV_ODF:
1998 static const ConventionOOO_A1_ODF ConvOOO_A1_ODF;
1999 return &ConvOOO_A1_ODF;
2001 case FormulaGrammar::CONV_XL_A1:
2003 static const ConventionXL_A1 ConvXL_A1;
2006 case FormulaGrammar::CONV_XL_R1C1:
2008 static const ConventionXL_R1C1 ConvXL_R1C1;
2009 return &ConvXL_R1C1;
2011 case FormulaGrammar::CONV_XL_OOX:
2013 static const ConventionXL_OOX ConvXL_OOX;
2016 case FormulaGrammar::CONV_UNSPECIFIED:
2028 OSL_ENSURE( FormulaGrammar::isSupported(
meGrammar),
2029 "ScCompiler::SetRefConvention: unsupported grammar resulting");
2041 while ( pDst < pStop )
2054 for (
size_t i=0;
i<n; ++
i)
2060 if (p1[i] <
'a' ||
'z' < p1[i])
2062 if (p2[i] <
'A' ||
'Z' < p2[i])
2064 if (p1[i] != p2[i] + 0x20)
2117 bool bQuote =
false;
2120 sal_Int32 nSpaces = 0;
2132 bool bAutoIntersection =
false;
2134 bool bErrorConstantHadSlash =
false;
2137 while ((c != 0) && (eState != ssStop) )
2144 if (c == cSep || (bInArray && (c == cArrayColSep || c == cArrayRowSep)))
2151 case ssGetReference:
2152 case ssSkipReference:
2153 case ssGetTableRefItem:
2154 case ssGetTableRefColumn:
2157 if (eState == ssGetChar)
2164 Label_MaskStateMachine:
2173 eState = ssGetTableRefColumn;
2188 if (!bAutoIntersection)
2192 bAutoIntersection =
true;
2203 goto Label_MaskStateMachine;
2217 goto Label_MaskStateMachine;
2228 if (c ==
'[' && FormulaGrammar::isExcelSyntax(
meGrammar)
2232 goto Label_MaskStateMachine;
2243 eState = ssGetReference;
2254 eState = ssGetValue;
2259 eState = ssGetString;
2265 eState = ssGetTableRefItem;
2267 eState = ssGetErrorConstant;
2277 eState = ssGetIdent;
2292 SetError(FormulaError::StringOverflow);
2312 SetError(FormulaError::StringOverflow);
2331 SetError(FormulaError::StringOverflow);
2340 else if ( 128 <= c ||
'\'' == c )
2372 SetError(FormulaError::StringOverflow);
2375 else if (c == cDecSep || (cDecSepAlt && c == cDecSepAlt))
2393 else if (c ==
'E' || c ==
'e')
2406 if (((cLast ==
'E') || (cLast ==
'e')) &&
2443 SetError(FormulaError::StringOverflow);
2444 eState = ssSkipString;
2455 case ssGetErrorConstant:
2475 eState = ssGetIdent;
2481 if (!bErrorConstantHadSlash)
2482 bErrorConstantHadSlash =
true;
2490 (c < 128 && !rtl::isAsciiAlphanumeric( c)))
2501 SetError( FormulaError::StringOverflow);
2509 case ssGetTableRefItem:
2516 SetError( FormulaError::StringOverflow);
2529 case ssGetTableRefColumn:
2532 if (c !=
']' || cLast ==
'\'')
2536 SetError( FormulaError::StringOverflow);
2549 case ssGetReference:
2552 SetError( FormulaError::StringOverflow);
2553 eState = ssSkipReference;
2556 case ssSkipReference:
2575 constexpr
int kDollar = (1 << 1);
2578 constexpr
int kOpen = (1 << 2);
2580 constexpr
int kName = (1 << 3);
2584 constexpr
int kQuote = (1 << 4);
2586 constexpr
int kClose = (1 << 5);
2588 constexpr
int kFileSep = (1 << 6);
2590 constexpr
int kPast = (1 << 7);
2594 constexpr
int kMarkAhead = (1 << 8);
2596 constexpr
int kDefName = (1 << 9);
2598 constexpr
int kRefErr = (1 << 10);
2600 bool bAddToSymbol =
true;
2603 OSL_ENSURE( nRefInName & (kPast | kDefName | kRefErr),
2604 "ScCompiler::NextSymbol: reference: "
2605 "closing bracket ']' without prior sheet name separator '.' violates ODF spec");
2607 bAddToSymbol =
false;
2610 else if (cSheetSep == c && nRefInName == 0)
2613 bAddToSymbol =
false;
2614 nRefInName |= kPast;
2615 if (
'$' == pSrc[0] &&
'$' == pSrc[1])
2616 nRefInName |= kMarkAhead;
2618 else if (!(nRefInName & kPast) || (nRefInName & (kMarkAhead | kDefName)))
2624 else if (
'$' == c &&
'$' == pSrc[0] && !(nRefInName & kOpen))
2626 nRefInName &= ~kMarkAhead;
2627 if (!(nRefInName & kDefName))
2630 bAddToSymbol =
false;
2632 nRefInName &= kPast;
2633 nRefInName |= kDefName;
2639 if (eState != ssSkipReference)
2644 bAddToSymbol =
false;
2647 else if (cSheetPrefix == c && nRefInName == 0)
2648 nRefInName |= kDollar;
2654 if (!(nRefInName & kName))
2656 nRefInName |= (kOpen | kName);
2657 bAddToSymbol = !(nRefInName & kDefName);
2659 else if (!(nRefInName & kOpen))
2661 OSL_FAIL(
"ScCompiler::NextSymbol: reference: "
2662 "a ''' without the name being enclosed in '...' violates ODF spec");
2664 else if (nRefInName & kQuote)
2667 nRefInName &= ~kQuote;
2675 nRefInName |= kQuote;
2679 nRefInName |= kFileSep;
2683 nRefInName |= kClose;
2684 nRefInName &= ~kOpen;
2686 bAddToSymbol = !(nRefInName & kDefName);
2689 else if (
'#' == c && nRefInName == 0)
2690 nRefInName |= kRefErr;
2691 else if (cSheetSep == c && !(nRefInName & kOpen))
2694 nRefInName |= kPast;
2695 if (
'$' == pSrc[0] &&
'$' == pSrc[1])
2696 nRefInName |= kMarkAhead;
2698 else if (
':' == c && !(nRefInName & kOpen))
2700 OSL_FAIL(
"ScCompiler::NextSymbol: reference: "
2701 "range operator ':' without prior sheet name separator '.' violates ODF spec");
2705 else if (!(nRefInName & kName))
2708 nRefInName |= kName;
2717 if (bAddToSymbol && eState != ssSkipReference)
2730 const sal_Int32 nOldSrcPos =
nSrcPos;
2731 nSrcPos = nSrcPos + nSpaces;
2739 const bool bGroupSeparator = (128 <= cGroupSep && cGroupSep != cSep &&
2740 cGroupSep != cArrayColSep && cGroupSep != cArrayRowSep &&
2741 cGroupSep != cDecSep && cGroupSep != cDecSepAlt &&
2742 cGroupSep != cSheetPrefix && cGroupSep != cSheetSep);
2743 OUStringBuffer aSymbol;
2750 if ( pStart[nSrcPos] == cSheetPrefix && pStart[nSrcPos+1] ==
'\'' )
2751 aSymbol.append(pStart[nSrcPos++]);
2755 if ( !aRes.TokenType )
2757 nErr = FormulaError::IllegalChar;
2760 if ( aRes.EndPos <= nSrcPos )
2764 nErr = FormulaError::IllegalChar;
2768 nSrcPos = nOldSrcPos;
2769 aSymbol.setLength(0);
2779 for (sal_Int32
i = nSrcPos;
i < aRes.EndPos; ++
i)
2781 if (pStart[
i] == cSep)
2785 aSymbol.append( pStart + nSrcPos, aRes.EndPos - nSrcPos);
2786 nSrcPos = aRes.EndPos;
2788 if ( aRes.TokenType & KParseType::SINGLE_QUOTE_NAME )
2799 aSymbol.append(pStart[nSrcPos++]);
2801 }
while ( bi18n && nErr == FormulaError::NONE );
2802 sal_Int32 nLen = aSymbol.getLength();
2805 SetError( FormulaError::StringOverflow );
2815 nSrcPos = pSrc - pStart;
2828 if (bAutoIntersection && nSpaces > 1)
2837 OpCodeHashMap::const_iterator iLook(
mxSymbols->getHashMap().find( rName));
2838 bool bFound = (iLook !=
mxSymbols->getHashMap().end());
2841 OpCode eOp = iLook->second;
2853 else if (rName ==
";")
2855 switch (FormulaGrammar::extractFormulaLanguage(
meGrammar))
2859 case css::sheet::FormulaLanguage::NATIVE:
2860 case css::sheet::FormulaLanguage::ENGLISH:
2861 case css::sheet::FormulaLanguage::ODFF:
2862 case css::sheet::FormulaLanguage::ODF_11:
2893 static const FunctionName aOdffAliases[] = {
2906 for (
const FunctionName& rOdffAlias : aOdffAliases)
2908 if (rName.equalsIgnoreAsciiCaseAscii( rOdffAlias.pName))
2925 static const FunctionName aOoxmlAliases[] = {
2934 for (
const FunctionName& rOoxmlAlias : aOoxmlAliases)
2936 if (rName.equalsIgnoreAsciiCaseAscii( rOoxmlAlias.pName))
2956 static const FunctionName aPodfAliases[] = {
2959 for (
const FunctionName& rPodfAlias : aPodfAliases)
2961 if (rName.equalsIgnoreAsciiCaseAscii( rPodfAlias.pName))
2976 ExternalHashMap::const_iterator iExt(
2977 mxSymbols->getExternalHashMap().find( rName));
2978 if (iExt !=
mxSymbols->getExternalHashMap().end())
2981 aIntName = (*iExt).second;
2997 if (!aIntName.isEmpty())
3008 bool bShouldBeNegSub =
3013 if (bShouldBeNegSub && eOp ==
ocSub)
3016 else if (!bShouldBeNegSub && eOp ==
ocNegSub)
3024 bool bFound =
false;
3046 const sal_Int32 nFormulaLanguage = FormulaGrammar::extractFormulaLanguage(
GetGrammar());
3047 if (nFormulaLanguage == css::sheet::FormulaLanguage::ODFF || nFormulaLanguage == css::sheet::FormulaLanguage::OOXML)
3051 rtl_math_ConversionStatus eStatus;
3052 sal_Int32 nParseEnd;
3053 double fVal = rtl::math::stringToDouble( rSym,
'.', 0, &eStatus, &nParseEnd);
3054 if (nParseEnd != rSym.getLength())
3066 if (rSym.equalsIgnoreAsciiCase(
"TRUE"))
3068 else if (rSym.equalsIgnoreAsciiCase(
"FALSE"))
3080 if (eStatus == rtl_math_ConversionStatus_OutOfRange)
3081 SetError( FormulaError::IllegalArgument );
3099 if (nType & (SvNumFormatType::TIME | SvNumFormatType::DATE))
3102 if (nType == SvNumFormatType::LOGICAL)
3108 if( nType == SvNumFormatType::TEXT )
3110 SetError( FormulaError::IllegalArgument );
3122 sal_Int32 nLen = sal::static_int_cast<sal_Int32>( p -
cSymbol - 1 );
3123 if (!nLen ||
cSymbol[nLen] !=
'"')
3149 const OUString aErrRef(
"#REF!");
3150 sal_Int32
nPos = rName.indexOf( aErrRef);
3164 if (rName.getLength() == 5)
3179 sal_Unicode c2 = nPos+5 < rName.getLength() ? rName[nPos+5] : 0;
3183 if (
'$' == c2 ||
'#' == c2 || (
'0' <= c2 && c2 <=
'9'))
3191 (
'.' == c2 ||
'$' == c2 ||
'#' == c2 ||
3192 (
'0' <= c2 && c2 <=
'9')))
3199 if (rtl::isAsciiAlpha(c) &&
3295 if( !( nFlags & ScRefFlags::VALID ) )
3301 if( !( nFlags & ScRefFlags::TAB_VALID ) )
3327 if ( ch1 == cDecSep )
3334 if ( ch1 == cDecSep )
3353 sal_Unicode const *
const pTabSep = rName.getStr() + nPos;
3355 if ( !(ch2 ==
'$' || rtl::isAsciiAlpha( ch2 )) )
3357 if ( cDecSep ==
'.' && (ch2 ==
'E' || ch2 ==
'e')
3370 OUString aTabName( rName.copy( 0, nPos ) );
3408 case FormulaGrammar::CONV_XL_A1:
3409 case FormulaGrammar::CONV_XL_OOX:
3413 if (rName[0] !=
'\'')
3416 case FormulaGrammar::CONV_XL_R1C1:
3430 #if !HAVE_FEATURE_SCRIPTING
3445 SAL_WARN(
"sc.core",
"ScCompiler::IsMacro - SolarMutex would deadlock, not obtaining Basic");
3449 OUString
aName( rName);
3472 if (FormulaGrammar::isODFF(
GetGrammar()) && aName.startsWithIgnoreAsciiCase(
"USER."))
3473 aName = aName.copy(5);
3483 || dynamic_cast<const SbMethod*>( pMeth) == nullptr )
3498 sal_Int16 nSheet =
aPos.
Tab();
3525 pData = pRangeName->findByUpperName(
aName);
3545 rbInvalidExternalNameRange =
false;
3550 OUString aFile,
aName;
3558 OUString aTmp = aFile;
3564 rbInvalidExternalNameRange =
true;
3589 bool bInList =
false;
3590 bool bFound =
false;
3592 OUString
aName( rName );
3595 for (
short jThisTab = 1; jThisTab >= 0 && !bInList; jThisTab-- )
3597 for (
short jRow=0; jRow<2 && !bInList; jRow++ )
3604 for (
size_t iPair = 0, nPairs = pRL->
size(); iPair < nPairs && !bInList; ++iPair )
3608 if ( jThisTab && (rNameRange.
aStart.
Tab() > nThisTab ||
3609 nThisTab > rNameRange.
aEnd.
Tab()) )
3612 for (
bool bHas = aIter.
first(); bHas && !bInList; bHas = aIter.
next())
3640 bInList = bFound =
true;
3667 for (
const ScAddress& aAddress : rAddresses )
3671 if ( nMax < static_cast<tools::Long>(aAddress.Col()) )
3674 if ( aAddress !=
aPos )
3678 SCCOL nCol = aAddress.Col();
3679 SCROW nRow = aAddress.Row();
3685 if ( nD < nDistance )
3687 if ( nC < 0 || nR < 0 )
3690 aTwo.Set( nCol, nRow, aAddress.Tab() );
3691 nMax = std::max( nMyCol + std::abs( nC ), nMyRow + std::abs( nR ) );
3694 else if ( nRow >= aOne.Row() || nMyRow < static_cast<tools::Long>(aOne.Row()) )
3700 aOne.Set( nCol, nRow, aAddress.Tab() );
3701 nMax = std::max( nMyCol + nC, nMyRow + nR );
3708 aOne.Set( nCol, nRow, aAddress.Tab() );
3709 nDistance = nC * nC + nR * nR;
3710 nMax = std::max( nMyCol + std::abs( nC ), nMyRow + std::abs( nR ) );
3720 for (
bool bHas = aIter.
first(); bHas; bHas = aIter.
next())
3724 if ( nMax < static_cast<tools::Long>(aIter.
GetPos().
Col()) )
3749 if ( nD < nDistance )
3751 if ( nC < 0 || nR < 0 )
3754 aTwo.Set( nCol, nRow, aIter.
GetPos().
Tab() );
3755 nMax = std::max( nMyCol + std::abs( nC ), nMyRow + std::abs( nR ) );
3758 else if ( nRow >= aOne.Row() || nMyRow < static_cast<tools::Long>(aOne.Row()) )
3764 aOne.Set( nCol, nRow, aIter.
GetPos().
Tab() );
3765 nMax = std::max( nMyCol + nC, nMyRow + nR );
3772 aOne.Set( nCol, nRow, aIter.
GetPos().
Tab() );
3773 nDistance = nC * nC + nR * nR;
3774 nMax = std::max( nMyCol + std::abs( nC ), nMyRow + std::abs( nR ) );
3787 if ( nMyCol >= static_cast<tools::Long>(aOne.Col()) && nMyRow >= static_cast<tools::Long>(aOne.Row()) )
3791 if ( nMyCol < static_cast<tools::Long>(aOne.Col()) )
3793 if ( nMyRow >= static_cast<tools::Long>(aTwo.Row()) )
3804 if ( nC1 * nC1 + nR1 * nR1 <= nC2 * nC2 + nR2 * nR2 )
3815 aAdr.
Col(), aAdr.
Row() + 1, aAdr.
Tab()))
3817 aAdr.
Col(), aAdr.
Row() - 1, aAdr.
Tab())))
3836 OpCodeHashMap::const_iterator iLook(
mxSymbols->getHashMap().find( rName ) );
3837 if( iLook !=
mxSymbols->getHashMap().end() &&
3838 ((*iLook).second ==
ocTrue ||
3851 if (nError != FormulaError::NONE)
3863 OpCodeHashMap::const_iterator iLook(
mxSymbols->getHashMap().find( rName));
3864 if (iLook !=
mxSymbols->getHashMap().end())
3871 switch ((*iLook).second)
3903 OUString unescapeTableRefColumnSpecifier(
const OUString& rStr )
3907 if (rStr.indexOf(
'\'' ) < 0)
3910 const sal_Int32
n = rStr.getLength();
3911 OUStringBuffer aBuf( n );
3914 bool bEscaped =
false;
3915 for ( ; p < pStop; ++p)
3928 return aBuf.makeStringAndClear();
3943 OUString
aName( unescapeTableRefColumnSpecifier( rName));
3975 for (
bool bHas = aIter.
first(); bHas; bHas = aIter.
next())
3994 SAL_WARN(
"sc.core",
"ScCompiler::IsTableRefColumn - falling back to cell lookup");
4034 if ( c1 == cQuote && c2 != cQuote )
4048 else if ( c1 != cQuote && c2 == cQuote )
4053 else if ( nPos == 0 && (c1 == cx || c1 == cX) )
4078 if ( aSymbol[0] ==
'\'' )
4080 sal_Int32 nPosition = aSymbol.indexOf(
"'#" );
4081 if (nPosition != -1)
4083 aDoc = aSymbol.copy(0, nPosition + 2);
4084 aSymbol = aSymbol.copy(nPosition + 2);
4093 OUString aTmp1( aSymbol.getToken( 0,
':', nIndex ) );
4094 sal_Int32 nLen1 = aTmp1.getLength();
4095 OUStringBuffer aSym;
4097 bool bLastAlp =
true;
4098 sal_Int32 nStrip = 0;
4099 sal_Int32
nCount = nRefs;
4100 for ( sal_Int32 j=1; j<nCount; j++ )
4102 aTmp2 = aSymbol.getToken( 0,
':', nIndex );
4103 sal_Int32 nLen2 = aTmp2.getLength();
4104 if ( nLen1 || nLen2 )
4114 if ( bLastAlp == bNextNum && nStrip < 1 )
4123 if ( !aSym.isEmpty() && aSym[aSym.getLength()-1] !=
':')
4127 bLastAlp = !bNextNum;
4144 aSymbol = aSym.makeStringAndClear() + aTmp1;
4148 if ( nRefs && nRefs <= 2 )
4150 OUString aTab[2], aRef[2];
4154 sal_Int32 nIdx{ 0 };
4155 aRef[0] = aSymbol.getToken( 0,
':', nIdx );
4156 aRef[1] = aSymbol.getToken( 0,
':', nIdx );
4161 bool bChanged =
false;
4164 for (
int j=0; j<nRefs; j++ )
4167 sal_Int32 nDotPos = -1;
4168 while ( (nTmp = aRef[j].indexOf(
'.', nTmp )) != -1 )
4170 if ( nDotPos != -1 )
4172 aTab[j] = aRef[j].copy( 0, nDotPos + 1 );
4173 aRef[j] = aRef[j].copy( nDotPos + 1 );
4175 OUString aOld( aRef[j] );
4176 OUStringBuffer aStr2;
4178 while ( *p && rtl::isAsciiDigit( *p ) )
4180 aRef[j] = OUString( p );
4181 aRef[j] += aStr2.makeStringAndClear();
4182 if ( bColons || aRef[j] != aOld )
4186 bOk &= ((aAdr.
Parse( aRef[j],
rDoc, aDetails ) & nMask) == nMask);
4189 if ( bChanged && bOk )
4208 if (FormulaGrammar::isODFF(
meGrammar ))
4212 rUpper = rOrg.toAsciiUpperCase();
4232 bool bAllowBooleans = bInArray;
4237 if (nSrcPos <
aFormula.getLength())
4242 const OUString aBad(
aFormula.copy( nSrcPos));
4257 aToken.
sbyte.cByte =
static_cast<sal_uInt8>( std::min<sal_Int32>(nSpaces, 255) );
4258 if( !static_cast<ScTokenArray*>(
pArr)->AddRawToken( aToken ) )
4260 SetError(FormulaError::CodeOverflow);
4269 bool bInvalidExternalNameRange;
4288 OUString aBad(
aFormula.copy( nSrcPos-1 ) );
4296 bool bMayBeFuncName;
4297 bool bAsciiNonAlnum;
4300 bMayBeFuncName = rtl::isAsciiAlpha(
cSymbol[0] );
4303 bMayBeFuncName = officecfg::Office::Common::Misc::ExperimentalMode::get();
4306 bAsciiNonAlnum = !bMayBeFuncName && !rtl::isAsciiDigit(
cSymbol[0] );
4310 OUString aTmpStr(
cSymbol[0] );
4311 bMayBeFuncName = pCharClass->
isLetter( aTmpStr, 0 );
4312 bAsciiNonAlnum =
false;
4328 if ( bMayBeFuncName )
4334 bMayBeFuncName = ( *p ==
'(' );
4344 const OUString aOrg(
cSymbol );
4358 bool bAsciiUpper =
false;
4387 if (aUpper.isEmpty())
4411 if (aUpper.isEmpty())
4416 if (bAllowBooleans &&
IsBoolean( aUpper ))
4444 bool bInvalidExternalNameRange;
4449 if (bInvalidExternalNameRange)
4463 if (bMayBeFuncName &&
IsMacro( aUpper ))
4465 if (bMayBeFuncName &&
IsOpCode2( aUpper ))
4474 if (aUpper.indexOf( aErrRef) >= 0 &&
IsReference( aUpper, &aErrRef))
4488 aUpper = pCharClass->
lowercase( aUpper );
4499 bool bExternal =
GetGrammar() == FormulaGrammar::GRAM_EXTERNAL;
4500 sal_uInt16 nExpectedCount = bExternal ? 2 : 1;
4501 OSL_ENSURE(
pArr->
GetLen() == nExpectedCount,
"ScCompiler::CreateStringFromXMLTokenArray - wrong number of tokens" );
4514 class ExternalFileInserter
4520 maPos(rPos), mrRefMgr(rRefMgr) {}
4522 void operator() (sal_uInt16 nFileId)
const
4532 OSL_ENSURE(
meGrammar != FormulaGrammar::GRAM_EXTERNAL,
"ScCompiler::CompileString - unexpected grammar GRAM_EXTERNAL" );
4533 if(
meGrammar == FormulaGrammar::GRAM_EXTERNAL )
4563 struct FunctionStack
4569 bool bPODF = FormulaGrammar::isPODF(
meGrammar);
4570 bool bOOXML = FormulaGrammar::isOOXML(
meGrammar);
4571 bool bUseFunctionStack = (bPODF || bOOXML);
4572 const size_t nAlloc = 512;
4573 FunctionStack aFuncs[ nAlloc ];
4574 FunctionStack* pFunctionStack = (bUseFunctionStack &&
o3tl::make_unsigned(rFormula.getLength()) > nAlloc ?
4575 new FunctionStack[rFormula.getLength()] : &aFuncs[0]);
4576 pFunctionStack[0].eOp =
ocNone;
4577 pFunctionStack[0].nSep = 0;
4578 size_t nFunction = 0;
4579 short nBrackets = 0;
4580 bool bInArray =
false;
4593 if (bUseFunctionStack)
4596 pFunctionStack[ nFunction ].eOp =
eLastOp;
4597 pFunctionStack[ nFunction ].nSep = 0;
4605 SetError( FormulaError::PairExpected );
4614 if (bUseFunctionStack && nFunction)
4620 if (bUseFunctionStack)
4621 ++pFunctionStack[ nFunction ].nSep;
4627 SetError( FormulaError::NestedArray );
4631 if (bUseFunctionStack)
4634 pFunctionStack[ nFunction ].eOp = eOp;
4635 pFunctionStack[ nFunction ].nSep = 0;
4647 SetError( FormulaError::PairExpected );
4654 if (bUseFunctionStack && nFunction)
4661 if (bUseFunctionStack)
4664 pFunctionStack[ nFunction ].eOp = eOp;
4665 pFunctionStack[ nFunction ].nSep = 0;
4671 if (bUseFunctionStack && nFunction)
4700 SetError(FormulaError::CodeOverflow);
break;
4707 size_t nFunc = nFunction + 1;
4709 (pFunctionStack[ nFunc ].eOp ==
ocWeek &&
4710 pFunctionStack[ nFunc ].nSep == 0))
4715 SetError(FormulaError::CodeOverflow);
break;
4725 pFunctionStack[ nFunction ].eOp ==
ocAddress &&
4726 pFunctionStack[ nFunction ].nSep == 3)
4731 SetError(FormulaError::CodeOverflow);
break;
4733 ++pFunctionStack[ nFunction ].nSep;
4742 SetError( FormulaError::BadArrayContent);
4744 else if (!pNewToken)
4746 SetError(FormulaError::CodeOverflow);
4763 FormulaTokenArray::ReplaceMode::CODE_ONLY);
4799 SetError(FormulaError::CodeOverflow);
4808 while( nBrackets-- )
4812 SetError(FormulaError::CodeOverflow);
4823 if (pFunctionStack != &aFuncs[0])
4824 delete [] pFunctionStack;
4827 std::unique_ptr<ScTokenArray> pNew(
new ScTokenArray( aArr ));
4847 OSL_ENSURE( (
GetGrammar() == FormulaGrammar::GRAM_EXTERNAL) || rFormulaNmsp.isEmpty(),
4848 "ScCompiler::CompileString - unexpected formula namespace for internal grammar" );
4849 if(
GetGrammar() == FormulaGrammar::GRAM_EXTERNAL )
try
4852 uno::Reference< sheet::XFormulaParser > xParser( rParserPool.
getFormulaParser( rFormulaNmsp ), uno::UNO_SET_THROW );
4853 table::CellAddress aReferencePos;
4855 uno::Sequence< sheet::FormulaToken > aTokenSeq = xParser->parseFormula( rFormula, aReferencePos );
4860 std::unique_ptr<ScTokenArray> pNew(
new ScTokenArray( aTokenArray ));
4867 catch( uno::Exception& )
4886 if( nErr != FormulaError::NONE )
4900 bool bBorder1 = (eOp1 ==
ocSep || eOp1 ==
ocOpen);
4902 bool bAddPair = !(bBorder1 && bBorder2);
4919 if (nSheetTab >= 0 && nSheetTab !=
aPos.
Tab())
4986 OSL_FAIL(
"Wrong type for external reference!");
5054 OUString
const & rStr, sal_Int32 nPos,
ScCharFlags nFlags )
5057 sal_Unicode cLast = nPos > 0 ? rStr[ nPos-1 ] : 0;
5064 ((
pConventions[nConv]->getCharTableFlags(c, cLast) & nFlags) != nFlags))
5077 sal_uInt16 nFileId = t->
GetIndex();