libzypp 17.37.10

VendorAttr.cc
Go to the documentation of this file.
1/*---------------------------------------------------------------------\
2| ____ _ __ __ ___ |
3| |__ / \ / / . \ . \ |
4| / / \ V /| _/ _/ |
5| / /__ | | | | | | |
6| /_____||_| |_| |_| |
7| |
8\---------------------------------------------------------------------*/
11#include <iostream>
12#include <fstream>
13#include <set>
14#include <map>
15#include <vector>
16
17#include <zypp/base/LogTools.h>
18#include <zypp/base/IOStream.h>
19#include <zypp/base/StringV.h>
20
21#include <zypp/PathInfo.h>
22#include <zypp/VendorAttr.h>
23#include <zypp/ZYppFactory.h>
24
25#include <zypp/ZConfig.h>
26#include <zypp/PathInfo.h>
27#include <zypp-core/parser/IniDict>
28
29#undef ZYPP_BASE_LOGGER_LOGGROUP
30#define ZYPP_BASE_LOGGER_LOGGROUP "zypp::VendorAttr"
31
33 namespace zypp
34{
35
40 class VendorAttr::Impl // : private base::NonCopyable
41 {
42 friend std::ostream & operator<<( std::ostream & str, const Impl & obj );
43 public:
50 Impl()
51 { _vendorGroupMap["suse"] = ++_vendorGroupId; }
52
53 public:
55 void addVendorList( VendorList && vendorList_r );
56
58 bool equivalent( IdString lVendor, IdString rVendor ) const
59 { return lVendor == rVendor || vendorMatchId( lVendor ) == vendorMatchId( rVendor ); }
60
62 bool relaxedEquivalent( IdString lVendor, IdString rVendor ) const
63 {
64 if ( equivalent( lVendor, rVendor ) )
65 return true;
66
67 static const IdString suse { "suse" };
68 static const IdString opensuse { "opensuse" };
69 unsigned sid = vendorMatchId( suse );
70 unsigned oid = vendorMatchId( opensuse );
71 if ( sid == oid )
72 return false; // (suse/opensuse) are equivalent, so these are not
73
74 auto isSuse = [sid,oid]( unsigned v )-> bool { return v==sid || v==oid; };
75 return isSuse( vendorMatchId(lVendor) ) && isSuse( vendorMatchId(rVendor) );
76 }
77
78 unsigned foreachVendorList( const std::function<bool(VendorList)>& fnc_r ) const
79 {
80 std::map<unsigned,VendorList> lists;
81 for( const auto & el : _vendorGroupMap )
82 lists[el.second].push_back( el.first );
83
84 unsigned ret = 0;
85 for ( auto& el : lists ) {
86 VendorList & vlist { el.second };
87 if ( vlist.empty() )
88 continue;
89 ++ret;
90 if ( fnc_r && !fnc_r( std::move(vlist) ) )
91 break;
92 }
93 return ret;
94 }
95
96 private:
97 using VendorGroupMap = std::map<std::string,unsigned>;
98 VendorGroupMap _vendorGroupMap;
99 unsigned _vendorGroupId = 0;
100
101 private:
102 using VendorMatchEntry = DefaultIntegral<unsigned int, 0>;
103 using VendorMatch = std::unordered_map<IdString, VendorMatchEntry>;
104 mutable VendorMatch _vendorMatch;
105 mutable unsigned _nextId = 0;
106
108 void vendorMatchIdReset()
109 {
110 _nextId = 0;
111 _vendorMatch.clear();
112 }
113
121 unsigned vendorMatchId( IdString vendor ) const;
122
123 private:
124 friend Impl * rwcowClone<Impl>( const Impl * rhs );
126 Impl * clone() const
127 { return new Impl( *this ); }
128 };
129
130 unsigned VendorAttr::Impl::vendorMatchId( IdString vendor ) const
131 {
132 VendorMatchEntry & ent { _vendorMatch[vendor] };
133 if ( ! ent )
134 {
135 IdString lcvendor { str::toLower( vendor.asString() ) };
136 VendorMatchEntry & lcent( _vendorMatch[lcvendor] );
137 if ( ! lcent )
138 {
139 // Cache miss - check whether it belongs to a vendor group.
140 // Otherwise assign a new class ID to it.
141 unsigned myid = 0;
142
143 // bnc#812608: no prefix compare in opensuse namespace
144 if ( str::hasPrefix( lcvendor.c_str(), "opensuse" ) )
145 {
146 if ( auto it = _vendorGroupMap.find( lcvendor.c_str() ); it != _vendorGroupMap.end() )
147 myid = it->second;
148 }
149 else
150 {
151 // Compare this entry with the global vendor map.
152 // Reversed to get the longest prefix.
153 for ( VendorGroupMap::const_reverse_iterator it = _vendorGroupMap.rbegin(); it != _vendorGroupMap.rend(); ++it )
154 {
155 if ( str::hasPrefix( lcvendor.c_str(), it->first ) ) {
156 myid = it->second;
157 break; // found
158 }
159 }
160 }
161
162 if ( ! myid )
163 myid = --_nextId; // get a new class ID
164
165 ent = lcent = myid; // remember the new DI
166 }
167 else
168 ent = lcent; // take the ID from the lowercased vendor string
169 }
170 return ent;
171 }
172
173 void VendorAttr::Impl::addVendorList( VendorList && vendorList_r )
174 {
175 // Will add a new equivalence group unless we merge with existing groups.
176 unsigned targetId = _vendorGroupId + 1;
177
178 // (!) Convert the group strings in place to lowercase before adding/checking.
179 // Extend/join already existing groups if they are referenced.
180 for ( std::string & vendor : vendorList_r )
181 {
182 vendor = str::toLower( std::move(vendor) );
183
184 if ( _vendorGroupMap.count( vendor ) )
185 {
186 unsigned joinId = _vendorGroupMap[vendor];
187 if ( targetId == _vendorGroupId + 1 ) {
188 targetId = joinId; // will extend the existing group
189 }
190 else if ( targetId != joinId ) {
191 // yet another existing group -> join it into the target group
192 for ( auto & el : _vendorGroupMap ) {
193 if ( el.second == joinId )
194 el.second = targetId;
195 }
196 }
197 vendor.clear(); // no need to add it later
198 }
199 }
200
201 // Now add the new entries
202 for ( std::string & vendor : vendorList_r ) {
203 if ( ! vendor.empty() )
204 _vendorGroupMap[vendor] = targetId;
205 }
206
207 if ( targetId == _vendorGroupId + 1 )
208 ++_vendorGroupId;
209
210 // invalidate any match cache
211 vendorMatchIdReset();
212 }
213
215 inline std::ostream & operator<<( std::ostream & str, const VendorAttr::Impl & obj )
216 {
217 str << "Equivalent vendors:";
218 for( const auto & p : obj._vendorGroupMap ) {
219 str << endl << " [" << p.second << "] " << p.first;
220 }
221 return str;
222 }
223
225 //
226 // CLASS NAME : VendorAttr
227 //
229
230 const VendorAttr & VendorAttr::instance()
231 {
232 Target_Ptr trg { getZYpp()->getTarget() };
233 return trg ? trg->vendorAttr() : noTargetInstance();
234 }
235
236 VendorAttr & VendorAttr::noTargetInstance()
237 {
238 static VendorAttr _val { ZConfig::instance().vendorPath() };
239 return _val;
240 }
241
242 VendorAttr::VendorAttr()
243 : _pimpl( new Impl )
244 {
245 MIL << "Initial: " << *this << endl;
246 }
247
248 VendorAttr::VendorAttr( const Pathname & initial_r )
249 : _pimpl( new Impl )
250 {
251 addVendorDirectory( initial_r );
252 MIL << "Initial " << initial_r << ": " << *this << endl;
253 }
254
255 VendorAttr::~VendorAttr()
256 {}
257
258 bool VendorAttr::addVendorDirectory( const Pathname & dirname_r )
259 {
260 if ( PathInfo pi { dirname_r }; ! pi.isDir() ) {
261 MIL << "Not a directory " << pi << endl;
262 return false;
263 }
264
265 filesystem::dirForEach( dirname_r, filesystem::matchNoDots(),
266 [this]( const Pathname & dir_r, const std::string & str_r )->bool
267 {
268 this->addVendorFile( dir_r/str_r );
269 return true;
270 }
271 );
272 return true;
273 }
274
275 bool VendorAttr::addVendorFile( const Pathname & filename_r )
276 {
277 if ( PathInfo pi { filename_r }; ! pi.isFile() ) {
278 MIL << "Not a file " << pi << endl;
279 return false;
280 }
281
282 parser::IniDict dict { InputStream(filename_r) };
283 for ( const auto & el : dict.entries("main") )
284 {
285 if ( el.first == "vendors" )
286 {
287 VendorList tmp;
288 strv::split( el.second, ",", strv::Trim::trim,
289 [&tmp]( std::string_view word ) {
290 if ( ! word.empty() )
291 tmp.push_back( std::string(word) );
292 } );
293 _addVendorList( std::move(tmp) );
294 break;
295 }
296 }
297 return true;
298 }
299
300 void VendorAttr::_addVendorList( VendorList && vendorList_r )
301 { _pimpl->addVendorList( std::move(vendorList_r) ); }
302
303 unsigned VendorAttr::foreachVendorList( std::function<bool(VendorList)> fnc_r ) const
304 { return _pimpl->foreachVendorList( std::move(fnc_r) ); }
305
307 // vendor equivalence:
309
310 bool VendorAttr::equivalent( IdString lVendor, IdString rVendor ) const
311 { return _pimpl->equivalent( lVendor, rVendor );}
312
313 bool VendorAttr::equivalent( const Vendor & lVendor, const Vendor & rVendor ) const
314 { return _pimpl->equivalent( IdString( lVendor ), IdString( rVendor ) ); }
315
316 bool VendorAttr::equivalent( sat::Solvable lVendor, sat::Solvable rVendor ) const
317 { return _pimpl->equivalent( lVendor.vendor(), rVendor.vendor() ); }
318
319 bool VendorAttr::equivalent( const PoolItem & lVendor, const PoolItem & rVendor ) const
320 { return _pimpl->equivalent( lVendor.satSolvable().vendor(), rVendor.satSolvable().vendor() ); }
321
322
323 bool VendorAttr::relaxedEquivalent( IdString lVendor, IdString rVendor ) const
324 { return _pimpl->relaxedEquivalent( lVendor, rVendor );}
325
326 bool VendorAttr::relaxedEquivalent( const Vendor & lVendor, const Vendor & rVendor ) const
327 { return _pimpl->relaxedEquivalent( IdString( lVendor ), IdString( rVendor ) ); }
328
329 bool VendorAttr::relaxedEquivalent( sat::Solvable lVendor, sat::Solvable rVendor ) const
330 { return _pimpl->relaxedEquivalent( lVendor.vendor(), rVendor.vendor() ); }
331
332 bool VendorAttr::relaxedEquivalent( const PoolItem & lVendor, const PoolItem & rVendor ) const
333 { return _pimpl->relaxedEquivalent( lVendor.satSolvable().vendor(), rVendor.satSolvable().vendor() ); }
334
336
337 std::ostream & operator<<( std::ostream & str, const VendorAttr & obj )
338 { return str << *obj._pimpl; }
339
341} // namespace zypp
343
VendorAttr.h
ZConfig.h
ZYppFactory.h
Target_Ptr
zypp::DefaultIntegral
Integral type with defined initial value when default constructed.
Definition defaultintegral.h:42
zypp::IdString
Access to the sat-pools string space.
Definition IdString.h:44
zypp::IdString::c_str
const char * c_str() const
Conversion to const char *
Definition IdString.cc:50
zypp::IdString::asString
std::string asString() const
Conversion to std::string
Definition IdString.h:99
zypp::InputStream
Helper to create and pass std::istream.
Definition inputstream.h:57
zypp::PoolItem
Combining sat::Solvable and ResStatus.
Definition PoolItem.h:51
zypp::VendorAttr::Impl
VendorAttr implementation.
Definition VendorAttr.cc:41
zypp::VendorAttr::Impl::relaxedEquivalent
bool relaxedEquivalent(IdString lVendor, IdString rVendor) const
Return whether two vendor strings should be treated as equivalent or are (suse/opensuse).
Definition VendorAttr.cc:62
zypp::VendorAttr::Impl::_vendorMatch
VendorMatch _vendorMatch
Cache mapping vendor strings to equivalence class ID.
Definition VendorAttr.cc:104
zypp::VendorAttr::Impl::VendorGroupMap
std::map< std::string, unsigned > VendorGroupMap
Definition VendorAttr.cc:97
zypp::VendorAttr::Impl::vendorMatchId
unsigned vendorMatchId(IdString vendor) const
Helper mapping a vendor string to its eqivalence class ID.
Definition VendorAttr.cc:130
zypp::VendorAttr::Impl::equivalent
bool equivalent(IdString lVendor, IdString rVendor) const
Return whether two vendor strings should be treated as equivalent.
Definition VendorAttr.cc:58
zypp::VendorAttr::Impl::VendorMatchEntry
DefaultIntegral< unsigned int, 0 > VendorMatchEntry
Definition VendorAttr.cc:102
zypp::VendorAttr::Impl::clone
Impl * clone() const
clone for RWCOW_pointer
Definition VendorAttr.cc:126
zypp::VendorAttr::Impl::vendorMatchIdReset
void vendorMatchIdReset()
Reset vendor match cache if _vendorGroupMap was changed.
Definition VendorAttr.cc:108
zypp::VendorAttr::Impl::rwcowClone
friend Impl * rwcowClone(const Impl *rhs)
zypp::VendorAttr::Impl::_vendorGroupMap
VendorGroupMap _vendorGroupMap
Vendor group definition. Equivalent groups share the same ID.
Definition VendorAttr.cc:98
zypp::VendorAttr::Impl::operator<<
std::ostream & operator<<(std::ostream &str, const VendorAttr::Impl &obj)
Stream output.
Definition VendorAttr.cc:215
zypp::VendorAttr::Impl::operator<<
friend std::ostream & operator<<(std::ostream &str, const Impl &obj)
zypp::VendorAttr::Impl::_nextId
unsigned _nextId
Least equivalence class ID in use (decremented).
Definition VendorAttr.cc:105
zypp::VendorAttr::Impl::Impl
Impl()
Ctor.
Definition VendorAttr.cc:50
zypp::VendorAttr::Impl::_vendorGroupId
unsigned _vendorGroupId
Highest group ID in use (incremented).
Definition VendorAttr.cc:99
zypp::VendorAttr::Impl::foreachVendorList
unsigned foreachVendorList(const std::function< bool(VendorList)> &fnc_r) const
Definition VendorAttr.cc:78
zypp::VendorAttr::Impl::VendorMatch
std::unordered_map< IdString, VendorMatchEntry > VendorMatch
Definition VendorAttr.cc:103
zypp::VendorAttr::Impl::addVendorList
void addVendorList(VendorList &&vendorList_r)
Add a new equivalent vendor set.
Definition VendorAttr.cc:173
zypp::VendorAttr::~VendorAttr
~VendorAttr()
Dtor.
Definition VendorAttr.cc:255
zypp::VendorAttr::VendorAttr
VendorAttr()
Ctor providing the default set.
Definition VendorAttr.cc:242
zypp::VendorAttr::noTargetInstance
static VendorAttr & noTargetInstance()
Singleton, settings used if no Target is active.
Definition VendorAttr.cc:236
zypp::VendorAttr::equivalent
bool equivalent(const Vendor &lVendor, const Vendor &rVendor) const
Return whether two vendor strings should be treated as the same vendor.
Definition VendorAttr.cc:313
zypp::VendorAttr::VendorList
std::vector< std::string > VendorList
Preferred type to pass equivalent vendor strings.
Definition VendorAttr.h:100
zypp::VendorAttr::addVendorFile
bool addVendorFile(const Pathname &filename_r)
Adding new equivalent vendors described in a file.
Definition VendorAttr.cc:275
zypp::VendorAttr::_pimpl
RWCOW_pointer< Impl > _pimpl
Implementation class.
Definition VendorAttr.h:159
zypp::VendorAttr::foreachVendorList
unsigned foreachVendorList(std::function< bool(VendorList)> fnc_r) const
Call fnc_r for each equivalent vendor list (return false to break).
Definition VendorAttr.cc:303
zypp::VendorAttr::relaxedEquivalent
bool relaxedEquivalent(const Vendor &lVendor, const Vendor &rVendor) const
Like equivalent but always unifies suse and openSUSE vendor.
Definition VendorAttr.cc:326
zypp::VendorAttr::instance
static const VendorAttr & instance()
(Pseudo)Singleton, mapped to the current Target::vendorAttr settings or to noTargetInstance.
Definition VendorAttr.cc:230
zypp::VendorAttr::_addVendorList
void _addVendorList(VendorList &&list_r)
Definition VendorAttr.cc:300
zypp::VendorAttr::addVendorDirectory
bool addVendorDirectory(const Pathname &dirname_r)
Adding new equivalent vendors described in a directory.
Definition VendorAttr.cc:258
zypp::ZConfig::vendorPath
Pathname vendorPath() const
Directory for equivalent vendor definitions (configPath()/vendors.d)
Definition ZConfig.cc:1174
zypp::ZConfig::instance
static ZConfig & instance()
Singleton ctor.
Definition ZConfig.cc:940
zypp::ZYppFactory::getZYpp
ZYpp::Ptr getZYpp()
Convenience to get the Pointer to the ZYpp instance.
Definition ZYppFactory.h:77
zypp::filesystem::PathInfo
Wrapper class for stat/lstat.
Definition PathInfo.h:226
zypp::filesystem::PathInfo::isDir
bool isDir() const
Definition PathInfo.h:296
zypp::filesystem::PathInfo::isFile
bool isFile() const
Definition PathInfo.h:295
zypp::filesystem::Pathname
Pathname.
Definition Pathname.h:47
zypp::parser::IniDict
Parses a INI file and offers its structure as a dictionary.
Definition inidict.h:42
zypp::parser::IniDict::entries
Iterable< entry_const_iterator > entries(const std::string &section) const
Definition inidict.cc:97
zypp::sat::Solvable
A Solvable object within the sat Pool.
Definition Solvable.h:54
zypp::sat::Solvable::vendor
IdString vendor() const
The vendor.
Definition Solvable.cc:358
str
String related utilities and Regular expression matching.
zypp::filesystem::matchNoDots
const StrMatcher & matchNoDots()
Convenience returning StrMatcher( "[^.]*", Match::GLOB )
Definition PathInfo.cc:26
zypp::filesystem::dirForEach
int dirForEach(const Pathname &dir_r, const StrMatcher &matcher_r, function< bool(const Pathname &, const char *const)> fnc_r)
Definition PathInfo.cc:32
zypp::str::hasPrefix
bool hasPrefix(const C_Str &str_r, const C_Str &prefix_r)
Return whether str_r has prefix prefix_r.
Definition String.h:1097
zypp::str::toLower
std::string toLower(const std::string &s)
Return lowercase version of s.
Definition String.cc:180
zypp
Easy-to use interface to the ZYPP dependency resolver.
Definition Application.cc:20
zypp::operator<<
std::ostream & operator<<(std::ostream &str, const SerialNumber &obj)
Definition SerialNumber.cc:52
zypp::Vendor
std::string Vendor
Definition Vendor.h:22
zypp::sat::SolvableType::satSolvable
Solvable satSolvable() const
Return the corresponding sat::Solvable.
Definition SolvableType.h:57
MIL
#define MIL
Definition Logger.h:100
PathInfo.h
IOStream.h
LogTools.h
StringV.h
c++17: std::string_view tools