libzypp  15.28.6
Arch.cc
Go to the documentation of this file.
1 /*---------------------------------------------------------------------\
2 | ____ _ __ __ ___ |
3 | |__ / \ / / . \ . \ |
4 | / / \ V /| _/ _/ |
5 | / /__ | | | | | | |
6 | /_____||_| |_| |_| |
7 | |
8 \---------------------------------------------------------------------*/
12 #include <iostream>
13 #include <list>
14 #include <inttypes.h>
15 
16 #include "zypp/base/Logger.h"
17 #include "zypp/base/Exception.h"
18 #include "zypp/base/NonCopyable.h"
19 #include "zypp/base/Hash.h"
20 #include "zypp/Arch.h"
21 #include "zypp/Bit.h"
22 
23 using std::endl;
24 
26 namespace zypp
27 {
28 
30  //
31  // CLASS NAME : Arch::CompatEntry
32  //
39  {
45 
46  CompatEntry( const std::string & archStr_r,
47  CompatBits::IntT idBit_r = 1 )
48  : _idStr( archStr_r )
49  , _archStr( archStr_r )
50  , _idBit( idBit_r )
51  , _compatBits( idBit_r )
52  {}
53 
54  CompatEntry( IdString archStr_r,
55  CompatBits::IntT idBit_r = 1 )
56  : _idStr( archStr_r )
57  , _archStr( archStr_r.asString() )
58  , _idBit( idBit_r )
59  , _compatBits( idBit_r )
60  {}
61 
62  void addCompatBit( const CompatBits & idBit_r ) const
63  {
64  if ( idBit_r && ! (_compatBits & idBit_r) )
65  {
66  _compatBits |= idBit_r;
67  }
68  }
69 
71  bool compatibleWith( const CompatEntry & targetEntry_r ) const
72  {
73  switch ( _idBit.value() )
74  {
75  case 0:
76  // this is noarch and always comatible
77  return true;
78  break;
79  case 1:
80  // this is a non builtin: self compatible only
81  return _archStr == targetEntry_r._archStr;
82  break;
83  }
84  // This is a builtin: compatible if mentioned in targetEntry_r
85  return bool( targetEntry_r._compatBits & _idBit );
86  }
87 
89  int compare( const CompatEntry & rhs ) const
90  {
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
94  }
95 
96  bool isBuiltIn() const
97  { return( _idBit != CompatBits(1) ); }
98 
100  { return _idStr.id(); }
101 
103  std::string _archStr; // frequently used by the UI so we keep a reference
106  };
108 
110  inline std::ostream & operator<<( std::ostream & str, const Arch::CompatEntry & obj )
111  {
113  unsigned bitnum = 0;
114  while ( bit )
115  {
116  ++bitnum;
117  bit >>= 1;
118  }
119  return str << str::form( "%-15s ", obj._archStr.c_str() ) << str::numstring(bitnum,2) << ' '
120  << obj._compatBits << ' ' << obj._compatBits.value();
121  }
122 
124  inline bool operator==( const Arch::CompatEntry & lhs, const Arch::CompatEntry & rhs )
125  { return lhs._idStr == rhs._idStr; }
127  inline bool operator!=( const Arch::CompatEntry & lhs, const Arch::CompatEntry & rhs )
128  { return ! ( lhs == rhs ); }
129 
131 } // namespace zypp
133 
135 
137 namespace zypp
138 {
139 
140  // Builtin architecture STRING VALUES to be
141  // used in defCompatibleWith below!
142  //
143  // const IdString _foo( "foo" );
144  // const Arch Arch_foo( _foo() );
145  //
146  // NOTE: Builtin CLASS Arch CONSTANTS are defined below.
147  // You have to change them accordingly in Arch.h.
148  //
149  // NOTE: Thake care CompatBits::IntT is able to provide one
150  // bit for each architecture.
151  //
152  #define DEF_BUILTIN(A) \
153  namespace { static inline const IdString & _##A () { static IdString __str(#A); return __str; } } \
154  const Arch Arch_##A( _##A() )
155 
156  DEF_BUILTIN( noarch );
157 
158  DEF_BUILTIN( i386 );
159  DEF_BUILTIN( i486 );
160  DEF_BUILTIN( i586 );
161  DEF_BUILTIN( i686 );
162  DEF_BUILTIN( athlon );
163  DEF_BUILTIN( x86_64 );
164 
165  DEF_BUILTIN( pentium3 );
166  DEF_BUILTIN( pentium4 );
167 
168  DEF_BUILTIN( s390 );
169  DEF_BUILTIN( s390x );
170 
171  DEF_BUILTIN( ppc );
172  DEF_BUILTIN( ppc64 );
173  DEF_BUILTIN( ppc64p7 );
174 
175  DEF_BUILTIN( ppc64le );
176 
177  DEF_BUILTIN( ia64 );
178 
179  DEF_BUILTIN( alphaev67 );
180  DEF_BUILTIN( alphaev6 );
181  DEF_BUILTIN( alphapca56 );
182  DEF_BUILTIN( alphaev56 );
183  DEF_BUILTIN( alphaev5 );
184  DEF_BUILTIN( alpha );
185 
186  DEF_BUILTIN( sparc64v );
187  DEF_BUILTIN( sparcv9v );
188  DEF_BUILTIN( sparc64 );
189  DEF_BUILTIN( sparcv9 );
190  DEF_BUILTIN( sparcv8 );
191  DEF_BUILTIN( sparc );
192 
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 );
207 
208  DEF_BUILTIN( sh3 );
209 
210  DEF_BUILTIN( sh4 );
211  DEF_BUILTIN( sh4a );
212 
213  DEF_BUILTIN( m68k );
214 
215  DEF_BUILTIN( mips );
216  DEF_BUILTIN( mipsel );
217  DEF_BUILTIN( mips64 );
218  DEF_BUILTIN( mips64el );
219 #undef DEF_BUILTIN
220 
222  namespace
223  {
224 
226  //
227  // CLASS NAME : CompatSet
228  //
236  struct ArchCompatSet : private base::NonCopyable
237  {
238  typedef Arch::CompatEntry CompatEntry;
239  typedef CompatEntry::CompatBits CompatBits;
240 
241  typedef std::unordered_set<CompatEntry> Set;
242  typedef Set::iterator iterator;
243  typedef Set::const_iterator const_iterator;
244 
246  static ArchCompatSet & instance()
247  {
248  static ArchCompatSet _instance;
249  return _instance;
250  }
251 
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; }
260 
261  const_iterator begin() const
262  { return _compatSet.begin(); }
263 
264  const_iterator end() const
265  { return _compatSet.end(); }
266 
267  struct DumpOnCompare
268  {
269  int operator()( const CompatEntry & lhs, const CompatEntry & rhs ) const
270  { return lhs._idBit.value() < rhs._idBit.value(); }
271  };
272 
273  std::ostream & dumpOn( std::ostream & str ) const
274  {
275  str << "ArchCompatSet:";
276  std::list<CompatEntry> ov( _compatSet.begin(), _compatSet.end() );
277  ov.sort( DumpOnCompare() );
278  for_( it, ov.begin(), ov.end() )
279  {
280  str << endl << ' ' << *it;
281  }
282  return str;
283  }
284 
285  private:
287  ArchCompatSet()
288  {
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 ) );
294  // Define the CompatibleWith relation:
295  //
296  // NOTE: Order of definition is significant! (Arch::compare)
297  // - define compatible (less) architectures first!
298  //
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() );
305 
306  defCompatibleWith( _pentium3(), _noarch(),_i386(),_i486(),_i586(),_i686() );
307  defCompatibleWith( _pentium4(), _noarch(),_i386(),_i486(),_i586(),_i686(),_pentium3() );
308 
309  defCompatibleWith( _ia64(), _noarch(),_i386(),_i486(),_i586(),_i686() );
310  //
311  defCompatibleWith( _s390(), _noarch() );
312  defCompatibleWith( _s390x(), _noarch(),_s390() );
313  //
314  defCompatibleWith( _ppc(), _noarch() );
315  defCompatibleWith( _ppc64(), _noarch(),_ppc() );
316  defCompatibleWith( _ppc64p7(), _noarch(),_ppc(),_ppc64() );
317  //
318  defCompatibleWith( _ppc64le(), _noarch() );
319  //
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() );
326  //
327  defCompatibleWith( _sparc(), _noarch() );
328  defCompatibleWith( _sparcv8(), _noarch(),_sparc() );
329  defCompatibleWith( _sparcv9(), _noarch(),_sparc(),_sparcv8() );
330  defCompatibleWith( _sparcv9v(), _noarch(),_sparc(),_sparcv8(),_sparcv9() );
331  //
332  defCompatibleWith( _sparc64(), _noarch(),_sparc(),_sparcv8(),_sparcv9() );
333  defCompatibleWith( _sparc64v(), _noarch(),_sparc(),_sparcv8(),_sparcv9(),_sparcv9v(),_sparc64() );
334  //
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() );
349  //
350  defCompatibleWith( _sh3(), _noarch() );
351  //
352  defCompatibleWith( _sh4(), _noarch() );
353  defCompatibleWith( _sh4a(), _noarch(),_sh4() );
354 
355  defCompatibleWith( _m68k(), _noarch() );
356 
357  defCompatibleWith( _mips(), _noarch() );
358  defCompatibleWith( _mipsel(), _noarch() );
359  defCompatibleWith( _mips64(), _noarch() );
360  defCompatibleWith( _mips64el(), _noarch() );
361  //
363  // dumpOn( USR ) << endl;
364  }
365 
366  private:
372  CompatBits::IntT nextIdBit() const
373  {
374  if ( CompatBits::size == _compatSet.size() )
375  {
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.") );
379  }
380  CompatBits::IntT nextBit = CompatBits::IntT(1) << (_compatSet.size());
381  return nextBit;
382  }
383 
387  const CompatEntry & assertCompatSetEntry( IdString archStr_r )
388  { return *_compatSet.insert( Arch::CompatEntry( archStr_r, nextIdBit() ) ).first; }
389 
392  void defCompatibleWith( IdString targetArch_r,
393  IdString arch0_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() )
403  {
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);
409 #undef SETARG
410  }
411 
412  private:
414  };
415 
417  } // namespace
419 
421  //
422  // CLASS NAME : Arch
423  //
425 
426  const Arch Arch_empty ( IdString::Empty );
427  // remaining Arch_* constants are defined by DEF_BUILTIN above.
428 
430  //
431  // METHOD NAME : Arch::Arch
432  // METHOD TYPE : Ctor
433  //
435  : _entry( &ArchCompatSet::instance().assertDef( _noarch() ) )
436  {}
437 
439  : _entry( &ArchCompatSet::instance().assertDef( IdString(id_r) ) )
440  {}
441 
442  Arch::Arch( const IdString & idstr_r )
443  : _entry( &ArchCompatSet::instance().assertDef( idstr_r ) )
444  {}
445 
446  Arch::Arch( const std::string & str_r )
447  : _entry( &ArchCompatSet::instance().assertDef( str_r ) )
448  {}
449 
450  Arch::Arch( const char * cstr_r )
451  : _entry( &ArchCompatSet::instance().assertDef( cstr_r ) )
452  {}
453 
454  Arch::Arch( const CompatEntry & rhs )
455  : _entry( &rhs )
456  {}
457 
459  //
460  // METHOD NAME : Arch::idStr
461  // METHOD TYPE : IdString
462  //
464  { return _entry->_idStr; }
465 
467  //
468  // METHOD NAME : Arch::asString
469  // METHOD TYPE : const std::string &
470  //
471  const std::string & Arch::asString() const
472  { return _entry->_archStr; }
473 
475  //
476  // METHOD NAME : Arch::isBuiltIn
477  // METHOD TYPE : bool
478  //
479  bool Arch::isBuiltIn() const
480  { return _entry->isBuiltIn(); }
481 
483  //
484  // METHOD NAME : Arch::compatibleWith
485  // METHOD TYPE : bool
486  //
487  bool Arch::compatibleWith( const Arch & targetArch_r ) const
488  { return _entry->compatibleWith( *targetArch_r._entry ); }
489 
491  //
492  // METHOD NAME : Arch::baseArch
493  // METHOD TYPE : Arch
494  //
496  {
497  // check the multilib archs:
498  if (Arch_x86_64.compatibleWith(*this))
499  {
500  return Arch_x86_64;
501  }
502  if (Arch_sparc64v.compatibleWith(*this))
503  {
504  return Arch_sparc64v;
505  }
506  if (Arch_sparc64.compatibleWith(*this))
507  {
508  return Arch_sparc64;
509  }
510  if (Arch_ppc64.compatibleWith(*this))
511  {
512  return Arch_ppc64;
513  }
514  if (Arch_s390x.compatibleWith(*this))
515  {
516  return Arch_s390x;
517  }
518  // Here: no multilib; return arch before noarch
519  CompatSet cset( compatSet( *this ) );
520  if ( cset.size() > 2 ) // systemArchitecture, ..., basearch, noarch
521  {
522  return *(++cset.rbegin());
523  }
524  return *this;
525  }
526 
528  //
529  // METHOD NAME : Arch::compare
530  // METHOD TYPE : bool
531  //
532  int Arch::compare( const Arch & rhs ) const
533  { return _entry->compare( *rhs._entry ); }
534 
536  //
537  // METHOD NAME : Arch::compatSet
538  // METHOD TYPE : Arch::CompatSet
539  //
540  Arch::CompatSet Arch::compatSet( const Arch & targetArch_r )
541  {
542  Arch::CompatSet ret;
543 
544  for ( ArchCompatSet::const_iterator it = ArchCompatSet::instance().begin();
545  it != ArchCompatSet::instance().end(); ++it )
546  {
547  if ( it->compatibleWith( *targetArch_r._entry ) )
548  {
549  ret.insert( Arch(*it) );
550  }
551  }
552 
553  return ret;
554  }
555 
557 } // namespace zypp
const Arch Arch_sparc64
Definition: Arch.h:219
bool compatibleWith(const Arch &targetArch_r) const
Compatibility relation.
Definition: Arch.cc:487
int compare(const CompatEntry &rhs) const
compare by score, then archStr.
Definition: Arch.cc:89
#define ZYPP_THROW(EXCPT)
Drops a logline and throws the Exception.
Definition: Exception.h:321
const std::string & asString() const
Definition: Arch.cc:471
Architecture.
Definition: Arch.h:36
IdType id() const
Expert backdoor.
Definition: IdString.h:115
std::set< Arch, CompareByGT< Arch > > CompatSet
Reversed arch order, best Arch first.
Definition: Arch.h:117
#define INT
Definition: Logger.h:68
const Arch Arch_empty(IdString::Empty)
IdString idStr() const
String representation of Arch.
Definition: Arch.cc:463
Access to the sat-pools string space.
Definition: IdString.h:41
const Arch Arch_s390x
Definition: Arch.h:186
#define for_(IT, BEG, END)
Convenient for-loops using iterator.
Definition: Easy.h:27
CompatEntry(const std::string &archStr_r, CompatBits::IntT idBit_r=1)
Definition: Arch.cc:46
std::string form(const char *format,...) __attribute__((format(printf
Printf style construction of std::string.
Definition: String.cc:36
#define SETARG(N)
int compare(const Arch &rhs) const
Arch comparison.
Definition: Arch.cc:532
Set _compatSet
Definition: Arch.cc:413
const CompatEntry * _entry
Definition: Arch.h:145
boost::noncopyable NonCopyable
Ensure derived classes cannot be copied.
Definition: NonCopyable.h:26
static const IdString Empty
Empty string.
Definition: IdString.h:70
sat::detail::IdType IdType
Definition: IdString.h:44
std::ostream & operator<<(std::ostream &str, const Arch::CompatEntry &obj)
Definition: Arch.cc:110
DEF_BUILTIN(noarch)
void addCompatBit(const CompatBits &idBit_r) const
Definition: Arch.cc:62
std::ostream & dumpOn(std::ostream &str, const Capability &obj)
Definition: Capability.cc:446
bit::BitField< uint64_t > CompatBits
Bitfield for architecture IDs and compatBits relation.
Definition: Arch.cc:44
std::string numstring(char n, int w=0)
Definition: String.h:304
static CompatSet compatSet(const Arch &targetArch_r)
Return a set of all Arch's compatibleWith a targetArch_r.
Definition: Arch.cc:540
const Arch Arch_x86_64
Definition: Arch.h:173
TInt value() const
Return the value.
Definition: Bit.h:179
const Arch Arch_ppc64
Definition: Arch.h:196
bool operator!=(const Arch::CompatEntry &lhs, const Arch::CompatEntry &rhs)
Definition: Arch.cc:127
const Arch Arch_sparc64v
Definition: Arch.h:217
bool isBuiltIn() const
Definition: Arch.cc:96
Arch()
Default ctor Arc_noarch.
Definition: Arch.cc:434
ZYPP_DEFINE_ID_HASHABLE(zypp::Arch::CompatEntry)
bool compatibleWith(const CompatEntry &targetEntry_r) const
Return whether this is compatible with targetEntry_r.
Definition: Arch.cc:71
IdString::IdType id() const
Definition: Arch.cc:99
Arch baseArch() const
Definition: Arch.cc:495
bool isBuiltIn() const
Whether this is a buitin (or known) architecture.
Definition: Arch.cc:479
CompatBits _compatBits
Definition: Arch.cc:105
std::string _archStr
Definition: Arch.cc:103
bool operator==(const Arch::CompatEntry &lhs, const Arch::CompatEntry &rhs)
Definition: Arch.cc:124
CompatEntry(IdString archStr_r, CompatBits::IntT idBit_r=1)
Definition: Arch.cc:54
CompatBits _idBit
Definition: Arch.cc:104
Holds an architecture ID and it's compatible relation.
Definition: Arch.cc:38