done LookupAttr, added ArrayAttr container to retrieve list attributes.
authorMichael Andres <ma@suse.de>
Mon, 7 Apr 2008 17:37:16 +0000 (17:37 +0000)
committerMichael Andres <ma@suse.de>
Mon, 7 Apr 2008 17:37:16 +0000 (17:37 +0000)
zypp/Package.cc
zypp/Package.h
zypp/Patch.cc
zypp/Patch.h
zypp/Pattern.h
zypp/ResObject.h
zypp/sat/LookupAttr.cc
zypp/sat/LookupAttr.h
zypp/sat/Pool.cc
zypp/sat/Solvable.h

index c0c3f78..fc888cc 100644 (file)
@@ -66,9 +66,8 @@ namespace zypp
   std::string Package::group() const
   { return lookupStrAttribute( sat::SolvAttr::group ); }
 
-#warning DUMMY keywords
   Package::Keywords Package::keywords() const
-  { return Keywords(); }
+  { return Keywords( sat::SolvAttr::keywords, satSolvable() ); }
 
   /** Don't ship it as class Url, because it might be
    * in fact anything but a legal Url. */
index 741d7ee..1f3a8e1 100644 (file)
@@ -37,7 +37,7 @@ namespace zypp
     typedef TraitsType::constPtrType constPtr;
 
   public:
-    typedef std::set<PackageKeyword> Keywords;
+    typedef sat::ArrayAttr<PackageKeyword,IdString> Keywords;
 
   public:
 
index 9954773..04dd40b 100644 (file)
@@ -55,10 +55,10 @@ namespace zypp
   bool Patch::affects_pkg_manager() const
   { return false; }
 
-  Patch::AtomList Patch::atoms() const
-  {
 #warning Implement PATCH::ATOMS
 #if 0
+  Patch::AtomList Patch::atoms() const
+  {
       if ( ! _atomlist )
       {
         if ( ! hasBackRef() )
@@ -96,9 +96,9 @@ namespace zypp
         }
       }
       return *_atomlist;
-#endif
     return AtomList();
   }
+#endif
 
   bool Patch::interactive() const
   {
index 89cc887..74be85e 100644 (file)
@@ -50,11 +50,13 @@ namespace zypp
     bool reboot_needed() const;
     /** Does the patch affect the package manager itself? */
     bool affects_pkg_manager() const;
-    /** The list of all atoms building the patch */
-    AtomList atoms() const;
     /** Is the patch installation interactive? (does it need user input?) */
     bool interactive() const;
 
+    /** The list of all atoms building the patch */
+    ZYPP_DEPRECATED AtomList atoms() const
+    { return AtomList(); }
+
   protected:
     friend Ptr make<Self>( const sat::Solvable & solvable_r );
     /** Ctor */
index 29277c8..0d634ac 100644 (file)
@@ -36,6 +36,9 @@ namespace zypp
     typedef TraitsType::constPtrType constPtr;
 
   public:
+   typedef sat::ArrayAttr<IdString,IdString> NameList;
+
+  public:
     /** */
     bool isDefault() const;
     /** */
index 844cbae..81295ce 100644 (file)
@@ -23,6 +23,8 @@
 #include "zypp/OnMediaLocation.h"
 #include "zypp/Repository.h"
 
+#include "zypp/sat/LookupAttr.h"
+
 #include "zypp/TranslatedText.h"
 
 ///////////////////////////////////////////////////////////////////
index dcfb001..6d23c8a 100644 (file)
 */
 #include <cstring>
 #include <iostream>
+#include <sstream>
+
 #include "zypp/base/Logger.h"
+#include "zypp/base/String.h"
 
 #include "zypp/sat/detail/PoolImpl.h"
 
 #include "zypp/sat/LookupAttr.h"
+#include "zypp/CheckSum.h"
 
 using std::endl;
 
@@ -56,6 +60,9 @@ namespace zypp
       return iterator();
     }
 
+    bool LookupAttr::empty() const
+    { return begin() == end(); }
+
     std::ostream & operator<<( std::ostream & str, const LookupAttr & obj )
     {
       if ( obj.attr() == SolvAttr::noAttr )
@@ -89,6 +96,10 @@ namespace zypp
     //
     ///////////////////////////////////////////////////////////////////
 
+    ///////////////////////////////////////////////////////////////////
+    // position and moving
+    ///////////////////////////////////////////////////////////////////
+
     Repository LookupAttr::iterator::inRepo() const
     { return Repository( _dip->repo ); }
 
@@ -98,9 +109,6 @@ namespace zypp
     SolvAttr LookupAttr::iterator::inSolvAttr() const
     { return SolvAttr( _dip->key->name ); }
 
-    detail::IdType LookupAttr::iterator::solvAttrType() const
-    { return _dip->key->type; }
-
     void LookupAttr::iterator::nextSkipSolvAttr()
     { ::dataiterator_skip_attribute( _dip.get() ); }
 
@@ -111,9 +119,216 @@ namespace zypp
     { ::dataiterator_skip_repo( _dip.get() ); }
 
     ///////////////////////////////////////////////////////////////////
+    // attr value type test
+    ///////////////////////////////////////////////////////////////////
+
+    detail::IdType LookupAttr::iterator::solvAttrType() const
+    { return _dip->key->type; }
+
+    bool LookupAttr::iterator::solvAttrNumeric() const
+    {
+      switch ( solvAttrType() )
+      {
+        case REPOKEY_TYPE_U32:
+        case REPOKEY_TYPE_NUM:
+        case REPOKEY_TYPE_CONSTANT:
+          return true;
+          break;
+      }
+      return false;
+    }
+
+    bool LookupAttr::iterator::solvAttrString() const
+    {
+      switch ( solvAttrType() )
+      {
+        case REPOKEY_TYPE_ID:
+        case REPOKEY_TYPE_IDARRAY:
+        case REPOKEY_TYPE_CONSTANTID:
+        case REPOKEY_TYPE_STR:
+        case REPOKEY_TYPE_DIRSTRARRAY:
+          return true;
+          break;
+      }
+      return false;
+    }
+
+    bool LookupAttr::iterator::solvAttrIdString() const
+    {
+      switch ( solvAttrType() )
+      {
+        case REPOKEY_TYPE_ID:
+        case REPOKEY_TYPE_IDARRAY:
+        case REPOKEY_TYPE_CONSTANTID:
+          return true;
+          break;
+      }
+      return false;
+    }
+
+    bool LookupAttr::iterator::solvAttrCheckSum() const
+    {
+      switch ( solvAttrType() )
+      {
+        case REPOKEY_TYPE_MD5:
+        case REPOKEY_TYPE_SHA1:
+        case REPOKEY_TYPE_SHA256:
+          return true;
+          break;
+      }
+      return false;
+    }
+
+    ///////////////////////////////////////////////////////////////////
+    // attr value type test
+    ///////////////////////////////////////////////////////////////////
+
+    int LookupAttr::iterator::asInt() const
+    {
+      switch ( solvAttrType() )
+      {
+        case REPOKEY_TYPE_U32:
+        case REPOKEY_TYPE_NUM:
+        case REPOKEY_TYPE_CONSTANT:
+          return _dip->kv.num;
+          break;
+      }
+      return 0;
+    }
+
+    unsigned LookupAttr::iterator::asUnsigned() const
+    { return asInt(); }
+
+    bool LookupAttr::iterator::asBool() const
+    { return asInt(); }
+
+
+    const char * LookupAttr::iterator::c_str() const
+    {
+      switch ( solvAttrType() )
+      {
+        case REPOKEY_TYPE_ID:
+        case REPOKEY_TYPE_IDARRAY:
+        case REPOKEY_TYPE_CONSTANTID:
+          if ( _dip->data && _dip->data->localpool )
+            return ::stringpool_id2str( &_dip->data->spool, _dip->kv.id ); // in local pool
+          else
+            return IdString( _dip->kv.id ).c_str(); // in global pool
+          break;
+
+        case REPOKEY_TYPE_STR:
+          return _dip->kv.str;
+          break;
+
+        case REPOKEY_TYPE_DIRSTRARRAY:
+          return ::repodata_dir2str( _dip->data, _dip->kv.id, _dip->kv.str );
+          break;
+      }
+      return 0;
+    }
+
+    std::string LookupAttr::iterator::asString() const
+    {
+      switch ( solvAttrType() )
+      {
+        case REPOKEY_TYPE_ID:
+        case REPOKEY_TYPE_IDARRAY:
+        case REPOKEY_TYPE_CONSTANTID:
+        case REPOKEY_TYPE_STR:
+        case REPOKEY_TYPE_DIRSTRARRAY:
+          {
+            const char * ret( c_str() );
+            return ret ? ret : "";
+          }
+          break;
+
+        case REPOKEY_TYPE_U32:
+        case REPOKEY_TYPE_NUM:
+        case REPOKEY_TYPE_CONSTANT:
+          return str::numstring( asInt() );
+          break;
+
+        case REPOKEY_TYPE_MD5:
+        case REPOKEY_TYPE_SHA1:
+        case REPOKEY_TYPE_SHA256:
+          {
+            std::ostringstream str;
+            str << asCheckSum();
+            return str.str();
+          }
+          break;
+      }
+     return std::string();
+    }
+
+    IdString LookupAttr::iterator::idStr() const
+    {
+      switch ( solvAttrType() )
+      {
+        case REPOKEY_TYPE_ID:
+        case REPOKEY_TYPE_IDARRAY:
+        case REPOKEY_TYPE_CONSTANTID:
+          return IdString( ::repodata_globalize_id( _dip->data, _dip->kv.id ) );
+          break;
+      }
+      return IdString();
+    }
+
+    CheckSum LookupAttr::iterator::asCheckSum() const
+    {
+      switch ( solvAttrType() )
+      {
+        case REPOKEY_TYPE_MD5:
+          return CheckSum::md5( ::repodata_chk2str( _dip->data, solvAttrType(), (unsigned char *)_dip->kv.str ) );
+          break;
+
+        case REPOKEY_TYPE_SHA1:
+          return CheckSum::sha1( ::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;
+      }
+      return CheckSum();
+    }
+
+    ///////////////////////////////////////////////////////////////////
     // internal stuff below
     ///////////////////////////////////////////////////////////////////
 
+    LookupAttr::iterator::~iterator()
+    {}
+
+    LookupAttr::iterator::iterator()
+    : iterator_adaptor_( 0 )
+    {}
+
+    LookupAttr::iterator::iterator( const iterator & rhs )
+    : iterator_adaptor_( cloneFrom( rhs.base() ) )
+    , _dip( base() )
+    {}
+
+    LookupAttr::iterator & LookupAttr::iterator::operator=( const iterator & rhs )
+    {
+      if ( &rhs != this )
+      {
+        _dip.reset( cloneFrom( rhs.base() ) );
+        base_reference() = _dip.get();
+      }
+      return *this;
+    }
+
+    LookupAttr::iterator::iterator( scoped_ptr< ::_Dataiterator> & dip_r, bool chain_r )
+    : iterator_adaptor_( dip_r.get() )
+    , _chainRepos( chain_r )
+    {
+      _dip.swap( dip_r ); // take ownership!
+      increment();
+    }
+
+    ///////////////////////////////////////////////////////////////////
+
     ::_Dataiterator * LookupAttr::iterator::cloneFrom( const ::_Dataiterator * rhs )
     {
       if ( ! rhs )
@@ -163,10 +378,13 @@ namespace zypp
       if ( ! dip )
         return str << "EndOfQuery" << endl;
 
-      str << obj.inSolvable()
-          << '<' << obj.inSolvAttr()
-          << "> = " << obj.solvAttrType()
-          << "(" <<  dip->kv.id << ")" << (dip->data && dip->data->localpool ? "*" : "" );
+      if ( obj.inSolvable() )
+        str << obj.inSolvable();
+      else if ( obj.inRepo() )
+        str << obj.inRepo();
+
+      str << '<' << obj.inSolvAttr()
+          << ">(" <<  obj.solvAttrType() << ") = " << obj.asString();
       return str;
     }
 
index 1a3f132..89f1ae7 100644 (file)
@@ -20,6 +20,7 @@ struct _Dataiterator;
 
 #include "zypp/base/PtrTypes.h"
 #include "zypp/base/DefaultIntegral.h"
+
 #include "zypp/sat/Pool.h"
 
 ///////////////////////////////////////////////////////////////////
@@ -33,17 +34,40 @@ namespace zypp
     //
     // CLASS NAME : LookupAttr
     //
-    /** Lightweight attribute lookup.
+    /** Lightweight attribute value lookup.
      *
-     * Search for an attribute \ref Pool, one \ref Repository or
-     * one \ref Solvable. \ref LookupAttr builds the query,
+     * Search for an attribute in \ref Pool, one \ref Repository
+     * or one \ref Solvable. \ref LookupAttr builds the query,
      * \ref LookupAttr::iterator iterates over the result.
      *
      * Modifying the query will not affect any running
      * iterator.
      *
      * Use \ref SolvAttr::allAttr to search all attributes.
-    */
+     *
+     * \code
+     *  // look for all attributes of one solvable
+     *  void ditest( sat::Solvable slv_r )
+     *  {
+     *    sat::LookupAttr q( sat::SolvAttr::allAttr, slv_r );
+     *    MIL << q << ": " << endl;
+     *    for_( it, q.begin(), q.end() )
+     *    {
+     *      MIL << "    " << it.inSolvAttr() << " = " << it.asString() << endl;
+     *    }
+     *  }
+     * \endcode
+     *
+     * \code
+     *  // look for an attribute in the pool.
+     *  sat::LookupAttr q( sat::SolvAttr("susetags:datadir") );
+     *  MIL << q << ": " << endl;
+     *  for_( it, q.begin(), q.end() )
+     *  {
+     *    MIL << "    " << it << endl;
+     *  }
+     * \endcode
+     */
     class LookupAttr
     {
       public:
@@ -77,7 +101,13 @@ namespace zypp
         /** Iterator behind the end of query results. */
         iterator end() const;
 
+        /** Whether the query is empty. */
+        bool empty() const;
+
+        /** TransformIterator returning an \ref iterator vaue of type \c _ResultT. */
+        template<class _ResultT, class _AttrT> class transformIterator;
         //@}
+
       public:
         /** \name What to search. */
         //@{
@@ -192,46 +222,74 @@ namespace zypp
 
         /** The current \ref SolvAttr. */
         SolvAttr inSolvAttr() const;
+        //@}
 
+        /** \name Test attribute value type. */
+        //@{
         /** The current \ref SolvAttr type. */
         detail::IdType solvAttrType() const;
+
+        /** Whether this is a numeric attribute (incl. boolean). */
+        bool solvAttrNumeric() const;
+
+        /** Whether this is a string attribute. */
+        bool solvAttrString() const;
+
+        /** *Whether this string attribute is available as \ref IdString. */
+        bool solvAttrIdString() const;
+
+        /** Whether this is a CheckSum attribute.*/
+        bool solvAttrCheckSum() const;
         //@}
 
         /** \name Retrieving attribute values. */
         //@{
+        /** Conversion to numeric types. */
+        int asInt() const;
+        /** \overload */
+        unsigned asUnsigned() const;
+        /** \overload */
+        bool asBool() const;
+
+        /** Conversion to string types. */
+        const char * c_str() const;
+        /** \overload
+         * If used with non-string types, this method tries to create
+         * some appropriate string representation.
+        */
+        std::string asString() const;
+
+        /** As \ref IdStr.
+         * This is only done for poolized string types. Large strings like
+         * summary or descriptions are not available via \ref IdStr, only
+         * via \ref c_str and \ref asString.
+         */
+        IdString idStr() const;
+
+        /** As \ref CheckSum. */
+        CheckSum asCheckSum() const;
+
+        /** Templated return type.
+         * Specialized for supported types.
+        */
+        template<class _Tp> _Tp asType() const;
         //@}
+
         ///////////////////////////////////////////////////////////////////
         // internal stuff below
         ///////////////////////////////////////////////////////////////////
       public:
-        iterator()
-        : iterator_adaptor_( 0 )
-        {}
+        iterator();
 
-        iterator( const iterator & rhs )
-        : iterator_adaptor_( cloneFrom( rhs.base() ) )
-        , _dip( base() )
-        {}
+        iterator( const iterator & rhs );
 
-        iterator & operator=( const iterator & rhs )
-        {
-          if ( &rhs != this )
-          {
-            _dip.reset( cloneFrom( rhs.base() ) );
-            base_reference() = _dip.get();
-          }
-          return *this;
-        }
+        iterator & operator=( const iterator & rhs );
+
+        ~iterator();
 
       private:
         friend class LookupAttr;
-        iterator( scoped_ptr< ::_Dataiterator> & dip_r, bool chain_r )
-        : iterator_adaptor_( dip_r.get() )
-        , _chainRepos( chain_r )
-        {
-          _dip.swap( dip_r ); // take ownership!
-          increment();
-        }
+        iterator( scoped_ptr< ::_Dataiterator> & dip_r, bool chain_r );
 
         ::_Dataiterator * cloneFrom( const ::_Dataiterator * rhs );
 
@@ -264,6 +322,178 @@ namespace zypp
     /** \relates LookupAttr::iterator Stream output. */
     std::ostream & operator<<( std::ostream & str, const LookupAttr::iterator & obj );
 
+    template<> inline int          LookupAttr::iterator::asType<int>()          const { return asInt(); }
+    template<> inline unsigned     LookupAttr::iterator::asType<unsigned>()     const { return asUnsigned(); }
+    template<> inline bool         LookupAttr::iterator::asType<bool>()         const { return asBool(); }
+    template<> inline const char * LookupAttr::iterator::asType<const char *>() const { return c_str(); }
+    template<> inline std::string  LookupAttr::iterator::asType<std::string>()  const { return asString(); }
+    template<> inline IdString     LookupAttr::iterator::asType<IdString>()     const { return idStr(); }
+
+    ///////////////////////////////////////////////////////////////////
+    //
+    // CLASS NAME : LookupAttr::transformIterator
+    //
+    /** TransformIterator returning an \ref iterator value of type \c _ResultT.
+     *
+     * The underlying LookupAttr::iterators value is retrieved \ref asType<_AttrT>
+     * and the returned \ref ResultT is constructed fron that value.
+     *
+     * \code
+     *   class Keywords
+     *   {
+     *     public:
+     *       Keywords( sat::Solvable solv_r )
+     *       : _q( sat::SolvAttr::keywords, solv_r )
+     *       {}
+     *
+     *     public:
+     *       typedef sat::LookupAttr::transformIterator<PackageKeyword,IdString> iterator;
+     *
+     *       iterator begin() const { return iterator( _q.begin() ); }
+     *       iterator end() const   { return iterator( _q.end() ); }
+     *
+     *     private:
+     *       sat::LookupAttr _q;
+     *   };
+     * \endcode
+     *
+     * \see \ref ArrayAttr.
+     */
+    template<class _ResultT, class _AttrT>
+    class LookupAttr::transformIterator : public boost::iterator_adaptor<
+          transformIterator<_ResultT,_AttrT> // Derived
+          , LookupAttr::iterator         // Base
+          , _ResultT                     // Value
+          , boost::forward_traversal_tag // CategoryOrTraversal
+          , _ResultT                     // Reference
+    >
+    {
+      public:
+        transformIterator()
+        {}
+
+        explicit
+        transformIterator( const LookupAttr::iterator & val_r )
+        { this->base_reference() = val_r; }
+
+      public:
+
+        /** \name Moving fast forward. */
+        //@{
+        /** On the next call to \ref operator++ advance to the next \ref SolvAttr. */
+        void nextSkipSolvAttr()
+        { this->base_reference().nextSkipSolvAttr(); }
+
+        /** On the next call to \ref operator++ advance to the next \ref Solvable. */
+        void nextSkipSolvable()
+        { this->base_reference().nextSkipSolvable(); }
+
+        /** On the next call to \ref operator++ advance to the next \ref Repository. */
+        void nextSkipRepo()
+        { this->base_reference().nextSkipRepo(); }
+
+        /** Immediately advance to the next \ref SolvAttr. */
+        void skipSolvAttr()
+        { this->base_reference().skipSolvAttr(); }
+
+        /** Immediately advance to the next \ref Solvable. */
+        void skipSolvable()
+        { this->base_reference().skipSolvable(); }
+
+        /** Immediately advance to the next \ref Repository. */
+        void skipRepo()
+        { this->base_reference().skipRepo(); }
+        //@}
+
+        /** \name Current position info. */
+        //@{
+        /** The current \ref Repository. */
+        Repository inRepo() const
+        { return this->base_reference().inRepo(); }
+
+        /** The current \ref Solvabele. */
+        Solvable inSolvable() const
+        { return this->base_reference().inSolvable(); }
+
+        /** The current \ref SolvAttr. */
+        SolvAttr inSolvAttr() const
+        { return this->base_reference().inSolvAttr(); }
+        //@}
+
+      private:
+        friend class boost::iterator_core_access;
+
+        _ResultT dereference() const
+        {
+          const LookupAttr::iterator lit( this->base_reference() );
+          return _ResultT( lit.asType<_AttrT>() );
+        }
+    };
+    ///////////////////////////////////////////////////////////////////
+
+    template<class _ResultT, class _AttrT>
+    class ArrayAttr;
+
+    template<class _ResultT, class _AttrT>
+    std::ostream & operator<<( std::ostream & str, const ArrayAttr<_ResultT,_AttrT> & obj );
+
+    ///////////////////////////////////////////////////////////////////
+    //
+    // CLASS NAME : ArrayAttr
+    //
+    /** \ref LookupAttr::transformIterator based container to retrieve list attributes.
+     *
+     * \code
+     *  typedef ArrayAttr<PackageKeyword,IdString> Keywords;
+     *  Keywords k( sat::SolvAttr::keywords );
+     *  dumpRange( MIL << "All Keywords: ", k.begin(), k.end() ) << endl;
+     * \endcode
+     *
+     * \todo Maybe add some way to unify the result.
+     */
+    template<class _ResultT, class _AttrT>
+    class ArrayAttr
+    {
+      friend std::ostream & operator<< <_ResultT,_AttrT>( std::ostream & str, const ArrayAttr<_ResultT,_AttrT> & obj );
+
+      public:
+        ArrayAttr()
+        {}
+
+        ArrayAttr( SolvAttr attr_r )
+        : _q( attr_r )
+        {}
+
+        ArrayAttr( SolvAttr attr_r, Repository repo_r )
+        : _q( attr_r, repo_r )
+        {}
+
+        ArrayAttr( SolvAttr attr_r, Solvable solv_r )
+        : _q( attr_r, solv_r )
+        {}
+
+      public:
+        typedef sat::LookupAttr::transformIterator<_ResultT,_AttrT> iterator;
+
+        iterator begin() const
+        { return iterator( _q.begin() ); }
+
+        iterator end() const
+        { return iterator( _q.end() ); }
+
+        bool empty() const
+        { return _q.empty(); }
+
+      private:
+        sat::LookupAttr _q;
+    };
+    ///////////////////////////////////////////////////////////////////
+
+    /** \relates LookupAttr::iterator Stream output. */
+    template<class _ResultT, class _AttrT>
+    inline std::ostream & operator<<( std::ostream & str, const ArrayAttr<_ResultT,_AttrT> & obj )
+    { return dumpOn( str, obj._q); }
+
     /////////////////////////////////////////////////////////////////
   } // namespace sat
   ///////////////////////////////////////////////////////////////////
index 910ea88..612e524 100644 (file)
@@ -26,6 +26,7 @@ extern "C"
 
 #include "zypp/sat/detail/PoolImpl.h"
 #include "zypp/sat/Pool.h"
+#include "zypp/sat/LookupAttr.h"
 
 ///////////////////////////////////////////////////////////////////
 namespace zypp
index e3fc92e..07e39be 100644 (file)
@@ -86,6 +86,11 @@ namespace zypp
 
       public:
 
+        /** \name Attribute lookup.
+         * \see \ref LookupAttr and  \ref ArrayAttr providing a general, more
+         * query like interface for attribute retrieval.
+        */
+        //@{
         /**
          * returns the string attribute value for \ref attr
          * or an empty string if it does not exists.
@@ -121,8 +126,6 @@ namespace zypp
          */
         detail::IdType lookupIdAttribute( const SolvAttr & attr ) const;
 
-
-
        /**
          * returns the CheckSum attribute value for \ref attr
          * or an empty CheckSum if ir does not exist.
@@ -135,6 +138,7 @@ namespace zypp
          */
         OnMediaLocation lookupLocation() const;
 
+        //@}
       public:
         /** The identifier.
          * This is the solvables \ref name, \b except for packages and
@@ -177,7 +181,7 @@ namespace zypp
         /** Returns true if the solvable is satisfied */
         bool isSatisfied() const;
         /** Returns true if the solvable is satisfied */
-        bool isBroken() const { return !isSatisfied(); }       
+        bool isBroken() const { return !isSatisfied(); }
 
       public:
         /** \name Locale support. */