From 933f0e4d5c5c5e7d3d8ec1be4d6fcdf72fe120ae Mon Sep 17 00:00:00 2001 From: =?utf8?q?Ale=C5=A1=20Mat=C4=9Bj?= Date: Tue, 1 Jul 2025 14:25:38 +0200 Subject: [PATCH] Add pool_dep_fulfilled_in_map function This is can be used to determine dependency closure on a given set of packages (even with complex dependencies). --- doc/libsolv-pool.txt | 4 +++ src/libsolv.ver | 1 + src/pool.c | 70 ++++++++++++++++++++++++++++++++++++++++++++ src/pool.h | 1 + 4 files changed, 76 insertions(+) diff --git a/doc/libsolv-pool.txt b/doc/libsolv-pool.txt index 2958437c..92232ab1 100644 --- a/doc/libsolv-pool.txt +++ b/doc/libsolv-pool.txt @@ -562,6 +562,10 @@ by the ``evr'' parts must overlap. Like pool_match_dep, but the provider is the "self-provides" dependency of the Solvable _s_, i.e. the dependency ``s->name = s->evr''. + int pool_dep_fulfilled_in_map(Pool *pool, const Map *map, Id dep); + +Returns ``1'' if the dependency _dep_ is provided by at least one package +from _map_, otherwise ``0'' is returned. Whatprovides Index ------------------ diff --git a/src/libsolv.ver b/src/libsolv.ver index accb5aa7..6f72ae16 100644 --- a/src/libsolv.ver +++ b/src/libsolv.ver @@ -91,6 +91,7 @@ SOLV_1.0 { pool_lookup_str; pool_lookup_void; pool_match_dep; + pool_dep_fulfilled_in_map; pool_match_nevr_rel; pool_prepend_rootdir; pool_prepend_rootdir_tmp; diff --git a/src/pool.c b/src/pool.c index 14511def..350153e4 100644 --- a/src/pool.c +++ b/src/pool.c @@ -2104,4 +2104,74 @@ int (*pool_get_custom_vendorcheck(Pool *pool))(Pool *, Solvable *, Solvable *) return pool->custom_vendorcheck; } +static int +pool_dep_fulfilled_in_map_cplx(Pool *pool, const Map *map, Reldep *rd) +{ + if (rd->flags == REL_COND) + { + if (ISRELDEP(rd->evr)) + { + Reldep *rd2 = GETRELDEP(pool, rd->evr); + if (rd2->flags == REL_ELSE) + { + if (pool_dep_fulfilled_in_map(pool, map, rd2->name)) + return pool_dep_fulfilled_in_map(pool, map, rd->name); + return pool_dep_fulfilled_in_map(pool, map, rd2->evr); + } + } + if (pool_dep_fulfilled_in_map(pool, map, rd->name)) + return 1; + return !pool_dep_fulfilled_in_map(pool, map, rd->evr); + } + if (rd->flags == REL_UNLESS) + { + if (ISRELDEP(rd->evr)) + { + Reldep *rd2 = GETRELDEP(pool, rd->evr); + if (rd2->flags == REL_ELSE) + { + if (!pool_dep_fulfilled_in_map(pool, map, rd2->name)) + return pool_dep_fulfilled_in_map(pool, map, rd->name); + return pool_dep_fulfilled_in_map(pool, map, rd2->evr); + } + } + if (!pool_dep_fulfilled_in_map(pool, map, rd->name)) + return 0; + return !pool_dep_fulfilled_in_map(pool, map, rd->evr); + } + if (rd->flags == REL_AND) + { + if (!pool_dep_fulfilled_in_map(pool, map, rd->name)) + return 0; + return pool_dep_fulfilled_in_map(pool, map, rd->evr); + } + if (rd->flags == REL_OR) + { + if (pool_dep_fulfilled_in_map(pool, map, rd->name)) + return 1; + return pool_dep_fulfilled_in_map(pool, map, rd->evr); + } + return 0; +} + + +int pool_dep_fulfilled_in_map(Pool *pool, const Map *map, Id dep) +{ + Id p, pp; + + if (ISRELDEP(dep)) { + Reldep *rd = GETRELDEP(pool, dep); + if (rd->flags == REL_COND || rd->flags == REL_UNLESS || + rd->flags == REL_AND || rd->flags == REL_OR) + return pool_dep_fulfilled_in_map_cplx(pool, map, rd); + if (rd->flags == REL_NAMESPACE && rd->name == NAMESPACE_SPLITPROVIDES) + return 0; + } + FOR_PROVIDES(p, pp, dep) { + if (MAPTST(map, p)) + return 1; + } + return 0; +} + /* EOF */ diff --git a/src/pool.h b/src/pool.h index d8c938e8..7c11e463 100644 --- a/src/pool.h +++ b/src/pool.h @@ -305,6 +305,7 @@ Id pool_id2langid(Pool *pool, Id id, const char *lang, int create); int pool_intersect_evrs(Pool *pool, int pflags, Id pevr, int flags, Id evr); int pool_match_dep(Pool *pool, Id d1, Id d2); +int pool_dep_fulfilled_in_map(Pool *pool, const Map *map, Id dep); /* semi private, used in pool_match_nevr */ int pool_match_nevr_rel(Pool *pool, Solvable *s, Id d); -- 2.47.2