1
/*---------------------------------------------------------------------\
3
| |__ / \ / / . \ . \ |
8
\---------------------------------------------------------------------*/
12
Author: Michael Andres <ma@suse.de>
13
Maintainer: Michael Andres <ma@suse.de>
15
Purpose: Manage vendor attributes
25
#include "zypp/base/LogTools.h"
26
#include "zypp/base/IOStream.h"
27
#include "zypp/base/String.h"
29
#include "zypp/PathInfo.h"
30
#include "zypp/VendorAttr.h"
31
#include "zypp/ZYppFactory.h"
33
#include "zypp/ZConfig.h"
34
#include "zypp/PathInfo.h"
35
#include "zypp/parser/IniDict.h"
39
#undef ZYPP_BASE_LOGGER_LOGGROUP
40
#define ZYPP_BASE_LOGGER_LOGGROUP "zypp::VendorAttr"
42
///////////////////////////////////////////////////////////////////
44
{ /////////////////////////////////////////////////////////////////
46
///////////////////////////////////////////////////////////////////
48
{ /////////////////////////////////////////////////////////////////
50
typedef map<Vendor,unsigned int> VendorMap;
52
unsigned int vendorGroupCounter;
54
/////////////////////////////////////////////////////////////////
56
///////////////////////////////////////////////////////////////////
58
///////////////////////////////////////////////////////////////////
60
{ /////////////////////////////////////////////////////////////////
61
typedef DefaultIntegral<int,0> VendorMatchEntry;
62
typedef std::tr1::unordered_map<IdString, VendorMatchEntry> VendorMatch;
64
VendorMatch _vendorMatch;
66
/** Reset match cache if global VendorMap was changed. */
67
inline void vendorMatchIdReset()
74
* Helper mapping vendor string to eqivalence class ID.
76
* \li Return the vendor strings eqivalence class ID stored in _vendorMatch.
77
* \li If not found, assign and return the eqivalence class ID of the lowercased string.
78
* \li If not found, assign and return a new ID (look into the predefined VendorMap (id>0),
79
* otherwise create a new ID (<0)).
81
inline unsigned vendorMatchId( IdString vendor )
83
VendorMatchEntry & ent( _vendorMatch[vendor] );
86
IdString lcvendor( str::toLower( vendor.asString() ) );
87
VendorMatchEntry & lcent( _vendorMatch[lcvendor] );
91
// bnc#812608: no pefix compare in opensuse namespace
92
static const IdString openSUSE( "opensuse" );
93
if ( lcvendor == openSUSE || ! str::hasPrefix( lcvendor.c_str(), openSUSE.c_str() ) )
95
// Compare this entry with the global vendor map.
96
// Reversed to get the longest prefix.
97
for ( VendorMap::reverse_iterator it = _vendorMap.rbegin(); it != _vendorMap.rend(); ++it )
99
if ( str::hasPrefix( lcvendor.c_str(), it->first ) )
108
myid = --_nextId; // get a new class ID
110
ent = lcent = myid; // remember the new DI
114
ent = lcent; // take the ID from the lowercased vendor string
119
/////////////////////////////////////////////////////////////////
121
///////////////////////////////////////////////////////////////////
123
const VendorAttr & VendorAttr::instance()
125
static VendorAttr _val;
129
VendorAttr::VendorAttr ()
131
vendorGroupCounter = 1;
132
Pathname vendorPath (ZConfig::instance().vendorPath());
134
Target_Ptr trg( getZYpp()->getTarget() );
136
vendorPath = trg->root() / vendorPath;
139
addVendorDirectory (vendorPath);
141
// Checking if suse,opensuse has been defined, else create entries:
142
// - if both are defined we leve them as thay are.
143
// - if only one of them is defined, we add the other to the same group.
144
// - if both are undefined they make up a new group
145
VendorMap::const_iterator suseit( _vendorMap.find("suse") );
146
VendorMap::const_iterator opensuseit( _vendorMap.find("opensuse") );
147
if ( suseit == _vendorMap.end() )
149
if ( opensuseit == _vendorMap.end() )
151
// both are undefined
152
_vendorMap["suse"] = _vendorMap["opensuse"] = ++vendorGroupCounter;
156
// add suse to opensuse
157
_vendorMap["suse"] = opensuseit->second;
160
else if ( opensuseit == _vendorMap.end() )
162
// add opensuse to suse
163
_vendorMap["opensuse"] = suseit->second;
166
MIL << *this << endl;
169
void VendorAttr::_addVendorList( VendorList & vendorList_r ) const
171
unsigned int nextId = vendorGroupCounter + 1;
172
// convert to lowercase and check if a vendor is already defined
173
// in an existing group.
175
for_( it, vendorList_r.begin(), vendorList_r.end() )
177
*it = str::toLower( *it );
178
if (_vendorMap.find(*it) != _vendorMap.end())
180
if (nextId != vendorGroupCounter + 1 &&
181
nextId != _vendorMap[*it])
183
// We have at least 3 groups which has to be mixed --> mix the third group to the first
184
unsigned int moveID = _vendorMap[*it];
185
for_( itMap, _vendorMap.begin(), _vendorMap.end() )
187
if (itMap->second == moveID)
188
itMap->second = nextId;
193
nextId = _vendorMap[*it];
194
WAR << "Vendor " << *it << " is already used in another vendor group. --> mixing these groups" << endl;
199
for_( it, vendorList_r.begin(), vendorList_r.end() )
201
_vendorMap[*it] = nextId;
204
if (nextId == vendorGroupCounter + 1)
205
++vendorGroupCounter;
207
// invalidate any match cache
208
vendorMatchIdReset();
211
bool VendorAttr::addVendorFile( const Pathname & filename ) const
213
parser::IniDict dict;
215
if ( PathInfo(filename).isExist())
217
InputStream is(filename);
222
MIL << filename << " not found." << endl;
226
for ( parser::IniDict::section_const_iterator sit = dict.sectionsBegin();
227
sit != dict.sectionsEnd();
230
string section(*sit);
231
//MIL << section << endl;
232
for ( parser::IniDict::entry_const_iterator it = dict.entriesBegin(*sit);
233
it != dict.entriesEnd(*sit);
236
string entry(it->first);
237
string value(it->second);
238
if ( section == "main" )
240
if ( entry == "vendors" )
242
VendorList vendorlist;
243
str::split( value, back_inserter(vendorlist), "," );
244
_addVendorList (vendorlist);
254
bool VendorAttr::addVendorDirectory( const Pathname & dirname ) const
256
parser::IniDict dict;
258
if ( PathInfo(dirname).isExist())
260
InputStream is(dirname);
265
MIL << dirname << " not found." << endl;
269
list<Pathname> filenames;
271
filesystem::readdir( filenames,
273
for (list<Pathname>::iterator it = filenames.begin();
274
it != filenames.end(); ++it) {
275
MIL << "Adding file " << *it << endl;
276
addVendorFile( *it );
281
//////////////////////////////////////////////////////////////////
282
// vendor equivalence:
283
//////////////////////////////////////////////////////////////////
285
bool VendorAttr::equivalent( IdString lVendor, IdString rVendor ) const
287
if ( lVendor == rVendor )
289
return vendorMatchId( lVendor ) == vendorMatchId( rVendor );
292
bool VendorAttr::equivalent( const Vendor & lVendor, const Vendor & rVendor ) const
293
{ return equivalent( IdString( lVendor ), IdString( rVendor ) );
296
bool VendorAttr::equivalent( sat::Solvable lVendor, sat::Solvable rVendor ) const
297
{ return equivalent( lVendor.vendor(), rVendor.vendor() ); }
299
bool VendorAttr::equivalent( const PoolItem & lVendor, const PoolItem & rVendor ) const
300
{ return equivalent( lVendor.satSolvable().vendor(), rVendor.satSolvable().vendor() ); }
302
//////////////////////////////////////////////////////////////////
304
std::ostream & operator<<( std::ostream & str, const VendorAttr & /*obj*/ )
306
str << "Equivalent vendors:";
307
for_( it, _vendorMap.begin(), _vendorMap.end() )
309
str << endl << " [" << it->second << "] " << it->first;
314
/////////////////////////////////////////////////////////////////
316
///////////////////////////////////////////////////////////////////