libzypp: zypp/Capability.cc Source File

libzypp 17.38.13

Capability.cc
Go to the documentation of this file.
1/*---------------------------------------------------------------------\
2| ____ _ __ __ ___ |
3| |__ / \ / / . \ . \ |
4| / / \ V /| _/ _/ |
5| / /__ | | | | | | |
6| /_____||_| |_| |_| |
7| |
8\---------------------------------------------------------------------*/
12#include <iostream>
13#include <zypp-core/base/LogTools.h>
14
15#include <zypp-core/base/String.h>
16#include <zypp-core/base/Regex.h>
17#include <zypp-core/base/Gettext.h>
18#include <zypp-core/base/Exception.h>
19
20#include <zypp/Arch.h>
21#include <zypp/Rel.h>
22#include <zypp/Edition.h>
23#include <zypp/Capability.h>
24#include <zypp/ResPool.h>
25#include <zypp/sat/Solvable.h>
26
27#include <zypp/ng/sat/stringpool.h>
28
29using std::endl;
30
32namespace zypp
33{
34
35 using zyppng::sat::StringPool;
36
37 namespace
38 {
39
41 template <unsigned TLen = 5>
42 struct TempStrings
43 {
45 std::string & getNext()
46 { unsigned c = _next; _next = (_next+1) % TLen; _buf[c].clear(); return _buf[c]; }
47
48 private:
49 unsigned _next = 0;
50 std::string _buf[TLen];
51 };
52
54 inline std::string::size_type backskipWs( const std::string & str_r, std::string::size_type pos_r )
55 {
56 for ( ; pos_r != std::string::npos; --pos_r )
57 {
58 char ch = str_r[pos_r];
59 if ( ch != ' ' && ch != '\t' )
60 break;
61 }
62 return pos_r;
63 }
64
66 inline std::string::size_type backskipNWs( const std::string & str_r, std::string::size_type pos_r )
67 {
68 for ( ; pos_r != std::string::npos; --pos_r )
69 {
70 char ch = str_r[pos_r];
71 if ( ch == ' ' || ch == '\t' )
72 break;
73 }
74 return pos_r;
75 }
76
78 void splitOpEdition( std::string & str_r, Rel & op_r, Edition & ed_r )
79 {
80 if ( str_r.empty() )
81 return;
82 std::string::size_type ch( str_r.size()-1 );
83
84 // check whether the one but last word is a valid Rel:
85 if ( (ch = backskipWs( str_r, ch )) != std::string::npos )
86 {
87 std::string::size_type ee( ch );
88 if ( (ch = backskipNWs( str_r, ch )) != std::string::npos )
89 {
90 std::string::size_type eb( ch );
91 if ( (ch = backskipWs( str_r, ch )) != std::string::npos )
92 {
93 std::string::size_type oe( ch );
94 ch = backskipNWs( str_r, ch ); // now before 'op'? begin
95 if ( op_r.parseFrom( str_r.substr( ch+1, oe-ch ) ) )
96 {
97 // found a legal 'op'
98 ed_r = Edition( str_r.substr( eb+1, ee-eb ) );
99 if ( ch != std::string::npos ) // 'op' is not at str_r begin, so skip WS
100 ch = backskipWs( str_r, ch );
101 str_r.erase( ch+1 );
102 return;
103 }
104 }
105 }
106 }
107 // HERE: Didn't find 'name op edition'
108 // As a convenience we check for an embeded 'op' (not surounded by WS).
109 // But just '[<=>]=?|!=' and not inside '()'.
110 ch = str_r.find_last_of( "<=>)" );
111 if ( ch != std::string::npos && str_r[ch] != ')' )
112 {
113 std::string::size_type oe( ch );
114
115 // do edition first:
116 ch = str_r.find_first_not_of( " \t", oe+1 );
117 if ( ch != std::string::npos )
118 ed_r = Edition( str_r.substr( ch ) );
119
120 // now finish op:
121 ch = oe-1;
122 if ( str_r[oe] != '=' ) // '[<>]'
123 {
124 op_r = ( str_r[oe] == '<' ) ? Rel::LT : Rel::GT;
125 }
126 else
127 { // '?='
128 if ( ch != std::string::npos )
129 {
130 switch ( str_r[ch] )
131 {
132 case '<': --ch; op_r = Rel::LE; break;
133 case '>': --ch; op_r = Rel::GE; break;
134 case '!': --ch; op_r = Rel::NE; break;
135 case '=': --ch; // fall through
136 default: op_r = Rel::EQ; break;
137 }
138 }
139 }
140
141 // finally name:
142 if ( ch != std::string::npos ) // 'op' is not at str_r begin, so skip WS
143 ch = backskipWs( str_r, ch );
144 str_r.erase( ch+1 );
145 return;
146 }
147 // HERE: It's a plain 'name'
148 }
149
152 sat::detail::IdType relFromStr( sat::detail::CPool * pool_r,
153 const Arch & arch_r,
154 const std::string & name_r,
155 Rel op_r,
156 const Edition & ed_r,
157 const ResKind & kind_r )
158 {
159 // First build the name, non-packages prefixed by kind
160 sat::Solvable::SplitIdent split( kind_r, name_r );
161 sat::detail::IdType nid( split.ident().id() );
162
163 if ( split.kind() == ResKind::srcpackage )
164 {
165 // map 'kind srcpackage' to 'arch src', the pseudo architecture
166 // libsolv uses.
167 nid = ::pool_rel2id( pool_r, nid, IdString(ARCH_SRC).id(), REL_ARCH, /*create*/true );
168 }
169
170 // Extend name by architecture, if provided and not a srcpackage
171 if ( ! arch_r.empty() && kind_r != ResKind::srcpackage )
172 {
173 nid = ::pool_rel2id( pool_r, nid, arch_r.id(), REL_ARCH, /*create*/true );
174 }
175
176 // Extend 'op edition', if provided
177 if ( op_r != Rel::ANY && ed_r != Edition::noedition )
178 {
179 nid = ::pool_rel2id( pool_r, nid, ed_r.id(), op_r.bits(), /*create*/true );
180 }
181
182 return nid;
183 }
184
188 sat::detail::IdType relFromStr( sat::detail::CPool * pool_r,
189 const std::string & name_r, Rel op_r, const Edition & ed_r,
190 const ResKind & kind_r )
191 {
192 static const Arch srcArch( IdString(ARCH_SRC).asString() );
193 static const Arch nosrcArch( IdString(ARCH_NOSRC).asString() );
194 static const std::string srcKindPrefix( ResKind::srcpackage.asString() + ':' );
195
196 // check for an embedded 'srcpackage:foo' to be mapped to 'foo' and 'ResKind::srcpackage'.
197 if ( kind_r.empty() && str::hasPrefix( name_r, srcKindPrefix ) )
198 {
199 return relFromStr( pool_r, Arch_empty, name_r.substr( srcKindPrefix.size() ), op_r, ed_r, ResKind::srcpackage );
200 }
201
202 Arch arch( Arch_empty );
203 std::string name( name_r );
204
205 std::string::size_type asep( name_r.rfind( '.' ) );
206 if ( asep != std::string::npos )
207 {
208 Arch ext( name_r.substr( asep+1 ) );
209 if ( ext.isBuiltIn() || ext == srcArch || ext == nosrcArch )
210 {
211 arch = ext;
212 name.erase( asep );
213 }
214 }
215
216 return relFromStr( pool_r, arch, name, op_r, ed_r, kind_r );
217 }
218
221 sat::detail::IdType relFromStr( sat::detail::CPool * pool_r,
222 const Arch & arch_r, // parse from name if empty
223 const std::string & str_r, const ResKind & kind_r,
224 Capability::CtorFlag flag_r )
225 {
226 std::string name( str_r );
227 Rel op;
228 Edition ed;
229 if ( flag_r == Capability::UNPARSED )
230 {
231 splitOpEdition( name, op, ed );
232 }
233
234 if ( arch_r.empty() )
235 return relFromStr( pool_r, name, op, ed, kind_r ); // parses for name[.arch]
236 // else
237 return relFromStr( pool_r, arch_r, name, op, ed, kind_r );
238 }
239
241 sat::detail::IdType richOrRelFromStr( sat::detail::CPool * pool_r, const std::string & str_r, const ResKind & prefix_r, Capability::CtorFlag flag_r )
242 {
243 if ( str_r[0] == '(' ) {
244 sat::detail::IdType res { StringPool::instance().parserpmrichdep( str_r.c_str() ) };
245 if ( res ) return res;
246 // else: no richdep, so fall back to the ordinary parser which in
247 // case of doubt turns the string into a NAMED cap.
248 }
249 return relFromStr( pool_r, Arch_empty, str_r, prefix_r, flag_r );
250 }
251
253 } // namespace
255
256 const Capability Capability::Null( STRID_NULL );
257 const Capability Capability::Empty( STRID_EMPTY );
258
260
261 Capability::Capability( const char * str_r, const ResKind & prefix_r, CtorFlag flag_r )
262 : _id( richOrRelFromStr( StringPool::instance().getPool(), str_r, prefix_r, flag_r ) )
263 {}
264
265 Capability::Capability( const std::string & str_r, const ResKind & prefix_r, CtorFlag flag_r )
266 : _id( richOrRelFromStr( StringPool::instance().getPool(), str_r, prefix_r, flag_r ) )
267 {}
268
269 Capability::Capability( const Arch & arch_r, const char * str_r, const ResKind & prefix_r, CtorFlag flag_r )
270 : _id( relFromStr( StringPool::instance().getPool(), arch_r, str_r, prefix_r, flag_r ) )
271 {}
272
273 Capability::Capability( const Arch & arch_r, const std::string & str_r, const ResKind & prefix_r, CtorFlag flag_r )
274 : _id( relFromStr( StringPool::instance().getPool(), arch_r, str_r, prefix_r, flag_r ) )
275 {}
276
277 Capability::Capability( const char * str_r, CtorFlag flag_r, const ResKind & prefix_r )
278 : _id( relFromStr( StringPool::instance().getPool(), Arch_empty, str_r, prefix_r, flag_r ) )
279 {}
280
281 Capability::Capability( const std::string & str_r, CtorFlag flag_r, const ResKind & prefix_r )
282 : _id( relFromStr( StringPool::instance().getPool(), Arch_empty, str_r, prefix_r, flag_r ) )
283 {}
284
285 Capability::Capability( const Arch & arch_r, const char * str_r, CtorFlag flag_r, const ResKind & prefix_r )
286 : _id( relFromStr( StringPool::instance().getPool(), arch_r, str_r, prefix_r, flag_r ) )
287 {}
288
289 Capability::Capability( const Arch & arch_r, const std::string & str_r, CtorFlag flag_r, const ResKind & prefix_r )
290 : _id( relFromStr( StringPool::instance().getPool(), arch_r, str_r, prefix_r, flag_r ) )
291 {}
292
294 // Ctor from <name[.arch] op edition>.
296
297 Capability::Capability( const std::string & name_r, const std::string & op_r, const std::string & ed_r, const ResKind & prefix_r )
298 : _id( relFromStr( StringPool::instance().getPool(), name_r, Rel(op_r), Edition(ed_r), prefix_r ) )
299 {}
300 Capability::Capability( const std::string & name_r, Rel op_r, const std::string & ed_r, const ResKind & prefix_r )
301 : _id( relFromStr( StringPool::instance().getPool(), name_r, op_r, Edition(ed_r), prefix_r ) )
302 {}
303 Capability::Capability( const std::string & name_r, Rel op_r, const Edition & ed_r, const ResKind & prefix_r )
304 : _id( relFromStr( StringPool::instance().getPool(), name_r, op_r, ed_r, prefix_r ) )
305 {}
306
308 // Ctor from <arch name op edition>.
310
311 Capability::Capability( const std::string & arch_r, const std::string & name_r, const std::string & op_r, const std::string & ed_r, const ResKind & prefix_r )
312 : _id( relFromStr( StringPool::instance().getPool(), Arch(arch_r), name_r, Rel(op_r), Edition(ed_r), prefix_r ) )
313 {}
314 Capability::Capability( const std::string & arch_r, const std::string & name_r, Rel op_r, const std::string & ed_r, const ResKind & prefix_r )
315 : _id( relFromStr( StringPool::instance().getPool(), Arch(arch_r), name_r, op_r, Edition(ed_r), prefix_r ) )
316 {}
317 Capability::Capability( const std::string & arch_r, const std::string & name_r, Rel op_r, const Edition & ed_r, const ResKind & prefix_r )
318 : _id( relFromStr( StringPool::instance().getPool(), Arch(arch_r), name_r, op_r, ed_r, prefix_r ) )
319 {}
320 Capability::Capability( const Arch & arch_r, const std::string & name_r, const std::string & op_r, const std::string & ed_r, const ResKind & prefix_r )
321 : _id( relFromStr( StringPool::instance().getPool(), arch_r, name_r, Rel(op_r), Edition(ed_r), prefix_r ) )
322 {}
323 Capability::Capability( const Arch & arch_r, const std::string & name_r, Rel op_r, const std::string & ed_r, const ResKind & prefix_r )
324 : _id( relFromStr( StringPool::instance().getPool(), arch_r, name_r, op_r, Edition(ed_r), prefix_r ) )
325 {}
326 Capability::Capability( const Arch & arch_r, const std::string & name_r, Rel op_r, const Edition & ed_r, const ResKind & prefix_r )
327 : _id( relFromStr( StringPool::instance().getPool(), arch_r, name_r, op_r, ed_r, prefix_r ) )
328 {}
329
331 // Ctor creating a namespace: capability.
333
334 Capability::Capability( ResolverNamespace namespace_r, IdString value_r )
335 : _id( ::pool_rel2id(StringPool::instance().getPool(), asIdString(namespace_r).id(), (value_r.empty() ? STRID_NULL : value_r.id() ), CAP_NAMESPACE, /*create*/true ) )
336 {}
337
339 // Ctor creating an expression
341
342 Capability::Capability( Capability::CapRel rel_r, const Capability & lhs_r, const Capability & rhs_r )
343 : _id( ::pool_rel2id( StringPool::instance().getPool(), lhs_r.id(), rhs_r.id(), rel_r, /*create*/true ) )
344 {}
345
347 // https://rpm-software-management.github.io/rpm/manual/boolean_dependencies.html
348 namespace
349 {
350 inline const char * opstr( int op_r )
351 {
352 switch ( op_r )
353 {
354 case REL_GT: return " > ";
355 case REL_EQ: return " = ";
356 case REL_LT: return " < ";
357 case REL_GT|REL_EQ: return " >= ";
358 case REL_LT|REL_EQ: return " <= ";
359 case REL_GT|REL_LT: return " != ";
360 case REL_GT|REL_LT|REL_EQ: return " <=> ";
361 case REL_AND: return " and ";
362 case REL_OR: return " or ";
363 case REL_COND: return " if ";
364 case REL_UNLESS: return " unless ";
365 case REL_ELSE: return " else ";
366 case REL_WITH: return " with ";
367 case REL_WITHOUT: return " without ";
368 }
369 return "UNKNOWNCAPREL";
370 }
371
372 inline bool isBoolOp( int op_r )
373 {
374 switch ( op_r ) {
375 case REL_AND:
376 case REL_OR:
377 case REL_COND:
378 case REL_UNLESS:
379 case REL_ELSE:
380 case REL_WITH:
381 case REL_WITHOUT:
382 return true;
383 }
384 return false;
385 }
386
387 inline bool needsBrace( int op_r, int parop_r )
388 {
389 return ( isBoolOp( parop_r ) || parop_r == 0 ) && isBoolOp( op_r )
390 && ( parop_r != op_r || op_r == REL_COND || op_r == REL_UNLESS || op_r == REL_ELSE )
391 && not ( ( parop_r == REL_COND || parop_r == REL_UNLESS ) && op_r == REL_ELSE );
392 }
393
394 void cap2strHelper( std::string & outs_r, sat::detail::CPool * pool_r, sat::detail::IdType id_r, int parop_r )
395 {
396 if ( ISRELDEP(id_r) ) {
397 ::Reldep * rd = GETRELDEP( pool_r, id_r );
398 int op = rd->flags;
399
400 if ( op == CapDetail::CAP_ARCH ) {
401 if ( rd->evr == ARCH_SRC || rd->evr == ARCH_NOSRC ) {
402 // map arch .{src,nosrc} to kind srcpackage
403 outs_r += ResKind::srcpackage.c_str();
404 outs_r += ":";
405 outs_r += IdString(rd->name).c_str();
406 return;
407 }
408 cap2strHelper( outs_r, pool_r, rd->name, op );
409 outs_r += ".";
410 cap2strHelper( outs_r, pool_r, rd->evr, op );
411 return;
412 }
413
414 if ( op == CapDetail::CAP_NAMESPACE ) {
415 cap2strHelper( outs_r, pool_r, rd->name, op );
416 outs_r += "(";
417 cap2strHelper( outs_r, pool_r, rd->evr, op );
418 outs_r += ")";
419 return;
420 }
421
422 if ( op == REL_FILECONFLICT )
423 {
424 cap2strHelper( outs_r, pool_r, rd->name, op );
425 return;
426 }
427
428 if ( needsBrace( op, parop_r ) ) {
429 outs_r += "(";
430 cap2strHelper( outs_r, pool_r, rd->name, op );
431 outs_r += opstr( op );
432 cap2strHelper( outs_r, pool_r, rd->evr, op );
433 outs_r += ")";
434 return;
435 }
436
437 cap2strHelper( outs_r, pool_r, rd->name, op );
438 outs_r += opstr( op );
439 cap2strHelper( outs_r, pool_r, rd->evr, op );
440 }
441 else
442 outs_r += IdString(id_r).c_str();
443 }
444 } // namespace
446
447 const char * Capability::c_str() const
448 {
449 if ( not id() ) return "";
450 if ( not ISRELDEP(id()) ) return IdString(id()).c_str();
451
452 static TempStrings<5> tempstrs; // Round Robin buffer to prolong the lifetime of the returned char*
453
454 std::string & outs { tempstrs.getNext() };
455 cap2strHelper( outs, StringPool::instance().getPool(), id(), 0 );
456 return outs.c_str();
457 }
458
459 CapMatch Capability::_doMatch( sat::detail::IdType lhs, sat::detail::IdType rhs )
460 {
461 if ( lhs == rhs )
462 return CapMatch::yes;
463
464 CapDetail l( lhs );
465 CapDetail r( rhs );
466
467 switch ( l.kind() )
468 {
469 case CapDetail::NOCAP:
470 return( r.kind() == CapDetail::NOCAP ); // NOCAP matches NOCAP only
471 break;
472 case CapDetail::EXPRESSION:
473 return CapMatch::irrelevant;
474 break;
475 case CapDetail::NAMED:
476 case CapDetail::VERSIONED:
477 break;
478 }
479
480 switch ( r.kind() )
481 {
482 case CapDetail::NOCAP:
483 return CapMatch::no; // match case handled above
484 break;
485 case CapDetail::EXPRESSION:
486 return CapMatch::irrelevant;
487 break;
488 case CapDetail::NAMED:
489 case CapDetail::VERSIONED:
490 break;
491 }
492 // comparing two simple caps:
493 if ( l.name() != r.name() )
494 return CapMatch::no;
495
496 // if both are arch restricted they must match
497 if ( l.arch() != r.arch()
498 && ! ( l.arch().empty() || r.arch().empty() ) )
499 return CapMatch::no;
500
501 // isNamed matches ANY edition:
502 if ( l.isNamed() || r.isNamed() )
503 return CapMatch::yes;
504
505 // both are versioned:
506 return overlaps( Edition::MatchRange( l.op(), l.ed() ),
507 Edition::MatchRange( r.op(), r.ed() ) );
508 }
509
510 bool Capability::isInterestingFileSpec( const char * name_r )
511 {
512 static str::smatch what;
513 static const str::regex filenameRegex(
514 "/(s?bin|lib(64)?|etc)/|^/usr/(games/|share/(dict/words|magic\\.mime)$)|^/opt/gnome/games/",
515 str::regex::nosubs );
516
517 return str::regex_match( name_r, what, filenameRegex );
518 }
519
520 Capability Capability::guessPackageSpec( const std::string & str_r, bool & rewrote_r )
521 {
522 Capability cap( str_r );
523 CapDetail detail( cap.detail() );
524
525 // str_r might be the form "libzypp-1.2.3-4.5(.arch)'
526 // correctly parsed as name capability by the ctor.
527 // TODO: Think about allowing glob char in name - for now don't process
528 if ( detail.isNamed() && !::strpbrk( detail.name().c_str(), "*?[{" )
529 && ::strrchr( detail.name().c_str(), '-' ) && sat::WhatProvides( cap ).empty() )
530 {
531 Arch origArch( detail.arch() ); // to support a trailing .arch
532
533 std::string guess( detail.name().asString() );
534 std::string::size_type pos( guess.rfind( '-' ) );
535 guess[pos] = '=';
536
537 Capability guesscap( origArch, guess );
538 detail = guesscap.detail();
539
540 ResPool pool( ResPool::instance() );
541 // require name part matching a pool items name (not just provides!)
542 if ( pool.byIdentBegin( detail.name() ) != pool.byIdentEnd( detail.name() ) )
543 {
544 rewrote_r = true;
545 return guesscap;
546 }
547
548 // try the one but last '-'
549 if ( pos )
550 {
551 guess[pos] = '-';
552 if ( (pos = guess.rfind( '-', pos-1 )) != std::string::npos )
553 {
554 guess[pos] = '=';
555
556 guesscap = Capability( origArch, guess );
557 detail = guesscap.detail();
558
559 // require name part matching a pool items name (not just provides!)
560 if ( pool.byIdentBegin( detail.name() ) != pool.byIdentEnd( detail.name() ) )
561 {
562 rewrote_r = true;
563 return guesscap;
564 }
565 }
566 }
567 }
568
569 rewrote_r = false;
570 return cap;
571 }
572
573 Capability Capability::guessPackageSpec( const std::string & str_r )
574 {
575 bool dummy = false;
576 return guessPackageSpec( str_r, dummy );
577 }
578
579 /******************************************************************
580 **
581 ** FUNCTION NAME : operator<<
582 ** FUNCTION TYPE : std::ostream &
583 */
584 std::ostream & operator<<( std::ostream & str, const Capability & obj )
585 {
586 return str << obj.c_str();
587 }
588
589 std::ostream & dumpOn( std::ostream & str, const Capability & obj )
590 {
591 return str << ( obj ? ::pool_dep2str( StringPool::instance().getPool(), obj.id() ) : "" );
592 }
593
594 std::ostream & operator<<( std::ostream & str, Capability::CapRel obj )
595 {
596 switch ( obj )
597 {
598 case Capability::CAP_AND: return str << "and"; break; // &
599 case Capability::CAP_OR: return str << "or"; break; // |
600 case Capability::CAP_COND: return str << "if"; break;
601 case Capability::CAP_UNLESS: return str << "unless"; break;
602 case Capability::CAP_ELSE: return str << "else"; break;
603 case Capability::CAP_WITH: return str << "with"; break; // +
604 case Capability::CAP_WITHOUT: return str << "without"; break; // -
605 case Capability::CAP_NAMESPACE: return str << "NAMESPACE"; break;
606 case Capability::CAP_ARCH: return str << "ARCH"; break;
607 }
608 return str << "UnknownCapRel("+str::numstring(obj)+")";
609 }
610
611 std::ostream & dumpCap::dumpOn( std::ostream & str ) const
612 { return _dumpRec( str, _cap ); }
613 std::ostream & dumpCap::_dumpRec( std::ostream & str, Capability cap_r, std::string lvl_r ) const
614 {
615 std::optional<decltype(lvl_r.rbegin())> lastch; // lvl_r last char if not empty
616 if ( not lvl_r.empty() )
617 lastch = lvl_r.rbegin();
618 auto d = cap_r.detail();
619 if ( d.isExpression() ) {
620 static const char* ts = " +|+ ";
621 const char* t = lastch && **lastch == 'l' ? ts : ts+2;
622 if ( lastch ) **lastch = t[0];
623 _dumpRec( str, d.lhs(), lvl_r+" l" ) << endl;
624 if ( lastch ) **lastch = t[1];
625 str << lvl_r << "<" << d.capRel() << endl;
626 if ( lastch ) **lastch = t[2];
627 _dumpRec( str, d.rhs(), lvl_r+" r" );
628 } else {
629 if ( lastch ) **lastch = ' ';
630 str << lvl_r << '"' << d << '"';
631 }
632 return str;
633 }
634
636 //
637 // CLASS NAME : CapDetail
638 //
640
641 void CapDetail::_init()
642 {
643 // : _kind( NOCAP ), _lhs( id_r ), _rhs( 0 ), _flag( 0 ), _archIfSimple( 0 )
644
645 if ( _lhs == sat::detail::emptyId || _lhs == sat::detail::noId )
646 return; // NOCAP
647
648 if ( ! ISRELDEP(_lhs) )
649 {
650 // this is name without arch!
651 _kind = NAMED;
652 return;
653 }
654
655 ::Reldep * rd = GETRELDEP( StringPool::instance().getPool(), _lhs );
656 _lhs = rd->name;
657 _rhs = rd->evr;
658 _flag = rd->flags;
659
660 if ( Rel::isRel( _flag ) )
661 {
662 _kind = VERSIONED;
663 // Check for name.arch...
664 if ( ! ISRELDEP(_lhs) )
665 return; // this is name without arch!
666 rd = GETRELDEP( StringPool::instance().getPool(), _lhs );
667 if ( rd->flags != CAP_ARCH )
668 return; // this is not name.arch
669 // This is name.arch:
670 _lhs = rd->name;
671 _archIfSimple = rd->evr;
672 }
673 else if ( rd->flags == CAP_ARCH )
674 {
675 _kind = NAMED;
676 // This is name.arch:
677 _lhs = rd->name;
678 _archIfSimple = rd->evr;
679 }
680 else
681 {
682 _kind = EXPRESSION;
683 return;
684 }
685 // map back libsolvs pseudo arch 'src' to kind srcpackage
686 if ( _archIfSimple == ARCH_SRC || _archIfSimple == ARCH_NOSRC )
687 {
688 _lhs = IdString( (ResKind::srcpackage.asString() + ":" + IdString(_lhs).c_str()).c_str() ).id();
689 _archIfSimple = 0;
690 }
691 }
692
693 /******************************************************************
694 **
695 ** FUNCTION NAME : operator<<
696 ** FUNCTION TYPE : std::ostream &
697 */
698 std::ostream & operator<<( std::ostream & str, const CapDetail & obj )
699 {
700 static const char archsep = '.';
701 switch ( obj.kind() )
702 {
703 case CapDetail::NOCAP:
704 return str << "<NoCap>";
705 break;
706
707 case CapDetail::NAMED:
708 str << obj.name();
709 if ( obj.hasArch() )
710 str << archsep << obj.arch();
711 return str;
712 break;
713
714 case CapDetail::VERSIONED:
715 str << obj.name();
716 if ( obj.hasArch() )
717 str << archsep << obj.arch();
718 return str << " " << obj.op() << " " << obj.ed();
719 break;
720
721 case CapDetail::EXPRESSION:
722 {
723 std::string outs;
724 auto pool = StringPool::instance().getPool();
725 auto op = obj.capRel();
726 if ( obj.capRel() == CapDetail::CAP_NAMESPACE ) {
727 cap2strHelper( outs, pool, obj.lhs().id(), op );
728 outs += "(";
729 cap2strHelper( outs, pool, obj.rhs().id(), op );
730 outs += ")";
731 }
732 else {
733 outs += "(";
734 cap2strHelper( outs, pool, obj.lhs().id(), op );
735 outs += opstr( op );
736 cap2strHelper( outs, pool, obj.rhs().id(), op );
737 outs += ")";
738 }
739 return str << outs;
740 }
741 break;
742 }
743 return str << "<UnknownCap(" << obj.lhs() << " " << obj.capRel() << " " << obj.rhs() << ")>";
744 }
745
746 std::ostream & operator<<( std::ostream & str, CapDetail::Kind obj )
747 {
748 switch ( obj )
749 {
750 case CapDetail::NOCAP: return str << "NoCap"; break;
751 case CapDetail::NAMED: return str << "NamedCap"; break;
752 case CapDetail::VERSIONED: return str << "VersionedCap"; break;
753 case CapDetail::EXPRESSION: return str << "CapExpression"; break;
754 }
755 return str << "UnknownCap";
756 }
757
758 std::ostream & operator<<( std::ostream & str, CapDetail::CapRel obj )
759 {
760 if ( obj == CapDetail::REL_NONE )
761 return str << "NoCapRel";
762 return str << static_cast<Capability::CapRel>(obj);
763 }
764
766} // namespace zypp
Arch.h
Capability.h
Edition.h
Exception.h
Gettext.h
LogTools.h
Regex.h
Rel.h
ResPool.h
Solvable.h
String.h
zypp::Arch
Architecture.
Definition Arch.h:37
zypp::CapDetail
Helper providing more detailed information about a Capability.
Definition Capability.h:366
zypp::CapDetail::isNamed
bool isNamed() const
Definition Capability.h:410
zypp::CapDetail::Kind
Kind
Definition Capability.h:369
zypp::CapDetail::NAMED
@ NAMED
Definition Capability.h:371
zypp::CapDetail::NOCAP
@ NOCAP
Definition Capability.h:370
zypp::CapDetail::EXPRESSION
@ EXPRESSION
Definition Capability.h:373
zypp::CapDetail::VERSIONED
@ VERSIONED
Definition Capability.h:372
zypp::CapDetail::name
IdString name() const
Definition Capability.h:419
zypp::CapDetail::hasArch
bool hasArch() const
Definition Capability.h:417
zypp::CapDetail::arch
IdString arch() const
Definition Capability.h:418
zypp::CapDetail::rhs
Capability rhs() const
Definition Capability.h:428
zypp::CapDetail::ed
Edition ed() const
Definition Capability.h:421
zypp::CapDetail::op
Rel op() const
Definition Capability.h:420
zypp::CapDetail::_archIfSimple
sat::detail::IdType _archIfSimple
Definition Capability.h:438
zypp::CapDetail::lhs
Capability lhs() const
Definition Capability.h:426
zypp::CapDetail::kind
Kind kind() const
Definition Capability.h:408
zypp::CapDetail::_init
void _init()
Definition Capability.cc:641
zypp::CapDetail::_kind
Kind _kind
Definition Capability.h:434
zypp::CapDetail::_rhs
sat::detail::IdType _rhs
Definition Capability.h:436
zypp::CapDetail::capRel
CapRel capRel() const
Definition Capability.h:427
zypp::CapDetail::_lhs
sat::detail::IdType _lhs
Definition Capability.h:435
zypp::CapDetail::_flag
unsigned _flag
Definition Capability.h:437
zypp::CapDetail::CapRel
CapRel
Enum values corresponding with libsolv defines.
Definition Capability.h:380
zypp::CapDetail::REL_NONE
@ REL_NONE
Not an expression.
Definition Capability.h:381
zypp::CapDetail::CAP_ARCH
@ CAP_ARCH
Used internally.
Definition Capability.h:393
zypp::CapDetail::CAP_NAMESPACE
@ CAP_NAMESPACE
Definition Capability.h:392
zypp::CapMatch
Tri state Capability match result.
Definition CapMatch.h:39
zypp::CapMatch::no
static const CapMatch no
Definition CapMatch.h:53
zypp::CapMatch::irrelevant
static const CapMatch irrelevant
Definition CapMatch.h:54
zypp::CapMatch::yes
static const CapMatch yes
Definition CapMatch.h:52
zypp::Capability
A sat capability.
Definition Capability.h:63
zypp::Capability::id
sat::detail::IdType id() const
Expert backdoor.
Definition Capability.h:289
zypp::Capability::Null
static const Capability Null
No or Null Capability ( Id 0 ).
Definition Capability.h:172
zypp::Capability::_id
sat::detail::IdType _id
Definition Capability.h:295
zypp::Capability::Capability
Capability()
Default ctor, Empty capability.
Definition Capability.h:69
zypp::Capability::empty
bool empty() const
Whether the Capability is empty.
Definition Capability.h:185
zypp::Capability::CapRel
CapRel
Enum values correspond with libsolv defines.
Definition Capability.h:152
zypp::Capability::CAP_OR
@ CAP_OR
or
Definition Capability.h:154
zypp::Capability::CAP_WITH
@ CAP_WITH
with
Definition Capability.h:160
zypp::Capability::CAP_WITHOUT
@ CAP_WITHOUT
without
Definition Capability.h:161
zypp::Capability::CAP_COND
@ CAP_COND
if
Definition Capability.h:156
zypp::Capability::CAP_ELSE
@ CAP_ELSE
else
Definition Capability.h:158
zypp::Capability::CAP_ARCH
@ CAP_ARCH
Used internally.
Definition Capability.h:164
zypp::Capability::CAP_UNLESS
@ CAP_UNLESS
unless
Definition Capability.h:157
zypp::Capability::CAP_NAMESPACE
@ CAP_NAMESPACE
Definition Capability.h:163
zypp::Capability::CAP_AND
@ CAP_AND
and
Definition Capability.h:153
zypp::Capability::detail
CapDetail detail() const
Helper providing more detailed information about a Capability.
Definition Capability.h:453
zypp::Capability::c_str
const char * c_str() const
Conversion to const char *.
Definition Capability.cc:447
zypp::Capability::_doMatch
static CapMatch _doMatch(sat::detail::IdType lhs, sat::detail::IdType rhs)
Match two Capabilities.
Definition Capability.cc:459
zypp::Capability::isInterestingFileSpec
static bool isInterestingFileSpec(const IdString &name_r)
Test for a filename that is likely being REQUIRED.
Definition Capability.h:251
zypp::Capability::CtorFlag
CtorFlag
Definition Capability.h:65
zypp::Capability::UNPARSED
@ UNPARSED
Definition Capability.h:65
zypp::Capability::Empty
static const Capability Empty
Empty Capability.
Definition Capability.h:175
zypp::Capability::guessPackageSpec
static Capability guessPackageSpec(const std::string &str_r)
Capability parser also guessing "libzypp-1.2.3-4.5.x86_64" formats.
Definition Capability.cc:573
zypp::Edition
Edition represents [epoch:]version[-release].
Definition Edition.h:60
zypp::Edition::MatchRange
Range< Edition, Match > MatchRange
Edition Range based on Match.
Definition Edition.h:168
zypp::Edition::noedition
static const Edition noedition
Value representing noedition ("") This is in fact a valid Edition.
Definition Edition.h:72
zypp::IdString
Access to the sat-pools string space.
Definition IdString.h:55
zypp::IdString::c_str
const char * c_str() const
Conversion to const char *.
Definition IdString.cc:51
zypp::IdString::empty
constexpr bool empty() const
Whether the string is empty.
Definition IdString.h:99
zypp::IdString::id
IdType id() const
Expert backdoor.
Definition IdString.h:144
zypp::ResKind
Resolvable kinds.
Definition ResKind.h:33
zypp::ResKind::srcpackage
static const ResKind srcpackage
Definition ResKind.h:44
zypp::ResPool
Global ResObject pool.
Definition ResPool.h:62
zypp::ResPool::instance
static ResPool instance()
Singleton ctor.
Definition ResPool.cc:38
zypp::StringPool::instance
static StringPool & instance()
Access the global StringPool instance.
Definition stringpool.cc:18
zypp::sat::Solvable::SplitIdent
Helper that splits an identifier into kind and name or vice versa.
Definition Solvable.h:381
zypp::sat::WhatProvides
Container of Solvable providing a Capability (read only).
Definition WhatProvides.h:89
zypp::sat::WhatProvides::empty
bool empty() const
Whether the container is empty.
Definition WhatProvides.cc:129
zypp::str::regex
Regular expression.
Definition Regex.h:95
zypp::str::regex::nosubs
@ nosubs
Support for substring addressing of matches is not required.
Definition Regex.h:100
zypp::str::smatch
Regular expression match result.
Definition Regex.h:168
zyppng::sat::StringPool
Singleton manager for the underlying libsolv string pool.
Definition stringpool.h:35
zyppng::sat::StringPool::getPool
detail::CPool * getPool() const
Explicit accessor for the raw sat-pool.
Definition stringpool.h:60
zyppng::sat::StringPool::parserpmrichdep
detail::IdType parserpmrichdep(const char *capstr_r)
libsolv capability parser
Definition stringpool.h:64
zypp::str::regex_match
bool regex_match(const char *s, smatch &matches, const regex &regex) ZYPP_API
Regular expression matching.
Definition Regex.cc:80
str
String related utilities and Regular expression matching.
zypp::pool
Definition ByIdent.h:24
zypp::sat::detail::emptyId
static const IdType emptyId(1)
zypp::sat::detail::noId
static const IdType noId(0)
zypp::sat::detail::IdType
int IdType
Generic Id type.
Definition PoolDefines.h:42
zypp::sat::detail::CPool
::s_Pool CPool
Wrapped libsolv C data type exposed as backdoor.
Definition PoolDefines.h:34
zypp::str::numstring
std::string numstring(char n, int w=0)
Definition String.h:290
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::url::split
void split(ParamVec &pvec, const std::string &pstr, const std::string &psep)
Split into a parameter vector.
Definition UrlUtils.cc:164
zypp
Easy-to use interface to the ZYPP dependency resolver.
Definition CodePitfalls.doc:2
zypp::ResolverNamespace
ResolverNamespace
The resolver's dependency namespaces.
Definition ResolverNamespace.h:25
zypp::overlaps
bool overlaps(const Range< Tp, TCompare > &lhs, const Range< Tp, TCompare > &rhs)
Definition Range.h:65
zypp::Arch_empty
const Arch Arch_empty(IdString::Empty)
zypp::asIdString
constexpr IdString asIdString(ResolverNamespace obj)
relates: ResolverNamespace The underlying libsolv ID
Definition ResolverNamespace.h:41
zypp::dumpOn
std::ostream & dumpOn(std::ostream &str, const Capability &obj)
relates: Capability Detailed stream output
Definition Capability.cc:589
zypp::asString
std::string asString(const Patch::Category &obj)
relates: Patch::Category string representation.
Definition Patch.cc:122
zypp::operator<<
std::ostream & operator<<(std::ostream &str, const Capabilities &obj)
relates: Capabilities Stream output
Definition Capabilities.cc:65
stringpool.h
zypp::Rel
Relational operators.
Definition Rel.h:46
zypp::Rel::LT
static const Rel LT
Definition Rel.h:54
zypp::Rel::LE
static const Rel LE
Definition Rel.h:55
zypp::Rel::GE
static const Rel GE
Definition Rel.h:57
zypp::Rel::NE
static const Rel NE
Definition Rel.h:53
zypp::Rel::ANY
static const Rel ANY
Definition Rel.h:58
zypp::Rel::EQ
static const Rel EQ
Definition Rel.h:52
zypp::Rel::isRel
static bool isRel(unsigned bits_r)
Test whether bits_r is a valid Rel (no extra bits set).
Definition Rel.h:113
zypp::dumpCap::_cap
Capability _cap
Definition Capability.h:341
zypp::dumpCap::_dumpRec
std::ostream & _dumpRec(std::ostream &str, Capability cap_r, std::string lvl_r="") const
Definition Capability.cc:613
zypp::dumpCap::dumpOn
std::ostream & dumpOn(std::ostream &str) const
Definition Capability.cc:611