[Libreoffice-commits] core.git: 6 commits - include/toolkit sw/CppunitTest_sw_macros_test.mk sw/inc sw/qa sw/source toolkit/source

Michael Stahl mstahl at redhat.com
Mon Feb 16 13:40:38 PST 2015


 include/toolkit/helper/macros.hxx                       |   10 +-
 sw/CppunitTest_sw_macros_test.mk                        |    1 
 sw/inc/ring.hxx                                         |   23 +++--
 sw/qa/core/macros-test.cxx                              |   64 ++++++++++++++++
 sw/qa/core/uwriter.cxx                                  |   11 ++
 sw/source/core/crsr/findtxt.cxx                         |   18 +++-
 sw/source/core/doc/DocumentContentOperationsManager.cxx |    9 +-
 sw/source/core/doc/docedt.cxx                           |    4 -
 sw/source/core/inc/docedt.hxx                           |    2 
 toolkit/source/helper/listenermultiplexer.cxx           |    9 ++
 10 files changed, 130 insertions(+), 21 deletions(-)

New commits:
commit 6b3aa0fe4094e87290bd33a30bd6cd99ee78ce38
Author: Michael Stahl <mstahl at redhat.com>
Date:   Sat Feb 14 00:17:06 2015 +0100

    tdf#78174: toolkit: work around GCC 4.9 -Os link failure
    
    A build with gcc (GCC) 4.9.2 20141101 (Red Hat 4.9.2-1) for 32-bit x86
    fails because of these undefined symbols:
    
    > nm --demangle workdir/CxxObject/svx/source/fmcomp/fmgridif.o | grep
     \\bWindowListenerMultiplexer::acquire
             U non-virtual thunk to WindowListenerMultiplexer::acquire()
    
    They should probably be generated inline.  Work around by out-lining the
    definition of the methods.
    
    https://gcc.gnu.org/bugzilla/show_bug.cgi?id=64812
    
    Change-Id: I318f7c39bdf1243be385bc6dc0a47862b22e92c5

diff --git a/include/toolkit/helper/macros.hxx b/include/toolkit/helper/macros.hxx
index 43ef27a..85474c8 100644
--- a/include/toolkit/helper/macros.hxx
+++ b/include/toolkit/helper/macros.hxx
@@ -112,8 +112,8 @@ class ClassName : public ListenerMultiplexerBase, public InterfaceName \
 public: \
     ClassName( ::cppu::OWeakObject& rSource ); \
     ::com::sun::star::uno::Any  SAL_CALL queryInterface( const ::com::sun::star::uno::Type & rType ) throw(::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE; \
-    void                        SAL_CALL acquire() throw() SAL_OVERRIDE  { ListenerMultiplexerBase::acquire(); } \
-    void                        SAL_CALL release() throw() SAL_OVERRIDE  { ListenerMultiplexerBase::release(); } \
+    void                        SAL_CALL acquire() throw() SAL_OVERRIDE; \
+    void                        SAL_CALL release() throw() SAL_OVERRIDE; \
     void                        SAL_CALL disposing( const ::com::sun::star::lang::EventObject& Source ) throw(::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
 
 
@@ -124,8 +124,8 @@ class TOOLKIT_DLLPUBLIC ClassName : public ListenerMultiplexerBase, public Inter
 public: \
     ClassName( ::cppu::OWeakObject& rSource ); \
     ::com::sun::star::uno::Any  SAL_CALL queryInterface( const ::com::sun::star::uno::Type & rType ) throw(::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE; \
-    void                        SAL_CALL acquire() throw() SAL_OVERRIDE  { ListenerMultiplexerBase::acquire(); } \
-    void                        SAL_CALL release() throw() SAL_OVERRIDE  { ListenerMultiplexerBase::release(); } \
+    void                        SAL_CALL acquire() throw() SAL_OVERRIDE; \
+    void                        SAL_CALL release() throw() SAL_OVERRIDE; \
     void                        SAL_CALL disposing( const ::com::sun::star::lang::EventObject& Source ) throw(::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
 
 
@@ -140,6 +140,8 @@ ClassName::ClassName( ::cppu::OWeakObject& rSource ) \
     : ListenerMultiplexerBase( rSource ) \
 { \
 } \
+void SAL_CALL ClassName::acquire() throw() { ListenerMultiplexerBase::acquire(); } \
+void SAL_CALL ClassName::release() throw() { ListenerMultiplexerBase::release(); } \
 ::com::sun::star::uno::Any ClassName::queryInterface( const ::com::sun::star::uno::Type & rType ) throw(::com::sun::star::uno::RuntimeException, std::exception) \
 { \
     ::com::sun::star::uno::Any aRet = ::cppu::queryInterface( rType, \
diff --git a/toolkit/source/helper/listenermultiplexer.cxx b/toolkit/source/helper/listenermultiplexer.cxx
index 797fad2..b109c5f 100644
--- a/toolkit/source/helper/listenermultiplexer.cxx
+++ b/toolkit/source/helper/listenermultiplexer.cxx
@@ -47,6 +47,15 @@ EventListenerMultiplexer::EventListenerMultiplexer( ::cppu::OWeakObject& rSource
 {
 }
 
+void SAL_CALL EventListenerMultiplexer::acquire() throw ()
+{
+    return ListenerMultiplexerBase::acquire();
+}
+void SAL_CALL EventListenerMultiplexer::release() throw ()
+{
+    return ListenerMultiplexerBase::release();
+}
+
 // ::com::sun::star::uno::XInterface
 ::com::sun::star::uno::Any EventListenerMultiplexer::queryInterface( const ::com::sun::star::uno::Type & rType ) throw(::com::sun::star::uno::RuntimeException, std::exception)
 {
commit ddadc1ee95c09eaadb0a1d01e234952b8581694c
Author: Michael Stahl <mstahl at redhat.com>
Date:   Mon Feb 16 22:14:27 2015 +0100

    tdf#80715: fix infinite loop in find-and-replace if SwTxtNode full
    
    In a regex searching for "$" to remove the paragraph break, sw_JoinText()
    may fail to join the nodes because the maximum size is reached; in this
    case the cursor has to be moved to the next node, otherwise the search
    will be stuck on that node forever.
    
    This would fix the problem in LO 4.2 but it's actually rather harder to
    trigger in 4.3+ because the 16-bit size limit of SwTxtNodes is gone.
    
    (regression from b60ce8465c8f01242354abccebe00742d164af60)
    
    Change-Id: Ie047cad37835adf95afe0d12b94a16ff4aecb17a

diff --git a/sw/source/core/crsr/findtxt.cxx b/sw/source/core/crsr/findtxt.cxx
index e73e4a8..6486526 100644
--- a/sw/source/core/crsr/findtxt.cxx
+++ b/sw/source/core/crsr/findtxt.cxx
@@ -583,9 +583,11 @@ int SwFindParaText::Find( SwPaM* pCrsr, SwMoveFn fnMove,
 
         boost::scoped_ptr<OUString> pRepl( (bRegExp)
                 ? ReplaceBackReferences( rSearchOpt, pCrsr ) : 0 );
-        rCursor.GetDoc()->getIDocumentContentOperations().ReplaceRange( *pCrsr,
-            (pRepl.get()) ? *pRepl : rSearchOpt.replaceString,
-            bRegExp );
+        bool const bReplaced =
+            rCursor.GetDoc()->getIDocumentContentOperations().ReplaceRange(
+                *pCrsr,
+                (pRepl.get()) ? *pRepl : rSearchOpt.replaceString,
+                bRegExp );
         rCursor.SaveTblBoxCntnt( pCrsr->GetPoint() );
 
         if( bRegExp )
@@ -599,7 +601,15 @@ int SwFindParaText::Find( SwPaM* pCrsr, SwMoveFn fnMove,
                 p->MoveTo( const_cast<SwPaM*>(pRegion) );
             } while( p != pPrev );
         }
-        pCrsr->Start()->nContent = nSttCnt;
+        if (bRegExp && !bReplaced)
+        {   // fdo#80715 avoid infinite loop if join failed
+            bool bRet = ((fnMoveForward == fnMove) ? &GoNextPara : &GoPrevPara)
+                (*pCrsr, fnMove);
+            (void) bRet;
+            assert(bRet); // if join failed, next node must be SwTxtNode
+        }
+        else
+            pCrsr->Start()->nContent = nSttCnt;
         return FIND_NO_RING;
     }
     return bFnd ? FIND_FOUND : FIND_NOT_FOUND;
diff --git a/sw/source/core/doc/DocumentContentOperationsManager.cxx b/sw/source/core/doc/DocumentContentOperationsManager.cxx
index 12c3345..4323e00 100644
--- a/sw/source/core/doc/DocumentContentOperationsManager.cxx
+++ b/sw/source/core/doc/DocumentContentOperationsManager.cxx
@@ -3982,11 +3982,14 @@ bool DocumentContentOperationsManager::ReplaceRangeImpl( SwPaM& rPam, const OUSt
         }
     }
 
-    if( bJoinTxt )
-        ::sw_JoinText( rPam, bJoinPrev );
+    bool bRet(true);
+    if (bJoinTxt)
+    {
+        bRet = ::sw_JoinText(rPam, bJoinPrev);
+    }
 
     m_rDoc.getIDocumentState().SetModified();
-    return true;
+    return bRet;
 }
 
 SwFlyFrmFmt* DocumentContentOperationsManager::_InsNoTxtNode( const SwPosition& rPos, SwNoTxtNode* pNode,
diff --git a/sw/source/core/doc/docedt.cxx b/sw/source/core/doc/docedt.cxx
index 5f00cc5..01c0b16 100644
--- a/sw/source/core/doc/docedt.cxx
+++ b/sw/source/core/doc/docedt.cxx
@@ -323,7 +323,7 @@ void sw_GetJoinFlags( SwPaM& rPam, bool& rJoinTxt, bool& rJoinPrev )
     }
 }
 
-void sw_JoinText( SwPaM& rPam, bool bJoinPrev )
+bool sw_JoinText( SwPaM& rPam, bool bJoinPrev )
 {
     SwNodeIndex aIdx( rPam.GetPoint()->nNode );
     SwTxtNode *pTxtNd = aIdx.GetNode().GetTxtNode();
@@ -445,7 +445,9 @@ void sw_JoinText( SwPaM& rPam, bool bJoinPrev )
             }
             pTxtNd->JoinNext();
         }
+        return true;
     }
+    else return false;
 }
 
 static void lcl_syncGrammarError( SwTxtNode &rTxtNode, linguistic2::ProofreadingResult& rResult,
diff --git a/sw/source/core/inc/docedt.hxx b/sw/source/core/inc/docedt.hxx
index 0d7513e..53ebea1 100644
--- a/sw/source/core/inc/docedt.hxx
+++ b/sw/source/core/inc/docedt.hxx
@@ -20,7 +20,7 @@
 #ifndef INCLUDED_SW_SOURCE_CORE_INC_DOCEDT_HXX
 #define INCLUDED_SW_SOURCE_CORE_INC_DOCEDT_HXX
 
-void sw_JoinText( SwPaM& rPam, bool bJoinPrev );
+bool sw_JoinText( SwPaM& rPam, bool bJoinPrev );
 
 void sw_GetJoinFlags( SwPaM& rPam, bool& rJoinTxt, bool& rJoinPrev );
 
commit 5a1fe97d70ca7c89ef74c05fd52783c9f54caf08
Author: Michael Stahl <mstahl at redhat.com>
Date:   Fri Feb 13 22:56:17 2015 +0100

    sw: test case for search-and-replace bug fixed by commit ...
    
    ... b60ce8465c8f01242354abccebe00742d164af60
    
    Change-Id: Iba1a059b3aeb5b2266398d80e6995f98fd580f14

diff --git a/sw/CppunitTest_sw_macros_test.mk b/sw/CppunitTest_sw_macros_test.mk
index c96084d..251597d 100644
--- a/sw/CppunitTest_sw_macros_test.mk
+++ b/sw/CppunitTest_sw_macros_test.mk
@@ -77,6 +77,7 @@ $(eval $(call gb_CppunitTest_use_components,sw_macros_test,\
 	forms/util/frm \
 	framework/util/fwk \
 	i18npool/util/i18npool \
+	i18npool/source/search/i18nsearch \
 	oox/util/oox \
 	package/source/xstor/xstor \
 	package/util/package2 \
diff --git a/sw/qa/core/macros-test.cxx b/sw/qa/core/macros-test.cxx
index 5267c34..d0c9e6d 100644
--- a/sw/qa/core/macros-test.cxx
+++ b/sw/qa/core/macros-test.cxx
@@ -18,6 +18,7 @@
 #include <com/sun/star/lang/XComponent.hpp>
 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
 #include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/util/SearchOptions.hpp>
 #include <com/sun/star/frame/Desktop.hpp>
 #include <com/sun/star/frame/XComponentLoader.hpp>
 #include <com/sun/star/frame/XStorable.hpp>
@@ -47,11 +48,14 @@
 #include <basic/sbxdef.hxx>
 #include <unotools/tempfile.hxx>
 
+#include <unocrsr.hxx>
+#include <ndtxt.hxx>
 #include <doc.hxx>
 #include <IDocumentLayoutAccess.hxx>
 #include <IDocumentUndoRedo.hxx>
 #include <IDocumentContentOperations.hxx>
 #include "docsh.hxx"
+#include <unotxdoc.hxx>
 
 typedef tools::SvRef<SwDocShell> SwDocShellRef;
 
@@ -80,6 +84,7 @@ public:
 #endif
     void testFdo55289();
     void testFdo68983();
+    void testFindReplace();
     CPPUNIT_TEST_SUITE(SwMacrosTest);
 #if !defined(MACOSX) && !defined(WNT)
     //enable this test if you want to play with star basic macros in unit tests
@@ -93,6 +98,7 @@ public:
 #endif
     CPPUNIT_TEST(testFdo55289);
     CPPUNIT_TEST(testFdo68983);
+    CPPUNIT_TEST(testFindReplace);
 
     CPPUNIT_TEST_SUITE_END();
 
@@ -393,6 +399,64 @@ void SwMacrosTest::testFdo68983()
     xDocCloseable->close(false);
 }
 
+void SwMacrosTest::testFindReplace()
+{
+    // we need a full document with view and layout etc. because ::GetNode()
+    Reference<lang::XComponent> const xComponent =
+        loadFromDesktop("private:factory/swriter", "com.sun.star.text.TextDocument");
+    SwXTextDocument *const pTxtDoc = dynamic_cast<SwXTextDocument *>(xComponent.get());
+    SwDoc *const pDoc = pTxtDoc->GetDocShell()->GetDoc();
+    SwNodeIndex aIdx(pDoc->GetNodes().GetEndOfContent(), -1);
+    // use a UnoCrsr so it will be corrected when deleting nodes
+    SwUnoCrsr *const pPaM(pDoc->CreateUnoCrsr(SwPosition(aIdx), false));
+
+    IDocumentContentOperations & rIDCO(pDoc->getIDocumentContentOperations());
+    rIDCO.InsertString(*pPaM, OUString("foo"));
+    rIDCO.AppendTxtNode(*pPaM->GetPoint());
+    rIDCO.InsertString(*pPaM, OUString("bar"));
+    rIDCO.AppendTxtNode(*pPaM->GetPoint());
+    rIDCO.InsertString(*pPaM, OUString("baz"));
+    pPaM->Move(fnMoveBackward, fnGoDoc);
+
+    bool bCancel(false);
+    util::SearchOptions opts(
+            util::SearchAlgorithms_REGEXP,
+            65536,
+            "$",
+            "",
+            lang::Locale("en", "US", ""),
+            2,
+            2,
+            2,
+            1073745152);
+
+    // find newline on 1st paragraph
+    bool bFound = pPaM->Find(
+            opts, false, DOCPOS_CURR, DOCPOS_END, bCancel, FND_IN_BODY, false);
+    CPPUNIT_ASSERT(bFound);
+    CPPUNIT_ASSERT(pPaM->HasMark());
+    CPPUNIT_ASSERT_EQUAL(OUString(""), pPaM->GetTxt());
+
+    // now do another Find, inside the selection from the first Find
+//    opts.searchFlags = 71680;
+    bFound = pPaM->Find(
+            opts, false, DOCPOS_CURR, DOCPOS_END, bCancel, FND_IN_SEL, false);
+    CPPUNIT_ASSERT(bFound);
+    CPPUNIT_ASSERT(pPaM->HasMark());
+    CPPUNIT_ASSERT_EQUAL(OUString(""), pPaM->GetTxt());
+
+    rIDCO.ReplaceRange(*pPaM, " ", true);
+
+    pPaM->DeleteMark();
+    pPaM->Move(fnMoveBackward, fnGoDoc);
+
+    // problem was that after the 2nd Find, the wrong newline was selected
+    CPPUNIT_ASSERT_EQUAL(OUString("foo bar"),
+            pPaM->Start()->nNode.GetNode().GetTxtNode()->GetTxt());
+    pPaM->Move(fnMoveForward, fnGoNode);
+    CPPUNIT_ASSERT_EQUAL(OUString("baz"),
+            pPaM->End()->nNode.GetNode().GetTxtNode()->GetTxt());
+}
 
 SwMacrosTest::SwMacrosTest()
       : m_aBaseString("/sw/qa/core/data")
commit 6c92e54a3abcaa1d8f5d83d74dfb0b77415be1d3
Author: Michael Stahl <mstahl at redhat.com>
Date:   Fri Feb 13 15:57:32 2015 +0100

    sw: work around buggy boost::intrusive::circular_list_algorithms::unlink()
    
    Boost is clearly following the C++ tradition of surprising omissions.
    
    Change-Id: I205ef17f87b176da938ebfa3e1a0748e94605daf

diff --git a/sw/inc/ring.hxx b/sw/inc/ring.hxx
index 9f70061..f6aac23 100644
--- a/sw/inc/ring.hxx
+++ b/sw/inc/ring.hxx
@@ -43,7 +43,14 @@ namespace sw
             typedef RingContainer<value_type> ring_container;
             typedef RingContainer<const_value_type> const_ring_container;
             virtual ~Ring()
-                { algo::unlink(this); };
+                { unlink(); };
+            /** algo::unlink is buggy! don't call it directly! */
+            void unlink()
+            {
+                algo::unlink(this);
+                pNext = this; // don't leave pointers to old list behind!
+                pPrev = this;
+            }
             /**
              * Removes this item from its current ring container and adds it to
              * another ring container. If the item was not alone in the original
@@ -135,7 +142,7 @@ namespace sw
     inline void Ring<value_type>::MoveTo(value_type* pDestRing)
     {
         value_type* pThis = static_cast< value_type* >(this);
-        algo::unlink(pThis);
+        unlink();
         // insert into "new"
         if (pDestRing)
         {
diff --git a/sw/qa/core/uwriter.cxx b/sw/qa/core/uwriter.cxx
index 0c06355..dcd0023 100644
--- a/sw/qa/core/uwriter.cxx
+++ b/sw/qa/core/uwriter.cxx
@@ -1381,6 +1381,8 @@ void SwDocTest::testIntrusiveRing()
     foo.MoveTo(&foo);
     CPPUNIT_ASSERT_EQUAL(&bar, bar.GetNext());
     CPPUNIT_ASSERT_EQUAL(&bar, bar.GetPrev());
+    CPPUNIT_ASSERT_EQUAL(&foo, foo.GetNext());
+    CPPUNIT_ASSERT_EQUAL(&foo, foo.GetPrev());
 }
 
 void SwDocTest::setUp()
commit 54e93460a53629c9428d3ed129a32f052b6bdd7e
Author: Michael Stahl <mstahl at redhat.com>
Date:   Fri Feb 13 15:06:16 2015 +0100

    (related: tdf#80715) sw: fix Ring::MoveTo() not doing anything...
    
    ... if the parameter is currently in the same list.
    
    The "boost::intrusive::circular_list_algorithms::transfer" has a
    precondition that the 2 parameters must not be in the same list.
    
    This causes an infinite loop in SwFindParaText::Find(), which is hiding
    the infinite loop that i'm trying to debug...
    
    While at it, remove some unnecessary complexity.
    
    Change-Id: Ib41f52c6d5c44ecc358c6170ee1e6e98729e1302

diff --git a/sw/inc/ring.hxx b/sw/inc/ring.hxx
index e0bfc5a..9f70061 100644
--- a/sw/inc/ring.hxx
+++ b/sw/inc/ring.hxx
@@ -135,16 +135,12 @@ namespace sw
     inline void Ring<value_type>::MoveTo(value_type* pDestRing)
     {
         value_type* pThis = static_cast< value_type* >(this);
+        algo::unlink(pThis);
         // insert into "new"
-        if( pDestRing )
+        if (pDestRing)
         {
-            if(algo::unique(pThis))
-                algo::link_before(pDestRing, pThis);
-            else
-                algo::transfer(pDestRing, pThis);
+            algo::link_before(pDestRing, pThis);
         }
-        else
-            algo::unlink(pThis);
     }
 
     /**
diff --git a/sw/qa/core/uwriter.cxx b/sw/qa/core/uwriter.cxx
index 96d2a34..0c06355 100644
--- a/sw/qa/core/uwriter.cxx
+++ b/sw/qa/core/uwriter.cxx
@@ -1372,6 +1372,15 @@ void SwDocTest::testIntrusiveRing()
         const TestRing* pRing = &r;
         CPPUNIT_ASSERT(pRing);
     }
+    TestRing foo, bar;
+    foo.MoveTo(&bar);
+    CPPUNIT_ASSERT_EQUAL(&foo, bar.GetNext());
+    CPPUNIT_ASSERT_EQUAL(&foo, bar.GetPrev());
+    CPPUNIT_ASSERT_EQUAL(&bar, foo.GetNext());
+    CPPUNIT_ASSERT_EQUAL(&bar, foo.GetPrev());
+    foo.MoveTo(&foo);
+    CPPUNIT_ASSERT_EQUAL(&bar, bar.GetNext());
+    CPPUNIT_ASSERT_EQUAL(&bar, bar.GetPrev());
 }
 
 void SwDocTest::setUp()
commit b6e43aac665d700d3474bb757afd7be492f65d2a
Author: Michael Stahl <mstahl at redhat.com>
Date:   Fri Feb 13 14:36:02 2015 +0100

    sw: RingContainer::merge(): assert that the Rings aren't already linked
    
    The function would un-merge them in that case, which is just a little
    bit surprising.
    
    Change-Id: Ife1d572635b812d3ff5b9f93c1ddf1954e12aca5

diff --git a/sw/inc/ring.hxx b/sw/inc/ring.hxx
index 8083e95..e0bfc5a 100644
--- a/sw/inc/ring.hxx
+++ b/sw/inc/ring.hxx
@@ -185,6 +185,10 @@ namespace sw
              */
             void merge( RingContainer< value_type > aDestRing )
             {
+                // first check that we aren't merged already, swapping would
+                // actually un-merge in this case!
+                assert(m_pStart->pPrev != aDestRing.m_pStart);
+                assert(m_pStart != aDestRing.m_pStart->pPrev);
                 std::swap(*(&m_pStart->pPrev->pNext), *(&aDestRing.m_pStart->pPrev->pNext));
                 std::swap(*(&m_pStart->pPrev), *(&aDestRing.m_pStart->pPrev));
             }


More information about the Libreoffice-commits mailing list