11 #define ZYPP_DBG_VAREXPAND 0 12 #if ( ZYPP_DBG_VAREXPAND ) 13 #warning ZYPP_DBG_VAREXPAND is on 18 #endif // ZYPP_DBG_VAREXPAND 39 const char * env = getenv(
"ZYPP_REPO_RELEASEVER");
40 return( env ? env :
"" );
66 FindVar(
const std::string & str_r,
bool embedded_r )
67 : _embedded( embedded_r )
68 , _sbeg( str_r.c_str() )
73 , _send( findVarStart( _sbeg ) )
87 if ( _vbeg && !_vend )
88 _send = findVarStart( _vbeg+1 );
90 _nbeg = _nend = _vend = _send =
nullptr;
93 }
while( ! findVarEnd() );
107 std::string var()
const 108 {
return std::string( _vbeg, _vend ); }
111 std::string varName()
const 112 {
return std::string( _nbeg, _nend ); }
115 bool varIsConditional()
const 116 {
return( *(_vbeg+1) ==
'{' && *_nend ==
':' ); }
125 {
return( varIsConditional() ? *(_nend+1) : *_vbeg ); }
128 std::string varEmbedded()
const 129 {
return( varIsConditional() ? std::string( _nend+2, _vend-1 ) : std::string() ); }
133 bool hasVarPrefix()
const 134 {
return ( _sbeg != _vbeg ); }
137 std::string varPrefix()
const 138 {
return std::string( _sbeg, _vbeg ); }
146 const char * findVarStart(
const char * sbeg_r )
const 148 for ( ; *sbeg_r; ++sbeg_r )
149 if ( *sbeg_r ==
'$' || ( _embedded && *sbeg_r ==
'\\' ) )
155 bool isnamech(
int ch )
const 156 {
return ch ==
'_' || isalpha( ch ); }
162 if ( ! findVarEnd( _vbeg, _nbeg, _nend, _vend ) )
164 _send = findVarStart( _vend );
169 const char * findVarEnd(
const char * vbeg )
const 172 const char * nbeg =
nullptr;
173 const char * nend =
nullptr;
174 const char * vend =
nullptr;
175 findVarEnd( vbeg, nbeg, nend, vend );
180 bool findVarEnd(
const char * vbeg,
const char *& nbeg,
const char *& nend,
const char *& vend )
const 183 if ( *_vbeg ==
'\\' )
190 nend = vend = vbeg+2;
199 bool braced = ( *(vbeg+1) ==
'{' );
200 nbeg = vbeg+( braced ? 2 : 1 );
201 if ( !isnamech( *nbeg ) )
203 for ( nend = nbeg+1; isnamech( *nend ); ++nend )
215 else if ( *nend ==
':' )
217 const char * scan = nend+1;
218 if ( *scan ==
'+' || *scan ==
'-' )
230 else if ( *scan ==
'$' )
233 if ( ! (scan = findVarEnd( scan )) )
236 else if ( *scan ==
'}' )
256 return( vend !=
nullptr );
260 bool _expand( std::string &,
const std::string & value_r,
unsigned level_r, RepoVarExpand::VarRetriever & varRetriever_r );
262 inline std::string expand(
const std::string & value_r,
unsigned level_r, RepoVarExpand::VarRetriever & varRetriever_r )
265 if ( ! _expand( ret, value_r, level_r, varRetriever_r ) )
270 inline std::string expand( std::string && value_r,
unsigned level_r, RepoVarExpand::VarRetriever & varRetriever_r )
273 if ( ! _expand( ret, value_r, level_r, varRetriever_r ) )
274 ret = std::move(value_r);
281 inline bool _expand( std::string & result_r,
const std::string & value_r,
unsigned level_r, RepoVarExpand::VarRetriever & varRetriever_r )
283 #if ( ZYPP_DBG_VAREXPAND ) 284 cout << std::string( 2*level_r,
' ' ) <<
"\033[7m>>" << value_r <<
"<<\033[27m" << endl;
285 std::ostringstream dbg;
286 const char * dbgsbeg = value_r.c_str();
288 dbg << std::string( 2*level_r,
' ' ) <<
">>";
289 #endif // ZYPP_DBG_VAREXPAND 291 bool expanded =
false;
293 if ( ! value_r.empty() )
295 FindVar scan( value_r, level_r );
296 while ( scan.nextVar() )
298 static const std::string _emptyValue;
299 const std::string *
const knownVar = ( varRetriever_r ? varRetriever_r( scan.varName() ) :
nullptr );
300 const std::string & varValue( knownVar ? *knownVar : _emptyValue );
302 #if ( ZYPP_DBG_VAREXPAND ) 303 dbg << std::string(dbgsbeg,scan._vbeg) <<
"\033[3" << ((dbgi%5)+1) <<
"m" << scan.var() <<
"\033[0m";
304 cout << dbg.str() <<
"|<< " << scan.varName() <<
" " << (knownVar?
"("+varValue+
")":
"-") <<
" {" << scan.varEmbedded() <<
"}" << endl;
305 dbgsbeg = scan._vend;
307 #endif // ZYPP_DBG_VAREXPAND 309 bool mustSubstitute =
false;
310 std::string substitutionValue;
312 int varType = scan.varType();
313 if ( varType ==
'$' )
317 mustSubstitute =
true;
318 substitutionValue = varValue;
323 else if ( varType ==
'-' )
325 mustSubstitute =
true;
326 if ( varValue.empty() )
327 substitutionValue = expand( scan.varEmbedded(), level_r+1, varRetriever_r );
329 substitutionValue = varValue;
331 else if ( varType ==
'+' )
333 mustSubstitute =
true;
334 if ( ! varValue.empty() )
335 substitutionValue = expand( scan.varEmbedded(), level_r+1, varRetriever_r );
339 else if ( varType ==
'\\' )
341 mustSubstitute =
true;
342 substitutionValue = scan.varName();
347 if ( mustSubstitute )
349 if ( scan.hasVarPrefix() )
350 result_r += scan.varPrefix();
351 if ( ! substitutionValue.empty() )
352 result_r += substitutionValue;
357 #if ( ZYPP_DBG_VAREXPAND ) 358 dbg << std::string( dbgsbeg ) << (scan._sbeg == value_r.c_str() ?
"<<\033[36m(moved)\033[0m" :
"");
359 #endif // ZYPP_DBG_VAREXPAND 362 if ( scan._sbeg != value_r.c_str() )
366 result_r += std::string( scan._sbeg );
372 #if ( ZYPP_DBG_VAREXPAND ) 374 cout << dbg.str() << endl;
375 cout << std::string( 2*level_r,
' ' ) <<
"\033[36m->" << result_r <<
"<-\033[0m" << endl;
376 #endif // ZYPP_DBG_VAREXPAND 382 std::string RepoVarExpand::operator()(
const std::string & value_r,
VarRetriever varRetriever_r )
const 383 {
return expand( value_r, 0, varRetriever_r ); }
385 std::string RepoVarExpand::operator()( std::string && value_r,
VarRetriever varRetriever_r )
const 386 {
return expand( std::move(value_r), 0, varRetriever_r ); }
393 inline std::string getReleaseverString()
400 ret = trg->distributionVersion();
405 WAR <<
"ENV overwrites $releasever=" << ret << endl;
414 typedef const std::string & (RepoVars::*Getter)()
const;
416 const std::string & arch()
const 422 const std::string & basearch()
const 428 const std::string & releasever()
const 430 assertReleaseverStr();
434 const std::string & releaseverMajor()
const 436 assertReleaseverStr();
440 const std::string & releaseverMinor()
const 442 assertReleaseverStr();
447 void assertArchStr()
const 457 void assertReleaseverStr()
const 460 std::string
check( getReleaseverString() );
466 if ( pos == std::string::npos )
487 const std::string * repoVarLookup(
const std::string & name_r )
489 RepoVars::Getter getter =
nullptr;
490 switch ( name_r.size() )
492 #define ASSIGN_IF(NAME,GETTER) if ( name_r == NAME ) getter = GETTER 493 case 4:
ASSIGN_IF(
"arch", &RepoVars::arch );
break;
494 case 8:
ASSIGN_IF(
"basearch", &RepoVars::basearch );
break;
495 case 10:
ASSIGN_IF(
"releasever", &RepoVars::releasever );
break;
496 case 16:
ASSIGN_IF(
"releasever_major", &RepoVars::releaseverMajor );
497 else ASSIGN_IF(
"releasever_minor", &RepoVars::releaseverMinor );
break;
501 const std::string * ret =
nullptr;
504 static const RepoVars _repoVars;
505 ret = &(_repoVars.*getter)();
512 std::string RepoVariablesStringReplacer::operator()(
const std::string & value )
const 516 std::string RepoVariablesStringReplacer::operator()( std::string && value )
const 521 Url RepoVariablesUrlReplacer::operator()(
const Url & value )
const std::string _releaseverMajor
const char * _nend
${variable[:]-word} / ${variable[}]
const char * _vend
${variable:-word}[] / ${variable}[]
std::string getPathData() const
Returns the encoded path component of the URL.
static ZConfig & instance()
Singleton ctor.
const std::string & asString() const
std::string distributionVersion() const
This is version attribute of the installed base product.
const char * _vbeg
[$]{variable:-word} / [$]{variable} / if embedded also on [\]
#define ASSIGN_IF(NAME, GETTER)
bool _embedded
A (formerly) embedded string may have esacped $, closebrace and backslash.
boost::noncopyable NonCopyable
Ensure derived classes cannot be copied.
Functor expanding repo variables in a string.
void setPathData(const std::string &pathdata)
Set the path data component in the URL.
std::string _releaseverMinor
std::string getQueryString() const
Returns the encoded query string component of the URL.
const char * _send
end of scan (next $ or nullptr if done)
void setQueryString(const std::string &querystr)
Set the query string in the URL.
const char * _sbeg
start of string to scan
bool check(const std::string &sequenceinfo_r, bool quick_r)
Check via sequence info.
function< const std::string *(const std::string &)> VarRetriever
Function taking a variable name and returning a pointer to the variable value or nullptr if unset...
Easy-to use interface to the ZYPP dependency resolver.
const char * _nbeg
${[v]ariable:-word} / ${[v]ariable}
std::string ZYPP_REPO_RELEASEVER()
Use faked releasever (e.g.