- added some locale support to sat::Solvable.
authorMichael Andres <ma@suse.de>
Mon, 18 Feb 2008 16:40:54 +0000 (16:40 +0000)
committerMichael Andres <ma@suse.de>
Mon, 18 Feb 2008 16:40:54 +0000 (16:40 +0000)
zypp/sat/Pool.h
zypp/sat/Solvable.cc
zypp/sat/Solvable.h

index 0127849..1016ae9 100644 (file)
@@ -19,7 +19,6 @@
 #include "zypp/sat/detail/PoolMember.h"
 #include "zypp/sat/Repo.h"
 #include "zypp/sat/WhatProvides.h"
-#include "zypp/Locale.h"
 
 ///////////////////////////////////////////////////////////////////
 namespace zypp
index b0a87ba..299d7c7 100644 (file)
@@ -14,6 +14,8 @@
 #include "zypp/base/Logger.h"
 #include "zypp/base/Gettext.h"
 #include "zypp/base/Exception.h"
+#include "zypp/base/Function.h"
+#include "zypp/base/Functional.h"
 
 #include "zypp/sat/detail/PoolImpl.h"
 #include "zypp/sat/Solvable.h"
@@ -356,6 +358,122 @@ namespace zypp
                    : Capabilities();
     }
 
+    ///////////////////////////////////////////////////////////////////
+    namespace
+    { /////////////////////////////////////////////////////////////////
+      int invokeOnEachSupportedLocale( Capability cap_r, function<bool (const Locale &)> fnc_r )
+      {
+        CapDetail detail( cap_r );
+        if ( detail.kind() == CapDetail::EXPRESSION )
+        {
+          switch ( detail.capRel() )
+          {
+            case CapDetail::CAP_AND:
+            case CapDetail::CAP_OR:
+                // expand
+            {
+              int res = invokeOnEachSupportedLocale( detail.lhs(), fnc_r );
+              if ( res < 0 )
+                return res; // negative on abort.
+              int res2 = invokeOnEachSupportedLocale( detail.rhs(), fnc_r );
+              if ( res2 < 0 )
+                return -res + res2; // negative on abort.
+              return res + res2;
+            }
+            break;
+
+            case CapDetail::CAP_NAMESPACE:
+              if ( detail.lhs().id() == NAMESPACE_LANGUAGE )
+              {
+                return ( !fnc_r || fnc_r( Locale( IdString(detail.rhs().id()) ) ) ) ? 1 : -1; // negative on abort.
+              }
+              break;
+
+            case CapDetail::REL_NONE:
+            case CapDetail::CAP_WITH:
+              break; // unwanted
+          }
+        }
+        return 0;
+      }
+
+      // return #invocations of fnc_r, negative if fnc_r returned false to indicate abort.
+      inline int invokeOnEachSupportedLocale( Capabilities cap_r, function<bool (const Locale &)> fnc_r )
+      {
+        int cnt = 0;
+        for_( cit, cap_r.begin(), cap_r.end() )
+        {
+          int res = invokeOnEachSupportedLocale( *cit, fnc_r );
+          if ( res < 0 )
+            return -cnt + res; // negative on abort.
+          cnt += res;
+        }
+        return cnt;
+      }
+
+      // Functor returning false if a Locale is in the set.
+      struct NoMatchIn
+      {
+        NoMatchIn( const LocaleSet & locales_r ) : _locales( locales_r ) {}
+
+        bool operator()( const Locale & locale_r ) const
+        {
+          return _locales.find( locale_r ) == _locales.end();
+        }
+
+        const LocaleSet & _locales;
+      };
+
+      template<class _OutputIterator>
+      struct _Collector
+      {
+        _Collector( _OutputIterator iter_r ) : _iter( iter_r ) {}
+
+        template<class _Tp>
+        bool operator()( const _Tp & value_r ) const
+        {
+          *_iter++ = value_r;
+          return true;
+        }
+
+        mutable _OutputIterator _iter;
+      };
+
+      template<class _OutputIterator>
+      inline _Collector<_OutputIterator> Collector( _OutputIterator iter_r )
+      { return _Collector<_OutputIterator>( iter_r ); }
+
+    } /////////////////////////////////////////////////////////////////
+
+    bool Solvable::supportsLocales() const
+    {
+      // false_c stops on 1st Locale.
+      return invokeOnEachSupportedLocale( supplements(), functor::false_c() ) < 0;
+    }
+
+    bool Solvable::supportsLocale( const Locale & locale_r ) const
+    {
+      // not_equal_to stops on == Locale.
+      return invokeOnEachSupportedLocale( supplements(), bind( std::not_equal_to<Locale>(), locale_r, _1 ) ) < 0;
+    }
+
+    bool Solvable::supportsLocale( const LocaleSet & locales_r ) const
+    {
+      if ( locales_r.empty() )
+        return false;
+      // NoMatchIn stops if Locale is included.
+      return invokeOnEachSupportedLocale( supplements(), NoMatchIn(locales_r) ) < 0;
+    }
+
+    bool Solvable::supportsRequestedLocales() const
+    { return supportsLocale( myPool().getRequestedLocales() ); }
+
+    void Solvable::getSupportedLocales( LocaleSet & locales_r ) const
+    {
+      invokeOnEachSupportedLocale( supplements(),
+                                   Collector( std::inserter( locales_r, locales_r.begin() ) ) );
+    }
+
     /******************************************************************
     **
     ** FUNCTION NAME : operator<<
index 42056fc..5a1b738 100644 (file)
@@ -26,6 +26,7 @@
 #include "zypp/Dep.h"
 #include "zypp/Capabilities.h"
 #include "zypp/Capability.h"
+#include "zypp/Locale.h"
 
 ///////////////////////////////////////////////////////////////////
 namespace zypp
@@ -97,12 +98,12 @@ namespace zypp
         * with a subdirectory.
         */
        std::string lookupLocation(unsigned &medianr) const;
-        
+
         /**
          *
          */
         bool lookupBoolAttribute( const SolvAttr &attr ) const;
-        
+
       public:
         /** The identifier.
          * This is the solvables \ref name, \b except for packages and
@@ -142,6 +143,26 @@ namespace zypp
         //@}
 
       public:
+        /** \name Locale support. */
+        //@{
+        /** Whether this \c Solvable claims to support locales. */
+        bool supportsLocales() const;
+        /** Whether this \c Solvable supports a specific \ref Locale. */
+        bool supportsLocale( const Locale & locale_r ) const;
+        /** Whether this \c Solvable supports at least one of the specified locales. */
+        bool supportsLocale( const LocaleSet & locales_r ) const;
+        /** Whether this \c Solvable supports at least one requested locale.
+         * \see \ref Pool::setRequestedLocales
+        */
+        bool supportsRequestedLocales() const;
+        /** Return the supported locales via locales_r. */
+        void getSupportedLocales( LocaleSet & locales_r ) const;
+        /** \overload */
+        LocaleSet getSupportedLocales() const
+        { LocaleSet ret; getSupportedLocales( ret ); return ret; }
+        //@}
+
+      public:
         /** Return next Solvable in \ref Pool (or \ref nosolvable). */
         Solvable nextInPool() const;
         /** Return next Solvable in \ref Repo (or \ref nosolvable). */