#include "zypp/sat/Pool.h"
#include "zypp/sat/LookupAttr.h"
-#include "zypp/sat/AttrMatcher.h"
+#include "zypp/base/StrMatcher.h"
#include "zypp/CheckSum.h"
{
public:
Impl()
+ : _parent( SolvAttr::noAttr )
{}
Impl( SolvAttr attr_r, Location loc_r )
- : _attr( attr_r ), _solv( loc_r == REPO_ATTR ? SOLVID_META : noSolvableId )
+ : _attr( attr_r ), _parent( attr_r.parent() ), _solv( loc_r == REPO_ATTR ? SOLVID_META : noSolvableId )
{}
Impl( SolvAttr attr_r, Repository repo_r, Location loc_r )
- : _attr( attr_r ), _repo( repo_r ), _solv( loc_r == REPO_ATTR ? SOLVID_META : noSolvableId )
+ : _attr( attr_r ), _parent( attr_r.parent() ), _repo( repo_r ), _solv( loc_r == REPO_ATTR ? SOLVID_META : noSolvableId )
{}
Impl( SolvAttr attr_r, Solvable solv_r )
- : _attr( attr_r ), _solv( solv_r )
+ : _attr( attr_r ), _parent( attr_r.parent() ), _solv( solv_r )
{}
public:
{ return _attr; }
void setAttr( SolvAttr attr_r )
- { _attr = attr_r; }
+ {
+ _attr = attr_r;
+ SolvAttr p( _attr.parent() );
+ if ( p != SolvAttr::noAttr )
+ _parent = p;
+ }
- const AttrMatcher & attrMatcher() const
- { return _attrMatcher; }
+ const StrMatcher & strMatcher() const
+ { return _strMatcher; }
- void setAttrMatcher( const AttrMatcher & matcher_r )
+ void setStrMatcher( const StrMatcher & matcher_r )
{
matcher_r.compile();
- _attrMatcher = matcher_r;
+ _strMatcher = matcher_r;
}
public:
_solv = solv_r;
}
+ SolvAttr parent() const
+ { return _parent; }
+
+ void setParent( SolvAttr attr_r )
+ { _parent = attr_r; }
+
+ public:
LookupAttr::iterator begin() const
{
if ( _attr == SolvAttr::noAttr || sat::Pool::instance().reposEmpty() )
else if ( _repo )
whichRepo = _repo.id();
- detail::DIWrap dip( whichRepo, _solv.id(), _attr.id(), _attrMatcher.searchstring(), _attrMatcher.flags().get() );
+ detail::DIWrap dip( whichRepo, _solv.id(), _attr.id(), _strMatcher.searchstring(), _strMatcher.flags().get() );
+ if ( _parent != SolvAttr::noAttr )
+ ::dataiterator_prepend_keyname( dip.get(), _parent.id() );
+
return iterator( dip ); // iterator takes over ownership!
}
private:
SolvAttr _attr;
+ SolvAttr _parent;
Repository _repo;
Solvable _solv;
- AttrMatcher _attrMatcher;
+ StrMatcher _strMatcher;
private:
friend Impl * rwcowClone<Impl>( const Impl * rhs );
LookupAttr::LookupAttr( SolvAttr attr_r, Location loc_r )
: _pimpl( new Impl( attr_r, loc_r ) )
{}
+ LookupAttr::LookupAttr( SolvAttr attr_r, SolvAttr parent_r, Location loc_r )
+ : _pimpl( new Impl( attr_r, loc_r ) )
+ { _pimpl->setParent( parent_r ); }
LookupAttr::LookupAttr( SolvAttr attr_r, Repository repo_r, Location loc_r )
: _pimpl( new Impl( attr_r, repo_r, loc_r ) )
{}
+ LookupAttr::LookupAttr( SolvAttr attr_r, SolvAttr parent_r, Repository repo_r, Location loc_r )
+ : _pimpl( new Impl( attr_r, repo_r, loc_r ) )
+ { _pimpl->setParent( parent_r ); }
LookupAttr::LookupAttr( SolvAttr attr_r, Solvable solv_r )
: _pimpl( new Impl( attr_r, solv_r ) )
{}
+ LookupAttr::LookupAttr( SolvAttr attr_r, SolvAttr parent_r, Solvable solv_r )
+ : _pimpl( new Impl( attr_r, solv_r ) )
+ { _pimpl->setParent( parent_r ); }
+
///////////////////////////////////////////////////////////////////
void LookupAttr::setAttr( SolvAttr attr_r )
{ _pimpl->setAttr( attr_r ); }
- const AttrMatcher & LookupAttr::attrMatcher() const
- { return _pimpl->attrMatcher(); }
+ const StrMatcher & LookupAttr::strMatcher() const
+ { return _pimpl->strMatcher(); }
- void LookupAttr::setAttrMatcher( const AttrMatcher & matcher_r )
- { _pimpl->setAttrMatcher( matcher_r ); }
+ void LookupAttr::setStrMatcher( const StrMatcher & matcher_r )
+ { _pimpl->setStrMatcher( matcher_r ); }
///////////////////////////////////////////////////////////////////
void LookupAttr::setSolvable( Solvable solv_r )
{ _pimpl->setSolvable( solv_r ); }
+ SolvAttr LookupAttr::parent() const
+ { return _pimpl->parent(); }
+
+ void LookupAttr::setParent( SolvAttr attr_r )
+ { _pimpl->setParent( attr_r ); }
+
///////////////////////////////////////////////////////////////////
LookupAttr::iterator LookupAttr::begin() const
if ( rhs._dip )
{
_dip = new ::Dataiterator;
- *_dip = *rhs._dip;
- // now we have to manually clone any allocated regex data matcher.
- ::Datamatcher & matcher( _dip->matcher );
- if ( matcher.match && ( matcher.flags & SEARCH_STRINGMASK ) == SEARCH_REGEX )
- {
- ::datamatcher_init( &matcher, _mstring.c_str(), matcher.flags );
- }
- else if ( matcher.match && matcher.match != _mstring.c_str() )
- {
- //SEC << "**" << rhs._dip << endl;
- SEC << "r " << rhs._dip->matcher.match << endl;
- SEC << "r " << rhs._dip->matcher.flags << endl;
- SEC << "r " << (const void*)rhs._mstring.c_str() << "'" << rhs._mstring << "'" << endl;
-
- SEC << "t " << matcher.match << endl;
- SEC << "t " << matcher.flags << endl;
- SEC << "t " << (const void*)_mstring.c_str() << "'" << _mstring << "'" << endl;
- throw( "this cant be!" );
- }
+ ::dataiterator_init_clone( _dip, rhs._dip );
+ ::dataiterator_strdup( _dip );
}
}
void LookupAttr::iterator::nextSkipRepo()
{ if ( _dip ) ::dataiterator_skip_repo( _dip.get() ); }
+ void LookupAttr::iterator::stayInThisSolvable()
+ { if ( _dip ) { _dip.get()->repoid = -1; _dip.get()->flags |= SEARCH_THISSOLVID; } }
+
+ void LookupAttr::iterator::stayInThisRepo()
+ { if ( _dip ) { _dip.get()->repoid = -1; } }
+
///////////////////////////////////////////////////////////////////
// attr value type test
///////////////////////////////////////////////////////////////////
return false;
}
- bool LookupAttr::iterator::solvAttrSubEntry() const
+ ///////////////////////////////////////////////////////////////////
+ namespace
{
- return solvAttrType() == REPOKEY_TYPE_FLEXARRAY;
+ enum SubType { ST_NONE, // no sub-structure
+ ST_FLEX, // flexarray
+ ST_SUB }; // inside sub-structure
+ SubType subType( const detail::DIWrap & dip )
+ {
+ if ( ! dip )
+ return ST_NONE;
+ if ( dip.get()->key->type == REPOKEY_TYPE_FLEXARRAY )
+ return ST_FLEX;
+ return dip.get()->kv.parent ? ST_SUB : ST_NONE;
+ }
}
+ ///////////////////////////////////////////////////////////////////
+
+ bool LookupAttr::iterator::solvAttrSubEntry() const
+ { return subType( _dip ) != ST_NONE; }
///////////////////////////////////////////////////////////////////
// Iterate sub-structures.
LookupAttr::iterator LookupAttr::iterator::subBegin() const
{
- if ( ! solvAttrSubEntry() )
+ SubType subtype( subType( _dip ) );
+ if ( subtype == ST_NONE )
return subEnd();
-
- // remember this position
- ::dataiterator_setpos( _dip.get() );
-
// setup the new sub iterator with the remembered position
- detail::DIWrap dip( 0, SOLVID_POS, 0, 0, 0 );
+ detail::DIWrap dip( 0, 0, 0 );
+ ::dataiterator_clonepos( dip.get(), _dip.get() );
+ switch ( subtype )
+ {
+ case ST_NONE: // not reached
+ break;
+ case ST_FLEX:
+ ::dataiterator_seek( dip.get(), DI_SEEK_CHILD|DI_SEEK_STAY );
+ break;
+ case ST_SUB:
+ ::dataiterator_seek( dip.get(), DI_SEEK_REWIND|DI_SEEK_STAY );
+ break;
+ }
return iterator( dip ); // iterator takes over ownership!
}
if ( attrname_r.empty() )
return subBegin();
+ SubType subtype( subType( _dip ) );
+ if ( subtype == ST_NONE )
+ return subBegin();
+
std::string subattr( inSolvAttr().asString() );
- subattr += ":";
- subattr += attrname_r;
+ if ( subtype == ST_FLEX )
+ {
+ // append ":attrname"
+ subattr += ":";
+ subattr += attrname_r;
+ }
+ else
+ {
+ // replace "oldname" after ':' with "attrname"
+ std::string::size_type pos( subattr.rfind( ':' ) );
+ if ( pos != std::string::npos )
+ {
+ subattr.erase( pos+1 );
+ subattr += attrname_r;
+ }
+ else
+ subattr = attrname_r; // no ':' so replace all.
+ }
return subFind( SolvAttr( subattr ) );
}
unsigned LookupAttr::iterator::asUnsigned() const
{ return asInt(); }
+ unsigned long long LookupAttr::iterator::asUnsignedLL() const
+ {
+ if ( _dip )
+ {
+ switch ( solvAttrType() )
+ {
+ case REPOKEY_TYPE_U32:
+ case REPOKEY_TYPE_NUM:
+ case REPOKEY_TYPE_CONSTANT:
+ return SOLV_KV_NUM64(&_dip->kv);
+ break;
+ }
+ }
+ return 0;
+ }
+
bool LookupAttr::iterator::asBool() const
{ return asInt(); }
break;
case REPOKEY_TYPE_DIRSTRARRAY:
- return ::repodata_dir2str( _dip->data, _dip->kv.id, _dip->kv.str );
+ // may or may not be stringified depending on SEARCH_FILES flag
+ return( _dip->flags & SEARCH_FILES
+ ? _dip->kv.str
+ : ::repodata_dir2str( _dip->data, _dip->kv.id, _dip->kv.str ) );
break;
}
}
case REPOKEY_TYPE_IDARRAY:
case REPOKEY_TYPE_CONSTANTID:
{
- detail::IdType id = ::repodata_globalize_id( _dip->data, _dip->kv.id );
+ detail::IdType id = ::repodata_globalize_id( _dip->data, _dip->kv.id, 1 );
return ISRELDEP(id) ? Capability( id ).asString()
: IdString( id ).asString();
}
{
str << " " << it.inSolvAttr() << " = " << it.asString() << endl;
}
- str << "}" << endl;
+ str << "}";
return str.str();
}
break;
case REPOKEY_TYPE_ID:
case REPOKEY_TYPE_IDARRAY:
case REPOKEY_TYPE_CONSTANTID:
- return IdString( ::repodata_globalize_id( _dip->data, _dip->kv.id ) );
+ return IdString( ::repodata_globalize_id( _dip->data, _dip->kv.id, 1 ) );
break;
}
}
return CheckSum::sha1( ::repodata_chk2str( _dip->data, solvAttrType(), (unsigned char *)_dip->kv.str ) );
break;
+ case REPOKEY_TYPE_SHA224:
+ return CheckSum::sha224( ::repodata_chk2str( _dip->data, solvAttrType(), (unsigned char *)_dip->kv.str ) );
+ break;
+
case REPOKEY_TYPE_SHA256:
return CheckSum::sha256( ::repodata_chk2str( _dip->data, solvAttrType(), (unsigned char *)_dip->kv.str ) );
break;
+
+ case REPOKEY_TYPE_SHA384:
+ return CheckSum::sha384( ::repodata_chk2str( _dip->data, solvAttrType(), (unsigned char *)_dip->kv.str ) );
+ break;
+
+ case REPOKEY_TYPE_SHA512:
+ return CheckSum::sha512( ::repodata_chk2str( _dip->data, solvAttrType(), (unsigned char *)_dip->kv.str ) );
+ break;
}
}
return CheckSum();
detail::IdType LookupAttr::iterator::dereference() const
{
- return _dip ? ::repodata_globalize_id( _dip->data, _dip->kv.id )
+ return _dip ? ::repodata_globalize_id( _dip->data, _dip->kv.id, 1 )
: detail::noId;
}
void LookupAttr::iterator::increment()
{
- if ( _dip && ! ::dataiterator_step( _dip.get() ) )
+ if ( _dip )
{
- _dip.reset();
- base_reference() = 0;
+ if ( ! ::dataiterator_step( _dip.get() ) )
+ {
+ _dip.reset();
+ base_reference() = 0;
+ }
+ else
+ {
+ ::dataiterator_strdup( _dip.get() );
+ }
}
}
else if ( obj.inRepo() )
str << obj.inRepo();
- str << '<' << obj.inSolvAttr()
- << ">(" << IdString(obj.solvAttrType()) << ") = " << obj.asString();
+ str << '<' << obj.inSolvAttr() << (obj.solvAttrSubEntry() ? ">(*" : ">(")
+ << IdString(obj.solvAttrType()) << ") = " << obj.asString();
return str;
}