00001
00002
00003
00004
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
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 )
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
00066 return true;
00067 break;
00068 case 1:
00069
00070 return _archStr == targetEntry_r._archStr;
00071 break;
00072 }
00073
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
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
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
00188
00189
00190 _compatSet.insert( Arch::CompatEntry( _noarch, 0 ) );
00192
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 );
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 }
00281
00283
00284 static const string canonical_arch (const string & arch);
00285
00286
00287
00288
00289 static const string
00290 canonical_arch (const string & arch)
00291 {
00292 typedef struct { char *from; char *to; } canonical;
00293
00294 static canonical canonical_archs[] = {
00295 { "noarch", "noarch" },
00296 { "unknown", "unknown" },
00297 { "any", "any" },
00298 { "all", "any" },
00299 { "i386", "i386" },
00300 { "ix86", "i386" },
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
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
00359
00360
00361 Arch::Arch()
00362 : _entry( &ArchCompatSet::instance().assertDef( _noarch ) )
00363 { assert( _entry ); }
00364
00366
00367
00368
00369
00370 Arch::Arch( const std::string & rhs )
00371 : _entry( &ArchCompatSet::instance().assertDef( rhs ) )
00372 { assert( _entry ); }
00373
00375
00376
00377
00378
00379 Arch::Arch( const CompatEntry & rhs )
00380 : _entry( &rhs )
00381 { assert( _entry ); }
00382
00384
00385
00386
00387
00388 const std::string & Arch::asString() const
00389 { return _entry->_archStr; }
00390
00392
00393
00394
00395
00396 bool Arch::compatibleWith( const Arch & targetArch_r ) const
00397 { return _entry->compatibleWith( *targetArch_r._entry ); }
00398
00400
00401
00402
00403
00404 int Arch::compare( const Arch & rhs ) const
00405 { return _entry->compare( *rhs._entry ); }
00406
00408
00409
00410
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 }