Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package libzypp for openSUSE:Factory checked 
in at 2021-03-10 08:47:12
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/libzypp (Old)
 and      /work/SRC/openSUSE:Factory/.libzypp.new.2378 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "libzypp"

Wed Mar 10 08:47:12 2021 rev:440 rq:874902 version:17.25.8

Changes:
--------
--- /work/SRC/openSUSE:Factory/libzypp/libzypp.changes  2021-02-23 
20:20:42.899672152 +0100
+++ /work/SRC/openSUSE:Factory/.libzypp.new.2378/libzypp.changes        
2021-03-10 08:47:31.570286444 +0100
@@ -1,0 +2,10 @@
+Wed Feb 24 17:07:52 CET 2021 - [email protected]
+
+- Try to provide a mounted /proc in --root installs (bsc#1181328)
+  Some systemd tools require /proc to be mounted and fail if it's
+  not there.
+- Enable release packages to request a releaxed suse/opensuse
+  vendorcheck in dup when migrating. (bsc#1182629)
+- version 17.25.8 (22)
+
+-------------------------------------------------------------------

Old:
----
  libzypp-17.25.7.tar.bz2

New:
----
  libzypp-17.25.8.tar.bz2

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ libzypp.spec ++++++
--- /var/tmp/diff_new_pack.M2GTeq/_old  2021-03-10 08:47:32.490287393 +0100
+++ /var/tmp/diff_new_pack.M2GTeq/_new  2021-03-10 08:47:32.494287397 +0100
@@ -31,7 +31,7 @@
 %bcond_without mediabackend_tests
 
 Name:           libzypp
-Version:        17.25.7
+Version:        17.25.8
 Release:        0
 URL:            https://github.com/openSUSE/libzypp
 Summary:        Library for package, patch, pattern and product management

++++++ libzypp-17.25.7.tar.bz2 -> libzypp-17.25.8.tar.bz2 ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libzypp-17.25.7/VERSION.cmake 
new/libzypp-17.25.8/VERSION.cmake
--- old/libzypp-17.25.7/VERSION.cmake   2021-02-17 09:16:38.000000000 +0100
+++ new/libzypp-17.25.8/VERSION.cmake   2021-02-24 17:11:46.000000000 +0100
@@ -61,8 +61,8 @@
 SET(LIBZYPP_MAJOR "17")
 SET(LIBZYPP_COMPATMINOR "22")
 SET(LIBZYPP_MINOR "25")
-SET(LIBZYPP_PATCH "7")
+SET(LIBZYPP_PATCH "8")
 #
-# LAST RELEASED: 17.25.7 (22)
+# LAST RELEASED: 17.25.8 (22)
 # (The number in parenthesis is LIBZYPP_COMPATMINOR)
 #=======
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libzypp-17.25.7/package/libzypp.changes 
new/libzypp-17.25.8/package/libzypp.changes
--- old/libzypp-17.25.7/package/libzypp.changes 2021-02-17 09:16:38.000000000 
+0100
+++ new/libzypp-17.25.8/package/libzypp.changes 2021-02-24 17:11:46.000000000 
+0100
@@ -1,4 +1,14 @@
 -------------------------------------------------------------------
+Wed Feb 24 17:07:52 CET 2021 - [email protected]
+
+- Try to provide a mounted /proc in --root installs (bsc#1181328)
+  Some systemd tools require /proc to be mounted and fail if it's
+  not there.
+- Enable release packages to request a releaxed suse/opensuse
+  vendorcheck in dup when migrating. (bsc#1182629)
+- version 17.25.8 (22)
+
+-------------------------------------------------------------------
 Wed Feb 17 09:06:49 CET 2021 - [email protected]
 
 - Patch: Identify well-known category names (bsc#117984)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libzypp-17.25.7/tests/zypp/StringV_test.cc 
new/libzypp-17.25.8/tests/zypp/StringV_test.cc
--- old/libzypp-17.25.7/tests/zypp/StringV_test.cc      2021-02-10 
15:19:44.000000000 +0100
+++ new/libzypp-17.25.8/tests/zypp/StringV_test.cc      2021-02-24 
16:52:50.000000000 +0100
@@ -34,7 +34,7 @@
 
 } // namespace tools
 
-BOOST_AUTO_TEST_CASE(splitRxCallbacks)
+BOOST_AUTO_TEST_CASE(WordConsumerSignature)
 {
   std::string l { "0b2" };
   regex r { "^|b|$" };
@@ -88,57 +88,148 @@
 
 namespace tools
 {
-  void expect( const std::string & l, const regex & rx, const 
std::initializer_list<const char*> & words )
+  using zypp::strv::detail::WordConsumer;
+
+  /* Call splitter_r and check whether CB results match word_r. May CB abort 
at stopAt_r. */
+  void checkSplit( std::function<unsigned(WordConsumer&&)> splitter_r, const 
std::initializer_list<const char*> & words_r,
+                  unsigned stopAt_r = -1U )
   {
-    //cout << "??? <" << rx << "> <" << l << "> " << words.size() << endl;
-    auto next = words.begin();
-    unsigned ret = splitRx( l, rx, [&]( std::string_view w, unsigned i ) {
+    //cout << "??? " << words_r.size() << endl;
+    auto next = words_r.begin();
+    unsigned ret = splitter_r( [&]( std::string_view w, unsigned i, bool f 
)->bool {
       //cout << "  ["<<i<<"] <"<<w<<">"<<endl;
-      BOOST_REQUIRE( next != words.end() );
+      BOOST_REQUIRE( next != words_r.end() );
       BOOST_CHECK_EQUAL( *next, w );
       ++next;
+      BOOST_CHECK_EQUAL( f, next == words_r.end() );
+      return i != stopAt_r;
     });
     //cout << " => " << ret << endl;
-    BOOST_CHECK_EQUAL( next, words.end() );
-    BOOST_CHECK_EQUAL( ret, words.size() );
+    BOOST_CHECK_EQUAL( next, words_r.end() );
+    BOOST_CHECK_EQUAL( ret, words_r.size() );
   }
+
+  void expectRx( const std::string & l, const regex & rx, const 
std::initializer_list<const char*> & words, unsigned stopAt = -1U )
+  { checkSplit( [&](WordConsumer && wc) { return splitRx( l, rx, wc ); }, 
words, stopAt ); }
+
+  void expectSp( std::string_view l, std::string_view sep, const 
std::initializer_list<const char*> & words, unsigned stopAt = -1U )
+  { checkSplit( [&](WordConsumer && wc) { return split( l, sep, wc ); }, 
words, stopAt ); }
+
+  void expectTp( std::string_view l, std::string_view sep, const 
std::initializer_list<const char*> & words, unsigned stopAt = -1U )
+  { checkSplit( [&](WordConsumer && wc) { return split( l, sep, Trim::trim, wc 
); }, words, stopAt ); }
 } // namespace tools
 
+
 BOOST_AUTO_TEST_CASE(splitRxResults)
 {
-  using tools::expect;
+  using tools::expectRx ;
 
   regex rx;    // no regex, no match ==> input reported
-  expect( "",  rx, {""} );
-  expect( "0",  rx, {"0"} );
-  expect( "01",  rx, {"01"} );
-  expect( "012",  rx, {"012"} );
+  expectRx( "",  rx, {""} );
+  expectRx( "0",  rx, {"0"} );
+  expectRx( "01",  rx, {"01"} );
+  expectRx( "012",  rx, {"012"} );
 
   rx = "";     // Empty regex, empty matches
-  expect( "",  rx, {"",""} );
-  expect( "0",  rx, {"","0",""} );
-  expect( "01",  rx, {"","0","1",""} );
-  expect( "012",  rx, {"","0","1","2",""} );
+  expectRx( "",  rx, {"",""} );
+  expectRx( "0",  rx, {"","0",""} );
+  expectRx( "01",  rx, {"","0","1",""} );
+  expectRx( "012",  rx, {"","0","1","2",""} );
 
   rx = "x*";   // Empty matches as above
-  expect( "",  rx, {"",""} );
-  expect( "0",  rx, {"","0",""} );
-  expect( "01",  rx, {"","0","1",""} );
-  expect( "012",  rx, {"","0","1","2",""} );
+  expectRx( "",  rx, {"",""} );
+  expectRx( "0",  rx, {"","0",""} );
+  expectRx( "01",  rx, {"","0","1",""} );
+  expectRx( "012",  rx, {"","0","1","2",""} );
 
   rx = "1*";
-  expect( "",  rx, {"",""} );
-  expect( "0",  rx, {"","0",""} );
-  expect( "01",  rx, {"","0",""} );
-  expect( "012",  rx, {"","0","2",""} );
-  expect( "012\n",  rx, {"","0","2","\n"} );   // no match behind a trailing NL
-  expect( "012\n\n",  rx, {"","0","2","\n","\n"} );    // no match behind a 
trailing NL
+  expectRx( "",  rx, {"",""} );
+  expectRx( "0",  rx, {"","0",""} );
+  expectRx( "01",  rx, {"","0",""} );
+  expectRx( "012",  rx, {"","0","2",""} );
+  expectRx( "012\n",  rx, {"","0","2","\n"} ); // no match behind a trailing NL
+  expectRx( "012\n\n",  rx, {"","0","2","\n","\n"} );  // no match behind a 
trailing NL
 
   rx = "^|1|$";
-  expect( "",  rx, {"",""} );
-  expect( "0",  rx, {"","0",""} );
-  expect( "01",  rx, {"","0",""} );
-  expect( "012",  rx, {"","0","2",""} );
-  expect( "012\n",  rx, {"","0","2","\n"} );   // no match behind a trailing NL
-  expect( "012\n\n",  rx, {"","0","2","\n","\n"} );    // no match behind a 
trailing NL
+  expectRx( "",  rx, {"",""} );
+  expectRx( "0",  rx, {"","0",""} );
+  expectRx( "01",  rx, {"","0",""} );
+  expectRx( "012",  rx, {"","0","2",""} );
+  expectRx( "012\n",  rx, {"","0","2","\n"} ); // no match behind a trailing NL
+  expectRx( "012\n\n",  rx, {"","0","2","\n","\n"} );  // no match behind a 
trailing NL
+}
+
+BOOST_AUTO_TEST_CASE(splitResults)
+{
+  using tools::expectSp;
+
+  std::string sep;     // empty sep; split [[:blank:]]+; report not empty words
+  expectSp( "",  sep, {} );
+  expectSp( " ",  sep, {} );
+  expectSp( "  ",  sep, {} );
+  expectSp( " 1 ",  sep, {"1"} );
+  expectSp( " 1 2 ",  sep, {"1","2"} );
+  expectSp( " 1  2 ",  sep, {"1","2"} );
+  expectSp( " 1  2 ",  sep, {"1","2"}, 0 );    // CB aborted
+  expectSp( " 1  2 ",  sep, {"1","2"}, 1 );    // CB aborted
+
+  sep = ",";   // not empty seps....
+  expectSp( "",  sep, {""} );
+  expectSp( ",",  sep, {"",""} );
+  expectSp( ",,",  sep, {"","",""} );
+  expectSp( "1",  sep, {"1"} );
+  expectSp( ",1,",  sep, {"","1",""} );
+  expectSp( ",1,2,",  sep, {"","1","2",""} );
+  expectSp( ",1,,2,",  sep, {"","1","","2",""} );
+
+  expectSp( " ",  sep, {" "} );
+  expectSp( " , ",  sep, {" "," "} );
+  expectSp( " , , ",  sep, {" "," "," "} );
+  expectSp( " 1 ",  sep, {" 1 "} );
+  expectSp( " , 1 , ",  sep, {" "," 1 "," "} );
+  expectSp( " , 1 , 2 , ",  sep, {" "," 1 "," 2 "," "} );
+  expectSp( " , 1 , , 2 , ",  sep, {" "," 1 "," "," 2 "," "} );
+  expectSp( " , 1 , , 2 , ",  sep, {" "," 1 , , 2 , "}, 0 );   // CB aborted
+
+  using tools::expectTp;       // trimmed split
+  expectTp( " ",  sep, {""} );
+  expectTp( " , ",  sep, {"",""} );
+  expectTp( " , , ",  sep, {"","",""} );
+  expectTp( " 1 ",  sep, {"1"} );
+  expectTp( " , 1 , ",  sep, {"","1",""} );
+  expectTp( " , 1 , 2 , ",  sep, {"","1","2",""} );
+  expectTp( " , 1 , , 2 , ",  sep, {"","1","","2",""} );
+  expectTp( " , 1 , , 2 , ",  sep, {"","1 , , 2 ,"}, 0 );      // CB aborted
+}
+
+BOOST_AUTO_TEST_CASE(trimming)
+{
+  BOOST_CHECK_EQUAL( ltrim(""),    "" );
+  BOOST_CHECK_EQUAL( ltrim(" "),   "" );
+  BOOST_CHECK_EQUAL( ltrim("1"),   "1" );
+  BOOST_CHECK_EQUAL( ltrim(" 1"),  "1" );
+  BOOST_CHECK_EQUAL( ltrim("1 "),  "1 " );
+  BOOST_CHECK_EQUAL( ltrim(" 1 "), "1 " );
+
+  BOOST_CHECK_EQUAL( rtrim(""),    "" );
+  BOOST_CHECK_EQUAL( rtrim(" "),   "" );
+  BOOST_CHECK_EQUAL( rtrim("1"),   "1" );
+  BOOST_CHECK_EQUAL( rtrim(" 1"),  " 1" );
+  BOOST_CHECK_EQUAL( rtrim("1 "),  "1" );
+  BOOST_CHECK_EQUAL( rtrim(" 1 "), " 1" );
+
+  BOOST_CHECK_EQUAL(  trim(""),     "" );
+  BOOST_CHECK_EQUAL(  trim(" "),    "" );
+  BOOST_CHECK_EQUAL(  trim("1"),    "1" );
+  BOOST_CHECK_EQUAL(  trim(" 1"),   "1" );
+  BOOST_CHECK_EQUAL(  trim("1 "),   "1" );
+  BOOST_CHECK_EQUAL(  trim(" 1 "),  "1" );
+
+  BOOST_CHECK_EQUAL( ltrim(" 1 "), trim(" 1 ", Trim::left) );
+  BOOST_CHECK_EQUAL( rtrim(" 1 "), trim(" 1 ", Trim::right) );
+  BOOST_CHECK_EQUAL(  trim(" 1 "), trim(" 1 ", Trim::left|Trim::right) );
+
+  BOOST_CHECK_EQUAL(  trim(" \t1\t "),         "1" );
+  BOOST_CHECK_EQUAL(  trim(" \t1\t ", " "),  "\t1\t" );
+  BOOST_CHECK_EQUAL(  trim(" \t1\t ", ""),  " \t1\t " );
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libzypp-17.25.7/tests/zypp/Vendor_test.cc 
new/libzypp-17.25.8/tests/zypp/Vendor_test.cc
--- old/libzypp-17.25.7/tests/zypp/Vendor_test.cc       2020-09-14 
16:35:23.000000000 +0200
+++ new/libzypp-17.25.8/tests/zypp/Vendor_test.cc       2021-02-24 
16:52:50.000000000 +0100
@@ -50,6 +50,13 @@
   BOOST_REQUIRE( !VendorAttr::instance().equivalent("opensuse as prefix", 
"SuSE as prefix") );
   BOOST_REQUIRE( !VendorAttr::instance().equivalent("opensuse",           
"opensuse as prefix") );
   BOOST_REQUIRE( !VendorAttr::instance().equivalent("opensuse as prefix", 
"opensuse but different prefix") );
+
+  // bsc#1182629: relaxed equivalence just adds suse/opensuse
+  BOOST_REQUIRE( !VendorAttr::instance().relaxedEquivalent("SuSE as 
prefix","foreign") );
+  BOOST_REQUIRE( VendorAttr::instance().relaxedEquivalent("opensuse",          
 "SuSE as prefix") );
+  BOOST_REQUIRE( !VendorAttr::instance().relaxedEquivalent("opensuse as 
prefix", "SuSE as prefix") );
+  BOOST_REQUIRE( !VendorAttr::instance().relaxedEquivalent("opensuse",         
  "opensuse as prefix") );
+  BOOST_REQUIRE( !VendorAttr::instance().relaxedEquivalent("opensuse as 
prefix", "opensuse but different prefix") );
 }
 
 BOOST_AUTO_TEST_CASE(vendor_test2)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libzypp-17.25.7/zypp/VendorAttr.cc 
new/libzypp-17.25.8/zypp/VendorAttr.cc
--- old/libzypp-17.25.7/zypp/VendorAttr.cc      2020-10-27 18:06:45.000000000 
+0100
+++ new/libzypp-17.25.8/zypp/VendorAttr.cc      2021-02-24 16:52:50.000000000 
+0100
@@ -58,6 +58,23 @@
     bool equivalent( IdString lVendor, IdString rVendor ) const
     { return lVendor == rVendor || vendorMatchId( lVendor ) == vendorMatchId( 
rVendor ); }
 
+    /** Return whether two vendor strings should be treated as equivalent or 
are (suse/opensuse).*/
+    bool relaxedEquivalent( IdString lVendor, IdString rVendor ) const
+    {
+      if ( equivalent( lVendor, rVendor ) )
+       return true;
+
+      static const IdString suse { "suse" };
+      static const IdString opensuse { "opensuse" };
+      unsigned sid = vendorMatchId( suse );
+      unsigned oid = vendorMatchId( opensuse );
+      if ( sid == oid )
+       return false; // (suse/opensuse) are equivalent, so these are not
+
+      auto isSuse = [sid,oid]( unsigned v )-> bool { return v==sid || v==oid; 
};
+      return isSuse( vendorMatchId(lVendor) ) && isSuse( 
vendorMatchId(rVendor) );
+    }
+
     unsigned foreachVendorList( std::function<bool(VendorList)> fnc_r ) const
     {
       std::map<unsigned,VendorList> lists;
@@ -320,6 +337,19 @@
   bool VendorAttr::equivalent( const PoolItem & lVendor, const PoolItem & 
rVendor ) const
   { return _pimpl->equivalent( lVendor.satSolvable().vendor(), 
rVendor.satSolvable().vendor() ); }
 
+
+  bool VendorAttr::relaxedEquivalent( IdString lVendor, IdString rVendor ) 
const
+  { return _pimpl->relaxedEquivalent( lVendor, rVendor );}
+
+  bool VendorAttr::relaxedEquivalent( const Vendor & lVendor, const Vendor & 
rVendor ) const
+  { return _pimpl->relaxedEquivalent( IdString( lVendor ), IdString( rVendor ) 
); }
+
+  bool VendorAttr::relaxedEquivalent( sat::Solvable lVendor, sat::Solvable 
rVendor ) const
+  { return _pimpl->relaxedEquivalent( lVendor.vendor(), rVendor.vendor() ); }
+
+  bool VendorAttr::relaxedEquivalent( const PoolItem & lVendor, const PoolItem 
& rVendor ) const
+  { return _pimpl->relaxedEquivalent( lVendor.satSolvable().vendor(), 
rVendor.satSolvable().vendor() ); }
+
   //////////////////////////////////////////////////////////////////
 
   std::ostream & operator<<( std::ostream & str, const VendorAttr & obj )
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libzypp-17.25.7/zypp/VendorAttr.h 
new/libzypp-17.25.8/zypp/VendorAttr.h
--- old/libzypp-17.25.7/zypp/VendorAttr.h       2020-10-27 18:06:45.000000000 
+0100
+++ new/libzypp-17.25.8/zypp/VendorAttr.h       2021-02-24 16:52:50.000000000 
+0100
@@ -142,6 +142,15 @@
     /** \overload using \ref PoolItem */
     bool equivalent( const PoolItem & lVendor, const PoolItem & rVendor ) 
const;
 
+    /** Like \ref equivalent but always unifies suse and openSUSE vendor */
+    bool relaxedEquivalent( const Vendor & lVendor, const Vendor & rVendor ) 
const;
+    /** \overload using \ref IdStrings */
+    bool relaxedEquivalent( IdString lVendor, IdString rVendor ) const;
+    /** \overload using \ref sat::Solvable */
+    bool relaxedEquivalent( sat::Solvable lVendor, sat::Solvable rVendor ) 
const;
+    /** \overload using \ref PoolItem */
+    bool relaxedEquivalent( const PoolItem & lVendor, const PoolItem & rVendor 
) const;
+
   public:
     /** Call \a fnc_r for each equivalent vendor list (return \c false to 
break).
      * \return The number of calls to \a fnc_r.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libzypp-17.25.7/zypp/base/StringV.cc 
new/libzypp-17.25.8/zypp/base/StringV.cc
--- old/libzypp-17.25.7/zypp/base/StringV.cc    2021-02-10 15:19:44.000000000 
+0100
+++ new/libzypp-17.25.8/zypp/base/StringV.cc    2021-02-24 16:52:50.000000000 
+0100
@@ -16,22 +16,118 @@
 {
   namespace strv
   {
+    namespace detail
+    {
+      /** \ref split working horse for empty \a sep_r case.
+       * Split at /[BLANK,TAB]+/ and report no-empty words. Trim::right is
+       * applied to the rest of the line in case the callback aborts further
+       * processing.
+       */
+      unsigned _splitSimple( std::string_view line_r, WordConsumer && fnc_r )
+      {
+       // callback stats
+       unsigned fncCall = 0;
+
+       // NOTE: line_r is not null-terminated!
+       const char *const eol = line_r.data() + line_r.size();  // the '\0'
+       const char * searchfrom = line_r.data();        // start of the next 
search (moves with each cycle!)
+
+       // Empty sep: split at /[BLANK,TAB]+/ and report no-empty words
+       auto isSep = []( char ch )->bool { return ch == ' '|| ch == '\t'; };
+
+       auto skipSep = [eol,&isSep]( const char *& ptr )->bool {
+         while ( ptr < eol && isSep( *ptr ) )
+           ++ptr;
+         return ptr < eol;     // whether we ended up at a new wordstart
+       };
+
+       auto skipWord = [eol,&isSep]( const char *& ptr )->void {
+         while ( ptr < eol && ! isSep( *ptr ) )
+           ++ptr;
+       };
+
+       // For the 'last' CB argument: we must remember a word
+       // until we know whether another one is following
+       std::string_view word;
+
+       while ( skipSep( searchfrom ) ) {
+         const char * wordstart = searchfrom;
+         // Report a previous word found
+         if ( ! word.empty() ) {
+           if ( fnc_r ) {
+             if ( ! fnc_r( word, fncCall, false/*more to come*/ ) ) {
+               // Stop searching for further matches. Final report will
+               // be the remaining line (right trimmed)
+               const char * wordend = eol;
+               while ( isSep( *(wordend-1) ) ) // noSep at wordstart stops loop
+                 --wordend;
+               word = std::string_view( wordstart, wordend-wordstart );
+               ++fncCall;
+               break;
+             }
+           }
+           ++fncCall;
+         }
+         // remember new word
+         ++searchfrom;
+         skipWord( searchfrom );
+         word = std::string_view( wordstart, searchfrom-wordstart );
+       }
+
+       // finally report the last word
+       if ( ! word.empty() ) {
+         if ( fnc_r ) {
+           fnc_r( word, fncCall, true/*last*/ );
+         }
+         ++fncCall;
+       }
 
-    unsigned split( std::string_view line_r, std::string_view sep_r, Trim 
trim_r,
-                   std::function<void(std::string_view)> fnc_r )
+       return fncCall;
+      }
+    } // namespace detail
+
+    unsigned detail::_split( std::string_view line_r, std::string_view sep_r, 
Trim trim_r, WordConsumer && fnc_r )
     {
-#warning REIMPLEMENT
-      std::vector<std::string> words;
-      str::split( std::string(line_r), std::back_inserter(words), 
std::string(sep_r), str::TRIM );
+      if ( sep_r.empty() )
+       return _splitSimple( line_r, std::move( fnc_r ) );
+
+      // callback stats
+      bool fncStop = false;
+      unsigned fncCall = 0;
+
+      using size_type = std::string_view::size_type;
+      size_type wordstart = 0; // start of the next string to be reported
+      size_type searchfrom = 0; // start of the next search for a separator
 
+      do {     // report lhs word of separator matches...
+       searchfrom = line_r.find( sep_r, searchfrom );
+       if ( fncStop || searchfrom == line_r.npos ) {
+         break;
+       }
+
+       // Report lhs word of the match and advance...
+       if ( fnc_r ) {
+         if ( ! fnc_r( trim( line_r.substr(wordstart,searchfrom-wordstart), 
trim_r ), fncCall, false/*more to come*/ ) )
+           fncStop= true;      // stop searching for further matches
+       }
+       ++fncCall;
+
+       // Next wordstart is behind the separator match.
+       searchfrom += sep_r.size();
+       wordstart = searchfrom;
+      } while( wordstart < line_r.size() );
+
+      // finally report rhs word of the last separator match (or no match)
       if ( fnc_r ) {
-       for ( const auto & w : words )
-         fnc_r( std::string_view(w) );
+       if ( wordstart < line_r.size() )
+         fnc_r( trim( line_r.substr(wordstart,line_r.size()-wordstart), trim_r 
), fncCall, true/*last*/ );
+       else    // a final match at $ so a final empty word reported (no trim 
needed)
+         fnc_r( std::string_view( line_r.data()+line_r.size(), 0 ), fncCall, 
true/*last*/ );
       }
-      return words.size();
+      ++fncCall;
+      return fncCall;
     }
 
-
     unsigned detail::_splitRx( const std::string & line_r, const regex & rx_r, 
WordConsumer && fnc_r )
     {
       // callback stats
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libzypp-17.25.7/zypp/base/StringV.h 
new/libzypp-17.25.8/zypp/base/StringV.h
--- old/libzypp-17.25.7/zypp/base/StringV.h     2021-02-10 15:19:44.000000000 
+0100
+++ new/libzypp-17.25.8/zypp/base/StringV.h     2021-02-24 16:52:50.000000000 
+0100
@@ -29,13 +29,67 @@
     /** Define how to trim. */
     enum class Trim {
       notrim = 0,
-      right  = 1<<0,
-      left   = 1<<1,
+      left   = 1<<0,
+      right  = 1<<1,
       trim   = (left|right),
     };
 
     ZYPP_DECLARE_FLAGS_AND_OPERATORS( TrimFlag, Trim );
 
+    /** The default blank. */
+    inline constexpr std::string_view blank = " \t";
+
+    /** Trim \a chars_r at the beginning of \a str_r. */
+    inline std::string_view ltrim( std::string_view str_r, std::string_view 
chars_r = blank )
+    {
+      if ( str_r.empty() )
+       return str_r;
+      auto pos = str_r.find_first_not_of( chars_r );
+      if ( pos == str_r.npos )
+       str_r.remove_prefix( str_r.size() );
+      else if ( pos )
+       str_r.remove_prefix( pos );
+      return str_r;
+    }
+
+    /** Trim \a chars_r at the end of \a str_r. */
+    inline std::string_view rtrim( std::string_view str_r, std::string_view 
chars_r = blank )
+    {
+      if ( str_r.empty() )
+       return str_r;
+      auto pos = str_r.find_last_not_of( chars_r );
+      if ( pos == str_r.npos )
+       str_r.remove_suffix( str_r.size() );
+      else if ( (pos = str_r.size()-1-pos) )
+       str_r.remove_suffix( pos );
+      return str_r;
+    }
+
+    /** Trim \a chars_r at both sides of \a str_r. */
+    inline std::string_view trim( std::string_view str_r, std::string_view 
chars_r = blank )
+    {
+      if ( str_r.empty() )
+       return str_r;
+      str_r = ltrim( std::move(str_r), chars_r );
+      str_r = rtrim( std::move(str_r), chars_r );
+      return str_r;
+    }
+
+    /** Trim \a chars_r at \a trim_r sides of \a str_r. */
+    inline std::string_view trim( std::string_view str_r, std::string_view 
chars_r, TrimFlag trim_r )
+    {
+      if ( str_r.empty() || trim_r == Trim::notrim )
+       return str_r;
+      if ( trim_r.testFlag( Trim::left ) )
+       str_r = ltrim( std::move(str_r), chars_r );
+      if ( trim_r.testFlag( Trim::right ) )
+       str_r = rtrim( std::move(str_r), chars_r );
+      return str_r;
+    }
+    /** \overload Trimming blanks at \a trim_r sides of \a str_r. */
+    inline std::string_view trim( std::string_view str_r, TrimFlag trim_r )
+    { return trim( std::move(str_r), blank, std::move(trim_r) ); }
+
     ///////////////////////////////////////////////////////////////////
     namespace detail
     {
@@ -113,8 +167,12 @@
       { return [&fnc_r](std::string_view,unsigned,bool)->bool { fnc_r(); 
return true; }; }
       //@}
 
+      /** \ref split working horse */
+      unsigned _split( std::string_view line_r, std::string_view sep_r, Trim 
trim_r, WordConsumer && fnc_r );
+
       /** \ref splitRx working horse */
       unsigned _splitRx( const std::string & line_r, const regex & rx_r, 
WordConsumer && fnc_r );
+
     }  // namespace detail
     ///////////////////////////////////////////////////////////////////
 
@@ -125,7 +183,7 @@
      * of \a line_r, or it there are consecutive separator match occurrences.
      *
      * Accepted callbacks: [bool|void]( [std::string_view[, unsigned[, bool]]] 
)
-     * (or no callback at all )
+     * (or no callback at all)
      *
      * A callback may take the \a word, the \a index of word (starting with 0) 
and a boolean
      * indicating whether this is going to be the \a last report.
@@ -145,17 +203,28 @@
 
     /** Split \a line_r into words separated by \a sep_r and invoke \a fnc_r 
with each word.
      *
-     * If \a sep_r is not empty, each separator found in \a line_r will be 
enclosed by 2
+     * - If \a sep_r is not empty, each separator found in \a line_r will be 
enclosed by 2
      * words being reported. Words may be empty if the separator is located at 
the beginning
-     * or the end of \a line_r of it there are consecutive occurrences. If the 
separator does
-     * not occur on the line the whole string is reported.
+     * or the end of \a line_r or it there are consecutive occurrences.
      *
-     * If \a sep_r is unspecified or empty, it splits on whitespace 
/[BLANK,TAB]+/. In this
-     * case only the (not empty) words found on the line are reported.
+     * - If \a sep_r is unspecified or empty, it splits on whitespace 
/[BLANK,TAB]+/. In this
+     * case only the (not empty) words found on the line are reported 
(trimmed).
      *
      * The optional \a trim_r argument tells whether whitespace around the 
words found
      * should be trimmed before reporting them. The default is not to trim.
      *
+     * Accepted callbacks: [bool|void]( [std::string_view[, unsigned[, bool]]] 
)
+     * (or no callback at all)
+     *
+     * A callback may take the \a word, the \a index of word (starting with 0) 
and a boolean
+     * indicating whether this is going to be the \a last report.
+     *
+     * A callback may optionally return a value convertible to \c bool. 
Returning \c false
+     * causes split to stop looking further separators. The final report will 
contain the
+     * remaining part of the \a line_r then.
+     *
+     * If the separator does not occur on the line the whole string is 
reported.
+     *
      * \returns the number of words reported.
      *
      * \code
@@ -192,18 +261,19 @@
      *   // ['1', '3 4 5']
      * \endcode
      */
-    unsigned split( std::string_view line_r, std::string_view sep_r, Trim 
trim_r,
-                   std::function<void(std::string_view)> fnc_r );
+    template <typename Callable = detail::WordConsumer>
+    unsigned split( std::string_view line_r, std::string_view sep_r, Trim 
trim_r, Callable && fnc_r = Callable() )
+    { return detail::_split( line_r, sep_r, trim_r, detail::wordConsumer( 
std::forward<Callable>(fnc_r) ) ); }
 
     /** \overload  Split at \a sep_r and Trim::notrim */
-    inline unsigned split( std::string_view line_r, std::string_view sep_r,
-                   std::function<void(std::string_view)> fnc_r )
-    { return split( line_r, sep_r, Trim::notrim, fnc_r ); }
+    template <typename Callable = detail::WordConsumer>
+    inline unsigned split( std::string_view line_r, std::string_view sep_r, 
Callable && fnc_r = Callable() )
+    { return detail::_split( line_r, sep_r, Trim::notrim, 
detail::wordConsumer( std::forward<Callable>(fnc_r) ) ); }
 
     /** \overload  Split at whitespace */
-    inline unsigned split( std::string_view line_r,
-                   std::function<void(std::string_view)> fnc_r )
-    { return split( line_r, std::string_view(), Trim::notrim, fnc_r ); }
+    template <typename Callable = detail::WordConsumer>
+    inline unsigned split( std::string_view line_r, Callable && fnc_r = 
Callable() )
+    { return detail::_split( line_r, std::string_view(), Trim::notrim, 
detail::wordConsumer( std::forward<Callable>(fnc_r) ) ); }
 
   } // namespace strv
 } // namespace zypp
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libzypp-17.25.7/zypp/solver/detail/SATResolver.cc 
new/libzypp-17.25.8/zypp/solver/detail/SATResolver.cc
--- old/libzypp-17.25.7/zypp/solver/detail/SATResolver.cc       2021-01-12 
19:31:38.000000000 +0100
+++ new/libzypp-17.25.8/zypp/solver/detail/SATResolver.cc       2021-02-24 
16:52:50.000000000 +0100
@@ -175,10 +175,10 @@
 //---------------------------------------------------------------------------
 
 int vendorCheck( sat::detail::CPool *pool, Solvable *solvable1, Solvable 
*solvable2 )
-{
-  return VendorAttr::instance().equivalent( IdString(solvable1->vendor),
-                                            IdString(solvable2->vendor) ) ? 0 
: 1;
-}
+{ return VendorAttr::instance().equivalent( IdString(solvable1->vendor), 
IdString(solvable2->vendor) ) ? 0 : 1; }
+
+int relaxedVendorCheck( sat::detail::CPool *pool, Solvable *solvable1, 
Solvable *solvable2 )
+{ return VendorAttr::instance().relaxedEquivalent( 
IdString(solvable1->vendor), IdString(solvable2->vendor) ) ? 0 : 1; }
 
 /** ResPool helper to compute the initial status of Patches etc.
  * An empty solver run (no jobs) just to compute the initial status
@@ -468,8 +468,6 @@
 SATResolver::solving(const CapabilitySet & requires_caps,
                     const CapabilitySet & conflict_caps)
 {
-    _satSolver = solver_create( _satPool );
-    ::pool_set_custom_vendorcheck( _satPool, &vendorCheck );
     if (_fixsystem) {
        queue_push( &(_jobQueue), SOLVER_VERIFY|SOLVER_SOLVABLE_ALL);
        queue_push( &(_jobQueue), 0 );
@@ -669,6 +667,23 @@
 
     // remove old stuff
     solverEnd();
+    _satSolver = solver_create( _satPool );
+    {
+      // bsc#1182629: in dup allow an available -release package providing 
'dup-vendor-relax(suse)'
+      // to let (suse/opensuse) vendor being treated as being equivalent.
+      bool toRelax = false;
+      if ( _distupgrade ) {
+       for ( sat::Solvable solv : sat::WhatProvides( 
Capability("dup-vendor-relax(suse)") ) ) {
+         if ( ! solv.isSystem() ) {
+           MIL << "Relaxed vendor check requested by " << solv << endl;
+           toRelax = true;
+           break;
+         }
+       }
+      }
+      ::pool_set_custom_vendorcheck( _satPool, toRelax ? &relaxedVendorCheck : 
&vendorCheck );
+    }
+
     queue_init( &_jobQueue );
 
     // clear and rebuild: _items_to_install, _items_to_remove, _items_to_lock, 
_items_to_keep
@@ -861,8 +876,6 @@
     // set locks for the solver
     setLocks();
 
-    _satSolver = solver_create( _satPool );
-    ::pool_set_custom_vendorcheck( _satPool, &vendorCheck );
     if (_fixsystem) {
        queue_push( &(_jobQueue), SOLVER_VERIFY|SOLVER_SOLVABLE_ALL);
        queue_push( &(_jobQueue), 0 );
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libzypp-17.25.7/zypp/target/TargetImpl.cc 
new/libzypp-17.25.8/zypp/target/TargetImpl.cc
--- old/libzypp-17.25.7/zypp/target/TargetImpl.cc       2021-02-10 
16:39:47.000000000 +0100
+++ new/libzypp-17.25.8/zypp/target/TargetImpl.cc       2021-02-24 
17:11:46.000000000 +0100
@@ -210,6 +210,56 @@
     ///////////////////////////////////////////////////////////////////
     namespace
     {
+      /// \brief Try to provide /proc fs if not present.
+      /// bsc#1181328: Some systemd tools require /proc to be mounted
+      class AssertProcMounted
+      {
+       NON_COPYABLE(AssertProcMounted);
+       NON_MOVABLE(AssertProcMounted);
+      public:
+
+       AssertProcMounted( Pathname root_r )
+       {
+         root_r /= "/proc";
+         if ( ! PathInfo(root_r/"self").isDir() ) {
+           MIL << "Try to make sure proc is mounted at" << _mountpoint << endl;
+           if ( filesystem::assert_dir(root_r) == 0
+             && execute({ "mount", "-t", "proc", "proc", root_r.asString() }) 
== 0 ) {
+             _mountpoint = std::move(root_r);  // so we'll later unmount it
+           }
+           else {
+             WAR << "Mounting proc at " << _mountpoint << " failed" << endl;
+           }
+         }
+       }
+
+       ~AssertProcMounted( )
+       {
+         if ( ! _mountpoint.empty() ) {
+           // we mounted it so we unmount...
+           MIL << "We mounted " << _mountpoint << " so we unmount it" << endl;
+           execute({ "umount", "-l", _mountpoint.asString() });
+         }
+       }
+
+      private:
+       int execute( ExternalProgram::Arguments && cmd_r ) const
+       {
+         ExternalProgram prog( cmd_r, ExternalProgram::Stderr_To_Stdout );
+         for( std::string line = prog.receiveLine(); ! line.empty(); line = 
prog.receiveLine() )
+         { DBG << line; }
+         return prog.close();
+       }
+
+      private:
+       Pathname _mountpoint;
+      };
+    } // namespace
+    ///////////////////////////////////////////////////////////////////
+
+    ///////////////////////////////////////////////////////////////////
+    namespace
+    {
       SolvIdentFile::Data getUserInstalledFromHistory( const Pathname & 
historyFile_r )
       {
        SolvIdentFile::Data onSystemByUserList;
@@ -1491,6 +1541,9 @@
 
       bool abort = false;
 
+      // bsc#1181328: Some systemd tools require /proc to be mounted
+      AssertProcMounted assertProcMounted( _root );
+
       RpmPostTransCollector postTransCollector( _root );
       std::vector<sat::Solvable> successfullyInstalledPackages;
       TargetImpl::PoolItemList remaining;

Reply via email to