Imported Upstream version 14.45.0
[platform/upstream/libzypp.git] / zypp / sat / LookupAttr.cc
index cd8cada..d3fb410 100644 (file)
@@ -19,7 +19,7 @@
 
 #include "zypp/sat/Pool.h"
 #include "zypp/sat/LookupAttr.h"
-#include "zypp/sat/AttrMatcher.h"
+#include "zypp/base/StrMatcher.h"
 
 #include "zypp/CheckSum.h"
 
@@ -56,15 +56,16 @@ namespace zypp
     {
       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:
@@ -72,15 +73,20 @@ namespace zypp
         { 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:
@@ -111,6 +117,13 @@ namespace zypp
           _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() )
@@ -122,7 +135,10 @@ namespace zypp
           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!
         }
 
@@ -131,9 +147,10 @@ namespace zypp
 
       private:
         SolvAttr   _attr;
+        SolvAttr   _parent;
         Repository _repo;
         Solvable   _solv;
-        AttrMatcher _attrMatcher;
+        StrMatcher _strMatcher;
 
       private:
         friend Impl * rwcowClone<Impl>( const Impl * rhs );
@@ -155,14 +172,24 @@ namespace zypp
     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 ); }
+
 
     ///////////////////////////////////////////////////////////////////
 
@@ -172,11 +199,11 @@ namespace zypp
     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 ); }
 
     ///////////////////////////////////////////////////////////////////
 
@@ -198,6 +225,12 @@ namespace zypp
     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
@@ -287,25 +320,8 @@ namespace zypp
         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 );
         }
       }
 
@@ -350,6 +366,12 @@ namespace zypp
     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
     ///////////////////////////////////////////////////////////////////
@@ -411,10 +433,25 @@ namespace zypp
       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.
@@ -433,14 +470,23 @@ namespace zypp
 
     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!
     }
 
@@ -465,9 +511,29 @@ namespace zypp
       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 ) );
     }
 
@@ -494,6 +560,22 @@ namespace zypp
     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(); }
 
@@ -518,7 +600,10 @@ namespace zypp
             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;
         }
       }
@@ -535,7 +620,7 @@ namespace zypp
           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();
             }
@@ -571,7 +656,7 @@ namespace zypp
               {
                 str << "  " << it.inSolvAttr() << " = " << it.asString() << endl;
               }
-              str << "}" << endl;
+              str << "}";
              return str.str();
             }
             break;
@@ -589,7 +674,7 @@ namespace zypp
           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;
         }
       }
@@ -610,9 +695,21 @@ namespace zypp
             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();
@@ -665,16 +762,23 @@ namespace zypp
 
     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() );
+       }
       }
     }
 
@@ -689,8 +793,8 @@ namespace zypp
       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;
     }