1 /*---------------------------------------------------------------------\
3 | |__ / \ / / . \ . \ |
8 \---------------------------------------------------------------------*/
15 #include "zypp/base/Logger.h"
16 #include "zypp/base/NonCopyable.h"
17 #include "zypp/base/Tr1hash.h"
18 #include "zypp/Arch.h"
23 ///////////////////////////////////////////////////////////////////
25 { /////////////////////////////////////////////////////////////////
27 ///////////////////////////////////////////////////////////////////
29 // CLASS NAME : Arch::CompatEntry
31 /** Holds an architecture ID and it's compatible relation.
32 * An architecture is compatibleWith, if it's _idBit is set in
33 * _compatBits. noarch has ID 0, non builtin archs ID 1 and
34 * have to be treated specialy.
36 struct Arch::CompatEntry
38 /** Bitfield for architecture IDs and compatBits relation.
39 * \note Need one bit for each builtin Arch.
41 typedef bit::BitField<uint32_t> CompatBits;
43 CompatEntry( const std::string & archStr_r,
44 CompatBits::IntT idBit_r = 1 )
46 , _archStr( archStr_r )
48 , _compatBits( idBit_r )
49 , _compatScore( idBit_r ? 1 : 0 ) // number of compatible archs
52 CompatEntry( IdString archStr_r,
53 CompatBits::IntT idBit_r = 1 )
55 , _archStr( archStr_r.asString() )
57 , _compatBits( idBit_r )
58 , _compatScore( idBit_r ? 1 : 0 ) // number of compatible archs
61 void addCompatBit( const CompatBits & idBit_r ) const
63 if ( idBit_r && ! (_compatBits & idBit_r) )
65 _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 targetEntry_r._compatBits & _idBit;
88 /** compare by score, then archStr. */
89 int compare( const CompatEntry & rhs ) const
91 if ( _compatScore != rhs._compatScore )
92 return( _compatScore < rhs._compatScore ? -1 : 1 );
93 return _archStr.compare( rhs._archStr );
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;
106 mutable unsigned _compatScore;
108 ///////////////////////////////////////////////////////////////////
110 /** \relates Arch::CompatEntry Stream output */
111 inline std::ostream & operator<<( std::ostream & str, const Arch::CompatEntry & obj )
113 return str << str::form( "%-15s ", obj._archStr.c_str() ) << obj._idBit << ' '
114 << obj._compatBits << ' ' << obj._compatScore;
117 /** \relates Arch::CompatEntry */
118 inline bool operator==( const Arch::CompatEntry & lhs, const Arch::CompatEntry & rhs )
119 { return lhs._idStr == rhs._idStr; }
120 /** \relates Arch::CompatEntry */
121 inline bool operator!=( const Arch::CompatEntry & lhs, const Arch::CompatEntry & rhs )
122 { return ! ( lhs == rhs ); }
124 /////////////////////////////////////////////////////////////////
126 ///////////////////////////////////////////////////////////////////
128 ZYPP_DEFINE_ID_HASHABLE( zypp::Arch::CompatEntry );
130 ///////////////////////////////////////////////////////////////////
132 { /////////////////////////////////////////////////////////////////
134 ///////////////////////////////////////////////////////////////////
136 { /////////////////////////////////////////////////////////////////
138 // builtin architecture STRING VALUES
140 // For arch 'foo' this macro defines:
141 // const IdString _foo( "foo" ); // to be used in defCompatibleWith below!
142 // const Arch Arch_foo( _foo );
144 #define DEF_BUILTIN(A) const IdString _##A( #A ); const Arch Arch_##A( _##A )
145 DEF_BUILTIN( noarch );
151 DEF_BUILTIN( athlon );
152 DEF_BUILTIN( x86_64 );
154 DEF_BUILTIN( pentium3 );
155 DEF_BUILTIN( pentium4 );
158 DEF_BUILTIN( s390x );
161 DEF_BUILTIN( ppc64 );
165 DEF_BUILTIN( alphaev67 );
166 DEF_BUILTIN( alphaev6 );
167 DEF_BUILTIN( alphapca56 );
168 DEF_BUILTIN( alphaev56 );
169 DEF_BUILTIN( alphaev5 );
170 DEF_BUILTIN( alpha );
172 DEF_BUILTIN( sparc64 );
173 DEF_BUILTIN( sparcv9 );
174 DEF_BUILTIN( sparcv8 );
175 DEF_BUILTIN( sparc );
177 DEF_BUILTIN( armv6l );
178 DEF_BUILTIN( armv5tejl );
179 DEF_BUILTIN( armv5tel );
180 DEF_BUILTIN( armv5l );
181 DEF_BUILTIN( armv4tl );
182 DEF_BUILTIN( armv4l );
183 DEF_BUILTIN( armv3l );
191 ///////////////////////////////////////////////////////////////////
193 // CLASS NAME : CompatSet
195 /** Maintain architecture compatibility (Singleton by the way it is used).
197 * Povides \ref Arch::CompatEntry for \ref Arch. Defines the
198 * compatibleWith relation.
199 * \li \c noarch has _idBit 0
200 * \li \c nonbuiltin archs have _idBit 1
202 struct ArchCompatSet : private base::NonCopyable
204 typedef Arch::CompatEntry CompatEntry;
205 typedef CompatEntry::CompatBits CompatBits;
207 typedef std::tr1::unordered_set<CompatEntry> Set;
208 typedef Set::iterator iterator;
209 typedef Set::const_iterator const_iterator;
211 /** Singleton access. */
212 static ArchCompatSet & instance()
214 static ArchCompatSet _instance;
218 /** Return the entry related to \a archStr_r.
219 * Creates an entry for nonbuiltin archs.
221 const Arch::CompatEntry & assertDef( const std::string & archStr_r )
222 { return *_compatSet.insert( Arch::CompatEntry( archStr_r ) ).first; }
224 const Arch::CompatEntry & assertDef( IdString archStr_r )
225 { return *_compatSet.insert( Arch::CompatEntry( archStr_r ) ).first; }
227 const_iterator begin() const
228 { return _compatSet.begin(); }
230 const_iterator end() const
231 { return _compatSet.end(); }
233 std::ostream & dumpOn( std::ostream & str ) const
235 str << "ArchCompatSet:";
236 for ( const_iterator it = _compatSet.begin(); it != _compatSet.end(); ++it )
238 str << endl << ' ' << *it;
244 /** Singleton ctor. */
247 // _noarch must have _idBit 0.
248 // Other builtins have 1-bit set
249 // and are initialized done on the fly.
250 _compatSet.insert( Arch::CompatEntry( _noarch, 0 ) );
251 ///////////////////////////////////////////////////////////////////
252 // Define the CompatibleWith relation:
254 defCompatibleWith( _i386, _noarch );
255 defCompatibleWith( _i486, _noarch,_i386 );
256 defCompatibleWith( _i586, _noarch,_i386,_i486 );
257 defCompatibleWith( _i686, _noarch,_i386,_i486,_i586 );
258 defCompatibleWith( _athlon, _noarch,_i386,_i486,_i586,_i686 );
259 defCompatibleWith( _x86_64, _noarch,_i386,_i486,_i586,_i686,_athlon );
261 defCompatibleWith( _pentium3, _noarch,_i386,_i486,_i586,_i686 );
262 defCompatibleWith( _pentium4, _noarch,_i386,_i486,_i586,_i686,_pentium3 );
264 defCompatibleWith( _ia64, _noarch,_i386,_i486,_i586,_i686 );
266 defCompatibleWith( _s390, _noarch );
267 defCompatibleWith( _s390x, _noarch,_s390 );
269 defCompatibleWith( _ppc, _noarch );
270 defCompatibleWith( _ppc64, _noarch,_ppc );
272 defCompatibleWith( _alpha, _noarch );
273 defCompatibleWith( _alphaev5, _noarch,_alpha );
274 defCompatibleWith( _alphaev56, _noarch,_alpha,_alphaev5 );
275 defCompatibleWith( _alphapca56, _noarch,_alpha,_alphaev5,_alphaev56 );
276 defCompatibleWith( _alphaev6, _noarch,_alpha,_alphaev5,_alphaev56,_alphapca56 );
277 defCompatibleWith( _alphaev67, _noarch,_alpha,_alphaev5,_alphaev56,_alphapca56,_alphaev6 );
279 defCompatibleWith( _sparc, _noarch );
280 defCompatibleWith( _sparcv8, _noarch,_sparc );
282 defCompatibleWith( _sparcv9, _noarch,_sparc );
283 defCompatibleWith( _sparc64, _noarch,_sparc,_sparcv9 );
285 defCompatibleWith( _armv3l, _noarch );
286 defCompatibleWith( _armv4l, _noarch,_armv3l );
287 defCompatibleWith( _armv4tl, _noarch,_armv3l,_armv4l );
288 defCompatibleWith( _armv5l, _noarch,_armv3l,_armv4l,_armv4tl );
289 defCompatibleWith( _armv5tel, _noarch,_armv3l,_armv4l,_armv4tl,_armv5l );
290 defCompatibleWith( _armv5tejl, _noarch,_armv3l,_armv4l,_armv4tl,_armv5l,_armv5tel );
291 defCompatibleWith( _armv6l, _noarch,_armv3l,_armv4l,_armv4tl,_armv5l,_armv5tel,_armv5tejl );
293 defCompatibleWith( _sh3, _noarch );
295 defCompatibleWith( _sh4, _noarch );
296 defCompatibleWith( _sh4a, _noarch,_sh4 );
298 ///////////////////////////////////////////////////////////////////
299 //dumpOn( USR ) << endl;
303 /** Return the next avialable _idBit.
304 * Ctor injects _noarch into the _compatSet, 1 is for
305 * nonbuiltin archs, so we can use <tt>size</tt> for
308 CompatBits::IntT nextIdBit() const
310 CompatBits::IntT nextBit = CompatBits::IntT(1) << (_compatSet.size());
311 assert( nextBit ); // need more bits in CompatBits::IntT
315 /** Assert each builtin Arch gets an unique _idBit when
316 * inserted into the _compatSet.
318 const CompatEntry & assertCompatSetEntry( IdString archStr_r )
319 { return *_compatSet.insert( Arch::CompatEntry( archStr_r, nextIdBit() ) ).first; }
321 /** Initialize builtin Archs and set _compatBits.
323 void defCompatibleWith( IdString targetArch_r,
325 IdString arch1_r = IdString(),
326 IdString arch2_r = IdString(),
327 IdString arch3_r = IdString(),
328 IdString arch4_r = IdString(),
329 IdString arch5_r = IdString(),
330 IdString arch6_r = IdString(),
331 IdString arch7_r = IdString(),
332 IdString arch8_r = IdString(),
333 IdString arch9_r = IdString() )
335 const CompatEntry & target( assertCompatSetEntry( targetArch_r ) );
336 target.addCompatBit( assertCompatSetEntry( arch0_r )._idBit );
337 #define _SETARG(N) if ( arch##N##_r.empty() ) return; target.addCompatBit( assertCompatSetEntry( arch##N##_r )._idBit )
338 _SETARG(1); _SETARG(2); _SETARG(3); _SETARG(4);
339 _SETARG(5); _SETARG(6); _SETARG(7); _SETARG(8); _SETARG(9);
347 /////////////////////////////////////////////////////////////////
349 ///////////////////////////////////////////////////////////////////
351 ///////////////////////////////////////////////////////////////////
355 ///////////////////////////////////////////////////////////////////
357 const Arch Arch_empty ( IdString::Empty );
359 // all other Arch_* constants are defined via
360 // the DEF_BUILTIN macro. See Above.
362 ///////////////////////////////////////////////////////////////////
364 // METHOD NAME : Arch::Arch
365 // METHOD TYPE : Ctor
368 : _entry( &ArchCompatSet::instance().assertDef( _noarch ) )
371 Arch::Arch( IdString::IdType id_r )
372 : _entry( &ArchCompatSet::instance().assertDef( IdString(id_r) ) )
375 Arch::Arch( const IdString & idstr_r )
376 : _entry( &ArchCompatSet::instance().assertDef( idstr_r ) )
379 Arch::Arch( const std::string & str_r )
380 : _entry( &ArchCompatSet::instance().assertDef( str_r ) )
383 Arch::Arch( const char * cstr_r )
384 : _entry( &ArchCompatSet::instance().assertDef( cstr_r ) )
387 Arch::Arch( const CompatEntry & rhs )
391 ///////////////////////////////////////////////////////////////////
393 // METHOD NAME : Arch::idStr
394 // METHOD TYPE : IdString
396 IdString Arch::idStr() const
397 { return _entry->_idStr; }
399 ///////////////////////////////////////////////////////////////////
401 // METHOD NAME : Arch::asString
402 // METHOD TYPE : const std::string &
404 const std::string & Arch::asString() const
405 { return _entry->_archStr; }
407 ///////////////////////////////////////////////////////////////////
409 // METHOD NAME : Arch::isBuiltIn
410 // METHOD TYPE : bool
412 bool Arch::isBuiltIn() const
413 { return _entry->isBuiltIn(); }
415 ///////////////////////////////////////////////////////////////////
417 // METHOD NAME : Arch::compatibleWith
418 // METHOD TYPE : bool
420 bool Arch::compatibleWith( const Arch & targetArch_r ) const
421 { return _entry->compatibleWith( *targetArch_r._entry ); }
423 ///////////////////////////////////////////////////////////////////
425 // METHOD NAME : Arch::compare
426 // METHOD TYPE : bool
428 int Arch::compare( const Arch & rhs ) const
429 { return _entry->compare( *rhs._entry ); }
431 ///////////////////////////////////////////////////////////////////
433 // METHOD NAME : Arch::compatSet
434 // METHOD TYPE : Arch::CompatSet
436 Arch::CompatSet Arch::compatSet( const Arch & targetArch_r )
440 for ( ArchCompatSet::const_iterator it = ArchCompatSet::instance().begin();
441 it != ArchCompatSet::instance().end(); ++it )
443 if ( it->compatibleWith( *targetArch_r._entry ) )
445 ret.insert( Arch(*it) );
452 /////////////////////////////////////////////////////////////////
454 ///////////////////////////////////////////////////////////////////