1 /*---------------------------------------------------------------------\
3 | |__ / \ / / . \ . \ |
8 \---------------------------------------------------------------------*/
15 #include "zypp/base/Logger.h"
16 #include "zypp/base/NonCopyable.h"
17 #include "zypp/Arch.h"
22 ///////////////////////////////////////////////////////////////////
24 { /////////////////////////////////////////////////////////////////
26 ///////////////////////////////////////////////////////////////////
28 // CLASS NAME : Arch::CompatEntry
30 /** Holds an architecture ID and it's compatible relation.
31 * An architecture is compatibleWith, if it's _idBit is set in
32 * _compatBits. noarch has ID 0, non builtin archs id 1 and
33 * have to be treated specialy.
35 struct Arch::CompatEntry
37 /** Bitfield for architecture IDs and compatBits relation.
38 * \note Need one bit for each builtin Arch.
40 typedef bit::BitField<uint16_t> CompatBits;
42 CompatEntry( const std::string & archStr_r,
43 CompatBits::IntT idBit_r = CompatBits::IntT(1) )
44 : _archStr( archStr_r )
46 , _compatBits( idBit_r )
47 , _compatScore( idBit_r ? 1 : 0 ) // number of compatible archs
50 void addCompatBit( const CompatBits & idBit_r ) const
52 if ( idBit_r && ! (_compatBits & idBit_r) )
54 _compatBits |= idBit_r;
59 /** Return whether \c this is compatible with \a targetEntry_r.*/
60 bool compatibleWith( const CompatEntry & targetEntry_r ) const
62 switch ( _idBit.value() )
65 // this is noarch and always comatible
69 // this is a non builtin: self compatible only
70 return _archStr == targetEntry_r._archStr;
73 // This is a builtin: compatible if mentioned in targetEntry_r
74 return targetEntry_r._compatBits & _idBit;
77 /** compare by score, then archStr. */
78 int compare( const CompatEntry & rhs ) const
80 if ( _compatScore != rhs._compatScore )
81 return( _compatScore < rhs._compatScore ? -1 : 1 );
82 return _archStr.compare( rhs._archStr );
87 mutable CompatBits _compatBits;
88 mutable unsigned _compatScore;
90 ///////////////////////////////////////////////////////////////////
92 /** \relates Arch::CompatEntry Stream output */
93 inline std::ostream & operator<<( std::ostream & str, const Arch::CompatEntry & obj )
95 return str << obj._archStr << '\t' << obj._idBit << ' '
96 << obj._compatBits << ' ' << obj._compatScore;
99 /** \relates Arch::CompatEntry ComaptSet ordering.
100 * \note This is purely based on _archStr, as required by class CompatSet.
102 inline bool operator<( const Arch::CompatEntry & lhs, const Arch::CompatEntry & rhs )
103 { return lhs._archStr < rhs._archStr; }
105 ///////////////////////////////////////////////////////////////////
107 { /////////////////////////////////////////////////////////////////
109 // builtin architecture STRING VALUES
110 #define DEF_BUILTIN(A) const std::string _##A( #A )
112 DEF_BUILTIN( noarch );
118 DEF_BUILTIN( athlon );
119 DEF_BUILTIN( x86_64 );
124 DEF_BUILTIN( s390x );
127 DEF_BUILTIN( ppc64 );
131 ///////////////////////////////////////////////////////////////////
133 // CLASS NAME : CompatSet
135 /** Maintain architecture compatibility (Singleton by the way it is used).
137 * Povides \ref Arch::CompatEntry for \ref Arch. Defines the
138 * compatibleWith relation.
139 * \li \c noarch has _idBit 0
140 * \li \c nonbuiltin archs have _idBit 1
142 struct ArchCompatSet : private base::NonCopyable
144 typedef Arch::CompatEntry CompatEntry;
145 typedef CompatEntry::CompatBits CompatBits;
147 typedef std::set<CompatEntry> Set;
148 typedef Set::iterator iterator;
149 typedef Set::const_iterator const_iterator;
151 /** Singleton access. */
152 static ArchCompatSet & instance()
154 static ArchCompatSet _instance;
158 /** Return the entry related to \a archStr_r.
159 * Creates an entry for nonbuiltin archs.
161 const Arch::CompatEntry & assertDef( const std::string & archStr_r )
163 return *_compatSet.insert( Arch::CompatEntry( archStr_r )
167 const_iterator begin() const
168 { return _compatSet.begin(); }
170 const_iterator end() const
171 { return _compatSet.end(); }
173 std::ostream & dumpOn( std::ostream & str ) const
175 str << "ArchCompatSet:";
176 for ( const_iterator it = _compatSet.begin(); it != _compatSet.end(); ++it )
178 str << endl << ' ' << *it;
184 /** Singleton ctor. */
187 // _noarch must have _idBit 0.
188 // Other builtins have 1-bit set
189 // and are initialized done on the fly.
190 _compatSet.insert( Arch::CompatEntry( _noarch, 0 ) );
191 ///////////////////////////////////////////////////////////////////
192 // Define the CompatibleWith relation:
194 defCompatibleWith( _noarch, _i386 );
196 defCompatibleWith( _noarch, _i486 );
197 defCompatibleWith( _i386, _i486 );
199 defCompatibleWith( _noarch, _i586 );
200 defCompatibleWith( _i386, _i586 );
201 defCompatibleWith( _i486, _i586 );
203 defCompatibleWith( _noarch, _i686 );
204 defCompatibleWith( _i386, _i686 );
205 defCompatibleWith( _i486, _i686 );
206 defCompatibleWith( _i586, _i686 );
208 defCompatibleWith( _noarch, _athlon );
209 defCompatibleWith( _i386, _athlon );
210 defCompatibleWith( _i486, _athlon );
211 defCompatibleWith( _i586, _athlon );
212 defCompatibleWith( _i686, _athlon );
214 defCompatibleWith( _noarch, _x86_64 );
215 defCompatibleWith( _i386, _x86_64 );
216 defCompatibleWith( _i486, _x86_64 );
217 defCompatibleWith( _i586, _x86_64 );
218 defCompatibleWith( _i686, _x86_64 );
219 defCompatibleWith( _athlon, _x86_64 );
222 defCompatibleWith( _noarch, _ia64 );
223 defCompatibleWith( _i386, _ia64 );
224 defCompatibleWith( _i486, _ia64 );
225 defCompatibleWith( _i586, _ia64 );
226 defCompatibleWith( _i686, _ia64 );
229 defCompatibleWith( _noarch, _s390 );
231 defCompatibleWith( _noarch, _s390x );
232 defCompatibleWith( _s390, _s390x );
235 defCompatibleWith( _noarch, _ppc );
237 defCompatibleWith( _noarch, _ppc64 );
238 defCompatibleWith( _ppc, _ppc64 );
240 ///////////////////////////////////////////////////////////////////
244 /** Return the next avialable _idBit.
245 * Ctor injects _noarch into the _compatSet, 1 is for
246 * nonbuiltin archs, so we can use <tt>size</tt> for
249 CompatBits::IntT nextIdBit() const
251 CompatBits::IntT nextBit = 1 << (_compatSet.size());
252 assert( nextBit ); // need more bits in CompatBits::IntT
256 /** Assert each builtin Arch gets an unique _idBit when
257 * inserted into the _compatSet.
259 const CompatEntry & assertCompatSetEntry( const std::string & archStr_r )
261 return *_compatSet.insert( Arch::CompatEntry( archStr_r, nextIdBit() )
265 /** Initialize builtin Archs and set _compatBits.
267 void defCompatibleWith( const std::string & arch_r, const std::string & targetArch_r )
269 const CompatEntry & arch ( assertCompatSetEntry( arch_r ) );
270 const CompatEntry & target( assertCompatSetEntry( targetArch_r ) );
271 target.addCompatBit( arch._idBit );
278 /////////////////////////////////////////////////////////////////
280 ///////////////////////////////////////////////////////////////////
282 ///////////////////////////////////////////////////////////////////
286 ///////////////////////////////////////////////////////////////////
288 const Arch Arch_noarch( _noarch );
290 const Arch Arch_x86_64( _x86_64 );
291 const Arch Arch_athlon( _athlon );
292 const Arch Arch_i686 ( _i686 );
293 const Arch Arch_i586 ( _i586 );
294 const Arch Arch_i486 ( _i486 );
295 const Arch Arch_i386 ( _i386 );
297 const Arch Arch_s390x ( _s390x );
298 const Arch Arch_s390 ( _s390 );
300 const Arch Arch_ppc64 ( _ppc64 );
301 const Arch Arch_ppc ( _ppc );
303 const Arch Arch_ia64 ( _ia64 );
305 ///////////////////////////////////////////////////////////////////
307 // METHOD NAME : Arch::Arch
308 // METHOD TYPE : Ctor
311 : _entry( &ArchCompatSet::instance().assertDef( _noarch ) )
312 { assert( _entry ); }
314 ///////////////////////////////////////////////////////////////////
316 // METHOD NAME : Arch::Arch
317 // METHOD TYPE : Ctor
319 Arch::Arch( const std::string & rhs )
320 : _entry( &ArchCompatSet::instance().assertDef( rhs ) )
321 { assert( _entry ); }
323 ///////////////////////////////////////////////////////////////////
325 // METHOD NAME : Arch::Arch
326 // METHOD TYPE : Ctor
328 Arch::Arch( const CompatEntry & rhs )
330 { assert( _entry ); }
332 ///////////////////////////////////////////////////////////////////
334 // METHOD NAME : Arch::asString
335 // METHOD TYPE : const std::string &
337 const std::string & Arch::asString() const
338 { return _entry->_archStr; }
340 ///////////////////////////////////////////////////////////////////
342 // METHOD NAME : Arch::compatibleWith
343 // METHOD TYPE : bool
345 bool Arch::compatibleWith( const Arch & targetArch_r ) const
346 { return _entry->compatibleWith( *targetArch_r._entry ); }
348 ///////////////////////////////////////////////////////////////////
350 // METHOD NAME : Arch::compare
351 // METHOD TYPE : bool
353 int Arch::compare( const Arch & rhs ) const
354 { return _entry->compare( *rhs._entry ); }
356 ///////////////////////////////////////////////////////////////////
358 // METHOD NAME : Arch::compatSet
359 // METHOD TYPE : Arch::CompatSet
361 Arch::CompatSet Arch::compatSet( const Arch & targetArch_r )
365 for ( ArchCompatSet::const_iterator it = ArchCompatSet::instance().begin();
366 it != ArchCompatSet::instance().end(); ++it )
368 if ( it->compatibleWith( *targetArch_r._entry ) )
370 ret.insert( Arch(*it) );
377 /////////////////////////////////////////////////////////////////
379 ///////////////////////////////////////////////////////////////////