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: comatible 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 ComaptSet.
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 intiialized 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 ///////////////////////////////////////////////////////////////////
284 static const string canonical_arch (const string & arch);
286 //---------------------------------------------------------------------------
287 // architecture stuff
290 canonical_arch (const string & arch)
292 typedef struct { char *from; char *to; } canonical;
293 // convert machine string to known_arch
294 static canonical canonical_archs[] = {
295 { "noarch", "noarch" },
296 { "unknown", "unknown" },
300 { "ix86", "i386" }, /* OpenPKG uses this */
304 { "x86_64", "x86_64" },
305 { "ia32e", "ia32e" },
306 { "athlon", "athlon" },
308 { "ppc64", "ppc64" },
310 { "s390x", "s390x" },
312 { "sparc", "sparc" },
313 { "sun4c", "sparc" },
314 { "sun4d", "sparc" },
315 { "sun4m", "sparc" },
316 { "sparc64", "sparc64" },
317 { "sun4u", "sparc64" },
318 { "sparcv9", "sparc64" },
322 for (canonical *ptr = canonical_archs; ptr->from; ptr++) {
323 if (arch == ptr->from) {
331 //---------------------------------------------------------------------------
333 ///////////////////////////////////////////////////////////////////
337 ///////////////////////////////////////////////////////////////////
339 const Arch Arch_noarch( _noarch );
341 const Arch Arch_x86_64( _x86_64 );
342 const Arch Arch_athlon( _athlon );
343 const Arch Arch_i686 ( _i686 );
344 const Arch Arch_i586 ( _i586 );
345 const Arch Arch_i486 ( _i486 );
346 const Arch Arch_i386 ( _i386 );
348 const Arch Arch_s390x ( _s390x );
349 const Arch Arch_s390 ( _s390 );
351 const Arch Arch_ppc64 ( _ppc64 );
352 const Arch Arch_ppc ( _ppc );
354 const Arch Arch_ia64 ( _ia64 );
356 ///////////////////////////////////////////////////////////////////
358 // METHOD NAME : Arch::Arch
359 // METHOD TYPE : Ctor
362 : _entry( &ArchCompatSet::instance().assertDef( _noarch ) )
363 { assert( _entry ); }
365 ///////////////////////////////////////////////////////////////////
367 // METHOD NAME : Arch::Arch
368 // METHOD TYPE : Ctor
370 Arch::Arch( const std::string & rhs )
371 : _entry( &ArchCompatSet::instance().assertDef( rhs ) )
372 { assert( _entry ); }
374 ///////////////////////////////////////////////////////////////////
376 // METHOD NAME : Arch::Arch
377 // METHOD TYPE : Ctor
379 Arch::Arch( const CompatEntry & rhs )
381 { assert( _entry ); }
383 ///////////////////////////////////////////////////////////////////
385 // METHOD NAME : Arch::asString
386 // METHOD TYPE : const std::string &
388 const std::string & Arch::asString() const
389 { return _entry->_archStr; }
391 ///////////////////////////////////////////////////////////////////
393 // METHOD NAME : Arch::compatibleWith
394 // METHOD TYPE : bool
396 bool Arch::compatibleWith( const Arch & targetArch_r ) const
397 { return _entry->compatibleWith( *targetArch_r._entry ); }
399 ///////////////////////////////////////////////////////////////////
401 // METHOD NAME : Arch::compare
402 // METHOD TYPE : bool
404 int Arch::compare( const Arch & rhs ) const
405 { return _entry->compare( *rhs._entry ); }
407 ///////////////////////////////////////////////////////////////////
409 // METHOD NAME : Arch::compatSet
410 // METHOD TYPE : Arch::CompatSet
412 Arch::CompatSet Arch::compatSet( const Arch & targetArch_r )
416 for ( ArchCompatSet::const_iterator it = ArchCompatSet::instance().begin();
417 it != ArchCompatSet::instance().end(); ++it )
419 if ( it->compatibleWith( *targetArch_r._entry ) )
421 ret.insert( Arch(*it) );
429 /////////////////////////////////////////////////////////////////
431 ///////////////////////////////////////////////////////////////////