[Libreoffice-commits] .: 7 commits - bin/convwatch.py cppu/source sfx2/source solenv/gdb svl/source sw/source

Michael Stahl mst at kemper.freedesktop.org
Mon Feb 27 12:00:23 PST 2012


 bin/convwatch.py                             |  424 +++++++++++++++++++++++++++
 cppu/source/threadpool/jobqueue.cxx          |    9 
 cppu/source/threadpool/jobqueue.hxx          |    6 
 sfx2/source/doc/sfxbasemodel.cxx             |   20 -
 solenv/gdb/libreoffice/__init__.py           |    2 
 solenv/gdb/libreoffice/cppu.py               |    2 
 solenv/gdb/libreoffice/sal.py                |    2 
 solenv/gdb/libreoffice/svl.py                |    2 
 solenv/gdb/libreoffice/sw.py                 |    2 
 solenv/gdb/libreoffice/tl.py                 |    2 
 solenv/gdb/libreoffice/util/__init__.py      |    2 
 solenv/gdb/libreoffice/util/compatibility.py |    2 
 solenv/gdb/libreoffice/util/printing.py      |    2 
 solenv/gdb/libreoffice/util/string.py        |    2 
 solenv/gdb/libreoffice/util/uno.py           |    2 
 svl/source/inc/poolio.hxx                    |    2 
 sw/source/core/inc/frame.hxx                 |    2 
 sw/source/core/inc/layfrm.hxx                |    4 
 sw/source/core/inc/rootfrm.hxx               |    2 
 sw/source/core/inc/sectfrm.hxx               |    2 
 sw/source/core/layout/newfrm.cxx             |    9 
 sw/source/core/layout/sectfrm.cxx            |   13 
 sw/source/core/layout/ssfrm.cxx              |   22 +
 23 files changed, 501 insertions(+), 36 deletions(-)

New commits:
commit fa5e41067bc15c38dcc6c0c6fb327adad0444774
Author: Michael Stahl <mstahl at redhat.com>
Date:   Mon Feb 27 20:55:58 2012 +0100

    add convwatch.py

diff --git a/bin/convwatch.py b/bin/convwatch.py
new file mode 100755
index 0000000..7880234
--- /dev/null
+++ b/bin/convwatch.py
@@ -0,0 +1,424 @@
+# -*- tab-width: 4; indent-tabs-mode: nil; py-indent-offset: 4 -*-
+# Version: MPL 1.1 / GPLv3+ / LGPLv3+
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License or as specified alternatively below. You may obtain a copy of
+# the License at http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# Major Contributor(s):
+# Copyright (C) 2012 Red Hat, Inc., Michael Stahl <mstahl at redhat.com>
+#  (initial developer)
+#
+# All Rights Reserved.
+#
+# For minor contributions see the git repository.
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 3 or later (the "GPLv3+"), or
+# the GNU Lesser General Public License Version 3 or later (the "LGPLv3+"),
+# in which case the provisions of the GPLv3+ or the LGPLv3+ are applicable
+# instead of those above.
+
+import getopt
+import os
+import subprocess
+import sys
+import time
+import uuid
+try:
+    from urllib.parse import quote
+except ImportError:
+    from urllib import quote
+
+try:
+    import pyuno
+    import uno
+    import unohelper
+except ImportError:
+    print("pyuno not found: try to set PYTHONPATH and URE_BOOTSTRAP variables")
+    print("PYTHONPATH=/installation/opt/program")
+    print("URE_BOOTSTRAP=file:///installation/opt/program/fundamentalrc")
+    raise
+
+try:
+    from com.sun.star.document import XDocumentEventListener
+except ImportError:
+    print("UNO API class not found: try to set URE_BOOTSTRAP variable")
+    print("URE_BOOTSTRAP=file:///installation/opt/program/fundamentalrc")
+    raise
+
+### utilities ###
+
+def partition(list, pred):
+    left = []
+    right = []
+    for e in list:
+        if pred(e):
+            left.append(e)
+        else:
+            right.append(e)
+    return (left, right)
+
+def filelist(dir, suffix):
+    if len(dir) == 0:
+        raise Exception("filelist: empty directory")
+    if not(dir[-1] == "/"):
+        dir += "/"
+    files = [dir + f for f in os.listdir(dir)]
+#    print(files)
+    return [f for f in files
+                    if os.path.isfile(f) and os.path.splitext(f)[1] == suffix]
+
+def getFiles(dirs, suffix):
+    files = []
+    for dir in dirs:
+        files += filelist(dir, suffix)
+    return files
+
+### UNO utilities ###
+
+class OfficeConnection:
+    def __init__(self, args):
+        self.args = args
+        self.soffice = None
+        self.socket = None
+        self.xContext = None
+    def setUp(self):
+        (method, sep, rest) = self.args["--soffice"].partition(":")
+        if sep != ":":
+            raise Exception("soffice parameter does not specify method")
+        if method == "path":
+                socket = "pipe,name=pytest" + str(uuid.uuid1())
+                try:
+                    userdir = self.args["--userdir"]
+                except KeyError:
+                    raise Exception("'path' method requires --userdir")
+                if not(userdir.startswith("file://")):
+                    raise Exception("--userdir must be file URL")
+                self.soffice = self.bootstrap(rest, userdir, socket)
+        elif method == "connect":
+                socket = rest
+        else:
+            raise Exception("unsupported connection method: " + method)
+        self.xContext = self.connect(socket)
+
+    def bootstrap(self, soffice, userdir, socket):
+        argv = [ soffice, "--accept=" + socket + ";urp",
+                "-env:UserInstallation=" + userdir,
+                "--quickstart=no", "--nofirststartwizard",
+                "--norestore", "--nologo", "--headless" ]
+        if "--valgrind" in self.args:
+            argv.append("--valgrind")
+        return subprocess.Popen(argv)
+
+    def connect(self, socket):
+        xLocalContext = uno.getComponentContext()
+        xUnoResolver = xLocalContext.ServiceManager.createInstanceWithContext(
+                "com.sun.star.bridge.UnoUrlResolver", xLocalContext)
+        url = "uno:" + socket + ";urp;StarOffice.ComponentContext"
+        print("OfficeConnection: connecting to: " + url)
+        while True:
+            try:
+                xContext = xUnoResolver.resolve(url)
+                return xContext
+#            except com.sun.star.connection.NoConnectException
+            except pyuno.getClass("com.sun.star.connection.NoConnectException"):
+                print("NoConnectException: sleeping...")
+                time.sleep(1)
+
+    def tearDown(self):
+        if self.soffice:
+            if self.xContext:
+                try:
+                    print("tearDown: calling terminate()...")
+                    xMgr = self.xContext.ServiceManager
+                    xDesktop = xMgr.createInstanceWithContext(
+                            "com.sun.star.frame.Desktop", self.xContext)
+                    xDesktop.terminate()
+                    print("...done")
+#                except com.sun.star.lang.DisposedException:
+                except pyuno.getClass("com.sun.star.beans.UnknownPropertyException"):
+                    print("caught UnknownPropertyException")
+                    pass # ignore, also means disposed
+                except pyuno.getClass("com.sun.star.lang.DisposedException"):
+                    print("caught DisposedException")
+                    pass # ignore
+            else:
+                self.soffice.terminate()
+            ret = self.soffice.wait()
+            self.xContext = None
+            self.socket = None
+            self.soffice = None
+            if ret != 0:
+                raise Exception("Exit status indicates failure: " + str(ret))
+#            return ret
+
+class PerTestConnection:
+    def __init__(self, args):
+        self.args = args
+        self.connection = None
+    def getContext(self):
+        return self.connection.xContext
+    def setUp(self):
+        assert(not(self.connection))
+    def preTest(self):
+        conn = OfficeConnection(self.args)
+        conn.setUp()
+        self.connection = conn
+    def postTest(self):
+        if self.connection:
+            try:
+                self.connection.tearDown()
+            finally:
+                self.connection = None
+    def tearDown(self):
+        assert(not(self.connection))
+
+class PersistentConnection:
+    def __init__(self, args):
+        self.args = args
+        self.connection = None
+    def getContext(self):
+        return self.connection.xContext
+    def setUp(self):
+        conn = OfficeConnection(self.args)
+        conn.setUp()
+        self.connection = conn
+    def preTest(self):
+        assert(self.connection)
+    def postTest(self):
+        assert(self.connection)
+    def tearDown(self):
+        if self.connection:
+            try:
+                self.connection.tearDown()
+            finally:
+                self.connection = None
+
+def simpleInvoke(connection, test):
+    try:
+        connection.preTest()
+        test.run(connection.getContext())
+    finally:
+        connection.postTest()
+
+def retryInvoke(connection, test):
+    tries = 5
+    while tries > 0:
+        try:
+            tries -= 1
+            try:
+                connection.preTest()
+                test.run(connection.getContext())
+                return
+            finally:
+                connection.postTest()
+        except KeyboardInterrupt:
+            raise # Ctrl+C should work
+        except:
+            print("retryInvoke: caught exception")
+    raise Exception("FAILED retryInvoke")
+
+def runConnectionTests(connection, invoker, tests):
+    try:
+        connection.setUp()
+        for test in tests:
+            invoker(connection, test)
+    finally:
+        connection.tearDown()
+
+class EventListener(XDocumentEventListener,unohelper.Base):
+    def __init__(self):
+        self.layoutFinished = False
+    def documentEventOccured(self, event):
+#        print(str(event.EventName))
+        if event.EventName == "OnLayoutFinished":
+            self.layoutFinished = True
+    def disposing(event):
+        pass
+
+def mkPropertyValue(name, value):
+    return uno.createUnoStruct("com.sun.star.beans.PropertyValue",
+            name, 0, value, 0)
+
+### tests ###
+
+def loadFromURL(xContext, url):
+    xDesktop = xContext.ServiceManager.createInstanceWithContext(
+            "com.sun.star.frame.Desktop", xContext)
+    props = [("Hidden", True), ("ReadOnly", True)] # FilterName?
+    loadProps = tuple([mkPropertyValue(name, value) for (name, value) in props])
+    xListener = EventListener()
+    xGEB = xContext.ServiceManager.createInstanceWithContext(
+        "com.sun.star.frame.GlobalEventBroadcaster", xContext)
+    xGEB.addDocumentEventListener(xListener)
+    try:
+        xDoc = xDesktop.loadComponentFromURL(url, "_blank", 0, loadProps)
+        time_ = 0
+        while time_ < 30:
+            if xListener.layoutFinished:
+                return xDoc
+            print("delaying...")
+            time_ += 1
+            time.sleep(1)
+        print("timeout: no OnLayoutFinished received")
+        return xDoc
+    except:
+        if xDoc:
+            print("CLOSING")
+            xDoc.close(True)
+        raise
+    finally:
+        if xListener:
+            xGEB.removeDocumentEventListener(xListener)
+
+def printDoc(xContext, xDoc, url):
+    props = [ mkPropertyValue("FileName", url) ]
+# xDoc.print(props)
+    uno.invoke(xDoc, "print", (tuple(props),)) # damn, that's a keyword!
+    busy = True
+    while busy:
+        print("printing...")
+        time.sleep(1)
+        prt = xDoc.getPrinter()
+        for value in prt:
+            if value.Name == "IsBusy":
+                busy = value.Value
+    print("...done printing")
+
+class LoadPrintFileTest:
+    def __init__(self, file, prtsuffix):
+        self.file = file
+        self.prtsuffix = prtsuffix
+    def run(self, xContext):
+        print("Loading document: " + self.file)
+        try:
+            url = "file://" + quote(self.file)
+            xDoc = loadFromURL(xContext, url)
+            printDoc(xContext, xDoc, url + self.prtsuffix)
+        finally:
+            if xDoc:
+                xDoc.close(True)
+            print("...done with: " + self.file)
+
+def runLoadPrintFileTests(opts, dirs, suffix, reference):
+    if reference:
+        prtsuffix = ".pdf.reference"
+    else:
+        prtsuffix = ".pdf"
+    files = getFiles(dirs, suffix)
+    tests = (LoadPrintFileTest(file, prtsuffix) for file in files)
+    connection = PersistentConnection(opts)
+#    connection = PerTestConnection(opts)
+    runConnectionTests(connection, simpleInvoke, tests)
+
+def mkImages(file, resolution):
+    argv = [ "gs", "-r" + resolution, "-sOutputFile=" + file + ".%04d.jpeg",
+             "-dNOPROMPT", "-dNOPAUSE", "-dBATCH", "-sDEVICE=jpeg", file ]
+    ret = subprocess.check_call(argv)
+
+def mkAllImages(dirs, suffix, resolution, reference):
+    if reference:
+        prtsuffix = ".pdf.reference"
+    else:
+        prtsuffix = ".pdf"
+    for dir in dirs:
+        files = filelist(dir, suffix)
+        print(files)
+        for f in files:
+            mkImages(f + prtsuffix, resolution)
+
+def identify(imagefile):
+    argv = ["identify", "-format", "%k", imagefile]
+    result = subprocess.check_output(argv)
+    if result.partition("\n")[0] != "1":
+        print("identify result: " + result)
+        print("DIFFERENCE in " + imagefile)
+
+def compose(refimagefile, imagefile, diffimagefile):
+    argv = [ "composite", "-compose", "difference",
+            refimagefile, imagefile, diffimagefile ]
+    subprocess.check_call(argv)
+
+def compareImages(file):
+    allimages = [f for f in filelist(os.path.dirname(file), ".jpeg")
+                   if f.startswith(file)]
+#    refimages = [f for f in filelist(os.path.dirname(file), ".jpeg")
+#                   if f.startswith(file + ".reference")]
+#    print("compareImages: allimages:" + str(allimages))
+    (refimages, images) = partition(sorted(allimages),
+            lambda f: f.startswith(file + ".pdf.reference"))
+#    print("compareImages: images" + str(images))
+    for (image, refimage) in zip(images, refimages):
+        compose(image, refimage, image + ".diff")
+        identify(image + ".diff")
+    if (len(images) != len(refimages)):
+        print("DIFFERENT NUMBER OF IMAGES FOR: " + file)
+
+def compareAllImages(dirs, suffix):
+    print "compareAllImages..."
+    for dir in dirs:
+        files = filelist(dir, suffix)
+#        print("compareAllImages:" + str(files))
+        for f in files:
+            compareImages(f)
+    print "...compareAllImages done"
+
+
+def parseArgs(argv):
+    (optlist,args) = getopt.getopt(argv[1:], "hr",
+            ["help", "soffice=", "userdir=", "reference", "valgrind"])
+#    print optlist
+    return (dict(optlist), args)
+
+def usage():
+    message = """usage: {program} [option]... [directory]..."
+ -h | --help:      print usage information
+ -r | --reference: generate new reference files (otherwise: compare)
+ --soffice=method:location
+                   specify soffice instance to connect to
+                   supported methods: 'path', 'connect'
+ --userdir=URL     specify user installation directory for 'path' method
+ --valgrind        pass --valgrind to soffice for 'path' method"""
+    print(message.format(program = os.path.basename(sys.argv[0])))
+
+def checkTools():
+    try:
+        subprocess.check_output(["gs", "--version"])
+    except:
+        print("Cannot execute 'gs'. Please install ghostscript.")
+        sys.exit(1)
+    try:
+        subprocess.check_output(["composite", "-version"])
+        subprocess.check_output(["identify", "-version"])
+    except:
+        print("Cannot execute 'composite' or 'identify'.")
+        print("Please install ImageMagick.")
+        sys.exit(1)
+
+if __name__ == "__main__":
+#    checkTools()
+    (opts,args) = parseArgs(sys.argv)
+    if len(args) == 0:
+        usage()
+        sys.exit(1)
+    if "-h" in opts or "--help" in opts:
+        usage()
+        sys.exit()
+    elif "--soffice" in opts:
+        reference = "-r" in opts or "--reference" in opts
+        runLoadPrintFileTests(opts, args, ".odt", reference)
+        mkAllImages(args, ".odt", "200", reference)
+        if not(reference):
+            compareAllImages(args, ".odt")
+    else:
+        usage()
+        sys.exit(1)
+
+# vim:set shiftwidth=4 softtabstop=4 expandtab:
commit a860cd108c7e3e1eb0e5dfef6020610da1c07ed3
Author: Michael Stahl <mstahl at redhat.com>
Date:   Mon Feb 27 20:43:29 2012 +0100

    cppu: JobQueue::enter: add mutex guards for m_nToDo
    
    Considered replacing it with oslInterlockedCount, but wondered why there is
    no osl_getInterlockedCount (similar to glib's g_atomic_int_get)...

diff --git a/cppu/source/threadpool/jobqueue.cxx b/cppu/source/threadpool/jobqueue.cxx
index 0864057..da525ee 100644
--- a/cppu/source/threadpool/jobqueue.cxx
+++ b/cppu/source/threadpool/jobqueue.cxx
@@ -122,12 +122,14 @@ namespace cppu_threadpool {
             if( job.doRequest )
             {
                 job.doRequest( job.pThreadSpecificData );
+                MutexGuard guard( m_mutex );
                 m_nToDo --;
             }
             else
             {
-                m_nToDo --;
                 pReturn = job.pThreadSpecificData;
+                MutexGuard guard( m_mutex );
+                m_nToDo --;
                 break;
             }
         }
@@ -177,13 +179,13 @@ namespace cppu_threadpool {
         }
     }
 
-    sal_Bool JobQueue::isEmpty()
+    sal_Bool JobQueue::isEmpty() const
     {
         MutexGuard guard( m_mutex );
         return m_lstJob.empty();
     }
 
-    sal_Bool JobQueue::isCallstackEmpty()
+    sal_Bool JobQueue::isCallstackEmpty() const
     {
         MutexGuard guard( m_mutex );
         return m_lstCallstack.empty();
@@ -191,6 +193,7 @@ namespace cppu_threadpool {
 
     sal_Bool JobQueue::isBusy() const
     {
+        MutexGuard guard( m_mutex );
         return m_nToDo > 0;
     }
 
diff --git a/cppu/source/threadpool/jobqueue.hxx b/cppu/source/threadpool/jobqueue.hxx
index 6bddcc7..65f4a60 100644
--- a/cppu/source/threadpool/jobqueue.hxx
+++ b/cppu/source/threadpool/jobqueue.hxx
@@ -68,12 +68,12 @@ namespace cppu_threadpool
         void suspend();
         void resume();
 
-        sal_Bool isEmpty();
-        sal_Bool isCallstackEmpty();
+        sal_Bool isEmpty() const;
+        sal_Bool isCallstackEmpty() const;
         sal_Bool isBusy() const;
 
     private:
-        ::osl::Mutex m_mutex;
+        mutable ::osl::Mutex m_mutex;
         JobList      m_lstJob;
         CallStackList m_lstCallstack;
         sal_Int32 m_nToDo;
commit 3f43ebb4c3daf3e5c20a30a84f97bb4c93bff8a6
Author: Michael Stahl <mstahl at redhat.com>
Date:   Mon Feb 27 20:43:29 2012 +0100

    fdo#46678: tweak SfxBaseModel::getSomething:
    
    Lock the SolarMutex only when necessary.  This is a workaround that just
    happens to make the deadlock go away for me.  This being called from pyuno
    is wasteful anyway, but apparently there is no way to determine whether
    a uno::Reference points at something local to the process.

diff --git a/sfx2/source/doc/sfxbasemodel.cxx b/sfx2/source/doc/sfxbasemodel.cxx
index 4fb211f..1ff0f27 100644
--- a/sfx2/source/doc/sfxbasemodel.cxx
+++ b/sfx2/source/doc/sfxbasemodel.cxx
@@ -3106,14 +3106,20 @@ void SAL_CALL SfxBaseModel::removePrintJobListener( const uno::Reference< view::
 class SvObject;
 sal_Int64 SAL_CALL SfxBaseModel::getSomething( const ::com::sun::star::uno::Sequence< sal_Int8 >& aIdentifier ) throw(::com::sun::star::uno::RuntimeException)
 {
-    SolarMutexGuard aGuard;
-    if ( GetObjectShell() )
+    SvGlobalName aName( aIdentifier );
+    if ((aName == SvGlobalName( SO3_GLOBAL_CLASSID )) ||
+        (aName == SvGlobalName( SFX_GLOBAL_CLASSID )))
     {
-        SvGlobalName aName( aIdentifier );
-        if ( aName == SvGlobalName( SO3_GLOBAL_CLASSID ) )
-             return (sal_Int64)(sal_IntPtr)(SvObject*)GetObjectShell();
-        else if ( aName == SvGlobalName( SFX_GLOBAL_CLASSID ) )
-             return (sal_Int64)(sal_IntPtr)(SfxObjectShell*)GetObjectShell();
+        SolarMutexGuard aGuard;
+        SfxObjectShell *const pObjectShell(GetObjectShell());
+        if (pObjectShell)
+        {
+            // SO3_GLOBAL_CLASSID is apparently used by binfilter :(
+            if ( aName == SvGlobalName( SO3_GLOBAL_CLASSID ) )
+                 return (sal_Int64)(sal_IntPtr)(SvObject*) pObjectShell;
+            else if ( aName == SvGlobalName( SFX_GLOBAL_CLASSID ) )
+                 return (sal_Int64)(sal_IntPtr)(SfxObjectShell*) pObjectShell;
+        }
     }
 
     return 0;
commit 7c7d5c0eec4efb95d18b735fb9df4754ba9d8b1f
Author: Michael Stahl <mstahl at redhat.com>
Date:   Mon Feb 27 20:43:28 2012 +0100

    SfxItemPool: replace deque with vector for SfxPoolItem array
    
    Yields measurable speedup on load/store of large documents, wonder where
    the equivalent patch i committed long time ago to OOo went...

diff --git a/svl/source/inc/poolio.hxx b/svl/source/inc/poolio.hxx
index 15f55ee..7c2cfc6 100644
--- a/svl/source/inc/poolio.hxx
+++ b/svl/source/inc/poolio.hxx
@@ -56,7 +56,7 @@ struct SfxPoolVersion_Impl
                     {}
 };
 
-typedef std::deque<SfxPoolItem*> SfxPoolItemArrayBase_Impl;
+typedef std::vector<SfxPoolItem*> SfxPoolItemArrayBase_Impl;
 
 typedef boost::shared_ptr< SfxPoolVersion_Impl > SfxPoolVersion_ImplPtr;
 typedef std::deque< SfxPoolVersion_ImplPtr > SfxPoolVersionArr_Impl;
commit a2db9f4d46080e7ea6bd045dd8d3a87612ee49ec
Author: Michael Stahl <mstahl at redhat.com>
Date:   Mon Feb 27 20:43:28 2012 +0100

    solenv/gdb: fix Emacs modelines

diff --git a/solenv/gdb/libreoffice/__init__.py b/solenv/gdb/libreoffice/__init__.py
index a3b4f4b..9175812 100644
--- a/solenv/gdb/libreoffice/__init__.py
+++ b/solenv/gdb/libreoffice/__init__.py
@@ -1,4 +1,4 @@
-# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+# -*- tab-width: 4; indent-tabs-mode: nil; py-indent-offset: 4 -*-
 # Version: MPL 1.1 / GPLv3+ / LGPLv3+
 #
 # The contents of this file are subject to the Mozilla Public License Version
diff --git a/solenv/gdb/libreoffice/cppu.py b/solenv/gdb/libreoffice/cppu.py
index 3403251..852281f 100644
--- a/solenv/gdb/libreoffice/cppu.py
+++ b/solenv/gdb/libreoffice/cppu.py
@@ -1,4 +1,4 @@
-# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+# -*- tab-width: 4; indent-tabs-mode: nil; py-indent-offset: 4 -*-
 # Version: MPL 1.1 / GPLv3+ / LGPLv3+
 #
 # The contents of this file are subject to the Mozilla Public License Version
diff --git a/solenv/gdb/libreoffice/sal.py b/solenv/gdb/libreoffice/sal.py
index df87ed5..75d1cb1 100644
--- a/solenv/gdb/libreoffice/sal.py
+++ b/solenv/gdb/libreoffice/sal.py
@@ -1,4 +1,4 @@
-# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+# -*- tab-width: 4; indent-tabs-mode: nil; py-indent-offset: 4 -*-
 # Version: MPL 1.1 / GPLv3+ / LGPLv3+
 #
 # The contents of this file are subject to the Mozilla Public License Version
diff --git a/solenv/gdb/libreoffice/svl.py b/solenv/gdb/libreoffice/svl.py
index 57d60d9..cfb22f9 100644
--- a/solenv/gdb/libreoffice/svl.py
+++ b/solenv/gdb/libreoffice/svl.py
@@ -1,4 +1,4 @@
-# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+# -*- tab-width: 4; indent-tabs-mode: nil; py-indent-offset: 4 -*-
 # Version: MPL 1.1 / GPLv3+ / LGPLv3+
 #
 # The contents of this file are subject to the Mozilla Public License Version
diff --git a/solenv/gdb/libreoffice/sw.py b/solenv/gdb/libreoffice/sw.py
index 8325bfa..5007d0d 100644
--- a/solenv/gdb/libreoffice/sw.py
+++ b/solenv/gdb/libreoffice/sw.py
@@ -1,4 +1,4 @@
-# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+# -*- tab-width: 4; indent-tabs-mode: nil; py-indent-offset: 4 -*-
 # Version: MPL 1.1 / GPLv3+ / LGPLv3+
 #
 # The contents of this file are subject to the Mozilla Public License Version
diff --git a/solenv/gdb/libreoffice/tl.py b/solenv/gdb/libreoffice/tl.py
index 4f944f0..9571573 100644
--- a/solenv/gdb/libreoffice/tl.py
+++ b/solenv/gdb/libreoffice/tl.py
@@ -1,4 +1,4 @@
-# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+# -*- tab-width: 4; indent-tabs-mode: nil; py-indent-offset: 4 -*-
 # Version: MPL 1.1 / GPLv3+ / LGPLv3+
 #
 # The contents of this file are subject to the Mozilla Public License Version
diff --git a/solenv/gdb/libreoffice/util/__init__.py b/solenv/gdb/libreoffice/util/__init__.py
index a3b4f4b..9175812 100644
--- a/solenv/gdb/libreoffice/util/__init__.py
+++ b/solenv/gdb/libreoffice/util/__init__.py
@@ -1,4 +1,4 @@
-# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+# -*- tab-width: 4; indent-tabs-mode: nil; py-indent-offset: 4 -*-
 # Version: MPL 1.1 / GPLv3+ / LGPLv3+
 #
 # The contents of this file are subject to the Mozilla Public License Version
diff --git a/solenv/gdb/libreoffice/util/compatibility.py b/solenv/gdb/libreoffice/util/compatibility.py
index 3419fa9..6751b7d 100644
--- a/solenv/gdb/libreoffice/util/compatibility.py
+++ b/solenv/gdb/libreoffice/util/compatibility.py
@@ -1,4 +1,4 @@
-# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+# -*- tab-width: 4; indent-tabs-mode: nil; py-indent-offset: 4 -*-
 # Version: MPL 1.1 / GPLv3+ / LGPLv3+
 #
 # The contents of this file are subject to the Mozilla Public License Version
diff --git a/solenv/gdb/libreoffice/util/printing.py b/solenv/gdb/libreoffice/util/printing.py
index a315603..e6c4136 100644
--- a/solenv/gdb/libreoffice/util/printing.py
+++ b/solenv/gdb/libreoffice/util/printing.py
@@ -1,4 +1,4 @@
-# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+# -*- tab-width: 4; indent-tabs-mode: nil; py-indent-offset: 4 -*-
 # Version: MPL 1.1 / GPLv3+ / LGPLv3+
 #
 # The contents of this file are subject to the Mozilla Public License Version
diff --git a/solenv/gdb/libreoffice/util/string.py b/solenv/gdb/libreoffice/util/string.py
index e85999a..5ad0e8d 100644
--- a/solenv/gdb/libreoffice/util/string.py
+++ b/solenv/gdb/libreoffice/util/string.py
@@ -1,4 +1,4 @@
-# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+# -*- tab-width: 4; indent-tabs-mode: nil; py-indent-offset: 4 -*-
 # Version: MPL 1.1 / GPLv3+ / LGPLv3+
 #
 # The contents of this file are subject to the Mozilla Public License Version
diff --git a/solenv/gdb/libreoffice/util/uno.py b/solenv/gdb/libreoffice/util/uno.py
index a3190d5..0ffeb5d 100644
--- a/solenv/gdb/libreoffice/util/uno.py
+++ b/solenv/gdb/libreoffice/util/uno.py
@@ -1,4 +1,4 @@
-# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+# -*- tab-width: 4; indent-tabs-mode: nil; py-indent-offset: 4 -*-
 # Version: MPL 1.1 / GPLv3+ / LGPLv3+
 #
 # The contents of this file are subject to the Mozilla Public License Version
commit f430b71c46186b53a6364a60b237c81245f3eabb
Author: Michael Stahl <mstahl at redhat.com>
Date:   Mon Feb 27 20:43:27 2012 +0100

    SwSectionFrm: initialised members are happy members
    
    Valgrind complained about uninitialised use in
    SwSectionFrm::_CheckClipping (sectfrm.cxx:1111).

diff --git a/sw/source/core/inc/sectfrm.hxx b/sw/source/core/inc/sectfrm.hxx
index f9a0805..9bbe9f9 100644
--- a/sw/source/core/inc/sectfrm.hxx
+++ b/sw/source/core/inc/sectfrm.hxx
@@ -71,7 +71,7 @@ protected:
 public:
     SwSectionFrm( SwSection &, SwFrm* );                 //Inhalt wird nicht erzeugt!
     SwSectionFrm( SwSectionFrm &, sal_Bool bMaster );//_Nur_ zum Erzeugen von Master/Follows
-    ~SwSectionFrm();
+    virtual ~SwSectionFrm();
 
     void Init();
     virtual void  CheckDirection( sal_Bool bVert );
diff --git a/sw/source/core/layout/sectfrm.cxx b/sw/source/core/layout/sectfrm.cxx
index ef1f379..63f2bbd 100644
--- a/sw/source/core/layout/sectfrm.cxx
+++ b/sw/source/core/layout/sectfrm.cxx
@@ -71,10 +71,15 @@ SV_IMPL_PTRARR_SORT( SwDestroyList, SwSectionFrmPtr )
 |*  SwSectionFrm::SwSectionFrm(), ~SwSectionFrm()
 |*
 |*************************************************************************/
-SwSectionFrm::SwSectionFrm( SwSection &rSect, SwFrm* pSib ) :
-    SwLayoutFrm( rSect.GetFmt(), pSib ),
-    SwFlowFrm( (SwFrm&)*this ),
-    pSection( &rSect )
+SwSectionFrm::SwSectionFrm( SwSection &rSect, SwFrm* pSib )
+    : SwLayoutFrm( rSect.GetFmt(), pSib )
+    , SwFlowFrm( static_cast<SwFrm&>(*this) )
+    , pSection( &rSect )
+    , bFtnAtEnd(false)
+    , bEndnAtEnd(false)
+    , bCntntLock(false)
+    , bOwnFtnNum(false)
+    , bFtnLock(false)
 {
     nType = FRMC_SECTION;
 
commit ebb74441790a9852b1a1532d6e025c324666f6fc
Author: Michael Stahl <mstahl at redhat.com>
Date:   Mon Feb 27 20:43:27 2012 +0100

    SwRootFrm::~SwRootFrm: refactor:
    
    Since CWS swlayoutrefactoring the SwRootFrms are destroyed with
    SwDoc::IsInDtor not set.  This can cause at least reads of freed
    SwRootFrm members when executing the dtors of SwRootFrm base class
    SwLayoutFrm calling into SwRootFrm::GetPageAtPos.
    
    Prevent this scenario by:
    - moving the implementation of SwRootFrm base class dtors to new
      methods SwFrm::Destroy and SwLayoutFrm::Destroy
    - calling SwFrm::Destroy and SwLayoutFrm::Destroy explicitly before
      SwRootFrm members are freed

diff --git a/sw/source/core/inc/frame.hxx b/sw/source/core/inc/frame.hxx
index e61ee3f..742a358 100644
--- a/sw/source/core/inc/frame.hxx
+++ b/sw/source/core/inc/frame.hxx
@@ -408,6 +408,8 @@ protected:
     void ColLock()      { bColLocked = sal_True; }
     void ColUnlock()    { bColLocked = sal_False; }
 
+    void Destroy(); // for ~SwRootFrm
+
     // Only used by SwRootFrm Ctor to get 'this' into mpRoot...
     void setRootFrm( SwRootFrm* pRoot ) { mpRoot = pRoot; }
 
diff --git a/sw/source/core/inc/layfrm.hxx b/sw/source/core/inc/layfrm.hxx
index 1144a9d..4c4e4e6 100644
--- a/sw/source/core/inc/layfrm.hxx
+++ b/sw/source/core/inc/layfrm.hxx
@@ -56,6 +56,8 @@ class SwLayoutFrm: public SwFrm
 
     void CopySubtree( const SwLayoutFrm *pDest );
 protected:
+    void Destroy(); // for ~SwRootFrm
+
     virtual void Format( const SwBorderAttrs *pAttrs = 0 );
     virtual void MakeAll();
 
@@ -104,7 +106,7 @@ public:
                                    const sal_Bool bDefaultExpand = sal_True ) const;
 
     SwLayoutFrm( SwFrmFmt*, SwFrm* );
-    ~SwLayoutFrm();
+    virtual ~SwLayoutFrm();
 
     virtual void Paint( SwRect const&,
                         SwPrintData const*const pPrintData = NULL ) const;
diff --git a/sw/source/core/inc/rootfrm.hxx b/sw/source/core/inc/rootfrm.hxx
index b8f0f8f..ce94912 100644
--- a/sw/source/core/inc/rootfrm.hxx
+++ b/sw/source/core/inc/rootfrm.hxx
@@ -178,7 +178,7 @@ public:
     static sal_Bool HasSameRect( const SwRect& rRect );
 
     SwRootFrm( SwFrmFmt*, ViewShell* );
-    ~SwRootFrm();
+    virtual ~SwRootFrm();
     void Init(SwFrmFmt*);
 
     ViewShell *GetCurrShell() const { return pCurrShell; }
diff --git a/sw/source/core/layout/newfrm.cxx b/sw/source/core/layout/newfrm.cxx
index 3aa7a13..40b4339 100644
--- a/sw/source/core/layout/newfrm.cxx
+++ b/sw/source/core/layout/newfrm.cxx
@@ -627,8 +627,15 @@ SwRootFrm::~SwRootFrm()
         (*pCurrShells)[i]->pRoot = 0;
 
     delete pCurrShells;
+    pCurrShells = 0;
 
-    OSL_ENSURE( 0==nAccessibleShells, "Some accessible shells are left" );
+    // Some accessible shells are left => problems on second SwFrm::Destroy call
+    assert(0 == nAccessibleShells);
+
+    // manually call base classes Destroy because it could call stuff
+    // that accesses members of this
+    SwLayoutFrm::Destroy();
+    SwFrm::Destroy();
 }
 
 /*************************************************************************
diff --git a/sw/source/core/layout/ssfrm.cxx b/sw/source/core/layout/ssfrm.cxx
index f935cc7..848c921 100644
--- a/sw/source/core/layout/ssfrm.cxx
+++ b/sw/source/core/layout/ssfrm.cxx
@@ -362,7 +362,7 @@ Point SwFrm::GetFrmAnchorPos( sal_Bool bIgnoreFlysAnchoredAtThisFrame ) const
 |*
 |*************************************************************************/
 
-SwFrm::~SwFrm()
+void SwFrm::Destroy()
 {
     // accessible objects for fly and cell frames have been already disposed
     // by the destructors of the derived classes.
@@ -401,6 +401,15 @@ SwFrm::~SwFrm()
             }
         }
         delete pDrawObjs;
+        pDrawObjs = 0;
+    }
+}
+
+SwFrm::~SwFrm()
+{
+    if (!IsRootFrm()) // ~SwRootFrm already calls Destroy!
+    {
+        Destroy();
     }
 
 #if OSL_DEBUG_LEVEL > 0
@@ -555,8 +564,7 @@ void SwCntntFrm::DelFrms( const SwCntntNode& rNode )
 |*
 |*************************************************************************/
 
-
-SwLayoutFrm::~SwLayoutFrm()
+void SwLayoutFrm::Destroy()
 {
     SwFrm *pFrm = pLower;
 
@@ -638,6 +646,14 @@ SwLayoutFrm::~SwLayoutFrm()
     }
 }
 
+SwLayoutFrm::~SwLayoutFrm()
+{
+    if (!IsRootFrm()) // ~SwRootFrm already calls Destroy!
+    {
+        Destroy();
+    }
+}
+
 /*************************************************************************
 |*
 |*  SwFrm::PaintArea()


More information about the Libreoffice-commits mailing list