Imported Upstream version 14.37.0 26/94626/1
authorDongHun Kwak <dh0128.kwak@samsung.com>
Tue, 1 Nov 2016 01:32:35 +0000 (10:32 +0900)
committerDongHun Kwak <dh0128.kwak@samsung.com>
Tue, 1 Nov 2016 01:32:36 +0000 (10:32 +0900)
Change-Id: I984a49843582896699ad5b43bb5324bf75c68e96
Signed-off-by: DongHun Kwak <dh0128.kwak@samsung.com>
16 files changed:
VERSION.cmake
package/libzypp.changes
po/zypp-po.tar.bz2
tests/repo/RepoVariables_test.cc
zypp/RepoInfo.cc
zypp/RepoInfo.h
zypp/RepoManager.cc
zypp/ServiceInfo.cc
zypp/ServiceInfo.h
zypp/base/Easy.h
zypp/base/Gettext.h
zypp/repo/RepoInfoBase.cc
zypp/repo/RepoVariables.cc
zypp/repo/RepoVariables.h
zypp/solver/detail/SATResolver.cc
zypp/target/RpmPostTransCollector.cc

index 336f9b5..42e8095 100644 (file)
@@ -60,9 +60,9 @@
 #
 SET(LIBZYPP_MAJOR "14")
 SET(LIBZYPP_COMPATMINOR "30")
-SET(LIBZYPP_MINOR "36")
+SET(LIBZYPP_MINOR "37")
 SET(LIBZYPP_PATCH "0")
 #
-# LAST RELEASED: 14.36.0 (30)
+# LAST RELEASED: 14.37.0 (30)
 # (The number in parenthesis is LIBZYPP_COMPATMINOR)
 #=======
index b8ab72c..bc824fc 100644 (file)
@@ -1,4 +1,37 @@
 -------------------------------------------------------------------
+Wed Mar 11 09:22:46 CET 2015 - ma@suse.de
+
+- New RepoVarExpand: Functor expanding repo variables in a 
+  string . Supports bash style default ${v:-w}' and alternate ${v:+w}
+  values (FATE#318354)
+- Easy.h: Use __typeof__ rather than typeof in header
+- Support repo variable replacement in service url
+- Support repo variable replacement in gpg url
+- Gettext.h: Fallback to ::gettext if accidentally included 
+  outside libzypp
+- version 14.37.0 (30)
+
+-------------------------------------------------------------------
+Sun Feb 22 01:13:12 CET 2015 - ma@suse.de
+
+- Update zypp-po.tar.bz2
+
+-------------------------------------------------------------------
+Thu Feb 19 01:13:13 CET 2015 - ma@suse.de
+
+- Update zypp-po.tar.bz2
+
+-------------------------------------------------------------------
+Sun Feb 15 01:13:28 CET 2015 - ma@suse.de
+
+- Update zypp-po.tar.bz2
+
+-------------------------------------------------------------------
+Thu Feb 12 01:13:34 CET 2015 - ma@suse.de
+
+- Update zypp-po.tar.bz2
+
+-------------------------------------------------------------------
 Mon Feb  9 16:05:38 CET 2015 - ma@suse.de
 
 - Don't execute scripts in /tmp or /var/tmp, as they could be 
index d1eff8e..8de47f2 100644 (file)
Binary files a/po/zypp-po.tar.bz2 and b/po/zypp-po.tar.bz2 differ
index 9ca2400..008c7dc 100644 (file)
@@ -1,24 +1,18 @@
-#include <stdio.h>
+#include <boost/test/auto_unit_test.hpp>
 #include <iostream>
-#include <fstream>
-#include <vector>
 #include <list>
-#include <boost/test/auto_unit_test.hpp>
+#include <map>
 
-#include "zypp/ZYppFactory.h"
-#include "zypp/Url.h"
-#include "zypp/PathInfo.h"
-#include "zypp/TmpPath.h"
 #include "zypp/ZConfig.h"
+#include "zypp/Pathname.h"
+#include "zypp/Url.h"
 #include "zypp/base/ValueTransform.h"
 #include "zypp/repo/RepoVariables.h"
 
 using std::cout;
 using std::endl;
-using std::string;
 using namespace zypp;
 using namespace boost::unit_test;
-using namespace zypp::repo;
 
 #define DATADIR (Pathname(TESTS_SRC_DIR) +  "/repo/yum/data")
 
@@ -34,14 +28,14 @@ namespace std {
   }
 }
 
-// plain functor
+// plain functor
 struct PlainTransformator
 {
   std::string operator()( const std::string & value_r ) const
   { return "{"+value_r+"}"; }
 };
 
-// plain functor + std::unary_function typedefs
+// plain functor + required std::unary_function typedefs
 struct FncTransformator : public PlainTransformator, public std::unary_function<const std::string &, std::string>
 {};
 
@@ -80,13 +74,114 @@ BOOST_AUTO_TEST_CASE(value_transform)
   BOOST_CHECK_EQUAL( rl.transformed( rl.rawBegin() ), "{a}" );
 }
 
+void helperGenRepVarExpandResults()
+{
+  // Generate test result strings for RepVarExpand:
+  //   ( STRING, REPLACED_all_vars_undef, REPLACED_all_vars_defined )
+  // Crefully check whether new stings are correct before
+  // adding them to the testccse.
+  std::map<std::string,std::string> vartable;
+  std::map<std::string,std::pair<std::string,std::string>> result;
+  bool varsoff = true;
+
+  auto varLookup = [&vartable,&varsoff]( const std::string & name_r )->const std::string *
+  {
+    if ( varsoff )
+      return nullptr;
+    std::string & val( vartable[name_r] );
+    if ( val.empty() )
+    { val = "["+name_r+"]"; }
+    return &val;
+  };
+
+  for ( auto && value : {
+    ""
+    , "$"
+    , "$${}"
+    , "$_:"
+    , "$_A:"
+    , "$_A_:"
+    , "$_A_B:"
+    , "${_A_B}"
+    , "\\${_A_B}"      // no escape on level 0
+    , "${_A_B\\}"      // no close brace
+    , "${C:-a$Bba}"
+    , "${C:+a$Bba}"
+    , "${C:+a${B}ba}"
+    , "${C:+a\\$Bba}"  // escape on level > 0; no var $Bba
+    , "${C:+a$Bba\\}"  // escape on level > 0; no close brace C
+    , "${C:+a${B}ba}"
+    , "${C:+a\\${B}ba}"        // escape on level > 0; no var ${B}
+    , "${C:+a${B\\}ba}"        // escape on level > 0; no close brace B
+    , "${C:+a\\${B\\}ba}"
+    , "__${D:+\\$X--{${E:-==\\$X{o\\}==}  }--}__\\${B}${}__"
+    , "__${D:+\\$X--{${E:-==\\$X{o\\}==}\\}--}__\\${B}${}__"
+  } ) {
+    varsoff = true;
+    result[value].first = repo::RepoVarExpand()( value, varLookup );
+    varsoff = false;
+    result[value].second = repo::RepoVarExpand()( value, varLookup );
+  }
+
+  for ( const auto & el : result )
+  {
+#define CSTR(STR) str::form( "%-40s", str::gsub( "\""+STR+"\"", "\\", "\\\\" ).c_str() )
+    cout << "RepVarExpandTest( " << CSTR(el.first) << ", " << CSTR(el.second.first) << ", " << CSTR(el.second.second) << " );" << endl;
+  }
+}
+
+void RepVarExpandTest( const std::string & string_r, const std::string & allUndef_r, const std::string & allDef_r )
+{
+  std::map<std::string,std::string> vartable;
+  bool varsoff = true;
+
+  auto varLookup = [&vartable,&varsoff]( const std::string & name_r )->const std::string *
+  {
+    if ( varsoff )
+      return nullptr;
+    std::string & val( vartable[name_r] );
+    if ( val.empty() )
+    { val = "["+name_r+"]"; }
+    return &val;
+  };
+
+  varsoff = true;
+  BOOST_CHECK_EQUAL( repo::RepoVarExpand()( string_r, varLookup ), allUndef_r );
+  varsoff = false;
+  BOOST_CHECK_EQUAL( repo::RepoVarExpand()( string_r, varLookup ), allDef_r );
+}
+
+BOOST_AUTO_TEST_CASE(RepVarExpand)
+{ //              ( STRING                                  , REPLACED_all_vars_undef                 , REPLACED_all_vars_defined                )
+  RepVarExpandTest( ""                                      , ""                                      , ""                                       );
+  RepVarExpandTest( "$"                                     , "$"                                     , "$"                                      );
+  RepVarExpandTest( "$${}"                                  , "$${}"                                  , "$${}"                                   );
+  RepVarExpandTest( "$_:"                                   , "$_:"                                   , "[_]:"                                   );
+  RepVarExpandTest( "$_A:"                                  , "$_A:"                                  , "[_A]:"                                  );
+  RepVarExpandTest( "$_A_:"                                 , "$_A_:"                                 , "[_A_]:"                                 );
+  RepVarExpandTest( "$_A_B:"                                , "$_A_B:"                                , "[_A_B]:"                                );
+  RepVarExpandTest( "${C:+a$Bba\\}"                         , "${C:+a$Bba\\}"                         , "${C:+a[Bba]\\}"                         );
+  RepVarExpandTest( "${C:+a$Bba}"                           , ""                                      , "a[Bba]"                                 );
+  RepVarExpandTest( "${C:+a${B\\}ba}"                       , "${C:+a${B\\}ba}"                       , "${C:+a${B\\}ba}"                        );
+  RepVarExpandTest( "${C:+a${B}ba}"                         , ""                                      , "a[B]ba"                                 );
+  RepVarExpandTest( "${C:+a\\$Bba}"                         , ""                                      , "a$Bba"                                  );
+  RepVarExpandTest( "${C:+a\\${B\\}ba}"                     , ""                                      , "a${B}ba"                                );
+  RepVarExpandTest( "${C:+a\\${B}ba}"                       , "ba}"                                   , "a${Bba}"                                );
+  RepVarExpandTest( "${C:-a$Bba}"                           , "a$Bba"                                 , "[C]"                                    );
+  RepVarExpandTest( "${_A_B\\}"                             , "${_A_B\\}"                             , "${_A_B\\}"                              );
+  RepVarExpandTest( "${_A_B}"                               , "${_A_B}"                               , "[_A_B]"                                 );
+  RepVarExpandTest( "\\${_A_B}"                             , "\\${_A_B}"                             , "\\[_A_B]"                               );
+  RepVarExpandTest( "__${D:+\\$X--{${E:-==\\$X{o\\}==}  }--}__\\${B}${}__", "__--}__\\${B}${}__"      , "__$X--{[E]  --}__\\[B]${}__"            );
+  RepVarExpandTest( "__${D:+\\$X--{${E:-==\\$X{o\\}==}\\}--}__\\${B}${}__", "____\\${B}${}__"         , "__$X--{[E]}--__\\[B]${}__"              );
+}
+
 BOOST_AUTO_TEST_CASE(replace_text)
 {
   /* check RepoVariablesStringReplacer */
   ZConfig::instance().setSystemArchitecture(Arch("i686"));
   ::setenv( "ZYPP_REPO_RELEASEVER", "13.2", 1 );
 
-  RepoVariablesStringReplacer replacer1;
+  repo::RepoVariablesStringReplacer replacer1;
   BOOST_CHECK_EQUAL( replacer1(""),            "" );
   BOOST_CHECK_EQUAL( replacer1("$"),           "$" );
   BOOST_CHECK_EQUAL( replacer1("$arc"),                "$arc" );
@@ -110,7 +205,7 @@ BOOST_AUTO_TEST_CASE(replace_text)
   BOOST_CHECK_EQUAL(replacer1("http://foo/$arch/bar"), "http://foo/i686/bar");
 
   /* check RepoVariablesUrlReplacer */
-  RepoVariablesUrlReplacer replacer2;
+  repo::RepoVariablesUrlReplacer replacer2;
 
   BOOST_CHECK_EQUAL(replacer2(Url("ftp://user:secret@site.org/$arch/")).asCompleteString(),
                    "ftp://user:secret@site.org/i686/");
index cd20b96..0ad8cf4 100644 (file)
@@ -68,28 +68,20 @@ namespace zypp
     Pathname licenseTgz() const
     { return metadatapath.empty() ? Pathname() : metadatapath / path / "license.tar.gz"; }
 
-    Url mirrorListUrl() const
-    { return replacer(mirrorlist_url); }
-
-    void mirrorListUrl( const Url & url_r )
-    { mirrorlist_url = url_r; }
-
-    const Url & rawMirrorListUrl() const
-    { return mirrorlist_url; }
-
-    const url_set & baseUrls() const
+    const RepoVariablesReplacedUrlList & baseUrls() const
     {
-      if ( _baseUrls.empty() && ! mirrorListUrl().asString().empty() )
+      const Url & mlurl( _mirrorListUrl.transformed() );       // Variables replaced!
+      if ( _baseUrls.empty() && ! mlurl.asString().empty() )
       {
         emptybaseurls = true;
         DBG << "MetadataPath: " << metadatapath << endl;
-       repo::RepoMirrorList rmurls( mirrorListUrl(), metadatapath );
-       _baseUrls.insert( _baseUrls.end(), rmurls.getUrls().begin(), rmurls.getUrls().end() );
+       repo::RepoMirrorList rmurls( mlurl, metadatapath );
+       _baseUrls.raw().insert( _baseUrls.raw().end(), rmurls.getUrls().begin(), rmurls.getUrls().end() );
       }
       return _baseUrls;
     }
 
-    url_set & baseUrls()
+    RepoVariablesReplacedUrlList & baseUrls()
     { return _baseUrls; }
 
     bool baseurl2dump() const
@@ -142,13 +134,13 @@ namespace zypp
        /////////////////////////////////////////////////////////////////
       }
       return( _keywords.find( keyword_r ) != _keywords.end() );
-
     }
 
   public:
     TriBool gpgcheck;
     TriBool keeppackages;
-    Url gpgkey_url;
+    RepoVariablesReplacedUrl _gpgKeyUrl;
+    RepoVariablesReplacedUrl _mirrorListUrl;
     repo::RepoType type;
     Pathname path;
     std::string service;
@@ -160,8 +152,7 @@ namespace zypp
     repo::RepoVariablesUrlReplacer replacer;
 
   private:
-    Url mirrorlist_url;
-    mutable url_set _baseUrls;
+    mutable RepoVariablesReplacedUrlList _baseUrls;
     mutable std::set<std::string> _keywords;
 
     friend Impl * rwcowClone<Impl>( const Impl * rhs );
@@ -216,24 +207,24 @@ namespace zypp
   void RepoInfo::setGpgCheck( bool check )
   { _pimpl->gpgcheck = check; }
 
-  void RepoInfo::setMirrorListUrl( const Url & url_r )
-  { _pimpl->mirrorListUrl( url_r ); }
+  void RepoInfo::setMirrorListUrl( const Url & url_r ) // Raw
+  { _pimpl->_mirrorListUrl.raw() = url_r; }
 
   void RepoInfo::setGpgKeyUrl( const Url & url_r )
-  { _pimpl->gpgkey_url = url_r; }
+  { _pimpl->_gpgKeyUrl.raw() = url_r; }
 
   void RepoInfo::addBaseUrl( const Url & url_r )
   {
-    for ( const auto & url : _pimpl->baseUrls() )      // unique!
+    for ( const auto & url : _pimpl->baseUrls().raw() )        // Raw unique!
       if ( url == url_r )
        return;
-    _pimpl->baseUrls().push_back( url_r );
+    _pimpl->baseUrls().raw().push_back( url_r );
   }
 
   void RepoInfo::setBaseUrl( const Url & url_r )
   {
-    _pimpl->baseUrls().clear();
-    _pimpl->baseUrls().push_back( url_r );
+    _pimpl->baseUrls().raw().clear();
+    _pimpl->baseUrls().raw().push_back( url_r );
   }
 
   void RepoInfo::setPath( const Pathname &path )
@@ -276,17 +267,23 @@ namespace zypp
   repo::RepoType RepoInfo::type() const
   { return _pimpl->type; }
 
-  Url RepoInfo::mirrorListUrl() const
-  { return _pimpl->mirrorListUrl(); }
+  Url RepoInfo::mirrorListUrl() const                  // Variables replaced!
+  { return _pimpl->_mirrorListUrl.transformed(); }
+
+  Url RepoInfo::rawMirrorListUrl() const               // Raw
+  { return _pimpl->_mirrorListUrl.raw(); }
+
+  Url RepoInfo::gpgKeyUrl() const                      // Variables replaced!
+  { return _pimpl->_gpgKeyUrl.transformed(); }
 
-  Url RepoInfo::rawMirrorListUrl() const
-  { return _pimpl->rawMirrorListUrl(); }
+  Url RepoInfo::rawGpgKeyUrl() const                   // Raw
+  {  return _pimpl->_gpgKeyUrl.raw(); }
 
-  Url RepoInfo::gpgKeyUrl() const
-  { return _pimpl->gpgkey_url; }
+  RepoInfo::url_set RepoInfo::baseUrls() const         // Variables replaced!
+  { return _pimpl->baseUrls().transformed(); }
 
-  RepoInfo::url_set RepoInfo::baseUrls() const
-  { return url_set( baseUrlsBegin(), baseUrlsEnd() ); }        // Variables replaced!
+  RepoInfo::url_set RepoInfo::rawBaseUrls() const      // Raw
+  { return _pimpl->baseUrls().raw(); }
 
   Pathname RepoInfo::path() const
   { return _pimpl->path; }
@@ -298,19 +295,13 @@ namespace zypp
   { return _pimpl->targetDistro; }
 
   Url RepoInfo::rawUrl() const
-  { return( _pimpl->baseUrls().empty() ? Url() : *_pimpl->baseUrls().begin() ); }
+  { return( _pimpl->baseUrls().empty() ? Url() : *_pimpl->baseUrls().rawBegin() ); }
 
   RepoInfo::urls_const_iterator RepoInfo::baseUrlsBegin() const
-  {
-    return make_transform_iterator( _pimpl->baseUrls().begin(),
-                                    _pimpl->replacer );
-  }
+  { return _pimpl->baseUrls().transformedBegin(); }
 
   RepoInfo::urls_const_iterator RepoInfo::baseUrlsEnd() const
-  {
-    return make_transform_iterator( _pimpl->baseUrls().end(),
-                                    _pimpl->replacer );
-  }
+  { return _pimpl->baseUrls().transformedEnd(); }
 
   RepoInfo::urls_size_type RepoInfo::baseUrlsSize() const
   { return _pimpl->baseUrls().size(); }
@@ -447,7 +438,7 @@ namespace zypp
     RepoInfoBase::dumpOn(str);
     if ( _pimpl->baseurl2dump() )
     {
-      for ( const auto & url : _pimpl->baseUrls() )
+      for ( const auto & url : _pimpl->baseUrls().raw() )
       {
         str << "- url         : " << url << std::endl;
       }
@@ -459,12 +450,12 @@ namespace zypp
        str << tag_r << value_r << std::endl;
     });
 
-    strif( "- mirrorlist  : ", _pimpl->rawMirrorListUrl().asString() );
+    strif( "- mirrorlist  : ", rawMirrorListUrl().asString() );
     strif( "- path        : ", path().asString() );
     str << "- type        : " << type() << std::endl;
     str << "- priority    : " << priority() << std::endl;
     str << "- gpgcheck    : " << gpgCheck() << std::endl;
-    strif( "- gpgkey      : ", gpgKeyUrl().asString() );
+    strif( "- gpgkey      : ", rawGpgKeyUrl().asString() );
 
     if ( ! indeterminate(_pimpl->keeppackages) )
       str << "- keeppackages: " << keepPackages() << std::endl;
@@ -485,7 +476,7 @@ namespace zypp
     {
       str << "baseurl=";
       std::string indent;
-      for ( const auto & url : _pimpl->baseUrls() )
+      for ( const auto & url : _pimpl->baseUrls().raw() )
       {
         str << indent << url << endl;
        if ( indent.empty() ) indent = "        ";      // "baseurl="
@@ -495,8 +486,8 @@ namespace zypp
     if ( ! _pimpl->path.empty() )
       str << "path="<< path() << endl;
 
-    if ( ! (_pimpl->rawMirrorListUrl().asString().empty()) )
-      str << "mirrorlist=" << _pimpl->rawMirrorListUrl() << endl;
+    if ( ! (rawMirrorListUrl().asString().empty()) )
+      str << "mirrorlist=" << rawMirrorListUrl() << endl;
 
     str << "type=" << type().asString() << endl;
 
@@ -505,8 +496,9 @@ namespace zypp
 
     if (!indeterminate(_pimpl->gpgcheck))
       str << "gpgcheck=" << (gpgCheck() ? "1" : "0") << endl;
-    if ( ! (gpgKeyUrl().asString().empty()) )
-      str << "gpgkey=" <<gpgKeyUrl() << endl;
+
+    if ( ! (rawGpgKeyUrl().asString().empty()) )
+      str << "gpgkey=" << rawGpgKeyUrl() << endl;
 
     if (!indeterminate(_pimpl->keeppackages))
       str << "keeppackages=" << keepPackages() << endl;
index 4d69974..be80cf4 100644 (file)
@@ -119,24 +119,30 @@ namespace zypp
        * iterator that points at end of repository urls
        */
       urls_const_iterator baseUrlsEnd() const;
+
       /**
        * Pars pro toto: The first repository url
        */
       Url url() const
       { return( baseUrlsEmpty() ? Url() : *baseUrlsBegin()); }
       /**
-       * Pars pro toto: The first repository url (no variables replaced)
+       * Pars pro toto: The first repository raw url (no variables replaced)
        */
       Url rawUrl() const;
+
       /**
-       * A Url under which the metadata are located, or a set of mirrors.
+       * The complete set of repository urls
        *
-       * This can't be empty in order the repository to be valid
-       * unless the download of the mirror list succeeds and it
-       * contains a valid url.
+       * These are either the configured baseurls, or if empty, the downloaded
+       * mirror list (\see \ref mirrorListUrl)
        */
       url_set baseUrls() const;
       /**
+       * The complete set of raw repository urls (no variables replaced)
+       */
+      url_set rawBaseUrls() const;
+
+      /**
        * Add a base url. \see baseUrls
        * \param url The base url for the repository.
        *
@@ -177,8 +183,7 @@ namespace zypp
       void setPath( const Pathname &path );
 
       /**
-       * Url of a file which contains a list of Urls
-       * If empty, the base url will be used.
+       * Url of a file which contains a list of repository urls
        */
       Url mirrorListUrl() const;
       /**
@@ -267,6 +272,10 @@ namespace zypp
        */
       Url gpgKeyUrl() const;
       /**
+       * The raw gpgKeyUrl (no variables replaced).
+       */
+      Url rawGpgKeyUrl() const;
+      /**
        * \short Key to use for gpg checking of this repository
        *
        * \param url Url to the key in ASCII armored format
index 5f2a672..9b717f2 100644 (file)
@@ -1985,7 +1985,7 @@ namespace zypp
       // if the repo url was not set by the repoindex parser, set service's url
       Url url;
       if ( it->baseUrlsEmpty() )
-        url = service.url();
+        url = service.rawUrl();
       else
       {
         // service repo can contain only one URL now, so no need to iterate.
index 470396c..1242990 100644 (file)
@@ -35,7 +35,7 @@ namespace zypp
     typedef ServiceInfo::ReposToDisable ReposToDisable;
 
   public:
-    Url url;
+    RepoVariablesReplacedUrl url;
     repo::ServiceType type;
     ReposToEnable  reposToEnable;
     ReposToDisable reposToDisable;
@@ -96,8 +96,14 @@ namespace zypp
   ServiceInfo::~ServiceInfo()
   {}
 
-  Url ServiceInfo::url() const { return _pimpl->url; }
-  void ServiceInfo::setUrl( const Url& url ) { _pimpl->url = url; }
+  Url ServiceInfo::url() const                 // Variables replaced
+  { return _pimpl->url.transformed(); }
+
+  Url ServiceInfo::rawUrl() const              // Raw
+  { return _pimpl->url.raw(); }
+
+  void ServiceInfo::setUrl( const Url& url )   // Raw
+  { _pimpl->url.raw() = url; }
 
   repo::ServiceType ServiceInfo::type() const
   { return _pimpl->type; }
@@ -179,7 +185,7 @@ namespace zypp
   std::ostream & ServiceInfo::dumpAsIniOn( std::ostream & str ) const
   {
     RepoInfoBase::dumpAsIniOn(str)
-      << "url = " << url() << endl
+      << "url = " << rawUrl() << endl
       << "type = " << type() << endl;
 
     if ( ! repoStates().empty() )
index ac5cf44..991f3a6 100644 (file)
@@ -26,10 +26,12 @@ namespace zypp
 { /////////////////////////////////////////////////////////////////
 
   ///////////////////////////////////////////////////////////////////
-  //
-  //   CLASS NAME : ServiceInfo
-  //
-  /** */
+  /// \class ServiceInfo
+  /// \brief Service data
+  ///
+  /// \note Name and Url are subject to repo variable replacement
+  /// (\see \ref RepoVariablesStringReplacer).
+  ///
   class ServiceInfo : public repo::RepoInfoBase
   {
   public:
@@ -59,32 +61,23 @@ namespace zypp
 
   public:
 
-    /**
-     * Gets url to service
-     *
-     * \return url to service
-     */
+    /** The service url */
     Url url() const;
 
-    /**
-     * Sets url for this service
-     *
-     * \param url url to this service
-     */
+    /** The service raw url (no variables replaced) */
+    Url rawUrl() const;
+
+    /** Set the service url (raw value) */
     void setUrl( const Url& url );
 
-    /**
-     *
-     */
+
+    /** Service type */
     repo::ServiceType type() const;
 
-    /**
-     * Set service type.
-     *
-     * \param type the new type
-     */
+    /** Set service type */
     void setType( const repo::ServiceType & type );
 
+    /** Lazy init service type */
     void setProbedType( const repo::ServiceType & t ) const;
 
 
index 018b399..aca670f 100644 (file)
@@ -24,7 +24,7 @@
  * \endcode
 */
 #ifndef __GXX_EXPERIMENTAL_CXX0X__
-#define for_(IT,BEG,END) for ( typeof(BEG) IT = BEG, _for_end = END; IT != _for_end; ++IT )
+#define for_(IT,BEG,END) for ( __typeof__(BEG) IT = BEG, _for_end = END; IT != _for_end; ++IT )
 #else
 #define for_(IT,BEG,END) for ( auto IT = BEG, _for_end = END; IT != _for_end; ++IT )
 #endif
index fb9fe8a..7d0f507 100644 (file)
 /** Just tag text for translation. */
 #define N_(MSG) MSG
 
+#ifdef ZYPP_DLL //defined if zypp is compiled as DLL
+
 /** Return translated text. */
 #define _(MSG) ::zypp::gettext::dgettext( MSG )
 
 /** Return translated text (plural form). */
 #define _PL(MSG1,MSG2,N) ::zypp::gettext::dngettext( MSG1, MSG2, N )
 
+#else
+#define _(MSG) ::gettext( MSG )
+#define _PL(MSG1,MSG2,N) ::ngettext( MSG1, MSG2, N )
+#endif
+
 ///////////////////////////////////////////////////////////////////
 namespace zypp
 { /////////////////////////////////////////////////////////////////
index f3bf4ff..7c96513 100644 (file)
@@ -48,7 +48,7 @@ namespace zypp
     TriBool    _autorefresh;
     std::string        _alias;
     std::string        _escaped_alias;
-    std::string        _name;
+    RepoVariablesReplacedString _name;
     Pathname   _filepath;
 
   public:
@@ -95,7 +95,7 @@ namespace zypp
   { _pimpl->setAlias(alias); }
 
   void RepoInfoBase::setName( const std::string &name )
-  { _pimpl->_name = name; }
+  { _pimpl->_name.raw() = name; }
 
   void RepoInfoBase::setFilepath( const Pathname &filepath )
   { _pimpl->_filepath = filepath; }
@@ -122,7 +122,7 @@ namespace zypp
   }
 
   std::string RepoInfoBase::rawName() const
-  { return _pimpl->_name; }
+  { return _pimpl->_name.raw(); }
 
   std::string RepoInfoBase::label() const
   {
index f70e3d6..d53e534 100644 (file)
@@ -6,6 +6,16 @@
 |                         /_____||_| |_| |_|                           |
 |                                                                      |
 \---------------------------------------------------------------------*/
+#include <cstring>
+
+#define ZYPP_DBG_VAREXPAND 0
+#if ( ZYPP_DBG_VAREXPAND )
+#warning ZYPP_DBG_VAREXPAND is on
+#include <iostream>
+#include <sstream>
+using std::cout;
+using std::endl;
+#endif // ZYPP_DBG_VAREXPAND
 
 #include "zypp/base/LogTools.h"
 #include "zypp/base/String.h"
@@ -34,13 +44,356 @@ namespace zypp
   namespace repo
   {
     ///////////////////////////////////////////////////////////////////
+    // RepoVarExpand
+    ///////////////////////////////////////////////////////////////////
+    namespace
+    {
+      ///////////////////////////////////////////////////////////////////
+      /// \class FindVar
+      /// \brief Helper scanning for variable definitions in a string
+      ///////////////////////////////////////////////////////////////////
+      struct FindVar
+      {
+       bool _embedded;         ///< A (formerly) embedded string may have esacped \c $, \c closebrace and \c backslash
+       const char * _sbeg;     ///< start of string to scan
+       const char * _vbeg;     ///< [$]{variable:-word} / [$]{variable} / if embedded also on [\\]
+       const char * _nbeg;     ///< ${[v]ariable:-word} / ${[v]ariable}
+       const char * _nend;     ///< ${variable[:]-word} / ${variable[}]
+       const char * _vend;     ///< ${variable:-word}[] / ${variable}[]
+       const char * _send;     ///< end of scan (next $ or nullptr if done)
+
+       FindVar( const std::string & str_r, bool embedded_r )
+       : _embedded( embedded_r )
+       , _sbeg( str_r.c_str() )
+       , _vbeg( nullptr )
+       , _nbeg( nullptr )
+       , _nend( nullptr )
+       , _vend( nullptr )
+       , _send( findVarStart( _sbeg ) )
+       {}
+
+       /** Nullptr in _send indicates we scanned the whole string. */
+       bool done() const
+       { return !_send; }
+
+       /** Advance to first/next var if there is one */
+       bool nextVar()
+       {
+         if ( done() )
+           return false;
+
+         do {
+           if ( _vbeg && !_vend )      // loop internal: no findVarEnd at current $; skip it
+             _send = findVarStart( _vbeg+1 );
+           _vbeg = _send;              // next $ or null if string end
+           _nbeg = _nend = _vend = _send = nullptr;
+           if ( ! _vbeg )              // done!
+             return false;
+         } while( ! findVarEnd() );
+
+         return true;
+       }
+
+       /** Valid _vend indicates valid var data in scan. */
+       bool hasVar() const
+       { return _vend; }
+
+       //
+       // Methods below are only valid if hasVar() == true
+       //
+
+       /** Return the full var text */
+       std::string var() const
+       { return std::string( _vbeg, _vend ); }
+
+       /** Return the var name */
+       std::string varName() const
+       { return std::string( _nbeg, _nend ); }
+
+       /** Whether this is a conditional var (${..:[+-]...}) */
+       bool varIsConditional() const
+       { return( *(_vbeg+1) == '{' && *_nend == ':' ); }
+
+       /** The var type: \c \, \c $, \c - , \c +
+       * \li \c \ backslash escaped literal
+       * \li \c $      plain variable
+       * \li \c - conditional: default value
+       * \li \c + conditional: alternate value
+       */
+       int varType() const
+       { return( varIsConditional() ? *(_nend+1) : *_vbeg ); }
+
+       /** Return embedded value in conditional vars or empty string */
+       std::string varEmbedded() const
+       { return( varIsConditional() ? std::string( _nend+2, _vend-1 ) : std::string() ); }
+
+
+       /** Have unwritten data before var? */
+       bool hasVarPrefix() const
+       { return ( _sbeg != _vbeg ); }
+
+       /** Return unwritten data before var */
+       std::string varPrefix() const
+       { return std::string( _sbeg, _vbeg ); }
+
+       /** Indicate all data up to _vend were written */
+       void wroteVar()
+       { _sbeg = _vend; }
+
+      private:
+       /** Return next \c $ */
+       const char * findVarStart( const char * sbeg_r ) const
+       {
+         for ( ; *sbeg_r; ++sbeg_r )
+           if ( *sbeg_r == '$' || ( _embedded && *sbeg_r == '\\' ) )
+             return sbeg_r;
+         return nullptr;
+       }
+
+       /** Valid var name char */
+       bool isnamech( int ch ) const
+       { return ch == '_' || isalpha( ch ); }
+
+       /** Scan for a valid variable starting at _vbeg (storing the values) */
+       bool findVarEnd()
+       {
+         // asserted: *_vbeg == '$' || '\\'
+         if ( ! findVarEnd( _vbeg, _nbeg, _nend, _vend ) )
+           return false;
+         _send = findVarStart( _vend );
+         return true;
+       }
+
+       /** Skip over valid variable starting at vbeg (return end in \a vend). */
+       const char * findVarEnd( const char * vbeg ) const
+       {
+         // asserted: *_vbeg == '$'
+         const char * nbeg = nullptr;
+         const char * nend = nullptr;
+         const char * vend = nullptr;
+         findVarEnd( vbeg, nbeg, nend, vend );
+         return vend;
+       }
+
+       /** Scan for a valid variable starting at vbeg (const version returning the values). */
+       bool findVarEnd( const char * vbeg, const char *& nbeg, const char *& nend, const char *& vend ) const
+       {
+         // embedded only: handle backslash escaped chars
+         if ( *_vbeg == '\\' )
+         {
+           nbeg = vbeg+1;
+           if ( *nbeg == '$'
+             || *nbeg == '}'
+             || *nbeg == '\\' )
+           {
+             nend = vend = vbeg+2;
+             return true;
+           }
+           return false;
+         }
+
+         // asserted: *vbeg == '$'
+         // vbeg: [$]{variable:-word} / [$]{variable}
+         // nbeg: ${[v]ariable:-word} / ${[v]ariable}
+         bool braced = ( *(vbeg+1) == '{' ); //}
+         nbeg = vbeg+( braced ? 2 : 1 );
+         if ( !isnamech( *nbeg ) )     // don't allow empty var name
+           return false;
+         for ( nend = nbeg+1; isnamech( *nend ); ++nend )
+         {;} // skip over var name
+         // nend: ${variable[:]-word} / ${variable[}]
+
+         // vend: ${variable:-word}[] / ${variable}[]
+         // stay with ( vend == nullptr ) until you know it's valid
+         if ( braced )
+         {
+           if ( *nend == '}' )
+           {
+             vend = nend+1;
+           }
+           else if ( *nend == ':' )
+           {
+             const char * scan = nend+1;
+             if ( *scan == '+' || *scan == '-' )
+             {
+               ++scan;
+               // find first not escaped '}'
+               while ( *scan )
+               {
+                 if ( *scan == '\\' )
+                 {
+                   ++scan;     // next char is skipped
+                   if ( *scan )
+                     ++scan;
+                 }
+                 else if ( *scan == '$' )
+                 {
+                   // an embedded var?
+                   if ( ! (scan = findVarEnd( scan )) )
+                     return false;
+                 }
+                 else if ( *scan == '}' )
+                 {
+                   vend = scan+1;      // ==> unesacped '}', we're done!
+                   break;
+                 }
+                 else
+                   ++scan;     // literal
+               }
+               // ( ! *scan ) => end of string while looking for unesacped '}'
+             }
+             else
+               ; // err: ':' not followed by '+' or '-'
+           }
+           else
+             ; // err: braced name must end with '}' or ':'
+         }
+         else
+         {
+           vend = nend;        // un-braced
+         }
+         return( vend != nullptr );
+       }
+      };
+
+      bool _expand( std::string &, const std::string & value_r, unsigned level_r, RepoVarExpand::VarRetriever & varRetriever_r );
+
+      inline std::string expand( const std::string & value_r, unsigned level_r, RepoVarExpand::VarRetriever & varRetriever_r )
+      {
+       std::string ret;
+       if ( ! _expand( ret, value_r, level_r, varRetriever_r ) )
+         ret = value_r;
+       return ret;
+      }
+
+      inline std::string expand( std::string && value_r, unsigned level_r, RepoVarExpand::VarRetriever & varRetriever_r )
+      {
+       std::string ret;
+       if ( ! _expand( ret, value_r, level_r, varRetriever_r ) )
+         ret = std::move(value_r);
+       return ret;
+      }
+
+      /** Expand variables in \a value_r depending on \a level-r
+      * <tt>level_r > 0</tt> may have escaped chars outside braces.
+      */
+      inline bool _expand( std::string & result_r, const std::string & value_r, unsigned level_r, RepoVarExpand::VarRetriever & varRetriever_r )
+      {
+#if ( ZYPP_DBG_VAREXPAND )
+       cout << std::string(  2*level_r, ' ' ) << "\033[7m>>" << value_r << "<<\033[27m" << endl;
+       std::ostringstream dbg;
+       const char * dbgsbeg = value_r.c_str(); // track vars we already added to dbg
+       unsigned dbgi = 0;                      // color 1-5 var / 6 moved value_r
+       dbg << std::string(  2*level_r, ' ' ) << ">>";
+#endif // ZYPP_DBG_VAREXPAND
+
+       bool expanded = false;
+
+       if ( ! value_r.empty() )
+       {
+         FindVar scan( value_r, level_r );     // level_r > 0 is embedded
+         while ( scan.nextVar() )
+         {
+           static const std::string _emptyValue;
+           const std::string *const knownVar = ( varRetriever_r ? varRetriever_r( scan.varName() ) : nullptr );
+           const std::string & varValue( knownVar ? *knownVar : _emptyValue );
+
+#if ( ZYPP_DBG_VAREXPAND )
+           dbg << std::string(dbgsbeg,scan._vbeg) << "\033[3" << ((dbgi%5)+1) << "m" << scan.var() << "\033[0m";
+           cout << dbg.str() << "|<< " << scan.varName() << " " << (knownVar?"("+varValue+")":"-") << " {" << scan.varEmbedded() << "}" << endl;
+           dbgsbeg = scan._vend;
+           dbgi++;
+#endif // ZYPP_DBG_VAREXPAND
+
+           bool mustSubstitute = false;        // keep original text per default
+           std::string substitutionValue;
+
+           int varType = scan.varType();
+           if ( varType == '$' )       // plain var
+           {
+             if ( knownVar )
+             {
+               mustSubstitute = true;
+               substitutionValue = varValue;
+             }
+             else
+               ; // keep original text per default
+           }
+           else if ( varType == '-' ) // ':-' default value
+           {
+             mustSubstitute = true;
+             if ( varValue.empty() )
+               substitutionValue = expand( scan.varEmbedded(), level_r+1, varRetriever_r );
+             else
+               substitutionValue = varValue;
+           }
+           else if ( varType == '+' ) // ':+' alternate value
+           {
+             mustSubstitute = true;
+             if ( ! varValue.empty() )
+               substitutionValue = expand( scan.varEmbedded(), level_r+1, varRetriever_r );
+             else
+               ; // empty substitutionValue
+           }
+           else if ( varType == '\\' ) // backslash escaped literal (in varName)
+           {
+             mustSubstitute = true;
+             substitutionValue = scan.varName();
+           }
+           else
+             ; // keep original text per default
+
+           if ( mustSubstitute  )
+           {
+             if ( scan.hasVarPrefix() )
+               result_r += scan.varPrefix();
+             if ( ! substitutionValue.empty() )
+               result_r += substitutionValue;
+             scan.wroteVar(); // this moves scan._sbeg so we can later see what's already written
+           }
+         }
+
+#if ( ZYPP_DBG_VAREXPAND )
+         dbg << std::string( dbgsbeg ) << (scan._sbeg == value_r.c_str() ? "<<\033[36m(moved)\033[0m" : "");
+#endif // ZYPP_DBG_VAREXPAND
+
+         // handle unwritten data:
+         if ( scan._sbeg != value_r.c_str() )
+         {
+           expanded = true;
+           if ( *scan._sbeg )
+             result_r += std::string( scan._sbeg );
+         }
+         else
+           ; // no replacements at all
+       }
+
+#if ( ZYPP_DBG_VAREXPAND )
+       dbg << "<<";
+       cout << dbg.str() << endl;
+       cout << std::string(  2*level_r, ' ' ) << "\033[36m->" << result_r << "<-\033[0m" << endl;
+#endif // ZYPP_DBG_VAREXPAND
+       return expanded;
+      }
+    } // namespace
+    ///////////////////////////////////////////////////////////////////
+
+    std::string RepoVarExpand::operator()( const std::string & value_r, VarRetriever varRetriever_r ) const
+    { return expand( value_r, 0, varRetriever_r ); }
+
+    std::string RepoVarExpand::operator()( std::string && value_r, VarRetriever varRetriever_r ) const
+    { return expand( std::move(value_r), 0, varRetriever_r ); }
+
+    ///////////////////////////////////////////////////////////////////
+    // RepoVariables*Replace
+    ///////////////////////////////////////////////////////////////////
     namespace
     {
       /** \brief Provide lazy initialized repo variables
        */
-      struct ReplacerData : private zypp::base::NonCopyable
+      struct RepoVars : private zypp::base::NonCopyable
       {
-       typedef const std::string & (ReplacerData::*Getter)() const;
+       typedef const std::string & (RepoVars::*Getter)() const;
 
        const std::string & arch() const
        {
@@ -82,6 +435,7 @@ namespace zypp
            _basearch = arch.baseArch().asString();
          }
        }
+
        void assertReleaseverStr() const
        {
          if ( _releasever.empty() )
@@ -114,60 +468,26 @@ namespace zypp
        mutable std::string _releaseverMinor;
       };
 
-     /** \brief Replace repo variables on demand
-       *
-       * Initialisation of repo variables is delayed until they actually occur in
-       * a string.
-       */
-      std::string replacer( std::string value_r )
+      /** \brief */
+      const std::string * repoVarLookup( const std::string & name_r )
       {
-       std::string ret;
-       if ( ! value_r.empty() )
+       RepoVars::Getter getter = nullptr;
+       switch ( name_r.size() )
        {
-         static const str::regex rxVAR( "^([^$]*)\\$(\\{[[:alnum:]_]+\\}|[[:alnum:]_]+)([^$]*)" );
-         str::smatch what;
-         while ( str::regex_match( value_r, what, rxVAR ) )
-         {
-           ReplacerData::Getter getter = nullptr;
-
-           const char * varStart = value_r.c_str() + what.begin( 2 );
-           std::string::size_type varSize = what.size( 2 );
-           if ( *varStart == '{' )     // enclosed in {}
-           {
-             ++varStart;
-             varSize -= 2;
-           }
-
-           switch ( varSize )
-           {
-#define ASSIGN_IF(NAME,GETTER) if ( ::strncmp( varStart, NAME, varSize ) == 0 ) getter = GETTER
-
-             case  4:  ASSIGN_IF( "arch",              &ReplacerData::arch );                  break;
-             case  8:  ASSIGN_IF( "basearch",          &ReplacerData::basearch );              break;
-             case 10:  ASSIGN_IF( "releasever",        &ReplacerData::releasever );            break;
-             case 16:  ASSIGN_IF( "releasever_major",  &ReplacerData::releaseverMajor );
-                  else ASSIGN_IF( "releasever_minor",  &ReplacerData::releaseverMinor );       break;
+#define ASSIGN_IF(NAME,GETTER) if ( name_r == NAME ) getter = GETTER
+         case  4:      ASSIGN_IF( "arch",              &RepoVars::arch );              break;
+         case  8:      ASSIGN_IF( "basearch",          &RepoVars::basearch );          break;
+         case 10:      ASSIGN_IF( "releasever",        &RepoVars::releasever );        break;
+         case 16:      ASSIGN_IF( "releasever_major",  &RepoVars::releaseverMajor );
+             else      ASSIGN_IF( "releasever_minor",  &RepoVars::releaseverMinor );   break;
 #undef ASSIGN_IF
-           }
-
-           if ( getter )       // known var?
-           {
-             static const ReplacerData _data;
-             if ( what.size( 1 ) > 0 ) ret += what[1]; // pre
-             ret += (_data.*getter)();                 // var
-             if ( what.size( 3 ) > 0 ) ret += what[3]; // post
-           }
-           else
-           {
-             ret += what[0];   // unchanged
-           }
+       }
 
-           value_r.erase( 0, what.size( 0 ) );
-           if ( value_r.empty() )
-             break;
-         }
-         if ( ! value_r.empty() )
-           ret += std::move(value_r);          // no match
+       const std::string * ret = nullptr;
+       if ( getter )   // known var
+       {
+         static const RepoVars _repoVars;
+         ret = &(_repoVars.*getter)();
        }
        return ret;
       }
@@ -176,14 +496,19 @@ namespace zypp
 
     std::string RepoVariablesStringReplacer::operator()( const std::string & value ) const
     {
-      return replacer( value );
+      return RepoVarExpand()( value, repoVarLookup );
+    }
+    std::string RepoVariablesStringReplacer::operator()( std::string && value ) const
+    {
+      return RepoVarExpand()( value, repoVarLookup );
     }
 
     Url RepoVariablesUrlReplacer::operator()( const Url & value ) const
     {
+      RepoVarExpand expand;
       Url newurl( value );
-      newurl.setPathData( replacer( value.getPathData() ) );
-      newurl.setQueryString( replacer( value.getQueryString() ) );
+      newurl.setPathData( expand( value.getPathData(), repoVarLookup ) );
+      newurl.setQueryString( expand( value.getQueryString(), repoVarLookup ) );
       return newurl;
     }
 
index 895764a..9e4a09b 100644 (file)
@@ -6,11 +6,14 @@
 |                         /_____||_| |_| |_|                           |
 |                                                                      |
 \---------------------------------------------------------------------*/
-
+/** \file      zypp/repo/RepoVariables.h
+ */
 #ifndef ZYPP_REPO_VARIABLES_H_
 #define ZYPP_REPO_VARIABLES_H_
 
 #include <string>
+#include "zypp/base/Function.h"
+#include "zypp/base/ValueTransform.h"
 #include "zypp/Url.h"
 
 ///////////////////////////////////////////////////////////////////
@@ -19,6 +22,50 @@ namespace zypp
   ///////////////////////////////////////////////////////////////////
   namespace repo
   {
+    ///////////////////////////////////////////////////////////////////
+    /// \class RepoVarExpand
+    /// \brief Functor expanding repo variables in a string
+    ///
+    /// Known variables are determined by a callback function taking a variable
+    /// name and returning a pointer to the variable value or \c nullptr if unset.
+    ///
+    /// The \c $ character introduces variable expansion. A valid variable name
+    /// is any non-empty case-insensitive sequence of <tt>[[:alnum:]_]</tt>.
+    /// The variable name to be expanded may be enclosed in braces, which are
+    /// optional but serve to protect the variable to be expanded from characters
+    /// immediately following it which could be interpreted as part of the name.
+    ///
+    /// When braces are used, the matching ending brace is the first \c } not
+    /// escaped by a backslash and not within an embedded variable expansion.
+    /// Within braces only \c $, \c } and \c backslash are escaped by a
+    /// backslash. There is no escaping outside braces, to stay comaptible
+    /// with \c YUM (which does not support braces).
+    ///
+    /// <ul>
+    /// <li> \c ${variable}
+    /// If \c variable is unset the original is preserved like in \c YUM.
+    /// Otherwise, the value of \c variable is substituted.</li>
+    ///
+    /// <li> \c ${variable:-word} (default value)
+    /// If \c variable is unset or empty, the expansion of \c word is substituted.
+    /// Otherwise, the value of \c variable is substituted.</li>
+    ///
+    /// <li> \c ${variable:+word} (alternate value)
+    /// If variable is unset or empty nothing is substituted.
+    /// Otherwise, the expansion of \c word is substituted.</li>
+    /// </ul>
+    struct RepoVarExpand
+    {
+      /** Function taking a variable name and returning a pointer to the variable value or \c nullptr if unset. */
+      typedef function<const std::string * ( const std::string & )> VarRetriever;
+
+      /** Return a copy of \a value_r with embedded variables expanded. */
+      std::string operator()( const std::string & value_r, VarRetriever varRetriever_r ) const;
+#ifndef SWIG // Swig treats it as syntax error
+      /** \overload moving */
+      std::string operator()( std::string && value_r, VarRetriever varRetriever_r ) const;
+#endif
+    };
 
     /**
      * \short Functor replacing repository variables
@@ -52,10 +99,16 @@ namespace zypp
      * ftp://user:secret@site.net/$arch/ -> ftp://user:secret@site.net/i686/
      * http://site.net/?basearch=$basearch -> http://site.net/?basearch=i386
      * \endcode
+     *
+     * \see \ref RepoVarExpand for supported variable syntax.
      */
     struct RepoVariablesStringReplacer : public std::unary_function<const std::string &, std::string>
     {
       std::string operator()( const std::string & value_r ) const;
+#ifndef SWIG // Swig treats it as syntax error
+      /** \overload moving */
+      std::string operator()( std::string && value_r ) const;
+#endif
     };
 
     /**
@@ -68,9 +121,21 @@ namespace zypp
     {
       Url operator()( const Url & url_r ) const;
     };
-
   } // namespace repo
   ///////////////////////////////////////////////////////////////////
+
+  /** \relates RepoVariablesStringReplacer Helper managing repo variables replaced strings */
+  typedef base::ValueTransform<std::string, repo::RepoVariablesStringReplacer> RepoVariablesReplacedString;
+
+  /** \relates RepoVariablesStringReplacer Helper managing repo variables replaced string lists */
+  typedef base::ContainerTransform<std::list<std::string>, repo::RepoVariablesStringReplacer> RepoVariablesReplacedStringList;
+
+  /** \relates RepoVariablesUrlReplacer Helper managing repo variables replaced urls */
+  typedef base::ValueTransform<Url, repo::RepoVariablesUrlReplacer> RepoVariablesReplacedUrl;
+
+  /** \relates RepoVariablesUrlReplacer Helper managing repo variables replaced url lists */
+  typedef base::ContainerTransform<std::list<Url>, repo::RepoVariablesUrlReplacer> RepoVariablesReplacedUrlList;
+
 } // namespace zypp
 ///////////////////////////////////////////////////////////////////
 
index 82a7e4f..9eebf40 100644 (file)
@@ -178,7 +178,7 @@ SATResolver::SATResolver (const ResPool & pool, Pool *SATPool)
     , _allowuninstall(false)
     , _updatesystem(false)
     , _noupdateprovide(false)
-    , _dosplitprovides(false)
+    , _dosplitprovides(true)
     , _onlyRequires(ZConfig::instance().solver_onlyRequires())
     , _ignorealreadyrecommended(true)
     , _distupgrade(false)
index 73f7e89..3014af9 100644 (file)
@@ -20,7 +20,7 @@
 #include "zypp/ZYppCallbacks.h"
 #include "zypp/ExternalProgram.h"
 #include "zypp/target/rpm/RpmHeader.h"
-
+#include "zypp/ZConfig.h"
 
 using std::endl;
 #undef ZYPP_BASE_LOGGER_LOGGROUP