1 /*---------------------------------------------------------------------\
3 | |__ / \ / / . \ . \ |
8 \---------------------------------------------------------------------*/
16 #include "zypp/base/Logger.h"
17 #include "zypp/base/Exception.h"
18 #include "zypp/base/NonCopyable.h"
19 #include "zypp/base/Tr1hash.h"
20 #include "zypp/Arch.h"
25 ///////////////////////////////////////////////////////////////////
27 { /////////////////////////////////////////////////////////////////
29 ///////////////////////////////////////////////////////////////////
31 // CLASS NAME : Arch::CompatEntry
33 /** Holds an architecture ID and it's compatible relation.
34 * An architecture is compatibleWith, if it's _idBit is set in
35 * _compatBits. noarch has ID 0, non builtin archs ID 1 and
36 * have to be treated specialy.
38 struct Arch::CompatEntry
40 /** Bitfield for architecture IDs and compatBits relation.
41 * \note Need one bit for each builtin Arch.
42 * \todo Migrate to some infinite BitField
44 typedef bit::BitField<uint64_t> CompatBits;
46 CompatEntry( const std::string & archStr_r,
47 CompatBits::IntT idBit_r = 1 )
49 , _archStr( archStr_r )
51 , _compatBits( idBit_r )
54 CompatEntry( IdString archStr_r,
55 CompatBits::IntT idBit_r = 1 )
57 , _archStr( archStr_r.asString() )
59 , _compatBits( idBit_r )
62 void addCompatBit( const CompatBits & idBit_r ) const
64 if ( idBit_r && ! (_compatBits & idBit_r) )
66 _compatBits |= idBit_r;
70 /** Return whether \c this is compatible with \a targetEntry_r.*/
71 bool compatibleWith( const CompatEntry & targetEntry_r ) const
73 switch ( _idBit.value() )
76 // this is noarch and always comatible
80 // this is a non builtin: self compatible only
81 return _archStr == targetEntry_r._archStr;
84 // This is a builtin: compatible if mentioned in targetEntry_r
85 return bool( targetEntry_r._compatBits & _idBit );
88 /** compare by score, then archStr. */
89 int compare( const CompatEntry & rhs ) const
91 if ( _idBit.value() != rhs. _idBit.value() )
92 return( _idBit.value() < rhs. _idBit.value() ? -1 : 1 );
93 return _archStr.compare( rhs._archStr ); // Id 1: non builtin
96 bool isBuiltIn() const
97 { return( _idBit != CompatBits(1) ); }
99 IdString::IdType id() const
100 { return _idStr.id(); }
103 std::string _archStr; // frequently used by the UI so we keep a reference
105 mutable CompatBits _compatBits;
107 ///////////////////////////////////////////////////////////////////
109 /** \relates Arch::CompatEntry Stream output */
110 inline std::ostream & operator<<( std::ostream & str, const Arch::CompatEntry & obj )
112 Arch::CompatEntry::CompatBits bit( obj._idBit );
119 return str << str::form( "%-15s ", obj._archStr.c_str() ) << str::numstring(bitnum,2) << ' '
120 << obj._compatBits << ' ' << obj._compatBits.value();
123 /** \relates Arch::CompatEntry */
124 inline bool operator==( const Arch::CompatEntry & lhs, const Arch::CompatEntry & rhs )
125 { return lhs._idStr == rhs._idStr; }
126 /** \relates Arch::CompatEntry */
127 inline bool operator!=( const Arch::CompatEntry & lhs, const Arch::CompatEntry & rhs )
128 { return ! ( lhs == rhs ); }
130 /////////////////////////////////////////////////////////////////
132 ///////////////////////////////////////////////////////////////////
134 ZYPP_DEFINE_ID_HASHABLE( zypp::Arch::CompatEntry );
136 ///////////////////////////////////////////////////////////////////
138 { /////////////////////////////////////////////////////////////////
140 // Builtin architecture STRING VALUES to be
141 // used in defCompatibleWith below!
143 // const IdString _foo( "foo" );
144 // const Arch Arch_foo( _foo() );
146 // NOTE: Builtin CLASS Arch CONSTANTS are defined below.
147 // You have to change them accordingly in Arch.h.
149 // NOTE: Thake care CompatBits::IntT is able to provide one
150 // bit for each architecture.
152 #define DEF_BUILTIN(A) \
153 namespace { static inline const IdString & _##A () { static IdString __str(#A); return __str; } } \
154 const Arch Arch_##A( _##A() )
156 DEF_BUILTIN( noarch );
162 DEF_BUILTIN( athlon );
163 DEF_BUILTIN( x86_64 );
165 DEF_BUILTIN( pentium3 );
166 DEF_BUILTIN( pentium4 );
169 DEF_BUILTIN( s390x );
172 DEF_BUILTIN( ppc64 );
173 DEF_BUILTIN( ppc64p7 );
175 DEF_BUILTIN( ppc64le );
179 DEF_BUILTIN( alphaev67 );
180 DEF_BUILTIN( alphaev6 );
181 DEF_BUILTIN( alphapca56 );
182 DEF_BUILTIN( alphaev56 );
183 DEF_BUILTIN( alphaev5 );
184 DEF_BUILTIN( alpha );
186 DEF_BUILTIN( sparc64v );
187 DEF_BUILTIN( sparcv9v );
188 DEF_BUILTIN( sparc64 );
189 DEF_BUILTIN( sparcv9 );
190 DEF_BUILTIN( sparcv8 );
191 DEF_BUILTIN( sparc );
193 DEF_BUILTIN( aarch64 );
194 DEF_BUILTIN( armv7tnhl );
195 DEF_BUILTIN( armv7thl );
196 DEF_BUILTIN( armv7nhl );
197 DEF_BUILTIN( armv7hl );
198 DEF_BUILTIN( armv7l );
199 DEF_BUILTIN( armv6hl );
200 DEF_BUILTIN( armv6l );
201 DEF_BUILTIN( armv5tejl );
202 DEF_BUILTIN( armv5tel );
203 DEF_BUILTIN( armv5l );
204 DEF_BUILTIN( armv4tl );
205 DEF_BUILTIN( armv4l );
206 DEF_BUILTIN( armv3l );
216 DEF_BUILTIN( mipsel );
217 DEF_BUILTIN( mips64 );
218 DEF_BUILTIN( mips64el );
221 ///////////////////////////////////////////////////////////////////
223 { /////////////////////////////////////////////////////////////////
225 ///////////////////////////////////////////////////////////////////
227 // CLASS NAME : CompatSet
229 /** Maintain architecture compatibility (Singleton by the way it is used).
231 * Povides \ref Arch::CompatEntry for \ref Arch. Defines the
232 * compatibleWith relation.
233 * \li \c noarch has _idBit 0
234 * \li \c nonbuiltin archs have _idBit 1
236 struct ArchCompatSet : private base::NonCopyable
238 typedef Arch::CompatEntry CompatEntry;
239 typedef CompatEntry::CompatBits CompatBits;
241 typedef std::tr1::unordered_set<CompatEntry> Set;
242 typedef Set::iterator iterator;
243 typedef Set::const_iterator const_iterator;
245 /** Singleton access. */
246 static ArchCompatSet & instance()
248 static ArchCompatSet _instance;
252 /** Return the entry related to \a archStr_r.
253 * Creates an entry for nonbuiltin archs.
255 const Arch::CompatEntry & assertDef( const std::string & archStr_r )
256 { return *_compatSet.insert( Arch::CompatEntry( archStr_r ) ).first; }
258 const Arch::CompatEntry & assertDef( IdString archStr_r )
259 { return *_compatSet.insert( Arch::CompatEntry( archStr_r ) ).first; }
261 const_iterator begin() const
262 { return _compatSet.begin(); }
264 const_iterator end() const
265 { return _compatSet.end(); }
269 int operator()( const CompatEntry & lhs, const CompatEntry & rhs ) const
270 { return lhs._idBit.value() < rhs._idBit.value(); }
273 std::ostream & dumpOn( std::ostream & str ) const
275 str << "ArchCompatSet:";
276 std::list<CompatEntry> ov( _compatSet.begin(), _compatSet.end() );
277 ov.sort( DumpOnCompare() );
278 for_( it, ov.begin(), ov.end() )
280 str << endl << ' ' << *it;
286 /** Singleton ctor. */
289 // _noarch must have _idBit 0.
290 // Other builtins have 1-bit set
291 // and are initialized done on the fly.
292 _compatSet.insert( Arch::CompatEntry( _noarch(), 0 ) );
293 ///////////////////////////////////////////////////////////////////
294 // Define the CompatibleWith relation:
296 // NOTE: Order of definition is significant! (Arch::compare)
297 // - define compatible (less) architectures first!
299 defCompatibleWith( _i386(), _noarch() );
300 defCompatibleWith( _i486(), _noarch(),_i386() );
301 defCompatibleWith( _i586(), _noarch(),_i386(),_i486() );
302 defCompatibleWith( _i686(), _noarch(),_i386(),_i486(),_i586() );
303 defCompatibleWith( _athlon(), _noarch(),_i386(),_i486(),_i586(),_i686() );
304 defCompatibleWith( _x86_64(), _noarch(),_i386(),_i486(),_i586(),_i686(),_athlon() );
306 defCompatibleWith( _pentium3(), _noarch(),_i386(),_i486(),_i586(),_i686() );
307 defCompatibleWith( _pentium4(), _noarch(),_i386(),_i486(),_i586(),_i686(),_pentium3() );
309 defCompatibleWith( _ia64(), _noarch(),_i386(),_i486(),_i586(),_i686() );
311 defCompatibleWith( _s390(), _noarch() );
312 defCompatibleWith( _s390x(), _noarch(),_s390() );
314 defCompatibleWith( _ppc(), _noarch() );
315 defCompatibleWith( _ppc64(), _noarch(),_ppc() );
316 defCompatibleWith( _ppc64p7(), _noarch(),_ppc(),_ppc64() );
318 defCompatibleWith( _ppc64le(), _noarch() );
320 defCompatibleWith( _alpha(), _noarch() );
321 defCompatibleWith( _alphaev5(), _noarch(),_alpha() );
322 defCompatibleWith( _alphaev56(), _noarch(),_alpha(),_alphaev5() );
323 defCompatibleWith( _alphapca56(), _noarch(),_alpha(),_alphaev5(),_alphaev56() );
324 defCompatibleWith( _alphaev6(), _noarch(),_alpha(),_alphaev5(),_alphaev56(),_alphapca56() );
325 defCompatibleWith( _alphaev67(), _noarch(),_alpha(),_alphaev5(),_alphaev56(),_alphapca56(),_alphaev6() );
327 defCompatibleWith( _sparc(), _noarch() );
328 defCompatibleWith( _sparcv8(), _noarch(),_sparc() );
329 defCompatibleWith( _sparcv9(), _noarch(),_sparc(),_sparcv8() );
330 defCompatibleWith( _sparcv9v(), _noarch(),_sparc(),_sparcv8(),_sparcv9() );
332 defCompatibleWith( _sparc64(), _noarch(),_sparc(),_sparcv8(),_sparcv9() );
333 defCompatibleWith( _sparc64v(), _noarch(),_sparc(),_sparcv8(),_sparcv9(),_sparcv9v(),_sparc64() );
335 defCompatibleWith( _armv3l(), _noarch() );
336 defCompatibleWith( _armv4l(), _noarch(),_armv3l() );
337 defCompatibleWith( _armv4tl(), _noarch(),_armv3l(),_armv4l() );
338 defCompatibleWith( _armv5l(), _noarch(),_armv3l(),_armv4l(),_armv4tl() );
339 defCompatibleWith( _armv5tel(), _noarch(),_armv3l(),_armv4l(),_armv4tl(),_armv5l() );
340 defCompatibleWith( _armv5tejl(), _noarch(),_armv3l(),_armv4l(),_armv4tl(),_armv5l(),_armv5tel() );
341 defCompatibleWith( _armv6l(), _noarch(),_armv3l(),_armv4l(),_armv4tl(),_armv5l(),_armv5tel(),_armv5tejl() );
342 defCompatibleWith( _armv6hl(), _noarch() );
343 defCompatibleWith( _armv7l(), _noarch(),_armv3l(),_armv4l(),_armv4tl(),_armv5l(),_armv5tel(),_armv5tejl(),_armv6l() );
344 defCompatibleWith( _armv7hl(), _noarch(),_armv6hl() );
345 defCompatibleWith( _armv7nhl(), _noarch(),_armv7hl() );
346 defCompatibleWith( _armv7thl(), _noarch(),_armv7hl() );
347 defCompatibleWith( _armv7tnhl(), _noarch(),_armv7hl(),_armv7nhl(),_armv7thl() );
348 defCompatibleWith( _aarch64(), _noarch() );
350 defCompatibleWith( _sh3(), _noarch() );
352 defCompatibleWith( _sh4(), _noarch() );
353 defCompatibleWith( _sh4a(), _noarch(),_sh4() );
355 defCompatibleWith( _m68k(), _noarch() );
357 defCompatibleWith( _mips(), _noarch() );
358 defCompatibleWith( _mipsel(), _noarch() );
359 defCompatibleWith( _mips64(), _noarch() );
360 defCompatibleWith( _mips64el(), _noarch() );
362 ///////////////////////////////////////////////////////////////////
363 // dumpOn( USR ) << endl;
367 /** Return the next avialable _idBit.
368 * Ctor injects _noarch into the _compatSet, 1 is for
369 * nonbuiltin archs, so we can use <tt>size</tt> for
372 CompatBits::IntT nextIdBit() const
374 if ( CompatBits::size == _compatSet.size() )
376 // Provide more bits in CompatBits::IntT
377 INT << "Need more than " << CompatBits::size << " bits to encode architectures." << endl;
378 ZYPP_THROW( Exception("Need more bits to encode architectures.") );
380 CompatBits::IntT nextBit = CompatBits::IntT(1) << (_compatSet.size());
384 /** Assert each builtin Arch gets an unique _idBit when
385 * inserted into the _compatSet.
387 const CompatEntry & assertCompatSetEntry( IdString archStr_r )
388 { return *_compatSet.insert( Arch::CompatEntry( archStr_r, nextIdBit() ) ).first; }
390 /** Initialize builtin Archs and set _compatBits.
392 void defCompatibleWith( IdString targetArch_r,
394 IdString arch1_r = IdString(),
395 IdString arch2_r = IdString(),
396 IdString arch3_r = IdString(),
397 IdString arch4_r = IdString(),
398 IdString arch5_r = IdString(),
399 IdString arch6_r = IdString(),
400 IdString arch7_r = IdString(),
401 IdString arch8_r = IdString(),
402 IdString arch9_r = IdString() )
404 const CompatEntry & target( assertCompatSetEntry( targetArch_r ) );
405 target.addCompatBit( assertCompatSetEntry( arch0_r )._idBit );
406 #define _SETARG(N) if ( arch##N##_r.empty() ) return; target.addCompatBit( assertCompatSetEntry( arch##N##_r )._idBit )
407 _SETARG(1); _SETARG(2); _SETARG(3); _SETARG(4);
408 _SETARG(5); _SETARG(6); _SETARG(7); _SETARG(8); _SETARG(9);
416 /////////////////////////////////////////////////////////////////
418 ///////////////////////////////////////////////////////////////////
420 ///////////////////////////////////////////////////////////////////
424 ///////////////////////////////////////////////////////////////////
426 const Arch Arch_empty ( IdString::Empty );
427 // remaining Arch_* constants are defined by DEF_BUILTIN above.
429 ///////////////////////////////////////////////////////////////////
431 // METHOD NAME : Arch::Arch
432 // METHOD TYPE : Ctor
435 : _entry( &ArchCompatSet::instance().assertDef( _noarch() ) )
438 Arch::Arch( IdString::IdType id_r )
439 : _entry( &ArchCompatSet::instance().assertDef( IdString(id_r) ) )
442 Arch::Arch( const IdString & idstr_r )
443 : _entry( &ArchCompatSet::instance().assertDef( idstr_r ) )
446 Arch::Arch( const std::string & str_r )
447 : _entry( &ArchCompatSet::instance().assertDef( str_r ) )
450 Arch::Arch( const char * cstr_r )
451 : _entry( &ArchCompatSet::instance().assertDef( cstr_r ) )
454 Arch::Arch( const CompatEntry & rhs )
458 ///////////////////////////////////////////////////////////////////
460 // METHOD NAME : Arch::idStr
461 // METHOD TYPE : IdString
463 IdString Arch::idStr() const
464 { return _entry->_idStr; }
466 ///////////////////////////////////////////////////////////////////
468 // METHOD NAME : Arch::asString
469 // METHOD TYPE : const std::string &
471 const std::string & Arch::asString() const
472 { return _entry->_archStr; }
474 ///////////////////////////////////////////////////////////////////
476 // METHOD NAME : Arch::isBuiltIn
477 // METHOD TYPE : bool
479 bool Arch::isBuiltIn() const
480 { return _entry->isBuiltIn(); }
482 ///////////////////////////////////////////////////////////////////
484 // METHOD NAME : Arch::compatibleWith
485 // METHOD TYPE : bool
487 bool Arch::compatibleWith( const Arch & targetArch_r ) const
488 { return _entry->compatibleWith( *targetArch_r._entry ); }
490 ///////////////////////////////////////////////////////////////////
492 // METHOD NAME : Arch::baseArch
493 // METHOD TYPE : Arch
495 Arch Arch::baseArch( ) const
497 // check the multilib archs:
498 if (Arch_x86_64.compatibleWith(*this))
502 if (Arch_sparc64v.compatibleWith(*this))
504 return Arch_sparc64v;
506 if (Arch_sparc64.compatibleWith(*this))
510 if (Arch_ppc64.compatibleWith(*this))
514 if (Arch_s390x.compatibleWith(*this))
518 // Here: no multilib; return arch before noarch
519 CompatSet cset( compatSet( *this ) );
520 if ( cset.size() > 2 ) // systemArchitecture, ..., basearch, noarch
522 return *(++cset.rbegin());
527 ///////////////////////////////////////////////////////////////////
529 // METHOD NAME : Arch::compare
530 // METHOD TYPE : bool
532 int Arch::compare( const Arch & rhs ) const
533 { return _entry->compare( *rhs._entry ); }
535 ///////////////////////////////////////////////////////////////////
537 // METHOD NAME : Arch::compatSet
538 // METHOD TYPE : Arch::CompatSet
540 Arch::CompatSet Arch::compatSet( const Arch & targetArch_r )
544 for ( ArchCompatSet::const_iterator it = ArchCompatSet::instance().begin();
545 it != ArchCompatSet::instance().end(); ++it )
547 if ( it->compatibleWith( *targetArch_r._entry ) )
549 ret.insert( Arch(*it) );
556 /////////////////////////////////////////////////////////////////
558 ///////////////////////////////////////////////////////////////////