libzypp  12.16.5
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/Tr1hash.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 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 
141  namespace
142  {
143 
144  // Builtin architecture STRING VALUES to be
145  // used in defCompatibleWith below!
146  //
147  // const IdString _foo( "foo" );
148  //
149  // NOTE: Builtin CLASS Arch CONSTANTS are defined below.
150  // You have to change them accordingly.
151  //
152  // NOTE: Thake care CompatBits::IntT is able to provide one
153  // bit for each architecture.
154  //
155 #define DEF_BUILTIN(A) static inline const IdString & _##A () { static IdString __str(#A); return __str; }
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 
174  DEF_BUILTIN( ia64 );
175 
176  DEF_BUILTIN( alphaev67 );
177  DEF_BUILTIN( alphaev6 );
178  DEF_BUILTIN( alphapca56 );
179  DEF_BUILTIN( alphaev56 );
180  DEF_BUILTIN( alphaev5 );
181  DEF_BUILTIN( alpha );
182 
183  DEF_BUILTIN( sparc64v );
184  DEF_BUILTIN( sparcv9v );
185  DEF_BUILTIN( sparc64 );
186  DEF_BUILTIN( sparcv9 );
187  DEF_BUILTIN( sparcv8 );
188  DEF_BUILTIN( sparc );
189 
190  DEF_BUILTIN( aarch64 );
191  DEF_BUILTIN( armv7tnhl );
192  DEF_BUILTIN( armv7thl );
193  DEF_BUILTIN( armv7nhl );
194  DEF_BUILTIN( armv7hl );
195  DEF_BUILTIN( armv7l );
196  DEF_BUILTIN( armv6l );
197  DEF_BUILTIN( armv5tejl );
198  DEF_BUILTIN( armv5tel );
199  DEF_BUILTIN( armv5l );
200  DEF_BUILTIN( armv4tl );
201  DEF_BUILTIN( armv4l );
202  DEF_BUILTIN( armv3l );
203 
204  DEF_BUILTIN( sh3 );
205 
206  DEF_BUILTIN( sh4 );
207  DEF_BUILTIN( sh4a );
208 #undef DEF_BUILTIN
209 
211  //
212  // CLASS NAME : CompatSet
213  //
221  struct ArchCompatSet : private base::NonCopyable
222  {
223  typedef Arch::CompatEntry CompatEntry;
224  typedef CompatEntry::CompatBits CompatBits;
225 
226  typedef std::tr1::unordered_set<CompatEntry> Set;
227  typedef Set::iterator iterator;
228  typedef Set::const_iterator const_iterator;
229 
231  static ArchCompatSet & instance()
232  {
233  static ArchCompatSet _instance;
234  return _instance;
235  }
236 
240  const Arch::CompatEntry & assertDef( const std::string & archStr_r )
241  { return *_compatSet.insert( Arch::CompatEntry( archStr_r ) ).first; }
243  const Arch::CompatEntry & assertDef( IdString archStr_r )
244  { return *_compatSet.insert( Arch::CompatEntry( archStr_r ) ).first; }
245 
246  const_iterator begin() const
247  { return _compatSet.begin(); }
248 
249  const_iterator end() const
250  { return _compatSet.end(); }
251 
252  struct DumpOnCompare
253  {
254  int operator()( const CompatEntry & lhs, const CompatEntry & rhs ) const
255  { return lhs._idBit.value() < rhs._idBit.value(); }
256  };
257 
258  std::ostream & dumpOn( std::ostream & str ) const
259  {
260  str << "ArchCompatSet:";
261  std::list<CompatEntry> ov( _compatSet.begin(), _compatSet.end() );
262  ov.sort( DumpOnCompare() );
263  for_( it, ov.begin(), ov.end() )
264  {
265  str << endl << ' ' << *it;
266  }
267  return str;
268  }
269 
270  private:
272  ArchCompatSet()
273  {
274  // _noarch must have _idBit 0.
275  // Other builtins have 1-bit set
276  // and are initialized done on the fly.
277  _compatSet.insert( Arch::CompatEntry( _noarch(), 0 ) );
279  // Define the CompatibleWith relation:
280  //
281  // NOTE: Order of definition is significant! (Arch::compare)
282  // - define compatible (less) architectures first!
283  //
284  defCompatibleWith( _i386(), _noarch() );
285  defCompatibleWith( _i486(), _noarch(),_i386() );
286  defCompatibleWith( _i586(), _noarch(),_i386(),_i486() );
287  defCompatibleWith( _i686(), _noarch(),_i386(),_i486(),_i586() );
288  defCompatibleWith( _athlon(), _noarch(),_i386(),_i486(),_i586(),_i686() );
289  defCompatibleWith( _x86_64(), _noarch(),_i386(),_i486(),_i586(),_i686(),_athlon() );
290 
291  defCompatibleWith( _pentium3(), _noarch(),_i386(),_i486(),_i586(),_i686() );
292  defCompatibleWith( _pentium4(), _noarch(),_i386(),_i486(),_i586(),_i686(),_pentium3() );
293 
294  defCompatibleWith( _ia64(), _noarch(),_i386(),_i486(),_i586(),_i686() );
295  //
296  defCompatibleWith( _s390(), _noarch() );
297  defCompatibleWith( _s390x(), _noarch(),_s390() );
298  //
299  defCompatibleWith( _ppc(), _noarch() );
300  defCompatibleWith( _ppc64(), _noarch(),_ppc() );
301  //
302  defCompatibleWith( _alpha(), _noarch() );
303  defCompatibleWith( _alphaev5(), _noarch(),_alpha() );
304  defCompatibleWith( _alphaev56(), _noarch(),_alpha(),_alphaev5() );
305  defCompatibleWith( _alphapca56(), _noarch(),_alpha(),_alphaev5(),_alphaev56() );
306  defCompatibleWith( _alphaev6(), _noarch(),_alpha(),_alphaev5(),_alphaev56(),_alphapca56() );
307  defCompatibleWith( _alphaev67(), _noarch(),_alpha(),_alphaev5(),_alphaev56(),_alphapca56(),_alphaev6() );
308  //
309  defCompatibleWith( _sparc(), _noarch() );
310  defCompatibleWith( _sparcv8(), _noarch(),_sparc() );
311  defCompatibleWith( _sparcv9(), _noarch(),_sparc(),_sparcv8() );
312  defCompatibleWith( _sparcv9v(), _noarch(),_sparc(),_sparcv8(),_sparcv9() );
313  //
314  defCompatibleWith( _sparc64(), _noarch(),_sparc(),_sparcv8(),_sparcv9() );
315  defCompatibleWith( _sparc64v(), _noarch(),_sparc(),_sparcv8(),_sparcv9(),_sparcv9v(),_sparc64() );
316  //
317  defCompatibleWith( _armv3l(), _noarch() );
318  defCompatibleWith( _armv4l(), _noarch(),_armv3l() );
319  defCompatibleWith( _armv4tl(), _noarch(),_armv3l(),_armv4l() );
320  defCompatibleWith( _armv5l(), _noarch(),_armv3l(),_armv4l(),_armv4tl() );
321  defCompatibleWith( _armv5tel(), _noarch(),_armv3l(),_armv4l(),_armv4tl(),_armv5l() );
322  defCompatibleWith( _armv5tejl(), _noarch(),_armv3l(),_armv4l(),_armv4tl(),_armv5l(),_armv5tel() );
323  defCompatibleWith( _armv6l(), _noarch(),_armv3l(),_armv4l(),_armv4tl(),_armv5l(),_armv5tel(),_armv5tejl() );
324  defCompatibleWith( _armv7l(), _noarch(),_armv3l(),_armv4l(),_armv4tl(),_armv5l(),_armv5tel(),_armv5tejl(),_armv6l() );
325  defCompatibleWith( _armv7hl(), _noarch() );
326  defCompatibleWith( _armv7nhl(), _noarch(),_armv7hl() );
327  defCompatibleWith( _armv7thl(), _noarch(),_armv7hl() );
328  defCompatibleWith( _armv7tnhl(), _noarch(),_armv7hl(),_armv7nhl(),_armv7thl() );
329  defCompatibleWith( _aarch64(), _noarch() );
330  //
331  defCompatibleWith( _sh3(), _noarch() );
332  //
333  defCompatibleWith( _sh4(), _noarch() );
334  defCompatibleWith( _sh4a(), _noarch(),_sh4() );
335  //
337  // dumpOn( USR ) << endl;
338  }
339 
340  private:
346  CompatBits::IntT nextIdBit() const
347  {
348  if ( CompatBits::size == _compatSet.size() )
349  {
350  // Provide more bits in CompatBits::IntT
351  INT << "Need more than " << CompatBits::size << " bits to encode architectures." << endl;
352  ZYPP_THROW( Exception("Need more bits to encode architectures.") );
353  }
354  CompatBits::IntT nextBit = CompatBits::IntT(1) << (_compatSet.size());
355  return nextBit;
356  }
357 
361  const CompatEntry & assertCompatSetEntry( IdString archStr_r )
362  { return *_compatSet.insert( Arch::CompatEntry( archStr_r, nextIdBit() ) ).first; }
363 
366  void defCompatibleWith( IdString targetArch_r,
367  IdString arch0_r,
368  IdString arch1_r = IdString(),
369  IdString arch2_r = IdString(),
370  IdString arch3_r = IdString(),
371  IdString arch4_r = IdString(),
372  IdString arch5_r = IdString(),
373  IdString arch6_r = IdString(),
374  IdString arch7_r = IdString(),
375  IdString arch8_r = IdString(),
376  IdString arch9_r = IdString() )
377  {
378  const CompatEntry & target( assertCompatSetEntry( targetArch_r ) );
379  target.addCompatBit( assertCompatSetEntry( arch0_r )._idBit );
380 #define _SETARG(N) if ( arch##N##_r.empty() ) return; target.addCompatBit( assertCompatSetEntry( arch##N##_r )._idBit )
381  _SETARG(1); _SETARG(2); _SETARG(3); _SETARG(4);
382  _SETARG(5); _SETARG(6); _SETARG(7); _SETARG(8); _SETARG(9);
383 #undef _SETARG
384  }
385 
386  private:
388  };
389 
391  } // namespace
393 
395  //
396  // CLASS NAME : Arch
397  //
399 
400  const Arch Arch_empty ( IdString::Empty );
401  const Arch Arch_noarch( _noarch() );
402 
403  const Arch Arch_i386( _i386() );
404  const Arch Arch_i486( _i486() );
405  const Arch Arch_i586( _i586() );
406  const Arch Arch_i686( _i686() );
407  const Arch Arch_athlon( _athlon() );
408  const Arch Arch_x86_64( _x86_64() );
409 
410  const Arch Arch_pentium3( _pentium3() );
411  const Arch Arch_pentium4( _pentium4() );
412 
413  const Arch Arch_s390( _s390() );
414  const Arch Arch_s390x( _s390x() );
415 
416  const Arch Arch_ppc( _ppc() );
417  const Arch Arch_ppc64( _ppc64() );
418 
419  const Arch Arch_ia64( _ia64() );
420 
421  const Arch Arch_alphaev67( _alphaev67() );
422  const Arch Arch_alphaev6( _alphaev6() );
423  const Arch Arch_alphapca56( _alphapca56() );
424  const Arch Arch_alphaev56( _alphaev56() );
425  const Arch Arch_alphaev5( _alphaev5() );
426  const Arch Arch_alpha( _alpha() );
427 
428  const Arch Arch_sparc64v( _sparc64v() );
429  const Arch Arch_sparc64( _sparc64() );
430  const Arch Arch_sparcv9v( _sparcv9v() );
431  const Arch Arch_sparcv9( _sparcv9() );
432  const Arch Arch_sparcv8( _sparcv8() );
433  const Arch Arch_sparc( _sparc() );
434 
435  const Arch Arch_aarch64( _aarch64() );
436  const Arch Arch_armv7tnhl( _armv7tnhl() );
437  const Arch Arch_armv7thl( _armv7thl() );
438  const Arch Arch_armv7nhl ( _armv7nhl() );
439  const Arch Arch_armv7hl ( _armv7hl() );
440  const Arch Arch_armv7l( _armv7l() );
441  const Arch Arch_armv6l( _armv6l() );
442  const Arch Arch_armv5tejl( _armv5tejl() );
443  const Arch Arch_armv5tel( _armv5tel() );
444  const Arch Arch_armv5l( _armv5l() );
445  const Arch Arch_armv4tl( _armv4tl() );
446  const Arch Arch_armv4l( _armv4l() );
447  const Arch Arch_armv3l( _armv3l() );
448 
449  const Arch Arch_sh3( _sh3() );
450 
451  const Arch Arch_sh4( _sh4() );
452  const Arch Arch_sh4a( _sh4a() );
453 
455  //
456  // METHOD NAME : Arch::Arch
457  // METHOD TYPE : Ctor
458  //
460  : _entry( &ArchCompatSet::instance().assertDef( _noarch() ) )
461  {}
462 
464  : _entry( &ArchCompatSet::instance().assertDef( IdString(id_r) ) )
465  {}
466 
467  Arch::Arch( const IdString & idstr_r )
468  : _entry( &ArchCompatSet::instance().assertDef( idstr_r ) )
469  {}
470 
471  Arch::Arch( const std::string & str_r )
472  : _entry( &ArchCompatSet::instance().assertDef( str_r ) )
473  {}
474 
475  Arch::Arch( const char * cstr_r )
476  : _entry( &ArchCompatSet::instance().assertDef( cstr_r ) )
477  {}
478 
479  Arch::Arch( const CompatEntry & rhs )
480  : _entry( &rhs )
481  {}
482 
484  //
485  // METHOD NAME : Arch::idStr
486  // METHOD TYPE : IdString
487  //
489  { return _entry->_idStr; }
490 
492  //
493  // METHOD NAME : Arch::asString
494  // METHOD TYPE : const std::string &
495  //
496  const std::string & Arch::asString() const
497  { return _entry->_archStr; }
498 
500  //
501  // METHOD NAME : Arch::isBuiltIn
502  // METHOD TYPE : bool
503  //
504  bool Arch::isBuiltIn() const
505  { return _entry->isBuiltIn(); }
506 
508  //
509  // METHOD NAME : Arch::compatibleWith
510  // METHOD TYPE : bool
511  //
512  bool Arch::compatibleWith( const Arch & targetArch_r ) const
513  { return _entry->compatibleWith( *targetArch_r._entry ); }
514 
516  //
517  // METHOD NAME : Arch::baseArch
518  // METHOD TYPE : Arch
519  //
521  {
522  // check the multilib archs:
523  if (Arch_x86_64.compatibleWith(*this))
524  {
525  return Arch_x86_64;
526  }
527  if (Arch_sparc64v.compatibleWith(*this))
528  {
529  return Arch_sparc64v;
530  }
531  if (Arch_sparc64.compatibleWith(*this))
532  {
533  return Arch_sparc64;
534  }
535  if (Arch_ppc64.compatibleWith(*this))
536  {
537  return Arch_ppc64;
538  }
539  if (Arch_s390x.compatibleWith(*this))
540  {
541  return Arch_s390x;
542  }
543  // Here: no multilib; return arch before noarch
544  CompatSet cset( compatSet( *this ) );
545  if ( cset.size() > 2 ) // systemArchitecture, ..., basearch, noarch
546  {
547  return *(++cset.rbegin());
548  }
549  return *this;
550  }
551 
553  //
554  // METHOD NAME : Arch::compare
555  // METHOD TYPE : bool
556  //
557  int Arch::compare( const Arch & rhs ) const
558  { return _entry->compare( *rhs._entry ); }
559 
561  //
562  // METHOD NAME : Arch::compatSet
563  // METHOD TYPE : Arch::CompatSet
564  //
565  Arch::CompatSet Arch::compatSet( const Arch & targetArch_r )
566  {
567  Arch::CompatSet ret;
568 
569  for ( ArchCompatSet::const_iterator it = ArchCompatSet::instance().begin();
570  it != ArchCompatSet::instance().end(); ++it )
571  {
572  if ( it->compatibleWith( *targetArch_r._entry ) )
573  {
574  ret.insert( Arch(*it) );
575  }
576  }
577 
578  return ret;
579  }
580 
582 } // namespace zypp