From: DongHun Kwak Date: Tue, 1 Nov 2016 01:32:35 +0000 (+0900) Subject: Imported Upstream version 14.37.0 X-Git-Tag: upstream/16.3.1~100 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=refs%2Fchanges%2F26%2F94626%2F1;p=platform%2Fupstream%2Flibzypp.git Imported Upstream version 14.37.0 Change-Id: I984a49843582896699ad5b43bb5324bf75c68e96 Signed-off-by: DongHun Kwak --- diff --git a/VERSION.cmake b/VERSION.cmake index 336f9b5..42e8095 100644 --- a/VERSION.cmake +++ b/VERSION.cmake @@ -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) #======= diff --git a/package/libzypp.changes b/package/libzypp.changes index b8ab72c..bc824fc 100644 --- a/package/libzypp.changes +++ b/package/libzypp.changes @@ -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 diff --git a/po/zypp-po.tar.bz2 b/po/zypp-po.tar.bz2 index d1eff8e..8de47f2 100644 Binary files a/po/zypp-po.tar.bz2 and b/po/zypp-po.tar.bz2 differ diff --git a/tests/repo/RepoVariables_test.cc b/tests/repo/RepoVariables_test.cc index 9ca2400..008c7dc 100644 --- a/tests/repo/RepoVariables_test.cc +++ b/tests/repo/RepoVariables_test.cc @@ -1,24 +1,18 @@ -#include +#include #include -#include -#include #include -#include +#include -#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 +// A 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 {}; @@ -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 vartable; + std::map> 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 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/"); diff --git a/zypp/RepoInfo.cc b/zypp/RepoInfo.cc index cd20b96..0ad8cf4 100644 --- a/zypp/RepoInfo.cc +++ b/zypp/RepoInfo.cc @@ -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 _keywords; friend Impl * rwcowClone( 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=" < 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 + * level_r > 0 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; } diff --git a/zypp/repo/RepoVariables.h b/zypp/repo/RepoVariables.h index 895764a..9e4a09b 100644 --- a/zypp/repo/RepoVariables.h +++ b/zypp/repo/RepoVariables.h @@ -6,11 +6,14 @@ | /_____||_| |_| |_| | | | \---------------------------------------------------------------------*/ - +/** \file zypp/repo/RepoVariables.h + */ #ifndef ZYPP_REPO_VARIABLES_H_ #define ZYPP_REPO_VARIABLES_H_ #include +#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 [[:alnum:]_]. + /// 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). + /// + ///
    + ///
  • \c ${variable} + /// If \c variable is unset the original is preserved like in \c YUM. + /// Otherwise, the value of \c variable is substituted.
  • + /// + ///
  • \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.
  • + /// + ///
  • \c ${variable:+word} (alternate value) + /// If variable is unset or empty nothing is substituted. + /// Otherwise, the expansion of \c word is substituted.
  • + ///
+ struct RepoVarExpand + { + /** Function taking a variable name and returning a pointer to the variable value or \c nullptr if unset. */ + typedef function 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 { 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 RepoVariablesReplacedString; + + /** \relates RepoVariablesStringReplacer Helper managing repo variables replaced string lists */ + typedef base::ContainerTransform, repo::RepoVariablesStringReplacer> RepoVariablesReplacedStringList; + + /** \relates RepoVariablesUrlReplacer Helper managing repo variables replaced urls */ + typedef base::ValueTransform RepoVariablesReplacedUrl; + + /** \relates RepoVariablesUrlReplacer Helper managing repo variables replaced url lists */ + typedef base::ContainerTransform, repo::RepoVariablesUrlReplacer> RepoVariablesReplacedUrlList; + } // namespace zypp /////////////////////////////////////////////////////////////////// diff --git a/zypp/solver/detail/SATResolver.cc b/zypp/solver/detail/SATResolver.cc index 82a7e4f..9eebf40 100644 --- a/zypp/solver/detail/SATResolver.cc +++ b/zypp/solver/detail/SATResolver.cc @@ -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) diff --git a/zypp/target/RpmPostTransCollector.cc b/zypp/target/RpmPostTransCollector.cc index 73f7e89..3014af9 100644 --- a/zypp/target/RpmPostTransCollector.cc +++ b/zypp/target/RpmPostTransCollector.cc @@ -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