[Libreoffice-commits] core.git: comphelper/source compilerplugins/clang i18nlangtag/source i18npool/source l10ntools/source opencl/source solenv/CompilerTest_compilerplugins_clang.mk svl/source tools/source UnoControls/source unoidl/source unotools/source

Libreoffice Gerrit user logerrit at kemper.freedesktop.org
Fri Jul 27 09:16:13 UTC 2018


 UnoControls/source/controls/progressmonitor.cxx    |   24 +-
 comphelper/source/misc/mimeconfighelper.cxx        |    9 -
 compilerplugins/clang/stringloop.cxx               |  170 +++++++++++++++++++++
 compilerplugins/clang/test/stringloop.cxx          |   38 ++++
 i18nlangtag/source/languagetag/languagetag.cxx     |   13 -
 i18npool/source/indexentry/genindex_data.cxx       |    5 
 l10ntools/source/po.cxx                            |    8 
 opencl/source/openclconfig.cxx                     |   11 -
 solenv/CompilerTest_compilerplugins_clang.mk       |    1 
 svl/source/items/slstitm.cxx                       |    9 -
 svl/source/items/style.cxx                         |    9 -
 svl/source/numbers/zformat.cxx                     |   12 -
 svl/source/passwordcontainer/passwordcontainer.cxx |   26 +--
 tools/source/inet/inetmime.cxx                     |   35 ++--
 unoidl/source/sourceprovider-parser.y              |   10 -
 unotools/source/config/defaultoptions.cxx          |   14 -
 16 files changed, 306 insertions(+), 88 deletions(-)

New commits:
commit c8fa03b1f565461364b9f6423b65680e09281c14
Author:     Noel Grandin <noel.grandin at collabora.co.uk>
AuthorDate: Thu Jul 26 13:15:05 2018 +0200
Commit:     Noel Grandin <noel.grandin at collabora.co.uk>
CommitDate: Fri Jul 27 11:15:46 2018 +0200

    new loplugin:stringloop, and applied in various
    
    look for OUString being appended to in a loop, better to use
    OUStringBuffer to accumulate the results.
    
    Change-Id: Ia36e06e2781a7c546ce9cbad62727aa4c5f10c4b
    Reviewed-on: https://gerrit.libreoffice.org/58092
    Tested-by: Jenkins
    Reviewed-by: Noel Grandin <noel.grandin at collabora.co.uk>

diff --git a/UnoControls/source/controls/progressmonitor.cxx b/UnoControls/source/controls/progressmonitor.cxx
index b43afd5d6e73..c7da6f15ab17 100644
--- a/UnoControls/source/controls/progressmonitor.cxx
+++ b/UnoControls/source/controls/progressmonitor.cxx
@@ -721,31 +721,31 @@ void ProgressMonitor::impl_rebuildFixedText ()
     // Rebuild left site of text
     if (m_xTopic_Top.is())
     {
-        OUString aCollectString;
+        OUStringBuffer aCollectString;
 
         // Collect all topics from list and format text.
         // "\n" MUST BE at the end of line!!! => Else ... topic and his text are not in the same line!!!
         for (auto const & pSearchItem : maTextlist_Top)
         {
-            aCollectString  +=  pSearchItem->sTopic + "\n";
+            aCollectString.append(pSearchItem->sTopic).append("\n");
         }
 
-        m_xTopic_Top->setText ( aCollectString );
+        m_xTopic_Top->setText ( aCollectString.makeStringAndClear() );
     }
 
     // Rebuild right site of text
     if (m_xText_Top.is())
     {
-        OUString        aCollectString;
+        OUStringBuffer aCollectString;
 
         // Collect all topics from list and format text.
         // "\n" MUST BE at the end of line!!! => Else ... topic and his text are not in the same line!!!
         for (auto const & pSearchItem : maTextlist_Top)
         {
-            aCollectString  +=  pSearchItem->sText + "\n";
+            aCollectString.append(pSearchItem->sText).append("\n");
         }
 
-        m_xText_Top->setText ( aCollectString );
+        m_xText_Top->setText ( aCollectString.makeStringAndClear() );
     }
 
     // Rebuild fixedtext below progress
@@ -753,31 +753,31 @@ void ProgressMonitor::impl_rebuildFixedText ()
     // Rebuild left site of text
     if (m_xTopic_Bottom.is())
     {
-        OUString        aCollectString;
+        OUStringBuffer aCollectString;
 
         // Collect all topics from list and format text.
         // "\n" MUST BE at the end of line!!! => Else ... topic and his text are not in the same line!!!
         for (auto const & pSearchItem : maTextlist_Bottom)
         {
-            aCollectString  +=  pSearchItem->sTopic + "\n";
+            aCollectString.append(pSearchItem->sTopic).append("\n");
         }
 
-        m_xTopic_Bottom->setText ( aCollectString );
+        m_xTopic_Bottom->setText ( aCollectString.makeStringAndClear() );
     }
 
     // Rebuild right site of text
     if (m_xText_Bottom.is())
     {
-        OUString        aCollectString;
+        OUStringBuffer aCollectString;
 
         // Collect all topics from list and format text.
         // "\n" MUST BE at the end of line!!! => Else ... topic and his text are not in the same line!!!
         for (auto const & pSearchItem : maTextlist_Bottom)
         {
-            aCollectString  +=  pSearchItem->sText + "\n";
+            aCollectString.append(pSearchItem->sText).append("\n");
         }
 
-        m_xText_Bottom->setText ( aCollectString );
+        m_xText_Bottom->setText ( aCollectString.makeStringAndClear() );
     }
 }
 
diff --git a/comphelper/source/misc/mimeconfighelper.cxx b/comphelper/source/misc/mimeconfighelper.cxx
index 08ac2f958f37..c027bc1ff00f 100644
--- a/comphelper/source/misc/mimeconfighelper.cxx
+++ b/comphelper/source/misc/mimeconfighelper.cxx
@@ -30,6 +30,7 @@
 #include <comphelper/sequenceashashmap.hxx>
 #include <comphelper/documentconstants.hxx>
 #include <comphelper/propertysequence.hxx>
+#include <rtl/ustrbuf.hxx>
 
 
 using namespace ::com::sun::star;
@@ -46,22 +47,22 @@ MimeConfigurationHelper::MimeConfigurationHelper( const uno::Reference< uno::XCo
 
 OUString MimeConfigurationHelper::GetStringClassIDRepresentation( const uno::Sequence< sal_Int8 >& aClassID )
 {
-    OUString aResult;
+    OUStringBuffer aResult;
 
     if ( aClassID.getLength() == 16 )
     {
         for ( sal_Int32 nInd = 0; nInd < aClassID.getLength(); nInd++ )
         {
             if ( nInd == 4 || nInd == 6 || nInd == 8 || nInd == 10 )
-                aResult += "-";
+                aResult.append("-");
 
             sal_Int32 nDigit1 = static_cast<sal_Int32>( static_cast<sal_uInt8>(aClassID[nInd]) / 16 );
             sal_Int32 nDigit2 = static_cast<sal_uInt8>(aClassID[nInd]) % 16;
-            aResult += OUString::number( nDigit1, 16 ) + OUString::number( nDigit2, 16 );
+            aResult.append(OUString::number( nDigit1, 16 )).append(OUString::number( nDigit2, 16 ));
         }
     }
 
-    return aResult;
+    return aResult.makeStringAndClear();
 }
 
 
diff --git a/compilerplugins/clang/stringloop.cxx b/compilerplugins/clang/stringloop.cxx
new file mode 100644
index 000000000000..91cba802f3a6
--- /dev/null
+++ b/compilerplugins/clang/stringloop.cxx
@@ -0,0 +1,170 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include "check.hxx"
+#include "plugin.hxx"
+#include <vector>
+
+/** Look for OUString/OString being appended to inside a loop, where OUStringBuffer/OStringBuffer would be a better idea
+ */
+namespace
+{
+class StringLoop : public clang::RecursiveASTVisitor<StringLoop>, public loplugin::Plugin
+{
+public:
+    explicit StringLoop(loplugin::InstantiationData const& rData)
+        : Plugin(rData)
+    {
+    }
+
+    void run() override;
+    bool TraverseForStmt(ForStmt*);
+    bool TraverseCXXForRangeStmt(CXXForRangeStmt*);
+    bool TraverseDoStmt(DoStmt*);
+    bool TraverseWhileStmt(WhileStmt*);
+    bool VisitVarDecl(VarDecl const*);
+    bool VisitCallExpr(CallExpr const*);
+
+private:
+    int m_insideLoop = 0;
+    using VarDeclList = std::vector<VarDecl const*>;
+    std::vector<VarDeclList> m_varsPerLoopLevel;
+};
+
+void StringLoop::run()
+{
+    StringRef fn(handler.getMainFileName());
+    if (loplugin::hasPathnamePrefix(fn, SRCDIR "/bridges/"))
+        return;
+    if (loplugin::isSamePathname(fn, SRCDIR "/cppuhelper/source/shlib.cxx"))
+        return;
+    if (loplugin::isSamePathname(fn, SRCDIR "/registry/source/regimpl.cxx"))
+        return;
+    if (loplugin::isSamePathname(fn, SRCDIR "/l10ntools/source/lngmerge.cxx"))
+        return;
+    if (loplugin::hasPathnamePrefix(fn, SRCDIR "/tools/qa/"))
+        return;
+    if (loplugin::hasPathnamePrefix(fn, SRCDIR "/jvmfwk/"))
+        return;
+    if (loplugin::isSamePathname(fn, SRCDIR "/svl/source/passwordcontainer/passwordcontainer.cxx"))
+        return;
+    if (loplugin::isSamePathname(fn, SRCDIR "/svl/source/numbers/zformat.cxx"))
+        return;
+    if (loplugin::isSamePathname(fn, SRCDIR "/svl/source/numbers/zforscan.cxx"))
+        return;
+    if (loplugin::isSamePathname(fn, SRCDIR "/vcl/source/control/combobox.cxx"))
+        return;
+
+    TraverseDecl(compiler.getASTContext().getTranslationUnitDecl());
+}
+
+bool StringLoop::TraverseForStmt(ForStmt* stmt)
+{
+    ++m_insideLoop;
+    m_varsPerLoopLevel.push_back({});
+    auto const ret = RecursiveASTVisitor::TraverseForStmt(stmt);
+    m_varsPerLoopLevel.pop_back();
+    --m_insideLoop;
+    return ret;
+}
+
+bool StringLoop::TraverseCXXForRangeStmt(CXXForRangeStmt* stmt)
+{
+    ++m_insideLoop;
+    m_varsPerLoopLevel.push_back({});
+    auto const ret = RecursiveASTVisitor::TraverseCXXForRangeStmt(stmt);
+    m_varsPerLoopLevel.pop_back();
+    --m_insideLoop;
+    return ret;
+}
+
+bool StringLoop::TraverseDoStmt(DoStmt* stmt)
+{
+    ++m_insideLoop;
+    m_varsPerLoopLevel.push_back({});
+    auto const ret = RecursiveASTVisitor::TraverseDoStmt(stmt);
+    m_varsPerLoopLevel.pop_back();
+    --m_insideLoop;
+    return ret;
+}
+
+bool StringLoop::TraverseWhileStmt(WhileStmt* stmt)
+{
+    ++m_insideLoop;
+    m_varsPerLoopLevel.push_back({});
+    auto const ret = RecursiveASTVisitor::TraverseWhileStmt(stmt);
+    m_varsPerLoopLevel.pop_back();
+    --m_insideLoop;
+    return ret;
+}
+
+bool StringLoop::VisitVarDecl(VarDecl const* varDecl)
+{
+    if (ignoreLocation(varDecl))
+        return true;
+    if (!m_insideLoop)
+        return true;
+    m_varsPerLoopLevel.back().push_back(varDecl);
+    return true;
+}
+
+bool StringLoop::VisitCallExpr(CallExpr const* callExpr)
+{
+    if (ignoreLocation(callExpr))
+        return true;
+    if (!m_insideLoop)
+        return true;
+    auto operatorCallExpr = dyn_cast<CXXOperatorCallExpr>(callExpr);
+    if (!operatorCallExpr)
+        return true;
+    if (operatorCallExpr->getOperator() != OO_PlusEqual)
+        return true;
+
+    if (auto memberExpr = dyn_cast<MemberExpr>(callExpr->getArg(0)))
+    {
+        auto tc = loplugin::TypeCheck(memberExpr->getType());
+        if (!tc.Class("OUString").Namespace("rtl").GlobalNamespace()
+            && !tc.Class("OString").Namespace("rtl").GlobalNamespace())
+            return true;
+        report(DiagnosticsEngine::Warning,
+               "appending to OUString in loop, rather use OUStringBuffer",
+               operatorCallExpr->getLocStart())
+            << operatorCallExpr->getSourceRange();
+        auto fieldDecl = dyn_cast<FieldDecl>(memberExpr->getMemberDecl());
+        report(DiagnosticsEngine::Note, "field here", fieldDecl->getLocStart())
+            << fieldDecl->getSourceRange();
+    }
+    else if (auto declRefExpr = dyn_cast<DeclRefExpr>(callExpr->getArg(0)))
+    {
+        if (auto varDecl = dyn_cast<VarDecl>(declRefExpr->getDecl()))
+        {
+            auto tc = loplugin::TypeCheck(varDecl->getType());
+            if (!tc.Class("OUString").Namespace("rtl").GlobalNamespace()
+                && !tc.Class("OString").Namespace("rtl").GlobalNamespace())
+                return true;
+            // if the var is at the same block scope as the +=, not interesting
+            auto vars = m_varsPerLoopLevel.back();
+            if (std::find(vars.begin(), vars.end(), varDecl) != vars.end())
+                return true;
+            report(DiagnosticsEngine::Warning,
+                   "appending to OUString in loop, rather use OUStringBuffer",
+                   operatorCallExpr->getLocStart())
+                << operatorCallExpr->getSourceRange();
+            report(DiagnosticsEngine::Note, "var here", varDecl->getLocStart())
+                << varDecl->getSourceRange();
+        }
+    }
+    return true;
+}
+
+loplugin::Plugin::Registration<StringLoop> X("stringloop", false);
+
+} // namespace
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/compilerplugins/clang/test/stringloop.cxx b/compilerplugins/clang/test/stringloop.cxx
new file mode 100644
index 000000000000..0e9183d42057
--- /dev/null
+++ b/compilerplugins/clang/test/stringloop.cxx
@@ -0,0 +1,38 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include "sal/config.h"
+#include "rtl/string.hxx"
+#include "rtl/ustring.hxx"
+
+struct Foo
+{
+    OUString m_field; // expected-note {{field here [loplugin:stringloop]}}
+    void func1()
+    {
+        for (int i = 0; i < 10; ++i)
+            m_field += "xxx";
+        // expected-error at -1 {{appending to OUString in loop, rather use OUStringBuffer [loplugin:stringloop]}}
+        // no warning expected
+        m_field += "xxx";
+    }
+};
+
+void func2()
+{
+    OUString s; // expected-note {{var here [loplugin:stringloop]}}
+    for (int i = 0; i < 10; ++i)
+        s += "xxx"; // expected-error {{appending to OUString in loop, rather use OUStringBuffer [loplugin:stringloop]}}
+
+    // no warning expected
+    OUString s2;
+    s2 += "xxx";
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/i18nlangtag/source/languagetag/languagetag.cxx b/i18nlangtag/source/languagetag/languagetag.cxx
index fd3f1156c744..862b4e24f777 100644
--- a/i18nlangtag/source/languagetag/languagetag.cxx
+++ b/i18nlangtag/source/languagetag/languagetag.cxx
@@ -1636,10 +1636,10 @@ OUString LanguageTagImpl::getRegionFromLangtag()
 
 OUString LanguageTagImpl::getVariantsFromLangtag()
 {
-    OUString aVariants;
+    OUStringBuffer aVariants;
     synCanonicalize();
     if (maBcp47.isEmpty())
-        return aVariants;
+        return OUString();
     if (mpImplLangtag)
     {
         const lt_list_t* pVariantsT = lt_tag_get_variants( mpImplLangtag);
@@ -1651,10 +1651,9 @@ OUString LanguageTagImpl::getVariantsFromLangtag()
                 const char* p = lt_variant_get_tag( pVariantT);
                 if (p)
                 {
-                    if (aVariants.isEmpty())
-                        aVariants = OUString::createFromAscii( p);
-                    else
-                        aVariants += "-" + OUString::createFromAscii( p);
+                    if (!aVariants.isEmpty())
+                        aVariants.append("-");
+                    aVariants.appendAscii(p);
                 }
             }
         }
@@ -1664,7 +1663,7 @@ OUString LanguageTagImpl::getVariantsFromLangtag()
         if (mbCachedVariants || cacheSimpleLSCV())
             aVariants = maCachedVariants;
     }
-    return aVariants;
+    return aVariants.makeStringAndClear();
 }
 
 
diff --git a/i18npool/source/indexentry/genindex_data.cxx b/i18npool/source/indexentry/genindex_data.cxx
index d505dc9b661f..871b742d9b86 100644
--- a/i18npool/source/indexentry/genindex_data.cxx
+++ b/i18npool/source/indexentry/genindex_data.cxx
@@ -25,6 +25,7 @@
 #include <sal/main.h>
 #include <sal/types.h>
 #include <rtl/ustring.hxx>
+#include <rtl/ustrbuf.hxx>
 
 #define MAX_ADDRESS 0x30000
 #define MAX_INDEX MAX_ADDRESS/0x100
@@ -48,7 +49,7 @@ SAL_IMPLEMENT_MAIN_WITH_ARGS(argc, argv)
     sal_Int32 address[MAX_ADDRESS];
     for (i=0; i<MAX_ADDRESS; i++) address[i]=-1;
     OUString sep=OUString('|');
-    OUString result=sep;
+    OUStringBuffer result=sep;
     sal_Int32 max=0;
 
     sal_Char str[1024];
@@ -78,7 +79,7 @@ SAL_IMPLEMENT_MAIN_WITH_ARGS(argc, argv)
             address[nChar]=idx;
         } else {
             address[nChar]=result.getLength();
-            result+=key;
+            result.append(key);
         }
     }
     fclose(fp);
diff --git a/l10ntools/source/po.cxx b/l10ntools/source/po.cxx
index 7959b8361d7d..c2ccb47cdfe1 100644
--- a/l10ntools/source/po.cxx
+++ b/l10ntools/source/po.cxx
@@ -28,7 +28,7 @@
 class GenPoEntry
 {
 private:
-    OString    m_sExtractCom;
+    OStringBuffer m_sExtractCom;
     OString    m_sReference;
     OString    m_sMsgCtxt;
     OString    m_sMsgId;
@@ -129,7 +129,7 @@ void GenPoEntry::writeToFile(std::ofstream& rOFStream) const
     if ( !m_sExtractCom.isEmpty() )
         rOFStream
             << "#. "
-            << m_sExtractCom.replaceAll("\n","\n#. ") << std::endl;
+            << m_sExtractCom.toString().replaceAll("\n","\n#. ") << std::endl;
     if ( !m_sReference.isEmpty() )
         rOFStream << "#: " << m_sReference << std::endl;
     if ( m_bFuzzy )
@@ -162,9 +162,9 @@ void GenPoEntry::readFromFile(std::ifstream& rIFStream)
         {
             if( !m_sExtractCom.isEmpty() )
             {
-                m_sExtractCom += "\n";
+                m_sExtractCom.append("\n");
             }
-            m_sExtractCom += sLine.copy(3);
+            m_sExtractCom.append(sLine.copy(3));
         }
         else if (sLine.startsWith("#: "))
         {
diff --git a/opencl/source/openclconfig.cxx b/opencl/source/openclconfig.cxx
index 0ec2347fb332..18a9f865be00 100644
--- a/opencl/source/openclconfig.cxx
+++ b/opencl/source/openclconfig.cxx
@@ -14,6 +14,7 @@
 #include <opencl/openclconfig.hxx>
 #include <opencl/platforminfo.hxx>
 #include <rtl/ustring.hxx>
+#include <rtl/ustrbuf.hxx>
 #include <sal/log.hxx>
 #include <sal/types.h>
 
@@ -69,16 +70,16 @@ css::uno::Sequence<OUString> SetOfImplMatcherToStringSequence(const OpenCLConfig
 OUString getToken(const OUString& string, sal_Int32& index)
 {
     OUString token(string.getToken(0, '/', index));
-    OUString result;
+    OUStringBuffer result;
     sal_Int32 i(0);
     sal_Int32 p;
     while ((p = token.indexOf('%', i)) >= 0)
     {
         if (p > i)
-            result += token.copy(i, p - i);
+            result.append(token.copy(i, p - i));
         if (p < token.getLength() - 2)
         {
-            result += OUStringLiteral1(token.copy(p+1, 2).toInt32(16));
+            result.append(OUStringLiteral1(token.copy(p+1, 2).toInt32(16)));
             i = p + 3;
         }
         else
@@ -86,9 +87,9 @@ OUString getToken(const OUString& string, sal_Int32& index)
             i = token.getLength();
         }
     }
-    result += token.copy(i);
+    result.append(token.copy(i));
 
-    return result;
+    return result.makeStringAndClear();
 }
 
 OpenCLConfig::ImplMatcherSet StringSequenceToSetOfImplMatcher(const css::uno::Sequence<OUString>& rSequence)
diff --git a/solenv/CompilerTest_compilerplugins_clang.mk b/solenv/CompilerTest_compilerplugins_clang.mk
index db6e7f23a3e2..499e33fe2faf 100644
--- a/solenv/CompilerTest_compilerplugins_clang.mk
+++ b/solenv/CompilerTest_compilerplugins_clang.mk
@@ -49,6 +49,7 @@ $(eval $(call gb_CompilerTest_add_exception_objects,compilerplugins_clang, \
     compilerplugins/clang/test/simplifybool \
     compilerplugins/clang/test/simplifydynamiccast \
     compilerplugins/clang/test/stringconstant \
+    compilerplugins/clang/test/stringloop \
     compilerplugins/clang/test/unnecessarycatchthrow \
     compilerplugins/clang/test/unnecessaryoverride \
     compilerplugins/clang/test/unnecessaryoverride-dtor \
diff --git a/svl/source/items/slstitm.cxx b/svl/source/items/slstitm.cxx
index 5399706c2e85..64d960226d86 100644
--- a/svl/source/items/slstitm.cxx
+++ b/svl/source/items/slstitm.cxx
@@ -25,6 +25,7 @@
 #include <osl/diagnose.h>
 #include <tools/stream.hxx>
 #include <stringio.hxx>
+#include <rtl/ustrbuf.hxx>
 
 SfxPoolItem* SfxStringListItem::CreateDefault() { return new SfxStringListItem; }
 
@@ -165,22 +166,22 @@ void SfxStringListItem::SetString( const OUString& rStr )
 
 OUString SfxStringListItem::GetString()
 {
-    OUString aStr;
+    OUStringBuffer aStr;
     if ( mpList )
     {
         std::vector<OUString>::const_iterator iter = mpList->begin();
         for (;;)
         {
-            aStr += *iter;
+            aStr.append(*iter);
             ++iter;
 
             if (iter == mpList->end())
                 break;
 
-            aStr += "\r";
+            aStr.append("\r");
         }
     }
-    return convertLineEnd(aStr, GetSystemLineEnd());
+    return convertLineEnd(aStr.makeStringAndClear(), GetSystemLineEnd());
 }
 
 
diff --git a/svl/source/items/style.cxx b/svl/source/items/style.cxx
index 5856393f57e9..0ab10a4c7801 100644
--- a/svl/source/items/style.cxx
+++ b/svl/source/items/style.cxx
@@ -36,6 +36,7 @@
 #include <algorithm>
 #include <comphelper/servicehelper.hxx>
 #include <o3tl/make_unique.hxx>
+#include <rtl/ustrbuf.hxx>
 
 #include <string.h>
 
@@ -328,7 +329,7 @@ bool SfxStyleSheetBase::IsUsed() const
 OUString SfxStyleSheetBase::GetDescription( MapUnit eMetric )
 {
     SfxItemIter aIter( GetItemSet() );
-    OUString aDesc;
+    OUStringBuffer aDesc;
     const SfxPoolItem* pItem = aIter.FirstItem();
 
     IntlWrapper aIntlWrapper(SvtSysLocale().GetUILanguageTag());
@@ -341,13 +342,13 @@ OUString SfxStyleSheetBase::GetDescription( MapUnit eMetric )
                 *pItem, eMetric, aItemPresentation, aIntlWrapper ) )
         {
             if ( !aDesc.isEmpty() && !aItemPresentation.isEmpty() )
-                aDesc += " + ";
+                aDesc.append(" + ");
             if ( !aItemPresentation.isEmpty() )
-                aDesc += aItemPresentation;
+                aDesc.append(aItemPresentation);
         }
         pItem = aIter.NextItem();
     }
-    return aDesc;
+    return aDesc.makeStringAndClear();
 }
 
 SfxStyleFamily SfxStyleSheetIterator::GetSearchFamily() const
diff --git a/svl/source/numbers/zformat.cxx b/svl/source/numbers/zformat.cxx
index 213e83a60a8c..f9e0b944b615 100644
--- a/svl/source/numbers/zformat.cxx
+++ b/svl/source/numbers/zformat.cxx
@@ -1930,7 +1930,7 @@ bool SvNumberformat::GetNewCurrencySymbol( OUString& rSymbol,
 // static
 OUString SvNumberformat::StripNewCurrencyDelimiters( const OUString& rStr )
 {
-    OUString aTmp;
+    OUStringBuffer aTmp;
     sal_Int32 nStartPos, nPos, nLen;
     nLen = rStr.getLength();
     nStartPos = 0;
@@ -1939,12 +1939,12 @@ OUString SvNumberformat::StripNewCurrencyDelimiters( const OUString& rStr )
         sal_Int32 nEnd;
         if ( (nEnd = GetQuoteEnd( rStr, nPos )) >= 0 )
         {
-            aTmp += rStr.copy( nStartPos, ++nEnd - nStartPos );
+            aTmp.append(rStr.copy( nStartPos, ++nEnd - nStartPos ));
             nStartPos = nEnd;
         }
         else
         {
-            aTmp += rStr.copy( nStartPos, nPos - nStartPos );
+            aTmp.append(rStr.copy( nStartPos, nPos - nStartPos ));
             nStartPos = nPos + 2;
             sal_Int32 nDash;
             nEnd = nStartPos - 1;
@@ -1975,15 +1975,15 @@ OUString SvNumberformat::StripNewCurrencyDelimiters( const OUString& rStr )
             {
                 nPos = nDash;
             }
-            aTmp += rStr.copy( nStartPos, nPos - nStartPos );
+            aTmp.append(rStr.copy( nStartPos, nPos - nStartPos ));
             nStartPos = nClose + 1;
         }
     }
     if ( nLen > nStartPos )
     {
-        aTmp += rStr.copy( nStartPos, nLen - nStartPos );
+        aTmp.append(rStr.copy( nStartPos, nLen - nStartPos ));
     }
-    return aTmp;
+    return aTmp.makeStringAndClear();
 }
 
 void SvNumberformat::ImpGetOutputStandard(double& fNumber, OUStringBuffer& rOutString) const
diff --git a/svl/source/passwordcontainer/passwordcontainer.cxx b/svl/source/passwordcontainer/passwordcontainer.cxx
index 6becfd9be78d..3a4aecef9874 100644
--- a/svl/source/passwordcontainer/passwordcontainer.cxx
+++ b/svl/source/passwordcontainer/passwordcontainer.cxx
@@ -36,6 +36,7 @@
 #include <rtl/cipher.h>
 #include <rtl/digest.h>
 #include <rtl/byteseq.hxx>
+#include <rtl/ustrbuf.hxx>
 
 using namespace osl;
 using namespace utl;
@@ -48,12 +49,12 @@ using namespace com::sun::star::ucb;
 
 static OUString createIndex(const std::vector< OUString >& lines)
 {
-    OUString aResult;
+    OUStringBuffer aResult;
 
     for( size_t i = 0; i < lines.size(); i++ )
     {
         if( i )
-            aResult += "__";
+            aResult.append("__");
         OString line = OUStringToOString( lines[i], RTL_TEXTENCODING_UTF8 );
         const sal_Char* pLine = line.getStr();
 
@@ -61,19 +62,18 @@ static OUString createIndex(const std::vector< OUString >& lines)
         {
             if (rtl::isAsciiAlphanumeric(static_cast<unsigned char>(*pLine)))
             {
-                aResult += OUStringLiteral1(*pLine);
+                aResult.append(*pLine);
             }
             else
             {
-                aResult += "_"
-                        + OUString::number(  *pLine, 16 );
+                aResult.append("_").append( OUString::number(  *pLine, 16 ) );
             }
 
             pLine++;
         }
     }
 
-    return aResult;
+    return aResult.makeStringAndClear();
 }
 
 
@@ -86,7 +86,7 @@ static std::vector< OUString > getInfoFromInd( const OUString& aInd )
     const sal_Char* pLine = line.getStr();
     do
     {
-        OUString newItem;
+        OUStringBuffer newItem;
         if( !aStart )
             pLine += 2;
         else
@@ -95,7 +95,7 @@ static std::vector< OUString > getInfoFromInd( const OUString& aInd )
         while( *pLine && !( pLine[0] == '_' && pLine[1] == '_' ))
             if( *pLine != '_' )
             {
-                newItem += OUStringLiteral1( *pLine );
+                newItem.append( *pLine );
                 pLine++;
             }
             else
@@ -115,11 +115,11 @@ static std::vector< OUString > getInfoFromInd( const OUString& aInd )
                     aNum += OUStringLiteral1( pLine[i] );
                 }
 
-                newItem += OUStringLiteral1( aNum.toUInt32( 16 ) );
+                newItem.append( OUStringLiteral1( aNum.toUInt32( 16 ) ) );
                 pLine += 3;
             }
 
-        aResult.push_back( newItem );
+        aResult.push_back( newItem.makeStringAndClear() );
     } while( pLine[0] == '_' && pLine[1] == '_' );
 
     if( *pLine )
@@ -766,11 +766,11 @@ UrlRecord PasswordContainer::find(
 
 OUString PasswordContainer::GetDefaultMasterPassword()
 {
-    OUString aResult;
+    OUStringBuffer aResult;
     for ( sal_Int32 nInd = 0; nInd < RTL_DIGEST_LENGTH_MD5; nInd++ )
-        aResult += "aa";
+        aResult.append("aa");
 
-    return aResult;
+    return aResult.makeStringAndClear();
 }
 
 OUString PasswordContainer::RequestPasswordFromUser( PasswordRequestMode aRMode, const uno::Reference< task::XInteractionHandler >& xHandler )
diff --git a/tools/source/inet/inetmime.cxx b/tools/source/inet/inetmime.cxx
index 0ec6bcdbb70e..7d344c060873 100644
--- a/tools/source/inet/inetmime.cxx
+++ b/tools/source/inet/inetmime.cxx
@@ -26,6 +26,7 @@
 #include <osl/diagnose.h>
 #include <rtl/ustring.hxx>
 #include <rtl/strbuf.hxx>
+#include <rtl/ustrbuf.hxx>
 #include <rtl/tencinfo.h>
 #include <tools/inetmime.hxx>
 #include <rtl/character.hxx>
@@ -305,7 +306,7 @@ bool translateUTF8Char(const sal_Char *& rBegin,
     return true;
 }
 
-void appendISO88591(OUString & rText, sal_Char const * pBegin,
+void appendISO88591(OUStringBuffer & rText, sal_Char const * pBegin,
                     sal_Char const * pEnd);
 
 struct Parameter
@@ -339,14 +340,14 @@ bool parseParameters(ParameterList const & rInput,
 
 //  appendISO88591
 
-void appendISO88591(OUString & rText, sal_Char const * pBegin,
+void appendISO88591(OUStringBuffer & rText, sal_Char const * pBegin,
                     sal_Char const * pEnd)
 {
     sal_Int32 nLength = pEnd - pBegin;
     std::unique_ptr<sal_Unicode[]> pBuffer(new sal_Unicode[nLength]);
     for (sal_Unicode * p = pBuffer.get(); pBegin != pEnd;)
         *p++ = static_cast<unsigned char>(*pBegin++);
-    rText += OUString(pBuffer.get(), nLength);
+    rText.append(pBuffer.get(), nLength);
 }
 
 //  parseParameters
@@ -376,7 +377,7 @@ bool parseParameters(ParameterList const & rInput,
                     = getCharsetEncoding(it->m_aCharset.getStr(),
                                                    it->m_aCharset.getStr()
                                                        + it->m_aCharset.getLength());
-            OUString aValue;
+            OUStringBuffer aValue;
             bool bBadEncoding = false;
             itNext = it;
             do
@@ -401,7 +402,7 @@ bool parseParameters(ParameterList const & rInput,
                     bBadEncoding = true;
                     break;
                 }
-                aValue += OUString(pUnicode, static_cast<sal_Int32>(nSize));
+                aValue.append(pUnicode, static_cast<sal_Int32>(nSize));
                 delete[] pUnicode;
                 ++itNext;
             }
@@ -409,22 +410,22 @@ bool parseParameters(ParameterList const & rInput,
 
             if (bBadEncoding)
             {
-                aValue.clear();
+                aValue.setLength(0);
                 itNext = it;
                 do
                 {
                     if (itNext->m_bExtended)
                     {
                         for (sal_Int32 i = 0; i < itNext->m_aValue.getLength(); ++i)
-                            aValue += OUStringLiteral1(
-                                sal_Unicode(
-                                    static_cast<unsigned char>(itNext->m_aValue[i]))
-                                | 0xF800); // map to unicode corporate use sub area
+                            aValue.append(
+                                static_cast<sal_Unicode>(
+                                    static_cast<unsigned char>(itNext->m_aValue[i])
+                                    | 0xF800)); // map to unicode corporate use sub area
                     }
                     else
                     {
                         for (sal_Int32 i = 0; i < itNext->m_aValue.getLength(); ++i)
-                            aValue += OUStringLiteral1( static_cast<unsigned char>(itNext->m_aValue[i]) );
+                            aValue.append( static_cast<char>(itNext->m_aValue[i]) );
                     }
                     ++itNext;
                 }
@@ -432,7 +433,7 @@ bool parseParameters(ParameterList const & rInput,
             }
             auto const ret = pOutput->insert(
                 {it->m_aAttribute,
-                 {it->m_aCharset, it->m_aLanguage, aValue, !bBadEncoding}});
+                 {it->m_aCharset, it->m_aLanguage, aValue.makeStringAndClear(), !bBadEncoding}});
             SAL_INFO_IF(!ret.second, "tools",
                 "INetMIME: dropping duplicate parameter: " << it->m_aAttribute);
         }
@@ -1156,7 +1157,7 @@ OUString INetMIME::decodeHeaderFieldBody(const OString& rBody)
     const sal_Char * pBegin = rBody.getStr();
     const sal_Char * pEnd = pBegin + rBody.getLength();
 
-    OUString sDecoded;
+    OUStringBuffer sDecoded;
     const sal_Char * pCopyBegin = pBegin;
 
     /* bool bStartEncodedWord = true; */
@@ -1408,7 +1409,7 @@ OUString INetMIME::decodeHeaderFieldBody(const OString& rBody)
             if (bEncodedWord)
             {
                 appendISO88591(sDecoded, pCopyBegin, pWSPBegin);
-                sDecoded += OUString(
+                sDecoded.append(
                     pUnicodeBuffer,
                     static_cast< sal_Int32 >(nUnicodeSize));
                 delete[] pUnicodeBuffer;
@@ -1424,7 +1425,7 @@ OUString INetMIME::decodeHeaderFieldBody(const OString& rBody)
         }
 
         if (!sEncodedText.isEmpty())
-            sDecoded += sEncodedText;
+            sDecoded.append(sEncodedText);
 
         if (p == pEnd)
             break;
@@ -1454,7 +1455,7 @@ OUString INetMIME::decodeHeaderFieldBody(const OString& rBody)
                     appendISO88591(sDecoded, pCopyBegin, p - 1);
                     sal_Unicode aUTF16Buf[2];
                     sal_Int32 nUTF16Len = putUTF32Character(aUTF16Buf, nCharacter) - aUTF16Buf;
-                    sDecoded += OUString(aUTF16Buf, nUTF16Len);
+                    sDecoded.append(aUTF16Buf, nUTF16Len);
                     p = pUTF8End;
                     pCopyBegin = p;
                 }
@@ -1466,7 +1467,7 @@ OUString INetMIME::decodeHeaderFieldBody(const OString& rBody)
     }
 
     appendISO88591(sDecoded, pCopyBegin, pEnd);
-    return sDecoded;
+    return sDecoded.makeStringAndClear();
 }
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/unoidl/source/sourceprovider-parser.y b/unoidl/source/sourceprovider-parser.y
index 529d2045a273..bb4f5dc2a92a 100644
--- a/unoidl/source/sourceprovider-parser.y
+++ b/unoidl/source/sourceprovider-parser.y
@@ -16,6 +16,8 @@
 
 #include <sal/config.h>
 
+#include <rtl/ustrbuf.hxx>
+
 #include <algorithm>
 #include <cassert>
 #include <cerrno>
@@ -4013,14 +4015,14 @@ OUString SourceProviderType::getName() const {
         return name;
     case unoidl::detail::SourceProviderType::TYPE_INSTANTIATED_POLYMORPHIC_STRUCT:
         {
-            OUString n(name + "<");
+            OUStringBuffer n(name + "<");
             for (auto i(subtypes.begin()); i != subtypes.end(); ++i) {
                 if (i != subtypes.begin()) {
-                    n += ",";
+                    n.append(",");
                 }
-                n += i->getName();
+                n.append(i->getName());
             }
-            return n + ">";
+            return n.append(">").makeStringAndClear();
         }
     default:
         assert(false && "this cannot happen"); for (;;) { std::abort(); }
diff --git a/unotools/source/config/defaultoptions.cxx b/unotools/source/config/defaultoptions.cxx
index c338a741e24c..0a74a321825a 100644
--- a/unotools/source/config/defaultoptions.cxx
+++ b/unotools/source/config/defaultoptions.cxx
@@ -32,6 +32,7 @@
 #include <osl/mutex.hxx>
 
 #include <rtl/instance.hxx>
+#include <rtl/ustrbuf.hxx>
 
 #include "itemholder1.hxx"
 
@@ -234,7 +235,8 @@ SvtDefaultOptions_Impl::SvtDefaultOptions_Impl() : ConfigItem( "Office.Common/Pa
     if ( aValues.getLength() == aNames.getLength() )
     {
         SvtPathOptions aPathOpt;
-        OUString aTempStr, aFullPath;
+        OUString aTempStr;
+        OUStringBuffer aFullPathBuf;
 
         for ( int nProp = 0; nProp < aNames.getLength(); nProp++ )
         {
@@ -246,7 +248,7 @@ SvtDefaultOptions_Impl::SvtDefaultOptions_Impl() : ConfigItem( "Office.Common/Pa
                     {
                         // multi paths
                         if ( pValues[nProp] >>= aTempStr )
-                            aFullPath = aPathOpt.SubstituteVariable( aTempStr );
+                            aFullPathBuf = aPathOpt.SubstituteVariable( aTempStr );
                         else
                         {
                             SAL_WARN( "unotools.config", "any operator >>= failed" );
@@ -257,17 +259,16 @@ SvtDefaultOptions_Impl::SvtDefaultOptions_Impl() : ConfigItem( "Office.Common/Pa
                     case css::uno::TypeClass_SEQUENCE :
                     {
                         // single paths
-                        aFullPath.clear();
+                        aFullPathBuf.setLength(0);
                         Sequence < OUString > aList;
                         if ( pValues[nProp] >>= aList )
                         {
                             sal_Int32 nCount = aList.getLength();
                             for ( sal_Int32 nPosition = 0; nPosition < nCount; ++nPosition )
                             {
-                                aTempStr = aPathOpt.SubstituteVariable( aList[ nPosition ] );
-                                aFullPath += aTempStr;
+                                aFullPathBuf.append(aPathOpt.SubstituteVariable( aList[ nPosition ] ));
                                 if ( nPosition < nCount-1 )
-                                    aFullPath += ";";
+                                    aFullPathBuf.append(";");
                             }
                         }
                         else
@@ -283,6 +284,7 @@ SvtDefaultOptions_Impl::SvtDefaultOptions_Impl() : ConfigItem( "Office.Common/Pa
                     }
                 }
 
+                auto aFullPath = aFullPathBuf.makeStringAndClear();
                 switch ( nProp )
                 {
                     case DEFAULTPATH_ADDIN:            m_aAddinPath = aFullPath;         break;


More information about the Libreoffice-commits mailing list