sc/inc/compiler.hxx | 3 +++ sc/qa/unit/data/xlsx/tdf83779.xlsx |binary sc/qa/unit/subsequent_export-test.cxx | 20 ++++++++++++++++++++ sc/source/core/tool/compiler.cxx | 22 ++++++++++++++++------ 4 files changed, 39 insertions(+), 6 deletions(-)
New commits: commit e46a0fa97f5cf31dbf302e44bdcc6f05139f61dd Author: Mike Kaganski <mike.kagan...@collabora.com> AuthorDate: Sun Jan 5 14:02:35 2020 +0300 Commit: Muhammet Kara <muhammet.k...@collabora.com> CommitDate: Fri Sep 4 23:04:31 2020 +0200 tdf#83779: convert TRUE/FALSE constants to functions TRUE()/FALSE() This avoids problems with round-tripping Excel spreadsheets, where previously a formula like =IF(ISNA(A1)=FALSE;"a";"b") was imported as =IF(ISNA(A1)=0;"a";"b"), and when exported back, it didn't work in Excel, because boolean values had a distinct type in it. Change-Id: I672a631bfa1a4811349794f714293404c6b24381 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/86238 Tested-by: Jenkins Reviewed-by: Eike Rathke <er...@redhat.com> (cherry picked from commit 197aa7911d5be5464efd19feaf3370eea1c15ab1) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/101969 Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com> Reviewed-by: Muhammet Kara <muhammet.k...@collabora.com> diff --git a/sc/inc/compiler.hxx b/sc/inc/compiler.hxx index b45af659ecab..c19ff834ded9 100644 --- a/sc/inc/compiler.hxx +++ b/sc/inc/compiler.hxx @@ -31,6 +31,7 @@ #include <rtl/ustrbuf.hxx> #include <com/sun/star/sheet/ExternalLinkInfo.hpp> #include <com/sun/star/i18n/ParseResult.hpp> +#include <queue> #include <vector> #include <memory> #include <set> @@ -279,6 +280,8 @@ private: sal_Int32 nSrcPos; // tokenizer position (source code) mutable ScRawToken maRawToken; + std::queue<OpCode> maPendingOpCodes; // additional opcodes generated from a single symbol + const CharClass* pCharClass; // which character classification is used for parseAnyToken sal_uInt16 mnPredetectedReference; // reference when reading ODF, 0 (none), 1 (single) or 2 (double) sal_Int32 mnRangeOpPosInSymbol; // if and where a range operator is in symbol diff --git a/sc/qa/unit/data/xlsx/tdf83779.xlsx b/sc/qa/unit/data/xlsx/tdf83779.xlsx new file mode 100644 index 000000000000..0a5d645c8122 Binary files /dev/null and b/sc/qa/unit/data/xlsx/tdf83779.xlsx differ diff --git a/sc/qa/unit/subsequent_export-test.cxx b/sc/qa/unit/subsequent_export-test.cxx index e220803967cb..bf0d74cdf830 100644 --- a/sc/qa/unit/subsequent_export-test.cxx +++ b/sc/qa/unit/subsequent_export-test.cxx @@ -232,6 +232,7 @@ public: void testRotatedImageODS(); void testTdf128976(); void testTdf120502(); + void testTdf83779(); CPPUNIT_TEST_SUITE(ScExportTest); CPPUNIT_TEST(test); @@ -364,6 +365,7 @@ public: CPPUNIT_TEST(testRotatedImageODS); CPPUNIT_TEST(testTdf128976); CPPUNIT_TEST(testTdf120502); + CPPUNIT_TEST(testTdf83779); CPPUNIT_TEST_SUITE_END(); @@ -4628,6 +4630,24 @@ void ScExportTest::testTdf120502() assertXPath(pSheet1, "/x:worksheet/x:cols/x:col", "max", OUString::number(nMaxCol + 1)); } +void ScExportTest::testTdf83779() +{ + // Roundtripping TRUE/FALSE constants (not functions) must convert them to functions + ScDocShellRef xShell = loadDoc("tdf83779.", FORMAT_XLSX); + CPPUNIT_ASSERT(xShell); + + auto pXPathFile = ScBootstrapFixture::exportTo(&(*xShell), FORMAT_XLSX); + + const xmlDocPtr pVmlDrawing + = XPathHelper::parseExport(pXPathFile, m_xSFactory, "xl/worksheets/sheet1.xml"); + CPPUNIT_ASSERT(pVmlDrawing); + + assertXPathContent(pVmlDrawing, "/x:worksheet/x:sheetData/x:row[1]/x:c/x:f", "FALSE()"); + assertXPathContent(pVmlDrawing, "/x:worksheet/x:sheetData/x:row[2]/x:c/x:f", "TRUE()"); + + xShell->DoClose(); +} + CPPUNIT_TEST_SUITE_REGISTRATION(ScExportTest); CPPUNIT_PLUGIN_IMPLEMENT(); diff --git a/sc/source/core/tool/compiler.cxx b/sc/source/core/tool/compiler.cxx index e31ab2731fa3..4305ea572854 100644 --- a/sc/source/core/tool/compiler.cxx +++ b/sc/source/core/tool/compiler.cxx @@ -2998,14 +2998,17 @@ bool ScCompiler::IsValue( const OUString& rSym ) return false; // some function name, not a constant // Could be TRUE or FALSE constant. + OpCode eOpFunc = ocNone; if (rSym.equalsIgnoreAsciiCase("TRUE")) + eOpFunc = ocTrue; + else if (rSym.equalsIgnoreAsciiCase("FALSE")) + eOpFunc = ocFalse; + if (eOpFunc != ocNone) { - maRawToken.SetDouble( 1.0 ); - return true; - } - if (rSym.equalsIgnoreAsciiCase("FALSE")) - { - maRawToken.SetDouble( 0.0 ); + maRawToken.SetOpCode(eOpFunc); + // add missing trailing parentheses + maPendingOpCodes.push(ocOpen); + maPendingOpCodes.push(ocClose); return true; } return false; @@ -4153,6 +4156,13 @@ static bool lcl_UpperAsciiOrI18n( OUString& rUpper, const OUString& rOrg, Formul bool ScCompiler::NextNewToken( bool bInArray ) { + if (!maPendingOpCodes.empty()) + { + maRawToken.SetOpCode(maPendingOpCodes.front()); + maPendingOpCodes.pop(); + return true; + } + bool bAllowBooleans = bInArray; sal_Int32 nSpaces = NextSymbol(bInArray); _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits