libzypp 17.25.7
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/parser/IniDict.h>
28
29#undef ZYPP_BASE_LOGGER_LOGGROUP
30#define ZYPP_BASE_LOGGER_LOGGROUP "zypp::VendorAttr"
31
33namespace zypp
34{
35
40 class VendorAttr::Impl // : private base::NonCopyable
41 {
42 friend std::ostream & operator<<( std::ostream & str, const Impl & obj );
43 public:
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
61 unsigned foreachVendorList( std::function<bool(VendorList)> fnc_r ) const
62 {
63 std::map<unsigned,VendorList> lists;
64 for( const auto & el : _vendorGroupMap )
65 lists[el.second].push_back( el.first );
66
67 unsigned ret = 0;
68 for ( auto el : lists ) {
69 VendorList & vlist { el.second };
70 if ( vlist.empty() )
71 continue;
72 ++ret;
73 if ( fnc_r && !fnc_r( std::move(vlist) ) )
74 break;
75 }
76 return ret;
77 }
78
79 private:
80 using VendorGroupMap = std::map<std::string,unsigned>;
82 unsigned _vendorGroupId = 0;
83
84 private:
86 typedef std::unordered_map<IdString, VendorMatchEntry> VendorMatch;
88 mutable unsigned _nextId = 0;
89
92 {
93 _nextId = 0;
94 _vendorMatch.clear();
95 }
96
104 unsigned vendorMatchId( IdString vendor ) const;
105
106 private:
107 friend Impl * rwcowClone<Impl>( const Impl * rhs );
109 Impl * clone() const
110 { return new Impl( *this ); }
111 };
112
114 {
115 VendorMatchEntry & ent { _vendorMatch[vendor] };
116 if ( ! ent )
117 {
118 IdString lcvendor { str::toLower( vendor.asString() ) };
119 VendorMatchEntry & lcent( _vendorMatch[lcvendor] );
120 if ( ! lcent )
121 {
122 // Cache miss - check whether it belongs to a vendor group.
123 // Otherwise assign a new class ID to it.
124 unsigned myid = 0;
125
126 // bnc#812608: no prefix compare in opensuse namespace
127 if ( str::hasPrefix( lcvendor.c_str(), "opensuse" ) )
128 {
129 if ( auto it = _vendorGroupMap.find( lcvendor.c_str() ); it != _vendorGroupMap.end() )
130 myid = it->second;
131 }
132 else
133 {
134 // Compare this entry with the global vendor map.
135 // Reversed to get the longest prefix.
136 for ( VendorGroupMap::const_reverse_iterator it = _vendorGroupMap.rbegin(); it != _vendorGroupMap.rend(); ++it )
137 {
138 if ( str::hasPrefix( lcvendor.c_str(), it->first ) ) {
139 myid = it->second;
140 break; // found
141 }
142 }
143 }
144
145 if ( ! myid )
146 myid = --_nextId; // get a new class ID
147
148 ent = lcent = myid; // remember the new DI
149 }
150 else
151 ent = lcent; // take the ID from the lowercased vendor string
152 }
153 return ent;
154 }
155
157 {
158 // Will add a new equivalence group unless we merge with existing groups.
159 unsigned targetId = _vendorGroupId + 1;
160
161 // (!) Convert the group strings in place to lowercase before adding/checking.
162 // Extend/join already existing groups if they are referenced.
163 for ( std::string & vendor : vendorList_r )
164 {
165 vendor = str::toLower( std::move(vendor) );
166
167 if ( _vendorGroupMap.count( vendor ) )
168 {
169 unsigned joinId = _vendorGroupMap[vendor];
170 if ( targetId == _vendorGroupId + 1 ) {
171 targetId = joinId; // will extend the existing group
172 }
173 else if ( targetId != joinId ) {
174 // yet another existing group -> join it into the target group
175 for ( auto & el : _vendorGroupMap ) {
176 if ( el.second == joinId )
177 el.second = targetId;
178 }
179 }
180 vendor.clear(); // no need to add it later
181 }
182 }
183
184 // Now add the new entries
185 for ( std::string & vendor : vendorList_r ) {
186 if ( ! vendor.empty() )
187 _vendorGroupMap[vendor] = targetId;
188 }
189
190 if ( targetId == _vendorGroupId + 1 )
191 ++_vendorGroupId;
192
193 // invalidate any match cache
194 vendorMatchIdReset();
195 }
196
198 inline std::ostream & operator<<( std::ostream & str, const VendorAttr::Impl & obj )
199 {
200 str << "Equivalent vendors:";
201 for( const auto & p : obj._vendorGroupMap ) {
202 str << endl << " [" << p.second << "] " << p.first;
203 }
204 return str;
205 }
206
208 //
209 // CLASS NAME : VendorAttr
210 //
212
214 {
215 Target_Ptr trg { getZYpp()->getTarget() };
216 return trg ? trg->vendorAttr() : noTargetInstance();
217 }
218
220 {
221 static VendorAttr _val { ZConfig::instance().vendorPath() };
222 return _val;
223 }
224
226 : _pimpl( new Impl )
227 {
228 MIL << "Initial: " << *this << endl;
229 }
230
231 VendorAttr::VendorAttr( const Pathname & initial_r )
232 : _pimpl( new Impl )
233 {
234 addVendorDirectory( initial_r );
235 MIL << "Initial " << initial_r << ": " << *this << endl;
236 }
237
239 {}
240
241 bool VendorAttr::addVendorDirectory( const Pathname & dirname_r )
242 {
243 if ( PathInfo pi { dirname_r }; ! pi.isDir() ) {
244 MIL << "Not a directory " << pi << endl;
245 return false;
246 }
247
249 [this]( const Pathname & dir_r, const std::string & str_r )->bool
250 {
251 this->addVendorFile( dir_r/str_r );
252 return true;
253 }
254 );
255 return true;
256 }
257
258 bool VendorAttr::addVendorFile( const Pathname & filename_r )
259 {
260 if ( PathInfo pi { filename_r }; ! pi.isFile() ) {
261 MIL << "Not a file " << pi << endl;
262 return false;
263 }
264
265 parser::IniDict dict { InputStream(filename_r) };
266 for ( const auto & el : dict.entries("main") )
267 {
268 if ( el.first == "vendors" )
269 {
270 VendorList tmp;
271 strv::split( el.second, ",", strv::Trim::trim,
272 [&tmp]( std::string_view word ) {
273 if ( ! word.empty() )
274 tmp.push_back( std::string(word) );
275 } );
276 _addVendorList( std::move(tmp) );
277 break;
278 }
279 }
280 return true;
281 }
282
284 { _pimpl->addVendorList( std::move(vendorList_r) ); }
285
286 unsigned VendorAttr::foreachVendorList( std::function<bool(VendorList)> fnc_r ) const
287 { return _pimpl->foreachVendorList( std::move(fnc_r) ); }
288
289#if LEGACY(1722)
290 bool VendorAttr::addVendorDirectory( const Pathname & dirname ) const
291 { return const_cast<VendorAttr*>(this)->addVendorDirectory( dirname ); }
292
293 bool VendorAttr::addVendorFile( const Pathname & filename ) const
294 { return const_cast<VendorAttr*>(this)->addVendorFile( filename ); }
295
296 void VendorAttr::_addVendorList( std::vector<std::string> & vendorList_r ) const
297 { return const_cast<VendorAttr*>(this)->_addVendorList( VendorList( vendorList_r.begin(), vendorList_r.end() ) ); }
298
299 void VendorAttr::_addVendorList( std::vector<IdString> && list_r )
300 {
301 VendorList tmp;
302 for ( const auto & el : list_r )
303 tmp.push_back( std::string(el) );
304 _addVendorList( std::move(tmp) );
305 }
306#endif
308 // vendor equivalence:
310
311 bool VendorAttr::equivalent( IdString lVendor, IdString rVendor ) const
312 { return _pimpl->equivalent( lVendor, rVendor );}
313
314 bool VendorAttr::equivalent( const Vendor & lVendor, const Vendor & rVendor ) const
315 { return _pimpl->equivalent( IdString( lVendor ), IdString( rVendor ) ); }
316
318 { return _pimpl->equivalent( lVendor.vendor(), rVendor.vendor() ); }
319
320 bool VendorAttr::equivalent( const PoolItem & lVendor, const PoolItem & rVendor ) const
321 { return _pimpl->equivalent( lVendor.satSolvable().vendor(), rVendor.satSolvable().vendor() ); }
322
324
325 std::ostream & operator<<( std::ostream & str, const VendorAttr & obj )
326 { return str << *obj._pimpl; }
327
329} // namespace zypp
331
#define MIL
Definition: Logger.h:79
c++17: std::string_view tools
Access to the sat-pools string space.
Definition: IdString.h:43
std::string asString() const
Conversion to std::string
Definition: IdString.h:98
Helper to create and pass std::istream.
Definition: InputStream.h:57
Combining sat::Solvable and ResStatus.
Definition: PoolItem.h:51
VendorAttr implementation.
Definition: VendorAttr.cc:41
VendorMatch _vendorMatch
Cache mapping vendor strings to equivalence class ID.
Definition: VendorAttr.cc:87
std::map< std::string, unsigned > VendorGroupMap
Definition: VendorAttr.cc:80
unsigned vendorMatchId(IdString vendor) const
Helper mapping a vendor string to it's eqivalence class ID.
Definition: VendorAttr.cc:113
bool equivalent(IdString lVendor, IdString rVendor) const
Return whether two vendor strings should be treated as equivalent.
Definition: VendorAttr.cc:58
Impl * clone() const
clone for RWCOW_pointer
Definition: VendorAttr.cc:109
void vendorMatchIdReset()
Reset vendor match cache if _vendorGroupMap was changed.
Definition: VendorAttr.cc:91
VendorGroupMap _vendorGroupMap
Vendor group definition. Equivalent groups share the same ID.
Definition: VendorAttr.cc:81
std::ostream & operator<<(std::ostream &str, const VendorAttr::Impl &obj)
Stream output.
Definition: VendorAttr.cc:198
friend std::ostream & operator<<(std::ostream &str, const Impl &obj)
unsigned _nextId
Least equivalence class ID in use (decremented).
Definition: VendorAttr.cc:88
std::unordered_map< IdString, VendorMatchEntry > VendorMatch
Definition: VendorAttr.cc:86
unsigned _vendorGroupId
Highest group ID in use (incremented).
Definition: VendorAttr.cc:82
DefaultIntegral< unsigned, 0 > VendorMatchEntry
Definition: VendorAttr.cc:85
void addVendorList(VendorList &&vendorList_r)
Add a new equivalent vendor set.
Definition: VendorAttr.cc:156
unsigned foreachVendorList(std::function< bool(VendorList)> fnc_r) const
Definition: VendorAttr.cc:61
Definition of vendor equivalence.
Definition: VendorAttr.h:61
VendorAttr()
Ctor providing the default set.
Definition: VendorAttr.cc:225
static VendorAttr & noTargetInstance()
Singleton, settings used if no Target is active.
Definition: VendorAttr.cc:219
bool equivalent(const Vendor &lVendor, const Vendor &rVendor) const
Return whether two vendor strings should be treated as the same vendor.
Definition: VendorAttr.cc:314
bool addVendorFile(const Pathname &filename_r)
Adding new equivalent vendors described in a file.
Definition: VendorAttr.cc:258
RWCOW_pointer< Impl > _pimpl
Implementation class.
Definition: VendorAttr.h:153
unsigned foreachVendorList(std::function< bool(VendorList)> fnc_r) const
Call fnc_r for each equivalent vendor list (return false to break).
Definition: VendorAttr.cc:286
static const VendorAttr & instance()
(Pseudo)Singleton, mapped to the current Target::vendorAttr settings or to noTargetInstance.
Definition: VendorAttr.cc:213
void _addVendorList(VendorList &&list_r)
Definition: VendorAttr.cc:283
std::vector< std::string > VendorList
Preferred type to pass equivalent vendor strings.
Definition: VendorAttr.h:103
bool addVendorDirectory(const Pathname &dirname_r)
Adding new equivalent vendors described in a directory.
Definition: VendorAttr.cc:241
Pathname vendorPath() const
Directory for equivalent vendor definitions (configPath()/vendors.d)
Definition: ZConfig.cc:996
static ZConfig & instance()
Singleton ctor.
Definition: Resolver.cc:126
Wrapper class for ::stat/::lstat.
Definition: PathInfo.h:221
Parses a INI file and offers its structure as a dictionary.
Definition: IniDict.h:42
A Solvable object within the sat Pool.
Definition: Solvable.h:54
IdString vendor() const
The vendor.
Definition: Solvable.cc:356
String related utilities and Regular expression matching.
const StrMatcher & matchNoDots()
Convenience returning StrMatcher( "[^.]*", Match::GLOB )
Definition: PathInfo.cc:545
int dirForEach(const Pathname &dir_r, function< bool(const Pathname &, const char *const)> fnc_r)
Invoke callback function fnc_r for each entry in directory dir_r.
Definition: PathInfo.cc:551
bool hasPrefix(const C_Str &str_r, const C_Str &prefix_r)
Return whether str_r has prefix prefix_r.
Definition: String.h:1023
std::string toLower(const std::string &s)
Return lowercase version of s.
Definition: String.cc:177
std::string trim(const std::string &s, const Trim trim_r)
Definition: String.cc:223
unsigned split(std::string_view line_r, std::string_view sep_r, Trim trim_r, std::function< void(std::string_view)> fnc_r)
Definition: StringV.cc:20
Easy-to use interface to the ZYPP dependency resolver.
Definition: CodePitfalls.doc:2
std::ostream & operator<<(std::ostream &str, const Exception &obj)
Definition: Exception.cc:147
std::string Vendor
Definition: Vendor.h:22
Solvable satSolvable() const
Return the corresponding sat::Solvable.
Definition: SolvableType.h:57