Add arch ppc64p7
[platform/upstream/libzypp.git] / zypp / Arch.cc
1 /*---------------------------------------------------------------------\
2 |                          ____ _   __ __ ___                          |
3 |                         |__  / \ / / . \ . \                         |
4 |                           / / \ V /|  _/  _/                         |
5 |                          / /__ | | | | | |                           |
6 |                         /_____||_| |_| |_|                           |
7 |                                                                      |
8 \---------------------------------------------------------------------*/
9 /** \file zypp/Arch.cc
10  *
11 */
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
25 ///////////////////////////////////////////////////////////////////
26 namespace zypp
27 { /////////////////////////////////////////////////////////////////
28
29   ///////////////////////////////////////////////////////////////////
30   //
31   //    CLASS NAME : Arch::CompatEntry
32   //
33   /** Holds an architecture ID and it's compatible relation.
34    * An architecture is compatibleWith, if it's _idBit is set in
35    * _compatBits. noarch has ID 0, non builtin archs ID 1 and
36    * have to be treated specialy.
37   */
38   struct Arch::CompatEntry
39   {
40     /** Bitfield for architecture IDs and compatBits relation.
41      * \note Need one bit for each builtin Arch.
42      * \todo Migrate to some infinite BitField
43     */
44     typedef bit::BitField<uint64_t> CompatBits;
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
70     /** Return whether \c this is compatible with \a targetEntry_r.*/
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
88     /** compare by score, then archStr. */
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
99     IdString::IdType id() const
100     { return _idStr.id(); }
101
102     IdString            _idStr;
103     std::string         _archStr; // frequently used by the UI so we keep a reference
104     CompatBits          _idBit;
105     mutable CompatBits  _compatBits;
106   };
107   ///////////////////////////////////////////////////////////////////
108
109   /** \relates Arch::CompatEntry Stream output */
110   inline std::ostream & operator<<( std::ostream & str, const Arch::CompatEntry & obj )
111   {
112     Arch::CompatEntry::CompatBits bit( obj._idBit );
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
123   /** \relates Arch::CompatEntry */
124   inline bool operator==( const Arch::CompatEntry & lhs, const Arch::CompatEntry & rhs )
125   { return lhs._idStr == rhs._idStr; }
126   /** \relates Arch::CompatEntry */
127   inline bool operator!=( const Arch::CompatEntry & lhs, const Arch::CompatEntry & rhs )
128   { return ! ( lhs == rhs ); }
129
130   /////////////////////////////////////////////////////////////////
131 } // namespace zypp
132 ///////////////////////////////////////////////////////////////////
133
134 ZYPP_DEFINE_ID_HASHABLE( zypp::Arch::CompatEntry );
135
136 ///////////////////////////////////////////////////////////////////
137 namespace zypp
138 { /////////////////////////////////////////////////////////////////
139
140   ///////////////////////////////////////////////////////////////////
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     DEF_BUILTIN( ppc64p7 );
174
175     DEF_BUILTIN( ia64 );
176
177     DEF_BUILTIN( alphaev67 );
178     DEF_BUILTIN( alphaev6 );
179     DEF_BUILTIN( alphapca56 );
180     DEF_BUILTIN( alphaev56 );
181     DEF_BUILTIN( alphaev5 );
182     DEF_BUILTIN( alpha );
183
184     DEF_BUILTIN( sparc64v );
185     DEF_BUILTIN( sparcv9v );
186     DEF_BUILTIN( sparc64 );
187     DEF_BUILTIN( sparcv9 );
188     DEF_BUILTIN( sparcv8 );
189     DEF_BUILTIN( sparc );
190
191     DEF_BUILTIN( aarch64 );
192     DEF_BUILTIN( armv7tnhl );
193     DEF_BUILTIN( armv7thl );
194     DEF_BUILTIN( armv7nhl );
195     DEF_BUILTIN( armv7hl );
196     DEF_BUILTIN( armv7l );
197     DEF_BUILTIN( armv6l );
198     DEF_BUILTIN( armv5tejl );
199     DEF_BUILTIN( armv5tel );
200     DEF_BUILTIN( armv5l );
201     DEF_BUILTIN( armv4tl );
202     DEF_BUILTIN( armv4l );
203     DEF_BUILTIN( armv3l );
204
205     DEF_BUILTIN( sh3 );
206
207     DEF_BUILTIN( sh4 );
208     DEF_BUILTIN( sh4a );
209 #undef DEF_BUILTIN
210
211     ///////////////////////////////////////////////////////////////////
212     //
213     //  CLASS NAME : CompatSet
214     //
215     /** Maintain architecture compatibility (Singleton by the way it is used).
216      *
217      * Povides \ref Arch::CompatEntry for \ref Arch. Defines the
218      * compatibleWith relation.
219      * \li \c noarch has _idBit 0
220      * \li \c nonbuiltin archs have _idBit 1
221     */
222     struct ArchCompatSet : private base::NonCopyable
223     {
224       typedef Arch::CompatEntry       CompatEntry;
225       typedef CompatEntry::CompatBits CompatBits;
226
227       typedef std::tr1::unordered_set<CompatEntry> Set;
228       typedef Set::iterator           iterator;
229       typedef Set::const_iterator     const_iterator;
230
231       /** Singleton access. */
232       static ArchCompatSet & instance()
233       {
234         static ArchCompatSet _instance;
235         return _instance;
236       }
237
238       /** Return the entry related to \a archStr_r.
239        * Creates an entry for nonbuiltin archs.
240       */
241       const Arch::CompatEntry & assertDef( const std::string & archStr_r )
242       { return *_compatSet.insert( Arch::CompatEntry( archStr_r ) ).first; }
243       /** \overload */
244       const Arch::CompatEntry & assertDef( IdString archStr_r )
245       { return *_compatSet.insert( Arch::CompatEntry( archStr_r ) ).first; }
246
247       const_iterator begin() const
248       { return _compatSet.begin(); }
249
250       const_iterator end() const
251       { return _compatSet.end(); }
252
253       struct DumpOnCompare
254       {
255         int operator()( const CompatEntry & lhs,  const CompatEntry & rhs ) const
256         { return lhs._idBit.value() < rhs._idBit.value(); }
257       };
258
259       std::ostream & dumpOn( std::ostream & str ) const
260       {
261         str << "ArchCompatSet:";
262         std::list<CompatEntry> ov( _compatSet.begin(), _compatSet.end() );
263         ov.sort( DumpOnCompare() );
264         for_( it, ov.begin(), ov.end() )
265           {
266             str << endl << ' ' << *it;
267           }
268         return str;
269       }
270
271     private:
272       /** Singleton ctor. */
273       ArchCompatSet()
274       {
275         // _noarch must have _idBit 0.
276         // Other builtins have 1-bit set
277         // and are initialized done on the fly.
278         _compatSet.insert( Arch::CompatEntry( _noarch(), 0 ) );
279         ///////////////////////////////////////////////////////////////////
280         // Define the CompatibleWith relation:
281         //
282         // NOTE: Order of definition is significant! (Arch::compare)
283         //       - define compatible (less) architectures first!
284         //
285         defCompatibleWith( _i386(),             _noarch() );
286         defCompatibleWith( _i486(),             _noarch(),_i386() );
287         defCompatibleWith( _i586(),             _noarch(),_i386(),_i486() );
288         defCompatibleWith( _i686(),             _noarch(),_i386(),_i486(),_i586() );
289         defCompatibleWith( _athlon(),           _noarch(),_i386(),_i486(),_i586(),_i686() );
290         defCompatibleWith( _x86_64(),           _noarch(),_i386(),_i486(),_i586(),_i686(),_athlon() );
291
292         defCompatibleWith( _pentium3(),         _noarch(),_i386(),_i486(),_i586(),_i686() );
293         defCompatibleWith( _pentium4(),         _noarch(),_i386(),_i486(),_i586(),_i686(),_pentium3() );
294
295         defCompatibleWith( _ia64(),             _noarch(),_i386(),_i486(),_i586(),_i686() );
296         //
297         defCompatibleWith( _s390(),             _noarch() );
298         defCompatibleWith( _s390x(),            _noarch(),_s390() );
299         //
300         defCompatibleWith( _ppc(),              _noarch() );
301         defCompatibleWith( _ppc64(),            _noarch(),_ppc() );
302         defCompatibleWith( _ppc64p7(),          _noarch(),_ppc(),_ppc64() );
303         //
304         defCompatibleWith( _alpha(),            _noarch() );
305         defCompatibleWith( _alphaev5(),         _noarch(),_alpha() );
306         defCompatibleWith( _alphaev56(),        _noarch(),_alpha(),_alphaev5() );
307         defCompatibleWith( _alphapca56(),       _noarch(),_alpha(),_alphaev5(),_alphaev56() );
308         defCompatibleWith( _alphaev6(),         _noarch(),_alpha(),_alphaev5(),_alphaev56(),_alphapca56() );
309         defCompatibleWith( _alphaev67(),        _noarch(),_alpha(),_alphaev5(),_alphaev56(),_alphapca56(),_alphaev6() );
310         //
311         defCompatibleWith( _sparc(),            _noarch() );
312         defCompatibleWith( _sparcv8(),          _noarch(),_sparc() );
313         defCompatibleWith( _sparcv9(),          _noarch(),_sparc(),_sparcv8() );
314         defCompatibleWith( _sparcv9v(),         _noarch(),_sparc(),_sparcv8(),_sparcv9() );
315         //
316         defCompatibleWith( _sparc64(),          _noarch(),_sparc(),_sparcv8(),_sparcv9() );
317         defCompatibleWith( _sparc64v(),         _noarch(),_sparc(),_sparcv8(),_sparcv9(),_sparcv9v(),_sparc64() );
318         //
319         defCompatibleWith( _armv3l(),           _noarch() );
320         defCompatibleWith( _armv4l(),           _noarch(),_armv3l() );
321         defCompatibleWith( _armv4tl(),          _noarch(),_armv3l(),_armv4l() );
322         defCompatibleWith( _armv5l(),           _noarch(),_armv3l(),_armv4l(),_armv4tl() );
323         defCompatibleWith( _armv5tel(),         _noarch(),_armv3l(),_armv4l(),_armv4tl(),_armv5l() );
324         defCompatibleWith( _armv5tejl(),        _noarch(),_armv3l(),_armv4l(),_armv4tl(),_armv5l(),_armv5tel() );
325         defCompatibleWith( _armv6l(),           _noarch(),_armv3l(),_armv4l(),_armv4tl(),_armv5l(),_armv5tel(),_armv5tejl() );
326         defCompatibleWith( _armv7l(),           _noarch(),_armv3l(),_armv4l(),_armv4tl(),_armv5l(),_armv5tel(),_armv5tejl(),_armv6l() );
327         defCompatibleWith( _armv7hl(),          _noarch() );
328         defCompatibleWith( _armv7nhl(),         _noarch(),_armv7hl() );
329         defCompatibleWith( _armv7thl(),         _noarch(),_armv7hl() );
330         defCompatibleWith( _armv7tnhl(),        _noarch(),_armv7hl(),_armv7nhl(),_armv7thl() );
331         defCompatibleWith( _aarch64(),          _noarch() );
332         //
333         defCompatibleWith( _sh3(),              _noarch() );
334         //
335         defCompatibleWith( _sh4(),              _noarch() );
336         defCompatibleWith( _sh4a(),             _noarch(),_sh4() );
337         //
338         ///////////////////////////////////////////////////////////////////
339         // dumpOn( USR ) << endl;
340       }
341
342     private:
343       /** Return the next avialable _idBit.
344        * Ctor injects _noarch into the _compatSet, 1 is for
345        * nonbuiltin archs, so we can use <tt>size</tt> for
346        * buitin archs.
347       */
348       CompatBits::IntT nextIdBit() const
349       {
350         if ( CompatBits::size == _compatSet.size() )
351         {
352           // Provide more bits in CompatBits::IntT
353           INT << "Need more than " << CompatBits::size << " bits to encode architectures." << endl;
354           ZYPP_THROW( Exception("Need more bits to encode architectures.") );
355         }
356         CompatBits::IntT nextBit = CompatBits::IntT(1) << (_compatSet.size());
357         return nextBit;
358       }
359
360       /** Assert each builtin Arch gets an unique _idBit when
361        *  inserted into the _compatSet.
362       */
363       const CompatEntry & assertCompatSetEntry( IdString archStr_r )
364       { return *_compatSet.insert( Arch::CompatEntry( archStr_r, nextIdBit() ) ).first; }
365
366       /** Initialize builtin Archs and set _compatBits.
367       */
368       void defCompatibleWith( IdString targetArch_r,
369                               IdString arch0_r,
370                               IdString arch1_r = IdString(),
371                               IdString arch2_r = IdString(),
372                               IdString arch3_r = IdString(),
373                               IdString arch4_r = IdString(),
374                               IdString arch5_r = IdString(),
375                               IdString arch6_r = IdString(),
376                               IdString arch7_r = IdString(),
377                               IdString arch8_r = IdString(),
378                               IdString arch9_r = IdString() )
379       {
380         const CompatEntry & target( assertCompatSetEntry( targetArch_r ) );
381         target.addCompatBit( assertCompatSetEntry( arch0_r )._idBit );
382 #define _SETARG(N) if ( arch##N##_r.empty() ) return; target.addCompatBit( assertCompatSetEntry( arch##N##_r )._idBit )
383         _SETARG(1); _SETARG(2); _SETARG(3); _SETARG(4);
384         _SETARG(5); _SETARG(6); _SETARG(7); _SETARG(8); _SETARG(9);
385 #undef _SETARG
386       }
387
388     private:
389       Set _compatSet;
390     };
391
392     /////////////////////////////////////////////////////////////////
393   } // namespace
394   ///////////////////////////////////////////////////////////////////
395
396   ///////////////////////////////////////////////////////////////////
397   //
398   //    CLASS NAME : Arch
399   //
400   ///////////////////////////////////////////////////////////////////
401
402   const Arch Arch_empty ( IdString::Empty );
403   const Arch Arch_noarch( _noarch() );
404
405   const Arch Arch_i386( _i386() );
406   const Arch Arch_i486( _i486() );
407   const Arch Arch_i586( _i586() );
408   const Arch Arch_i686( _i686() );
409   const Arch Arch_athlon( _athlon() );
410   const Arch Arch_x86_64( _x86_64() );
411
412   const Arch Arch_pentium3( _pentium3() );
413   const Arch Arch_pentium4( _pentium4() );
414
415   const Arch Arch_s390( _s390() );
416   const Arch Arch_s390x( _s390x() );
417
418   const Arch Arch_ppc( _ppc() );
419   const Arch Arch_ppc64( _ppc64() );
420   const Arch Arch_ppc64p7( _ppc64p7() );
421
422   const Arch Arch_ia64( _ia64() );
423
424   const Arch Arch_alphaev67( _alphaev67() );
425   const Arch Arch_alphaev6( _alphaev6() );
426   const Arch Arch_alphapca56( _alphapca56() );
427   const Arch Arch_alphaev56( _alphaev56() );
428   const Arch Arch_alphaev5( _alphaev5() );
429   const Arch Arch_alpha( _alpha() );
430
431   const Arch Arch_sparc64v( _sparc64v() );
432   const Arch Arch_sparc64( _sparc64() );
433   const Arch Arch_sparcv9v( _sparcv9v() );
434   const Arch Arch_sparcv9( _sparcv9() );
435   const Arch Arch_sparcv8( _sparcv8() );
436   const Arch Arch_sparc( _sparc() );
437
438   const Arch Arch_aarch64( _aarch64() );
439   const Arch Arch_armv7tnhl( _armv7tnhl() );
440   const Arch Arch_armv7thl( _armv7thl() );
441   const Arch Arch_armv7nhl ( _armv7nhl() );
442   const Arch Arch_armv7hl ( _armv7hl() );
443   const Arch Arch_armv7l( _armv7l() );
444   const Arch Arch_armv6l( _armv6l() );
445   const Arch Arch_armv5tejl( _armv5tejl() );
446   const Arch Arch_armv5tel( _armv5tel() );
447   const Arch Arch_armv5l( _armv5l() );
448   const Arch Arch_armv4tl( _armv4tl() );
449   const Arch Arch_armv4l( _armv4l() );
450   const Arch Arch_armv3l( _armv3l() );
451
452   const Arch Arch_sh3( _sh3() );
453
454   const Arch Arch_sh4( _sh4() );
455   const Arch Arch_sh4a( _sh4a() );
456
457   ///////////////////////////////////////////////////////////////////
458   //
459   //    METHOD NAME : Arch::Arch
460   //    METHOD TYPE : Ctor
461   //
462   Arch::Arch()
463   : _entry( &ArchCompatSet::instance().assertDef( _noarch() ) )
464   {}
465
466   Arch::Arch( IdString::IdType id_r )
467   : _entry( &ArchCompatSet::instance().assertDef( IdString(id_r) ) )
468   {}
469
470   Arch::Arch( const IdString & idstr_r )
471   : _entry( &ArchCompatSet::instance().assertDef( idstr_r ) )
472   {}
473
474   Arch::Arch( const std::string & str_r )
475   : _entry( &ArchCompatSet::instance().assertDef( str_r ) )
476   {}
477
478   Arch::Arch( const char * cstr_r )
479   : _entry( &ArchCompatSet::instance().assertDef( cstr_r ) )
480   {}
481
482   Arch::Arch( const CompatEntry & rhs )
483   : _entry( &rhs )
484   {}
485
486   ///////////////////////////////////////////////////////////////////
487   //
488   //    METHOD NAME : Arch::idStr
489   //    METHOD TYPE : IdString
490   //
491   IdString Arch::idStr() const
492   { return _entry->_idStr; }
493
494   ///////////////////////////////////////////////////////////////////
495   //
496   //    METHOD NAME : Arch::asString
497   //    METHOD TYPE : const std::string &
498   //
499   const std::string & Arch::asString() const
500   { return _entry->_archStr; }
501
502   ///////////////////////////////////////////////////////////////////
503   //
504   //    METHOD NAME : Arch::isBuiltIn
505   //    METHOD TYPE : bool
506   //
507   bool Arch::isBuiltIn() const
508   { return _entry->isBuiltIn(); }
509
510   ///////////////////////////////////////////////////////////////////
511   //
512   //    METHOD NAME : Arch::compatibleWith
513   //    METHOD TYPE : bool
514   //
515   bool Arch::compatibleWith( const Arch & targetArch_r ) const
516   { return _entry->compatibleWith( *targetArch_r._entry ); }
517
518   ///////////////////////////////////////////////////////////////////
519   //
520   //    METHOD NAME : Arch::baseArch
521   //    METHOD TYPE : Arch
522   //
523   Arch Arch::baseArch( ) const
524   {
525     // check the multilib archs:
526     if (Arch_x86_64.compatibleWith(*this))
527     {
528       return Arch_x86_64;
529     }
530     if (Arch_sparc64v.compatibleWith(*this))
531     {
532       return Arch_sparc64v;
533     }
534     if (Arch_sparc64.compatibleWith(*this))
535     {
536       return Arch_sparc64;
537     }
538     if (Arch_ppc64.compatibleWith(*this))
539     {
540       return Arch_ppc64;
541     }
542     if (Arch_s390x.compatibleWith(*this))
543     {
544       return Arch_s390x;
545     }
546     // Here: no multilib; return arch before noarch
547     CompatSet cset( compatSet( *this ) );
548     if ( cset.size() > 2 )      // systemArchitecture, ..., basearch, noarch
549     {
550       return *(++cset.rbegin());
551     }
552     return *this;
553   }
554
555   ///////////////////////////////////////////////////////////////////
556   //
557   //    METHOD NAME : Arch::compare
558   //    METHOD TYPE : bool
559   //
560   int Arch::compare( const Arch & rhs ) const
561   { return _entry->compare( *rhs._entry ); }
562
563   ///////////////////////////////////////////////////////////////////
564   //
565   //    METHOD NAME : Arch::compatSet
566   //    METHOD TYPE : Arch::CompatSet
567   //
568   Arch::CompatSet Arch::compatSet( const Arch & targetArch_r )
569   {
570     Arch::CompatSet ret;
571
572     for ( ArchCompatSet::const_iterator it = ArchCompatSet::instance().begin();
573           it != ArchCompatSet::instance().end(); ++it )
574       {
575         if ( it->compatibleWith( *targetArch_r._entry ) )
576           {
577             ret.insert( Arch(*it) );
578           }
579       }
580
581     return ret;
582   }
583
584   /////////////////////////////////////////////////////////////////
585 } // namespace zypp
586 ///////////////////////////////////////////////////////////////////