provide minimal scoring on architectures
[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 <set>
14 #include <map>
15
16 #include "zypp/Arch.h"
17
18 using namespace std;
19
20 ///////////////////////////////////////////////////////////////////
21 namespace
22 { /////////////////////////////////////////////////////////////////
23
24   /** Dumb Arch compat table
25    * \todo improve
26    */
27   struct CompatTable
28   {
29       static set<string> _compatTable;
30
31       /** \return Whether \a lhs is compatible with \a rhs. */
32       static bool compatible( const zypp::Arch & lhs, const zypp::Arch & rhs )
33           {
34               if ( lhs == zypp::Arch_noarch )
35                   return true;
36
37               if ( _compatTable.empty() )
38               {
39                   // initialize
40 #define DEF_COMPAT(L,R) _compatTable.insert( #L "|" #R )
41                   DEF_COMPAT( noarch,   i386 );
42                   DEF_COMPAT( noarch,   i486 );
43                   DEF_COMPAT( i386,     i486 );
44                   DEF_COMPAT( noarch,   i586 );
45                   DEF_COMPAT( i386,     i586 );
46                   DEF_COMPAT( i486,     i586 );
47                   DEF_COMPAT( noarch,   i686 );
48                   DEF_COMPAT( i386,     i686 );
49                   DEF_COMPAT( i486,     i686 );
50                   DEF_COMPAT( i586,     i686 );
51                   DEF_COMPAT( noarch,   athlon );
52                   DEF_COMPAT( i386,     athlon );
53                   DEF_COMPAT( i486,     athlon );
54                   DEF_COMPAT( i586,     athlon );
55                   DEF_COMPAT( i686,     athlon );
56                   DEF_COMPAT( noarch,   x86_64 );
57                   DEF_COMPAT( i386,     x86_64 );
58                   DEF_COMPAT( i486,     x86_64 );
59                   DEF_COMPAT( i586,     x86_64 );
60                   DEF_COMPAT( i686,     x86_64 );
61                   DEF_COMPAT( athlon,   x86_64 );
62
63                   DEF_COMPAT( noarch,   s390 );
64                   DEF_COMPAT( noarch,   s390x );
65                   DEF_COMPAT( s390,     s390x );
66
67                   DEF_COMPAT( noarch,   ppc );
68                   DEF_COMPAT( noarch,   ppc64 );
69                   DEF_COMPAT( ppc,      ppc64 );
70
71                   DEF_COMPAT( noarch,   ia64 );
72 #undef DEF_COMPAT
73               }
74
75               return _compatTable.find( lhs.asString()+"|"+rhs.asString() )
76                   != _compatTable.end();
77           }
78   };
79
80     set<string> CompatTable::_compatTable;
81
82     /////////////////////////////////////////////////////////////////
83 } // namespace
84 ///////////////////////////////////////////////////////////////////
85
86 ///////////////////////////////////////////////////////////////////
87 namespace zypp
88 { /////////////////////////////////////////////////////////////////
89
90   ///////////////////////////////////////////////////////////////////
91 #define DEF_BUILTIN(A) const Arch Arch_##A( #A )
92
93   DEF_BUILTIN( noarch );
94   DEF_BUILTIN( src );
95
96   DEF_BUILTIN( x86_64 );
97   DEF_BUILTIN( athlon );
98   DEF_BUILTIN( i686 );
99   DEF_BUILTIN( i586 );
100   DEF_BUILTIN( i486 );
101   DEF_BUILTIN( i386 );
102
103   DEF_BUILTIN( s390x );
104   DEF_BUILTIN( s390 );
105
106   DEF_BUILTIN( ppc64 );
107   DEF_BUILTIN( ppc );
108
109   DEF_BUILTIN( ia64 );
110
111 #undef DEF_BUILTIN
112
113  static const string canonical_arch (const string & arch);
114
115  //---------------------------------------------------------------------------
116  // architecture stuff
117       
118  static const string
119  canonical_arch (const string & arch)
120  {
121      typedef struct { char *from; char *to; } canonical;
122      // convert machine string to known_arch
123      static canonical canonical_archs[] = {
124          { "noarch",  "noarch" },
125          { "unknown", "unknown" },
126          { "any",     "any" },
127          { "all",     "any" },
128          { "i386",    "i386" },
129          { "ix86",    "i386" }, /* OpenPKG uses this */
130          { "i486",    "i486" },
131          { "i586",    "i586" },
132          { "i686",    "i686" },
133          { "x86_64",  "x86_64" },
134          { "ia32e",   "ia32e" },
135          { "athlon",  "athlon" },
136          { "ppc",     "ppc" },
137          { "ppc64",   "ppc64" },
138          { "s390",    "s390" },
139          { "s390x",   "s390x" },
140          { "ia64",    "ia64" },
141          { "sparc",   "sparc" },
142          { "sun4c",   "sparc" },
143          { "sun4d",   "sparc" },
144          { "sun4m",   "sparc" },
145          { "sparc64", "sparc64" },
146          { "sun4u",   "sparc64" },
147          { "sparcv9", "sparc64" },
148          { 0 }
149      };
150       
151      for (canonical *ptr = canonical_archs; ptr->from; ptr++) {
152          if (arch == ptr->from) {
153              return ptr->to;
154          }
155      }
156       
157      return "canonical";
158  }
159       
160 //---------------------------------------------------------------------------
161     
162   ///////////////////////////////////////////////////////////////////
163
164   ///////////////////////////////////////////////////////////////////
165   //
166   //    METHOD NAME : Arch::Arch
167   //    METHOD TYPE : Ctor
168   //
169   Arch::Arch( const std::string & rhs )
170   : _value( rhs )
171   , _score( 0 )
172   {
173       static map<string,int> arch_scores;
174       if (arch_scores.empty()) {
175         arch_scores["noarch"] = 0;
176         arch_scores["src"] = 0;
177         arch_scores["i386"] = 1;
178         arch_scores["i486"] = 2;
179         arch_scores["i586"] = 3;
180         arch_scores["i686"] = 4;
181         arch_scores["athlon"] = 4;
182         arch_scores["x86_64"] = 5;
183         arch_scores["ia64"] = 1;
184         arch_scores["ppc"] = 1;
185         arch_scores["ppc64"] = 2;
186         arch_scores["s390"] = 1;
187         arch_scores["s390x"] = 2;
188       };
189       map<string,int>::const_iterator it = arch_scores.find( rhs );
190       if (it != arch_scores.end())
191         _score = it->second;
192   }
193
194   ///////////////////////////////////////////////////////////////////
195   //
196   //    METHOD NAME : Arch::compatibleWith
197   //    METHOD TYPE : bool
198   //
199   bool Arch::compatibleWith( const Arch & rhs ) const
200   {
201     return _value.empty()
202         || *this == rhs
203         || CompatTable::compatible( *this, rhs );
204   }
205
206   /////////////////////////////////////////////////////////////////
207 } // namespace zypp
208 ///////////////////////////////////////////////////////////////////