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 )
52 , _compatScore( idBit_r ? 1 : 0 ) // number of compatible archs
55 CompatEntry( IdString archStr_r,
56 CompatBits::IntT idBit_r = 1 )
58 , _archStr( archStr_r.asString() )
60 , _compatBits( idBit_r )
61 , _compatScore( idBit_r ? 1 : 0 ) // number of compatible archs
64 void addCompatBit( const CompatBits & idBit_r ) const
66 if ( idBit_r && ! (_compatBits & idBit_r) )
68 _compatBits |= idBit_r;
73 /** Return whether \c this is compatible with \a targetEntry_r.*/
74 bool compatibleWith( const CompatEntry & targetEntry_r ) const
76 switch ( _idBit.value() )
79 // this is noarch and always comatible
83 // this is a non builtin: self compatible only
84 return _archStr == targetEntry_r._archStr;
87 // This is a builtin: compatible if mentioned in targetEntry_r
88 return targetEntry_r._compatBits & _idBit;
91 /** compare by score, then archStr. */
92 int compare( const CompatEntry & rhs ) const
94 if ( _compatScore != rhs._compatScore )
95 return( _compatScore < rhs._compatScore ? -1 : 1 );
96 return _archStr.compare( rhs._archStr );
99 bool isBuiltIn() const
100 { return( _idBit != CompatBits(1) ); }
102 IdString::IdType id() const
103 { return _idStr.id(); }
106 std::string _archStr; // frequently used by the UI so we keep a reference
108 mutable CompatBits _compatBits;
109 mutable unsigned _compatScore;
111 ///////////////////////////////////////////////////////////////////
113 /** \relates Arch::CompatEntry Stream output */
114 inline std::ostream & operator<<( std::ostream & str, const Arch::CompatEntry & obj )
116 Arch::CompatEntry::CompatBits bit( obj._idBit );
123 return str << str::form( "%-15s ", obj._archStr.c_str() ) << str::numstring(bitnum,2) << ' '
124 << obj._compatBits << ' ' << obj._compatScore;
127 /** \relates Arch::CompatEntry */
128 inline bool operator==( const Arch::CompatEntry & lhs, const Arch::CompatEntry & rhs )
129 { return lhs._idStr == rhs._idStr; }
130 /** \relates Arch::CompatEntry */
131 inline bool operator!=( const Arch::CompatEntry & lhs, const Arch::CompatEntry & rhs )
132 { return ! ( lhs == rhs ); }
134 /////////////////////////////////////////////////////////////////
136 ///////////////////////////////////////////////////////////////////
138 ZYPP_DEFINE_ID_HASHABLE( zypp::Arch::CompatEntry );
140 ///////////////////////////////////////////////////////////////////
142 { /////////////////////////////////////////////////////////////////
144 ///////////////////////////////////////////////////////////////////
146 { /////////////////////////////////////////////////////////////////
148 // Builtin architecture STRING VALUES to be
149 // used in defCompatibleWith below!
151 // const IdString _foo( "foo" );
153 // NOTE: Builtin CLASS Arch CONSTANTS are defined below.
154 // You have to change them accordingly.
156 // NOTE: Thake care CompatBits::IntT is able to provide one
157 // bit for each architectue.
159 #define DEF_BUILTIN(A) const IdString _##A( #A );
160 DEF_BUILTIN( noarch );
166 DEF_BUILTIN( athlon );
167 DEF_BUILTIN( x86_64 );
169 DEF_BUILTIN( pentium3 );
170 DEF_BUILTIN( pentium4 );
173 DEF_BUILTIN( s390x );
176 DEF_BUILTIN( ppc64 );
180 DEF_BUILTIN( alphaev67 );
181 DEF_BUILTIN( alphaev6 );
182 DEF_BUILTIN( alphapca56 );
183 DEF_BUILTIN( alphaev56 );
184 DEF_BUILTIN( alphaev5 );
185 DEF_BUILTIN( alpha );
187 DEF_BUILTIN( sparc64 );
188 DEF_BUILTIN( sparcv9 );
189 DEF_BUILTIN( sparcv8 );
190 DEF_BUILTIN( sparc );
192 DEF_BUILTIN( armv6l );
193 DEF_BUILTIN( armv5tejl );
194 DEF_BUILTIN( armv5tel );
195 DEF_BUILTIN( armv5l );
196 DEF_BUILTIN( armv4tl );
197 DEF_BUILTIN( armv4l );
198 DEF_BUILTIN( armv3l );
206 ///////////////////////////////////////////////////////////////////
208 // CLASS NAME : CompatSet
210 /** Maintain architecture compatibility (Singleton by the way it is used).
212 * Povides \ref Arch::CompatEntry for \ref Arch. Defines the
213 * compatibleWith relation.
214 * \li \c noarch has _idBit 0
215 * \li \c nonbuiltin archs have _idBit 1
217 struct ArchCompatSet : private base::NonCopyable
219 typedef Arch::CompatEntry CompatEntry;
220 typedef CompatEntry::CompatBits CompatBits;
222 typedef std::tr1::unordered_set<CompatEntry> Set;
223 typedef Set::iterator iterator;
224 typedef Set::const_iterator const_iterator;
226 /** Singleton access. */
227 static ArchCompatSet & instance()
229 static ArchCompatSet _instance;
233 /** Return the entry related to \a archStr_r.
234 * Creates an entry for nonbuiltin archs.
236 const Arch::CompatEntry & assertDef( const std::string & archStr_r )
237 { return *_compatSet.insert( Arch::CompatEntry( archStr_r ) ).first; }
239 const Arch::CompatEntry & assertDef( IdString archStr_r )
240 { return *_compatSet.insert( Arch::CompatEntry( archStr_r ) ).first; }
242 const_iterator begin() const
243 { return _compatSet.begin(); }
245 const_iterator end() const
246 { return _compatSet.end(); }
250 int operator()( const CompatEntry & lhs, const CompatEntry & rhs ) const
251 { return lhs._idBit.value() < rhs._idBit.value(); }
254 std::ostream & dumpOn( std::ostream & str ) const
256 str << "ArchCompatSet:";
257 std::list<CompatEntry> ov( _compatSet.begin(), _compatSet.end() );
258 ov.sort( DumpOnCompare() );
259 for_( it, ov.begin(), ov.end() )
261 str << endl << ' ' << *it;
267 /** Singleton ctor. */
270 // _noarch must have _idBit 0.
271 // Other builtins have 1-bit set
272 // and are initialized done on the fly.
273 _compatSet.insert( Arch::CompatEntry( _noarch, 0 ) );
274 ///////////////////////////////////////////////////////////////////
275 // Define the CompatibleWith relation:
277 defCompatibleWith( _i386, _noarch );
278 defCompatibleWith( _i486, _noarch,_i386 );
279 defCompatibleWith( _i586, _noarch,_i386,_i486 );
280 defCompatibleWith( _i686, _noarch,_i386,_i486,_i586 );
281 defCompatibleWith( _athlon, _noarch,_i386,_i486,_i586,_i686 );
282 defCompatibleWith( _x86_64, _noarch,_i386,_i486,_i586,_i686,_athlon );
284 defCompatibleWith( _pentium3, _noarch,_i386,_i486,_i586,_i686 );
285 defCompatibleWith( _pentium4, _noarch,_i386,_i486,_i586,_i686,_pentium3 );
287 defCompatibleWith( _ia64, _noarch,_i386,_i486,_i586,_i686 );
289 defCompatibleWith( _s390, _noarch );
290 defCompatibleWith( _s390x, _noarch,_s390 );
292 defCompatibleWith( _ppc, _noarch );
293 defCompatibleWith( _ppc64, _noarch,_ppc );
295 defCompatibleWith( _alpha, _noarch );
296 defCompatibleWith( _alphaev5, _noarch,_alpha );
297 defCompatibleWith( _alphaev56, _noarch,_alpha,_alphaev5 );
298 defCompatibleWith( _alphapca56, _noarch,_alpha,_alphaev5,_alphaev56 );
299 defCompatibleWith( _alphaev6, _noarch,_alpha,_alphaev5,_alphaev56,_alphapca56 );
300 defCompatibleWith( _alphaev67, _noarch,_alpha,_alphaev5,_alphaev56,_alphapca56,_alphaev6 );
302 defCompatibleWith( _sparc, _noarch );
303 defCompatibleWith( _sparcv8, _noarch,_sparc );
305 defCompatibleWith( _sparcv9, _noarch,_sparc );
306 defCompatibleWith( _sparc64, _noarch,_sparc,_sparcv9 );
308 defCompatibleWith( _armv3l, _noarch );
309 defCompatibleWith( _armv4l, _noarch,_armv3l );
310 defCompatibleWith( _armv4tl, _noarch,_armv3l,_armv4l );
311 defCompatibleWith( _armv5l, _noarch,_armv3l,_armv4l,_armv4tl );
312 defCompatibleWith( _armv5tel, _noarch,_armv3l,_armv4l,_armv4tl,_armv5l );
313 defCompatibleWith( _armv5tejl, _noarch,_armv3l,_armv4l,_armv4tl,_armv5l,_armv5tel );
314 defCompatibleWith( _armv6l, _noarch,_armv3l,_armv4l,_armv4tl,_armv5l,_armv5tel,_armv5tejl );
316 defCompatibleWith( _sh3, _noarch );
318 defCompatibleWith( _sh4, _noarch );
319 defCompatibleWith( _sh4a, _noarch,_sh4 );
321 ///////////////////////////////////////////////////////////////////
322 // dumpOn( USR ) << endl;
326 /** Return the next avialable _idBit.
327 * Ctor injects _noarch into the _compatSet, 1 is for
328 * nonbuiltin archs, so we can use <tt>size</tt> for
331 CompatBits::IntT nextIdBit() const
333 if ( CompatBits::size == _compatSet.size() )
335 // Provide more bits in CompatBits::IntT
336 INT << "Need more than " << CompatBits::size << " bits to encode architectures." << endl;
337 ZYPP_THROW( Exception("Need more bits to encode architectures.") );
339 CompatBits::IntT nextBit = CompatBits::IntT(1) << (_compatSet.size());
343 /** Assert each builtin Arch gets an unique _idBit when
344 * inserted into the _compatSet.
346 const CompatEntry & assertCompatSetEntry( IdString archStr_r )
347 { return *_compatSet.insert( Arch::CompatEntry( archStr_r, nextIdBit() ) ).first; }
349 /** Initialize builtin Archs and set _compatBits.
351 void defCompatibleWith( IdString targetArch_r,
353 IdString arch1_r = IdString(),
354 IdString arch2_r = IdString(),
355 IdString arch3_r = IdString(),
356 IdString arch4_r = IdString(),
357 IdString arch5_r = IdString(),
358 IdString arch6_r = IdString(),
359 IdString arch7_r = IdString(),
360 IdString arch8_r = IdString(),
361 IdString arch9_r = IdString() )
363 const CompatEntry & target( assertCompatSetEntry( targetArch_r ) );
364 target.addCompatBit( assertCompatSetEntry( arch0_r )._idBit );
365 #define _SETARG(N) if ( arch##N##_r.empty() ) return; target.addCompatBit( assertCompatSetEntry( arch##N##_r )._idBit )
366 _SETARG(1); _SETARG(2); _SETARG(3); _SETARG(4);
367 _SETARG(5); _SETARG(6); _SETARG(7); _SETARG(8); _SETARG(9);
375 /////////////////////////////////////////////////////////////////
377 ///////////////////////////////////////////////////////////////////
379 ///////////////////////////////////////////////////////////////////
383 ///////////////////////////////////////////////////////////////////
385 const Arch Arch_empty ( IdString::Empty );
386 const Arch Arch_noarch( _noarch );
388 const Arch Arch_i386( _i386 );
389 const Arch Arch_i486( _i486 );
390 const Arch Arch_i586( _i586 );
391 const Arch Arch_i686( _i686 );
392 const Arch Arch_athlon( _athlon );
393 const Arch Arch_x86_64( _x86_64 );
395 const Arch Arch_pentium3( _pentium3 );
396 const Arch Arch_pentium4( _pentium4 );
398 const Arch Arch_s390( _s390 );
399 const Arch Arch_s390x( _s390x );
401 const Arch Arch_ppc( _ppc );
402 const Arch Arch_ppc64( _ppc64 );
404 const Arch Arch_ia64( _ia64 );
406 const Arch Arch_alphaev67( _alphaev67 );
407 const Arch Arch_alphaev6( _alphaev6 );
408 const Arch Arch_alphapca56( _alphapca56 );
409 const Arch Arch_alphaev56( _alphaev56 );
410 const Arch Arch_alphaev5( _alphaev5 );
411 const Arch Arch_alpha( _alpha );
413 const Arch Arch_sparc64( _sparc64 );
414 const Arch Arch_sparcv9( _sparcv9 );
415 const Arch Arch_sparcv8( _sparcv8 );
416 const Arch Arch_sparc( _sparc );
418 const Arch Arch_armv6l( _armv6l );
419 const Arch Arch_armv5tejl( _armv5tejl );
420 const Arch Arch_armv5tel( _armv5tel );
421 const Arch Arch_armv5l( _armv5l );
422 const Arch Arch_armv4tl( _armv4tl );
423 const Arch Arch_armv4l( _armv4l );
424 const Arch Arch_armv3l( _armv3l );
426 const Arch Arch_sh3( _sh3 );
428 const Arch Arch_sh4( _sh4 );
429 const Arch Arch_sh4a( _sh4a );
431 ///////////////////////////////////////////////////////////////////
433 // METHOD NAME : Arch::Arch
434 // METHOD TYPE : Ctor
437 : _entry( &ArchCompatSet::instance().assertDef( _noarch ) )
440 Arch::Arch( IdString::IdType id_r )
441 : _entry( &ArchCompatSet::instance().assertDef( IdString(id_r) ) )
444 Arch::Arch( const IdString & idstr_r )
445 : _entry( &ArchCompatSet::instance().assertDef( idstr_r ) )
448 Arch::Arch( const std::string & str_r )
449 : _entry( &ArchCompatSet::instance().assertDef( str_r ) )
452 Arch::Arch( const char * cstr_r )
453 : _entry( &ArchCompatSet::instance().assertDef( cstr_r ) )
456 Arch::Arch( const CompatEntry & rhs )
460 ///////////////////////////////////////////////////////////////////
462 // METHOD NAME : Arch::idStr
463 // METHOD TYPE : IdString
465 IdString Arch::idStr() const
466 { return _entry->_idStr; }
468 ///////////////////////////////////////////////////////////////////
470 // METHOD NAME : Arch::asString
471 // METHOD TYPE : const std::string &
473 const std::string & Arch::asString() const
474 { return _entry->_archStr; }
476 ///////////////////////////////////////////////////////////////////
478 // METHOD NAME : Arch::isBuiltIn
479 // METHOD TYPE : bool
481 bool Arch::isBuiltIn() const
482 { return _entry->isBuiltIn(); }
484 ///////////////////////////////////////////////////////////////////
486 // METHOD NAME : Arch::compatibleWith
487 // METHOD TYPE : bool
489 bool Arch::compatibleWith( const Arch & targetArch_r ) const
490 { return _entry->compatibleWith( *targetArch_r._entry ); }
492 ///////////////////////////////////////////////////////////////////
494 // METHOD NAME : Arch::compare
495 // METHOD TYPE : bool
497 int Arch::compare( const Arch & rhs ) const
498 { return _entry->compare( *rhs._entry ); }
500 ///////////////////////////////////////////////////////////////////
502 // METHOD NAME : Arch::compatSet
503 // METHOD TYPE : Arch::CompatSet
505 Arch::CompatSet Arch::compatSet( const Arch & targetArch_r )
509 for ( ArchCompatSet::const_iterator it = ArchCompatSet::instance().begin();
510 it != ArchCompatSet::instance().end(); ++it )
512 if ( it->compatibleWith( *targetArch_r._entry ) )
514 ret.insert( Arch(*it) );
521 /////////////////////////////////////////////////////////////////
523 ///////////////////////////////////////////////////////////////////