From 7fea982667f20409403e794ab916dbb183681b4b Mon Sep 17 00:00:00 2001 From: Michael Schroeder Date: Thu, 3 Aug 2017 14:54:26 +0200 Subject: [PATCH] Support REL_WITHOUT Because we can. --- bindings/solv.i | 1 + ext/pool_parserpmrichdep.c | 10 ++++++---- ext/testcase.c | 1 + src/pool.c | 28 +++++++++++++++++++++++----- src/pool.h | 1 + src/poolid.c | 6 ++++-- src/selection.c | 4 ++-- 7 files changed, 38 insertions(+), 13 deletions(-) diff --git a/bindings/solv.i b/bindings/solv.i index 354cde7..ec069c7 100644 --- a/bindings/solv.i +++ b/bindings/solv.i @@ -946,6 +946,7 @@ typedef int Id; %constant int REL_MULTIARCH; %constant int REL_ELSE; %constant int REL_ERROR; +%constant int REL_WITHOUT; typedef struct { Pool* const pool; diff --git a/ext/pool_parserpmrichdep.c b/ext/pool_parserpmrichdep.c index d3e559e..0b54677 100644 --- a/ext/pool_parserpmrichdep.c +++ b/ext/pool_parserpmrichdep.c @@ -17,10 +17,12 @@ static struct RichOpComp { int l; Id fl; } RichOps[] = { - { "and", 3, REL_AND }, - { "or", 2, REL_OR }, - { "if", 2, REL_COND }, - { "else", 4, REL_ELSE }, + { "and", 3, REL_AND }, + { "or", 2, REL_OR }, + { "if", 2, REL_COND }, + { "else", 4, REL_ELSE }, + { "with", 4, REL_WITH }, + { "without", 7, REL_WITHOUT }, { NULL, 0, 0}, }; diff --git a/ext/testcase.c b/ext/testcase.c index 26acefa..25c23cb 100644 --- a/ext/testcase.c +++ b/ext/testcase.c @@ -383,6 +383,7 @@ struct oplist { { REL_AND, "&" }, { REL_OR , "|" }, { REL_WITH , "+" }, + { REL_WITHOUT , "-" }, { REL_NAMESPACE , "" }, { REL_ARCH, "." }, { REL_MULTIARCH, "" }, diff --git a/src/pool.c b/src/pool.c index bd97026..5d2d033 100644 --- a/src/pool.c +++ b/src/pool.c @@ -705,6 +705,10 @@ pool_match_nevr_rel(Pool *pool, Solvable *s, Id d) if (!pool_match_nevr(pool, s, name)) return 0; return pool_match_nevr(pool, s, evr); + case REL_WITHOUT: + if (!pool_match_nevr(pool, s, name)) + return 0; + return !pool_match_nevr(pool, s, evr); case REL_MULTIARCH: if (evr != ARCH_ANY) return 0; @@ -818,7 +822,7 @@ pool_match_dep(Pool *pool, Id d1, Id d2) { /* we use potentially matches for complex deps */ rd1 = GETRELDEP(pool, d1); - if (rd1->flags == REL_AND || rd1->flags == REL_OR || rd1->flags == REL_WITH || rd1->flags == REL_COND) + if (rd1->flags == REL_AND || rd1->flags == REL_OR || rd1->flags == REL_WITH || rd1->flags == REL_WITHOUT || rd1->flags == REL_COND) { if (pool_match_dep(pool, rd1->name, d2)) return 1; @@ -828,7 +832,7 @@ pool_match_dep(Pool *pool, Id d1, Id d2) if (rd1->flags != REL_ELSE) return 0; } - if (rd1->flags != REL_COND && pool_match_dep(pool, rd1->evr, d2)) + if (rd1->flags != REL_COND && rd1->flags != REL_WITHOUT && pool_match_dep(pool, rd1->evr, d2)) return 1; return 0; } @@ -837,7 +841,7 @@ pool_match_dep(Pool *pool, Id d1, Id d2) { /* we use potentially matches for complex deps */ rd2 = GETRELDEP(pool, d2); - if (rd2->flags == REL_AND || rd2->flags == REL_OR || rd2->flags == REL_WITH || rd2->flags == REL_COND) + if (rd2->flags == REL_AND || rd2->flags == REL_OR || rd2->flags == REL_WITH || rd2->flags == REL_WITHOUT || rd2->flags == REL_COND) { if (pool_match_dep(pool, d1, rd2->name)) return 1; @@ -847,7 +851,7 @@ pool_match_dep(Pool *pool, Id d1, Id d2) if (rd2->flags != REL_ELSE) return 0; } - if (rd2->flags != REL_COND && pool_match_dep(pool, d1, rd2->evr)) + if (rd2->flags != REL_COND && rd2->flags != REL_WITHOUT && pool_match_dep(pool, d1, rd2->evr)) return 1; return 0; } @@ -1108,7 +1112,21 @@ pool_addrelproviders(Pool *pool, Id d) wp = 0; } break; - + case REL_WITHOUT: + wp = pool_whatprovides(pool, name); + pp2 = pool_whatprovides_ptr(pool, evr); + pp = pool->whatprovidesdata + wp; + while ((p = *pp++) != 0) + { + for (pp3 = pp2; *pp3; pp3++) + if (*pp3 == p) + break; + if (!*pp3) + queue_push(&plist, p); /* use it */ + else + wp = 0; + } + break; case REL_AND: case REL_OR: case REL_COND: diff --git a/src/pool.h b/src/pool.h index 3eeea06..1d15de2 100644 --- a/src/pool.h +++ b/src/pool.h @@ -229,6 +229,7 @@ struct _Pool { #define REL_MULTIARCH 25 /* debian multiarch annotation */ #define REL_ELSE 26 /* only as evr part of REL_COND */ #define REL_ERROR 27 /* parse errors and the like */ +#define REL_WITHOUT 28 #if !defined(__GNUC__) && !defined(__attribute__) # define __attribute__(x) diff --git a/src/poolid.c b/src/poolid.c index 3a8a3c8..de1ce29 100644 --- a/src/poolid.c +++ b/src/poolid.c @@ -178,6 +178,8 @@ pool_id2rel(const Pool *pool, Id id) return pool->disttype == DISTTYPE_RPM ? " or " : " | "; case REL_WITH: return pool->disttype == DISTTYPE_RPM ? " with " : " + "; + case REL_WITHOUT: + return pool->disttype == DISTTYPE_RPM ? " without " : " - "; case REL_NAMESPACE: return " NAMESPACE "; /* actually not used in dep2str */ case REL_ARCH: @@ -238,8 +240,8 @@ dep2strcpy(const Pool *pool, char *p, Id id, int oldrel) { Reldep *rd = GETRELDEP(pool, id); int rel = rd->flags; - if (oldrel == REL_AND || oldrel == REL_OR || oldrel == REL_WITH || oldrel == REL_COND || oldrel == REL_ELSE || oldrel == -1) - if (rel == REL_AND || rel == REL_OR || rel == REL_WITH || rel == REL_COND || rel == REL_ELSE) + if (oldrel == REL_AND || oldrel == REL_OR || oldrel == REL_WITH || oldrel == REL_WITHOUT || oldrel == REL_COND || oldrel == REL_ELSE || oldrel == -1) + if (rel == REL_AND || rel == REL_OR || rel == REL_WITH || rel == REL_WITHOUT || rel == REL_COND || rel == REL_ELSE) if ((oldrel != rel || rel == REL_COND || rel == REL_ELSE) && !(oldrel == REL_COND && rel == REL_ELSE)) { *p++ = '('; diff --git a/src/selection.c b/src/selection.c index 37c6184..e6ea84b 100644 --- a/src/selection.c +++ b/src/selection.c @@ -890,7 +890,7 @@ matchdep(Pool *pool, Id id, char *rname, int rflags, char *revr, int flags) if (ISRELDEP(id)) { Reldep *rd = GETRELDEP(pool, id); - if (rd->flags == REL_AND || rd->flags == REL_OR || rd->flags == REL_WITH || rd->flags == REL_COND) + if (rd->flags == REL_AND || rd->flags == REL_OR || rd->flags == REL_WITH || rd->flags == REL_WITHOUT || rd->flags == REL_COND) { if (matchdep(pool, rd->name, rname, rflags, revr, flags)) return 1; @@ -900,7 +900,7 @@ matchdep(Pool *pool, Id id, char *rname, int rflags, char *revr, int flags) if (rd->flags != REL_ELSE) return 0; } - if (rd->flags != REL_COND && matchdep(pool, rd->evr, rname, rflags, revr, flags)) + if (rd->flags != REL_COND && rd->flags != REL_WITHOUT && matchdep(pool, rd->evr, rname, rflags, revr, flags)) return 1; return 0; } -- 2.13.4