[Libreoffice-commits] core.git: Branch 'distro/collabora/cp-6.2' - sc/inc sc/qa sc/source
Mike Kaganski (via logerrit)
logerrit at kemper.freedesktop.org
Fri Sep 4 21:58:15 UTC 2020
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 f5785760e288d84c1f961d05e7bcb3da45b5d2b6
Author: Mike Kaganski <mike.kaganski at collabora.com>
AuthorDate: Sun Jan 5 14:02:35 2020 +0300
Commit: Muhammet Kara <muhammet.kara at collabora.com>
CommitDate: Fri Sep 4 23:57:41 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 <erack at redhat.com>
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/102064
Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoffice at gmail.com>
Reviewed-by: Muhammet Kara <muhammet.kara at collabora.com>
diff --git a/sc/inc/compiler.hxx b/sc/inc/compiler.hxx
index 7095db44e930..5bd9068da8d2 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>
@@ -277,6 +278,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 c448b3cf54a7..266695313aeb 100644
--- a/sc/qa/unit/subsequent_export-test.cxx
+++ b/sc/qa/unit/subsequent_export-test.cxx
@@ -225,6 +225,7 @@ public:
void testPivotCacheAfterExportXLSX();
void testTdf114969XLSX();
void testTdf128976();
+ void testTdf83779();
CPPUNIT_TEST_SUITE(ScExportTest);
CPPUNIT_TEST(test);
@@ -345,6 +346,7 @@ public:
CPPUNIT_TEST(testPivotCacheAfterExportXLSX);
CPPUNIT_TEST(testTdf114969XLSX);
CPPUNIT_TEST(testTdf128976);
+ CPPUNIT_TEST(testTdf83779);
CPPUNIT_TEST_SUITE_END();
@@ -4342,6 +4344,24 @@ void ScExportTest::testTdf128976()
xDocSh->DoClose();
}
+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 edb4f9fadb0b..e4620b1f14a1 100644
--- a/sc/source/core/tool/compiler.cxx
+++ b/sc/source/core/tool/compiler.cxx
@@ -2963,14 +2963,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;
@@ -4121,6 +4124,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);
More information about the Libreoffice-commits
mailing list