Arch.cc

Go to the documentation of this file.
00001 /*---------------------------------------------------------------------\
00002 |                          ____ _   __ __ ___                          |
00003 |                         |__  / \ / / . \ . \                         |
00004 |                           / / \ V /|  _/  _/                         |
00005 |                          / /__ | | | | | |                           |
00006 |                         /_____||_| |_| |_|                           |
00007 |                                                                      |
00008 \---------------------------------------------------------------------*/
00012 #include <iostream>
00013 #include <set>
00014 
00015 #include "zypp/base/Logger.h"
00016 #include "zypp/base/NonCopyable.h"
00017 #include "zypp/Arch.h"
00018 #include "zypp/Bit.h"
00019 
00020 using namespace std;
00021 
00023 namespace zypp
00024 { 
00025 
00027   //
00028   //    CLASS NAME : Arch::CompatEntry
00029   //
00035   struct Arch::CompatEntry
00036   {
00040     typedef bit::BitField<uint16_t> CompatBits;
00041 
00042     CompatEntry( const std::string & archStr_r,
00043                  CompatBits::IntT idBit_r = CompatBits::IntT(1) )
00044     : _archStr( archStr_r )
00045     , _idBit( idBit_r )
00046     , _compatBits( idBit_r )
00047     , _compatScore( idBit_r ? 1 : 0 ) // number of compatible archs
00048     {}
00049 
00050     void addCompatBit( const CompatBits & idBit_r ) const
00051     {
00052       if ( idBit_r && ! (_compatBits & idBit_r) )
00053         {
00054           _compatBits |= idBit_r;
00055           ++_compatScore;
00056         }
00057     }
00058 
00060     bool compatibleWith( const CompatEntry & targetEntry_r ) const
00061     {
00062       switch ( _idBit.value() )
00063         {
00064         case 0:
00065           // this is noarch and always comatible
00066           return true;
00067           break;
00068         case 1:
00069           // this is a non builtin: self compatible only
00070           return _archStr == targetEntry_r._archStr;
00071           break;
00072         }
00073       // This is a builtin: comatible if mentioned in targetEntry_r
00074       return targetEntry_r._compatBits & _idBit;
00075     }
00076 
00078     int compare( const CompatEntry & rhs ) const
00079     {
00080       if ( _compatScore != rhs._compatScore )
00081         return( _compatScore < rhs._compatScore ? -1 : 1 );
00082       return _archStr.compare( rhs._archStr );
00083     }
00084 
00085     std::string         _archStr;
00086     CompatBits          _idBit;
00087     mutable CompatBits  _compatBits;
00088     mutable unsigned    _compatScore;
00089   };
00091 
00093   inline std::ostream & operator<<( std::ostream & str, const Arch::CompatEntry & obj )
00094   {
00095     return str << obj._archStr << '\t' << obj._idBit << ' '
00096                << obj._compatBits << ' ' << obj._compatScore;
00097   }
00098 
00102   inline bool operator<( const Arch::CompatEntry & lhs, const Arch::CompatEntry & rhs )
00103   { return lhs._archStr < rhs._archStr; }
00104 
00106   namespace
00107   { 
00108 
00109     // builtin architecture STRING VALUES
00110 #define DEF_BUILTIN(A) const std::string  _##A( #A )
00111 
00112     DEF_BUILTIN( noarch );
00113 
00114     DEF_BUILTIN( i386 );
00115     DEF_BUILTIN( i486 );
00116     DEF_BUILTIN( i586 );
00117     DEF_BUILTIN( i686 );
00118     DEF_BUILTIN( athlon );
00119     DEF_BUILTIN( x86_64 );
00120 
00121     DEF_BUILTIN( ia64 );
00122 
00123     DEF_BUILTIN( s390 );
00124     DEF_BUILTIN( s390x );
00125 
00126     DEF_BUILTIN( ppc );
00127     DEF_BUILTIN( ppc64 );
00128 
00129 #undef DEF_BUILTIN
00130 
00132     //
00133     //  CLASS NAME : CompatSet
00134     //
00142     struct ArchCompatSet : private base::NonCopyable
00143     {
00144       typedef Arch::CompatEntry       CompatEntry;
00145       typedef CompatEntry::CompatBits CompatBits;
00146 
00147       typedef std::set<CompatEntry>   Set;
00148       typedef Set::iterator           iterator;
00149       typedef Set::const_iterator     const_iterator;
00150 
00152       static ArchCompatSet & instance()
00153       {
00154         static ArchCompatSet _instance;
00155         return _instance;
00156       }
00157 
00161       const Arch::CompatEntry & assertDef( const std::string & archStr_r )
00162       {
00163         return *_compatSet.insert( Arch::CompatEntry( archStr_r )
00164                                  ).first;
00165       }
00166 
00167       const_iterator begin() const
00168       { return _compatSet.begin(); }
00169 
00170       const_iterator end() const
00171       { return _compatSet.end(); }
00172 
00173       std::ostream & dumpOn( std::ostream & str ) const
00174       {
00175         str << "ArchCompatSet:";
00176         for ( const_iterator it = _compatSet.begin(); it != _compatSet.end(); ++it )
00177           {
00178             str << endl << ' ' << *it;
00179           }
00180         return str;
00181       }
00182 
00183     private:
00185       ArchCompatSet()
00186       {
00187         // _noarch must have _idBit 0.
00188         // Other builtins have 1-bit set
00189         // and are intiialized done on the fly.
00190         _compatSet.insert( Arch::CompatEntry( _noarch, 0 ) );
00192         // Define the CompatibleWith relation:
00193         //
00194         defCompatibleWith( _noarch,     _i386 );
00195 
00196         defCompatibleWith( _noarch,     _i486 );
00197         defCompatibleWith( _i386,       _i486 );
00198 
00199         defCompatibleWith( _noarch,     _i586 );
00200         defCompatibleWith( _i386,       _i586 );
00201         defCompatibleWith( _i486,       _i586 );
00202 
00203         defCompatibleWith( _noarch,     _i686 );
00204         defCompatibleWith( _i386,       _i686 );
00205         defCompatibleWith( _i486,       _i686 );
00206         defCompatibleWith( _i586,       _i686 );
00207 
00208         defCompatibleWith( _noarch,     _athlon );
00209         defCompatibleWith( _i386,       _athlon );
00210         defCompatibleWith( _i486,       _athlon );
00211         defCompatibleWith( _i586,       _athlon );
00212         defCompatibleWith( _i686,       _athlon );
00213 
00214         defCompatibleWith( _noarch,     _x86_64 );
00215         defCompatibleWith( _i386,       _x86_64 );
00216         defCompatibleWith( _i486,       _x86_64 );
00217         defCompatibleWith( _i586,       _x86_64 );
00218         defCompatibleWith( _i686,       _x86_64 );
00219         defCompatibleWith( _athlon,     _x86_64 );
00220 
00222         defCompatibleWith( _noarch,     _ia64 );
00223         defCompatibleWith( _i386,       _ia64 );
00224         defCompatibleWith( _i486,       _ia64 );
00225         defCompatibleWith( _i586,       _ia64 );
00226         defCompatibleWith( _i686,       _ia64 );
00227 
00229         defCompatibleWith( _noarch,     _s390 );
00230 
00231         defCompatibleWith( _noarch,     _s390x );
00232         defCompatibleWith( _s390,       _s390x );
00233 
00235         defCompatibleWith( _noarch,     _ppc );
00236 
00237         defCompatibleWith( _noarch,     _ppc64 );
00238         defCompatibleWith( _ppc,        _ppc64 );
00239         //
00241       }
00242 
00243     private:
00249       CompatBits::IntT nextIdBit() const
00250       {
00251         CompatBits::IntT nextBit = 1 << (_compatSet.size());
00252         assert( nextBit ); // need more bits in CompatBits::IntT
00253         return nextBit;
00254       }
00255 
00259       const CompatEntry & assertCompatSetEntry( const std::string & archStr_r )
00260       {
00261         return *_compatSet.insert( Arch::CompatEntry( archStr_r, nextIdBit() )
00262                                  ).first;
00263       }
00264 
00267       void defCompatibleWith( const std::string & arch_r, const std::string & targetArch_r )
00268       {
00269         const CompatEntry & arch  ( assertCompatSetEntry( arch_r ) );
00270         const CompatEntry & target( assertCompatSetEntry( targetArch_r ) );
00271         target.addCompatBit( arch._idBit );
00272       }
00273 
00274     private:
00275       Set _compatSet;
00276     };
00277 
00279   } // namespace
00281 
00283 
00284   static const string canonical_arch (const string & arch);
00285 
00286   //---------------------------------------------------------------------------
00287   // architecture stuff
00288 
00289   static const string
00290   canonical_arch (const string & arch)
00291   {
00292     typedef struct { char *from; char *to; } canonical;
00293     // convert machine string to known_arch
00294     static canonical canonical_archs[] = {
00295       { "noarch",  "noarch" },
00296       { "unknown", "unknown" },
00297       { "any",     "any" },
00298       { "all",     "any" },
00299       { "i386",    "i386" },
00300       { "ix86",    "i386" }, /* OpenPKG uses this */
00301       { "i486",    "i486" },
00302       { "i586",    "i586" },
00303       { "i686",    "i686" },
00304       { "x86_64",  "x86_64" },
00305       { "ia32e",   "ia32e" },
00306       { "athlon",  "athlon" },
00307       { "ppc",     "ppc" },
00308       { "ppc64",   "ppc64" },
00309       { "s390",    "s390" },
00310       { "s390x",   "s390x" },
00311       { "ia64",    "ia64" },
00312       { "sparc",   "sparc" },
00313       { "sun4c",   "sparc" },
00314       { "sun4d",   "sparc" },
00315       { "sun4m",   "sparc" },
00316       { "sparc64", "sparc64" },
00317       { "sun4u",   "sparc64" },
00318       { "sparcv9", "sparc64" },
00319       { 0 }
00320     };
00321 
00322     for (canonical *ptr = canonical_archs; ptr->from; ptr++) {
00323       if (arch == ptr->from) {
00324         return ptr->to;
00325       }
00326     }
00327 
00328     return "canonical";
00329   }
00330 
00331   //---------------------------------------------------------------------------
00332 
00334   //
00335   //    CLASS NAME : Arch
00336   //
00338 
00339   const Arch Arch_noarch( _noarch );
00340 
00341   const Arch Arch_x86_64( _x86_64 );
00342   const Arch Arch_athlon( _athlon );
00343   const Arch Arch_i686  ( _i686 );
00344   const Arch Arch_i586  ( _i586 );
00345   const Arch Arch_i486  ( _i486 );
00346   const Arch Arch_i386  ( _i386 );
00347 
00348   const Arch Arch_s390x ( _s390x );
00349   const Arch Arch_s390  ( _s390 );
00350 
00351   const Arch Arch_ppc64 ( _ppc64 );
00352   const Arch Arch_ppc   ( _ppc );
00353 
00354   const Arch Arch_ia64  ( _ia64 );
00355 
00357   //
00358   //    METHOD NAME : Arch::Arch
00359   //    METHOD TYPE : Ctor
00360   //
00361   Arch::Arch()
00362   : _entry( &ArchCompatSet::instance().assertDef( _noarch ) )
00363   { assert( _entry ); }
00364 
00366   //
00367   //    METHOD NAME : Arch::Arch
00368   //    METHOD TYPE : Ctor
00369   //
00370   Arch::Arch( const std::string & rhs )
00371   : _entry( &ArchCompatSet::instance().assertDef( rhs ) )
00372   { assert( _entry ); }
00373 
00375   //
00376   //    METHOD NAME : Arch::Arch
00377   //    METHOD TYPE : Ctor
00378   //
00379   Arch::Arch( const CompatEntry & rhs )
00380   : _entry( &rhs )
00381   { assert( _entry ); }
00382 
00384   //
00385   //    METHOD NAME : Arch::asString
00386   //    METHOD TYPE : const std::string &
00387   //
00388   const std::string & Arch::asString() const
00389   { return _entry->_archStr; }
00390 
00392   //
00393   //    METHOD NAME : Arch::compatibleWith
00394   //    METHOD TYPE : bool
00395   //
00396   bool Arch::compatibleWith( const Arch & targetArch_r ) const
00397   { return _entry->compatibleWith( *targetArch_r._entry ); }
00398 
00400   //
00401   //    METHOD NAME : Arch::compare
00402   //    METHOD TYPE : bool
00403   //
00404   int Arch::compare( const Arch & rhs ) const
00405   { return _entry->compare( *rhs._entry ); }
00406 
00408   //
00409   //    METHOD NAME : Arch::compatSet
00410   //    METHOD TYPE : Arch::CompatSet
00411   //
00412   Arch::CompatSet Arch::compatSet( const Arch & targetArch_r )
00413   {
00414     Arch::CompatSet ret;
00415 
00416     for ( ArchCompatSet::const_iterator it = ArchCompatSet::instance().begin();
00417           it != ArchCompatSet::instance().end(); ++it )
00418       {
00419         if ( it->compatibleWith( *targetArch_r._entry ) )
00420           {
00421             ret.insert( Arch(*it) );
00422           }
00423       }
00424 
00425     return ret;
00426   }
00427 
00428 
00430 } // namespace zypp

Generated on Thu Jul 6 00:07:20 2006 for zypp by  doxygen 1.4.6