libzypp
10.5.0
|
00001 /*---------------------------------------------------------------------\ 00002 | ____ _ __ __ ___ | 00003 | |__ / \ / / . \ . \ | 00004 | / / \ V /| _/ _/ | 00005 | / /__ | | | | | | | 00006 | /_____||_| |_| |_| | 00007 | | 00008 \---------------------------------------------------------------------*/ 00012 #include <iostream> 00013 #include <list> 00014 #include <inttypes.h> 00015 00016 #include "zypp/base/Logger.h" 00017 #include "zypp/base/Exception.h" 00018 #include "zypp/base/NonCopyable.h" 00019 #include "zypp/base/Tr1hash.h" 00020 #include "zypp/Arch.h" 00021 #include "zypp/Bit.h" 00022 00023 using std::endl; 00024 00026 namespace zypp 00027 { 00028 00030 // 00031 // CLASS NAME : Arch::CompatEntry 00032 // 00038 struct Arch::CompatEntry 00039 { 00044 typedef bit::BitField<uint64_t> CompatBits; 00045 00046 CompatEntry( const std::string & archStr_r, 00047 CompatBits::IntT idBit_r = 1 ) 00048 : _idStr( archStr_r ) 00049 , _archStr( archStr_r ) 00050 , _idBit( idBit_r ) 00051 , _compatBits( idBit_r ) 00052 {} 00053 00054 CompatEntry( IdString archStr_r, 00055 CompatBits::IntT idBit_r = 1 ) 00056 : _idStr( archStr_r ) 00057 , _archStr( archStr_r.asString() ) 00058 , _idBit( idBit_r ) 00059 , _compatBits( idBit_r ) 00060 {} 00061 00062 void addCompatBit( const CompatBits & idBit_r ) const 00063 { 00064 if ( idBit_r && ! (_compatBits & idBit_r) ) 00065 { 00066 _compatBits |= idBit_r; 00067 } 00068 } 00069 00071 bool compatibleWith( const CompatEntry & targetEntry_r ) const 00072 { 00073 switch ( _idBit.value() ) 00074 { 00075 case 0: 00076 // this is noarch and always comatible 00077 return true; 00078 break; 00079 case 1: 00080 // this is a non builtin: self compatible only 00081 return _archStr == targetEntry_r._archStr; 00082 break; 00083 } 00084 // This is a builtin: compatible if mentioned in targetEntry_r 00085 return targetEntry_r._compatBits & _idBit; 00086 } 00087 00089 int compare( const CompatEntry & rhs ) const 00090 { 00091 if ( _idBit.value() != rhs. _idBit.value() ) 00092 return( _idBit.value() < rhs. _idBit.value() ? -1 : 1 ); 00093 return _archStr.compare( rhs._archStr ); // Id 1: non builtin 00094 } 00095 00096 bool isBuiltIn() const 00097 { return( _idBit != CompatBits(1) ); } 00098 00099 IdString::IdType id() const 00100 { return _idStr.id(); } 00101 00102 IdString _idStr; 00103 std::string _archStr; // frequently used by the UI so we keep a reference 00104 CompatBits _idBit; 00105 mutable CompatBits _compatBits; 00106 }; 00108 00110 inline std::ostream & operator<<( std::ostream & str, const Arch::CompatEntry & obj ) 00111 { 00112 Arch::CompatEntry::CompatBits bit( obj._idBit ); 00113 unsigned bitnum = 0; 00114 while ( bit ) 00115 { 00116 ++bitnum; 00117 bit >>= 1; 00118 } 00119 return str << str::form( "%-15s ", obj._archStr.c_str() ) << str::numstring(bitnum,2) << ' ' 00120 << obj._compatBits << ' ' << obj._compatBits.value(); 00121 } 00122 00124 inline bool operator==( const Arch::CompatEntry & lhs, const Arch::CompatEntry & rhs ) 00125 { return lhs._idStr == rhs._idStr; } 00127 inline bool operator!=( const Arch::CompatEntry & lhs, const Arch::CompatEntry & rhs ) 00128 { return ! ( lhs == rhs ); } 00129 00131 } // namespace zypp 00133 00134 ZYPP_DEFINE_ID_HASHABLE( zypp::Arch::CompatEntry ); 00135 00137 namespace zypp 00138 { 00139 00141 namespace 00142 { 00143 00144 // Builtin architecture STRING VALUES to be 00145 // used in defCompatibleWith below! 00146 // 00147 // const IdString _foo( "foo" ); 00148 // 00149 // NOTE: Builtin CLASS Arch CONSTANTS are defined below. 00150 // You have to change them accordingly. 00151 // 00152 // NOTE: Thake care CompatBits::IntT is able to provide one 00153 // bit for each architecture. 00154 // 00155 #define DEF_BUILTIN(A) static inline const IdString & _##A () { static IdString __str(#A); return __str; } 00156 DEF_BUILTIN( noarch ); 00157 00158 DEF_BUILTIN( i386 ); 00159 DEF_BUILTIN( i486 ); 00160 DEF_BUILTIN( i586 ); 00161 DEF_BUILTIN( i686 ); 00162 DEF_BUILTIN( athlon ); 00163 DEF_BUILTIN( x86_64 ); 00164 00165 DEF_BUILTIN( pentium3 ); 00166 DEF_BUILTIN( pentium4 ); 00167 00168 DEF_BUILTIN( s390 ); 00169 DEF_BUILTIN( s390x ); 00170 00171 DEF_BUILTIN( ppc ); 00172 DEF_BUILTIN( ppc64 ); 00173 00174 DEF_BUILTIN( ia64 ); 00175 00176 DEF_BUILTIN( alphaev67 ); 00177 DEF_BUILTIN( alphaev6 ); 00178 DEF_BUILTIN( alphapca56 ); 00179 DEF_BUILTIN( alphaev56 ); 00180 DEF_BUILTIN( alphaev5 ); 00181 DEF_BUILTIN( alpha ); 00182 00183 DEF_BUILTIN( sparc64v ); 00184 DEF_BUILTIN( sparcv9v ); 00185 DEF_BUILTIN( sparc64 ); 00186 DEF_BUILTIN( sparcv9 ); 00187 DEF_BUILTIN( sparcv8 ); 00188 DEF_BUILTIN( sparc ); 00189 00190 DEF_BUILTIN( armv7tnhl ); 00191 DEF_BUILTIN( armv7thl ); 00192 DEF_BUILTIN( armv7nhl ); 00193 DEF_BUILTIN( armv7hl ); 00194 DEF_BUILTIN( armv7l ); 00195 DEF_BUILTIN( armv6l ); 00196 DEF_BUILTIN( armv5tejl ); 00197 DEF_BUILTIN( armv5tel ); 00198 DEF_BUILTIN( armv5l ); 00199 DEF_BUILTIN( armv4tl ); 00200 DEF_BUILTIN( armv4l ); 00201 DEF_BUILTIN( armv3l ); 00202 00203 DEF_BUILTIN( sh3 ); 00204 00205 DEF_BUILTIN( sh4 ); 00206 DEF_BUILTIN( sh4a ); 00207 #undef DEF_BUILTIN 00208 00210 // 00211 // CLASS NAME : CompatSet 00212 // 00220 struct ArchCompatSet : private base::NonCopyable 00221 { 00222 typedef Arch::CompatEntry CompatEntry; 00223 typedef CompatEntry::CompatBits CompatBits; 00224 00225 typedef std::tr1::unordered_set<CompatEntry> Set; 00226 typedef Set::iterator iterator; 00227 typedef Set::const_iterator const_iterator; 00228 00230 static ArchCompatSet & instance() 00231 { 00232 static ArchCompatSet _instance; 00233 return _instance; 00234 } 00235 00239 const Arch::CompatEntry & assertDef( const std::string & archStr_r ) 00240 { return *_compatSet.insert( Arch::CompatEntry( archStr_r ) ).first; } 00242 const Arch::CompatEntry & assertDef( IdString archStr_r ) 00243 { return *_compatSet.insert( Arch::CompatEntry( archStr_r ) ).first; } 00244 00245 const_iterator begin() const 00246 { return _compatSet.begin(); } 00247 00248 const_iterator end() const 00249 { return _compatSet.end(); } 00250 00251 struct DumpOnCompare 00252 { 00253 int operator()( const CompatEntry & lhs, const CompatEntry & rhs ) const 00254 { return lhs._idBit.value() < rhs._idBit.value(); } 00255 }; 00256 00257 std::ostream & dumpOn( std::ostream & str ) const 00258 { 00259 str << "ArchCompatSet:"; 00260 std::list<CompatEntry> ov( _compatSet.begin(), _compatSet.end() ); 00261 ov.sort( DumpOnCompare() ); 00262 for_( it, ov.begin(), ov.end() ) 00263 { 00264 str << endl << ' ' << *it; 00265 } 00266 return str; 00267 } 00268 00269 private: 00271 ArchCompatSet() 00272 { 00273 // _noarch must have _idBit 0. 00274 // Other builtins have 1-bit set 00275 // and are initialized done on the fly. 00276 _compatSet.insert( Arch::CompatEntry( _noarch(), 0 ) ); 00278 // Define the CompatibleWith relation: 00279 // 00280 // NOTE: Order of definition is significant! (Arch::compare) 00281 // - define compatible (less) architectures first! 00282 // 00283 defCompatibleWith( _i386(), _noarch() ); 00284 defCompatibleWith( _i486(), _noarch(),_i386() ); 00285 defCompatibleWith( _i586(), _noarch(),_i386(),_i486() ); 00286 defCompatibleWith( _i686(), _noarch(),_i386(),_i486(),_i586() ); 00287 defCompatibleWith( _athlon(), _noarch(),_i386(),_i486(),_i586(),_i686() ); 00288 defCompatibleWith( _x86_64(), _noarch(),_i386(),_i486(),_i586(),_i686(),_athlon() ); 00289 00290 defCompatibleWith( _pentium3(), _noarch(),_i386(),_i486(),_i586(),_i686() ); 00291 defCompatibleWith( _pentium4(), _noarch(),_i386(),_i486(),_i586(),_i686(),_pentium3() ); 00292 00293 defCompatibleWith( _ia64(), _noarch(),_i386(),_i486(),_i586(),_i686() ); 00294 // 00295 defCompatibleWith( _s390(), _noarch() ); 00296 defCompatibleWith( _s390x(), _noarch(),_s390() ); 00297 // 00298 defCompatibleWith( _ppc(), _noarch() ); 00299 defCompatibleWith( _ppc64(), _noarch(),_ppc() ); 00300 // 00301 defCompatibleWith( _alpha(), _noarch() ); 00302 defCompatibleWith( _alphaev5(), _noarch(),_alpha() ); 00303 defCompatibleWith( _alphaev56(), _noarch(),_alpha(),_alphaev5() ); 00304 defCompatibleWith( _alphapca56(), _noarch(),_alpha(),_alphaev5(),_alphaev56() ); 00305 defCompatibleWith( _alphaev6(), _noarch(),_alpha(),_alphaev5(),_alphaev56(),_alphapca56() ); 00306 defCompatibleWith( _alphaev67(), _noarch(),_alpha(),_alphaev5(),_alphaev56(),_alphapca56(),_alphaev6() ); 00307 // 00308 defCompatibleWith( _sparc(), _noarch() ); 00309 defCompatibleWith( _sparcv8(), _noarch(),_sparc() ); 00310 defCompatibleWith( _sparcv9(), _noarch(),_sparc(),_sparcv8() ); 00311 defCompatibleWith( _sparcv9v(), _noarch(),_sparc(),_sparcv8(),_sparcv9() ); 00312 // 00313 defCompatibleWith( _sparc64(), _noarch(),_sparc(),_sparcv8(),_sparcv9() ); 00314 defCompatibleWith( _sparc64v(), _noarch(),_sparc(),_sparcv8(),_sparcv9(),_sparcv9v(),_sparc64() ); 00315 // 00316 defCompatibleWith( _armv3l(), _noarch() ); 00317 defCompatibleWith( _armv4l(), _noarch(),_armv3l() ); 00318 defCompatibleWith( _armv4tl(), _noarch(),_armv3l(),_armv4l() ); 00319 defCompatibleWith( _armv5l(), _noarch(),_armv3l(),_armv4l(),_armv4tl() ); 00320 defCompatibleWith( _armv5tel(), _noarch(),_armv3l(),_armv4l(),_armv4tl(),_armv5l() ); 00321 defCompatibleWith( _armv5tejl(), _noarch(),_armv3l(),_armv4l(),_armv4tl(),_armv5l(),_armv5tel() ); 00322 defCompatibleWith( _armv6l(), _noarch(),_armv3l(),_armv4l(),_armv4tl(),_armv5l(),_armv5tel(),_armv5tejl() ); 00323 defCompatibleWith( _armv7l(), _noarch(),_armv3l(),_armv4l(),_armv4tl(),_armv5l(),_armv5tel(),_armv5tejl(),_armv6l() ); 00324 defCompatibleWith( _armv7hl(), _noarch() ); 00325 defCompatibleWith( _armv7nhl(), _noarch(),_armv7hl() ); 00326 defCompatibleWith( _armv7thl(), _noarch(),_armv7hl() ); 00327 defCompatibleWith( _armv7tnhl(), _noarch(),_armv7hl(),_armv7nhl(),_armv7thl() ); 00328 // 00329 defCompatibleWith( _sh3(), _noarch() ); 00330 // 00331 defCompatibleWith( _sh4(), _noarch() ); 00332 defCompatibleWith( _sh4a(), _noarch(),_sh4() ); 00333 // 00335 // dumpOn( USR ) << endl; 00336 } 00337 00338 private: 00344 CompatBits::IntT nextIdBit() const 00345 { 00346 if ( CompatBits::size == _compatSet.size() ) 00347 { 00348 // Provide more bits in CompatBits::IntT 00349 INT << "Need more than " << CompatBits::size << " bits to encode architectures." << endl; 00350 ZYPP_THROW( Exception("Need more bits to encode architectures.") ); 00351 } 00352 CompatBits::IntT nextBit = CompatBits::IntT(1) << (_compatSet.size()); 00353 return nextBit; 00354 } 00355 00359 const CompatEntry & assertCompatSetEntry( IdString archStr_r ) 00360 { return *_compatSet.insert( Arch::CompatEntry( archStr_r, nextIdBit() ) ).first; } 00361 00364 void defCompatibleWith( IdString targetArch_r, 00365 IdString arch0_r, 00366 IdString arch1_r = IdString(), 00367 IdString arch2_r = IdString(), 00368 IdString arch3_r = IdString(), 00369 IdString arch4_r = IdString(), 00370 IdString arch5_r = IdString(), 00371 IdString arch6_r = IdString(), 00372 IdString arch7_r = IdString(), 00373 IdString arch8_r = IdString(), 00374 IdString arch9_r = IdString() ) 00375 { 00376 const CompatEntry & target( assertCompatSetEntry( targetArch_r ) ); 00377 target.addCompatBit( assertCompatSetEntry( arch0_r )._idBit ); 00378 #define _SETARG(N) if ( arch##N##_r.empty() ) return; target.addCompatBit( assertCompatSetEntry( arch##N##_r )._idBit ) 00379 _SETARG(1); _SETARG(2); _SETARG(3); _SETARG(4); 00380 _SETARG(5); _SETARG(6); _SETARG(7); _SETARG(8); _SETARG(9); 00381 #undef _SETARG 00382 } 00383 00384 private: 00385 Set _compatSet; 00386 }; 00387 00389 } // namespace 00391 00393 // 00394 // CLASS NAME : Arch 00395 // 00397 00398 const Arch Arch_empty ( IdString::Empty ); 00399 const Arch Arch_noarch( _noarch() ); 00400 00401 const Arch Arch_i386( _i386() ); 00402 const Arch Arch_i486( _i486() ); 00403 const Arch Arch_i586( _i586() ); 00404 const Arch Arch_i686( _i686() ); 00405 const Arch Arch_athlon( _athlon() ); 00406 const Arch Arch_x86_64( _x86_64() ); 00407 00408 const Arch Arch_pentium3( _pentium3() ); 00409 const Arch Arch_pentium4( _pentium4() ); 00410 00411 const Arch Arch_s390( _s390() ); 00412 const Arch Arch_s390x( _s390x() ); 00413 00414 const Arch Arch_ppc( _ppc() ); 00415 const Arch Arch_ppc64( _ppc64() ); 00416 00417 const Arch Arch_ia64( _ia64() ); 00418 00419 const Arch Arch_alphaev67( _alphaev67() ); 00420 const Arch Arch_alphaev6( _alphaev6() ); 00421 const Arch Arch_alphapca56( _alphapca56() ); 00422 const Arch Arch_alphaev56( _alphaev56() ); 00423 const Arch Arch_alphaev5( _alphaev5() ); 00424 const Arch Arch_alpha( _alpha() ); 00425 00426 const Arch Arch_sparc64v( _sparc64v() ); 00427 const Arch Arch_sparc64( _sparc64() ); 00428 const Arch Arch_sparcv9v( _sparcv9v() ); 00429 const Arch Arch_sparcv9( _sparcv9() ); 00430 const Arch Arch_sparcv8( _sparcv8() ); 00431 const Arch Arch_sparc( _sparc() ); 00432 00433 const Arch Arch_armv7tnhl( _armv7tnhl() ); 00434 const Arch Arch_armv7thl( _armv7thl() ); 00435 const Arch Arch_armv7nhl ( _armv7nhl() ); 00436 const Arch Arch_armv7hl ( _armv7hl() ); 00437 const Arch Arch_armv7l( _armv7l() ); 00438 const Arch Arch_armv6l( _armv6l() ); 00439 const Arch Arch_armv5tejl( _armv5tejl() ); 00440 const Arch Arch_armv5tel( _armv5tel() ); 00441 const Arch Arch_armv5l( _armv5l() ); 00442 const Arch Arch_armv4tl( _armv4tl() ); 00443 const Arch Arch_armv4l( _armv4l() ); 00444 const Arch Arch_armv3l( _armv3l() ); 00445 00446 const Arch Arch_sh3( _sh3() ); 00447 00448 const Arch Arch_sh4( _sh4() ); 00449 const Arch Arch_sh4a( _sh4a() ); 00450 00452 // 00453 // METHOD NAME : Arch::Arch 00454 // METHOD TYPE : Ctor 00455 // 00456 Arch::Arch() 00457 : _entry( &ArchCompatSet::instance().assertDef( _noarch() ) ) 00458 {} 00459 00460 Arch::Arch( IdString::IdType id_r ) 00461 : _entry( &ArchCompatSet::instance().assertDef( IdString(id_r) ) ) 00462 {} 00463 00464 Arch::Arch( const IdString & idstr_r ) 00465 : _entry( &ArchCompatSet::instance().assertDef( idstr_r ) ) 00466 {} 00467 00468 Arch::Arch( const std::string & str_r ) 00469 : _entry( &ArchCompatSet::instance().assertDef( str_r ) ) 00470 {} 00471 00472 Arch::Arch( const char * cstr_r ) 00473 : _entry( &ArchCompatSet::instance().assertDef( cstr_r ) ) 00474 {} 00475 00476 Arch::Arch( const CompatEntry & rhs ) 00477 : _entry( &rhs ) 00478 {} 00479 00481 // 00482 // METHOD NAME : Arch::idStr 00483 // METHOD TYPE : IdString 00484 // 00485 IdString Arch::idStr() const 00486 { return _entry->_idStr; } 00487 00489 // 00490 // METHOD NAME : Arch::asString 00491 // METHOD TYPE : const std::string & 00492 // 00493 const std::string & Arch::asString() const 00494 { return _entry->_archStr; } 00495 00497 // 00498 // METHOD NAME : Arch::isBuiltIn 00499 // METHOD TYPE : bool 00500 // 00501 bool Arch::isBuiltIn() const 00502 { return _entry->isBuiltIn(); } 00503 00505 // 00506 // METHOD NAME : Arch::compatibleWith 00507 // METHOD TYPE : bool 00508 // 00509 bool Arch::compatibleWith( const Arch & targetArch_r ) const 00510 { return _entry->compatibleWith( *targetArch_r._entry ); } 00511 00513 // 00514 // METHOD NAME : Arch::baseArch 00515 // METHOD TYPE : Arch 00516 // 00517 Arch Arch::baseArch( ) const 00518 { 00519 // check the multilib archs: 00520 if (Arch_x86_64.compatibleWith(*this)) 00521 { 00522 return Arch_x86_64; 00523 } 00524 if (Arch_sparc64v.compatibleWith(*this)) 00525 { 00526 return Arch_sparc64v; 00527 } 00528 if (Arch_sparc64.compatibleWith(*this)) 00529 { 00530 return Arch_sparc64; 00531 } 00532 if (Arch_ppc64.compatibleWith(*this)) 00533 { 00534 return Arch_ppc64; 00535 } 00536 if (Arch_s390x.compatibleWith(*this)) 00537 { 00538 return Arch_s390x; 00539 } 00540 // Here: no multilib; return arch before noarch 00541 CompatSet cset( compatSet( *this ) ); 00542 if ( cset.size() > 2 ) // systemArchitecture, ..., basearch, noarch 00543 { 00544 return *(++cset.rbegin()); 00545 } 00546 return *this; 00547 } 00548 00550 // 00551 // METHOD NAME : Arch::compare 00552 // METHOD TYPE : bool 00553 // 00554 int Arch::compare( const Arch & rhs ) const 00555 { return _entry->compare( *rhs._entry ); } 00556 00558 // 00559 // METHOD NAME : Arch::compatSet 00560 // METHOD TYPE : Arch::CompatSet 00561 // 00562 Arch::CompatSet Arch::compatSet( const Arch & targetArch_r ) 00563 { 00564 Arch::CompatSet ret; 00565 00566 for ( ArchCompatSet::const_iterator it = ArchCompatSet::instance().begin(); 00567 it != ArchCompatSet::instance().end(); ++it ) 00568 { 00569 if ( it->compatibleWith( *targetArch_r._entry ) ) 00570 { 00571 ret.insert( Arch(*it) ); 00572 } 00573 } 00574 00575 return ret; 00576 } 00577 00579 } // namespace zypp