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

Reply via email to