Skip to content

Commit 321bb2a

Browse files
committed
Add selection_make_matchsolvable and selection_make_matchsolvablelist
This is like pool_whatmatchessolvable, but works on a selection. The advantage is that it supports filtering.
1 parent 692bd3e commit 321bb2a

4 files changed

Lines changed: 162 additions & 31 deletions

File tree

examples/solv/solv.c

Lines changed: 7 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -169,34 +169,6 @@ find_repo(const char *name, Pool *pool, struct repoinfo *repoinfos, int nrepoinf
169169
return 0;
170170
}
171171

172-
static void
173-
selection_alldeps(Pool *pool, Queue *selection, int keyname, int marker)
174-
{
175-
Queue pkgs, q;
176-
int i, j;
177-
178-
queue_init(&pkgs);
179-
queue_init(&q);
180-
selection_solvables(pool, selection, &pkgs);
181-
queue_empty(selection);
182-
for (i = 0; i < pkgs.count; i++)
183-
{
184-
queue_empty(&q);
185-
pool_whatmatchessolvable(pool, keyname, pkgs.elements[i], &q, marker);
186-
for (j = 0; j < q.count; j++)
187-
queue_pushunique(selection, q.elements[j]);
188-
}
189-
queue_free(&q);
190-
queue_free(&pkgs);
191-
j = selection->count;
192-
queue_insertn(selection, 0, j, 0);
193-
for (i = 0; i < j; i++)
194-
{
195-
selection->elements[2 * i] = SOLVER_SOLVABLE | SOLVER_NOAUTOSET;
196-
selection->elements[2 * i + 1] = selection->elements[i + j];
197-
}
198-
}
199-
200172
#define MODE_LIST 0
201173
#define MODE_INSTALL 1
202174
#define MODE_ERASE 2
@@ -609,7 +581,13 @@ main(int argc, char **argv)
609581
if (rflags & SELECTION_PROVIDES)
610582
printf("[using capability match for '%s']\n", argv[i]);
611583
if (keyname && keyname_alldeps)
612-
selection_alldeps(pool, &job2, pool_str2id(pool, keyname, 1), 0);
584+
{
585+
Queue q;
586+
queue_init(&q);
587+
selection_solvables(pool, &job2, &q);
588+
selection_make_matchsolvablelist(pool, &job2, &q, 0, pool_str2id(pool, keyname, 1), 0);
589+
queue_free(&q);
590+
}
613591
queue_insertn(&job, job.count, job2.count, job2.elements);
614592
queue_free(&job2);
615593
}

src/libsolv.ver

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -259,6 +259,8 @@ SOLV_1.0 {
259259
selection_make;
260260
selection_make_matchdepid;
261261
selection_make_matchdeps;
262+
selection_make_matchsolvable;
263+
selection_make_matchsolvablelist;
262264
selection_solvables;
263265
solv_bin2hex;
264266
solv_calloc;

src/selection.c

Lines changed: 148 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1430,6 +1430,137 @@ matchdep(Pool *pool, Id id, char *rname, int rflags, Id revr, int flags)
14301430
return matchdep_str(rname, pool_id2str(pool, id), flags);
14311431
}
14321432

1433+
static int
1434+
selection_make_matchsolvable_common_limited(Pool *pool, Queue *selection, Queue *solvidq, Id solvid, int flags, int keyname, int marker, struct limiter *limiter)
1435+
{
1436+
Id *wp;
1437+
Map m, missc;
1438+
int reloff, boff;
1439+
int li, i, j;
1440+
Id p;
1441+
Queue q;
1442+
1443+
if (solvidq)
1444+
{
1445+
map_init(&m, pool->nsolvables);
1446+
for (i = 0; i < solvidq->count; i++)
1447+
MAPSET(&m, solvidq->elements[i]);
1448+
}
1449+
queue_init(&q);
1450+
reloff = pool->ss.nstrings;
1451+
map_init(&missc, reloff + pool->nrels);
1452+
for (li = limiter->start; li < limiter->end; li++)
1453+
{
1454+
Solvable *s;
1455+
p = limiter->mapper ? limiter->mapper[li] : li;
1456+
if (solvidq && MAPTST(&m, p))
1457+
continue;
1458+
if (!solvidq && p == solvid)
1459+
continue;
1460+
s = pool->solvables + p;
1461+
if (!s->repo || (limiter->repofilter && s->repo != limiter->repofilter))
1462+
continue;
1463+
if (s->arch == ARCH_SRC || s->arch == ARCH_NOSRC)
1464+
{
1465+
if (!(flags & SELECTION_SOURCE_ONLY) && !(flags & SELECTION_WITH_SOURCE))
1466+
continue;
1467+
if (!(flags & SELECTION_WITH_DISABLED) && pool_disabled_solvable(pool, s))
1468+
continue;
1469+
}
1470+
else
1471+
{
1472+
if ((flags & SELECTION_SOURCE_ONLY) != 0)
1473+
continue;
1474+
if (s->repo != pool->installed)
1475+
{
1476+
if (!(flags & SELECTION_WITH_DISABLED) && pool_disabled_solvable(pool, s))
1477+
continue;
1478+
if (!(flags & SELECTION_WITH_BADARCH) && pool_badarch_solvable(pool, s))
1479+
continue;
1480+
}
1481+
}
1482+
if (q.count)
1483+
queue_empty(&q);
1484+
repo_lookup_deparray(s->repo, p, keyname, &q, marker);
1485+
if (!q.count)
1486+
continue;
1487+
for (i = 0; i < q.count; i++)
1488+
{
1489+
Id dep = q.elements[i];
1490+
boff = ISRELDEP(dep) ? reloff + GETRELID(dep) : dep;
1491+
if (MAPTST(&missc, boff))
1492+
continue;
1493+
if (ISRELDEP(dep))
1494+
{
1495+
Reldep *rd = GETRELDEP(pool, dep);
1496+
if (!ISRELDEP(rd->name) && rd->flags < 8)
1497+
{
1498+
/* do pre-filtering on the base */
1499+
if (MAPTST(&missc, rd->name))
1500+
continue;
1501+
wp = pool_whatprovides_ptr(pool, rd->name);
1502+
if (solvidq)
1503+
{
1504+
for (wp = pool_whatprovides_ptr(pool, dep); *wp; wp++)
1505+
if (MAPTST(&m, *wp))
1506+
break;
1507+
}
1508+
else
1509+
{
1510+
for (wp = pool_whatprovides_ptr(pool, dep); *wp; wp++)
1511+
if (*wp == solvid)
1512+
break;
1513+
}
1514+
if (!*wp)
1515+
{
1516+
/* the base does not include solvid, no need to check the complete dep */
1517+
MAPSET(&missc, rd->name);
1518+
MAPSET(&missc, boff);
1519+
continue;
1520+
}
1521+
}
1522+
}
1523+
wp = pool_whatprovides_ptr(pool, dep);
1524+
if (solvidq)
1525+
{
1526+
for (wp = pool_whatprovides_ptr(pool, dep); *wp; wp++)
1527+
if (MAPTST(&m, *wp))
1528+
break;
1529+
}
1530+
else
1531+
{
1532+
for (wp = pool_whatprovides_ptr(pool, dep); *wp; wp++)
1533+
if (*wp == solvid)
1534+
break;
1535+
}
1536+
if (*wp)
1537+
{
1538+
queue_push(selection, p);
1539+
break;
1540+
}
1541+
MAPSET(&missc, boff);
1542+
}
1543+
}
1544+
queue_free(&q);
1545+
map_free(&missc);
1546+
if (solvidq)
1547+
map_free(&m);
1548+
if (!selection->count)
1549+
return 0;
1550+
1551+
/* convert package list to selection */
1552+
j = selection->count;
1553+
queue_insertn(selection, 0, selection->count, 0);
1554+
for (i = 0; i < selection->count; )
1555+
{
1556+
selection->elements[i++] = SOLVER_SOLVABLE | SOLVER_NOAUTOSET;
1557+
selection->elements[i++] = selection->elements[j++];
1558+
}
1559+
if ((flags & SELECTION_FLAT) != 0)
1560+
selection_flatten(pool, selection);
1561+
return SELECTION_PROVIDES;
1562+
}
1563+
14331564
static int
14341565
selection_make_matchdeps_common_limited(Pool *pool, Queue *selection, const char *name, Id dep, int flags, int keyname, int marker, struct limiter *limiter)
14351566
{
@@ -1449,6 +1580,9 @@ selection_make_matchdeps_common_limited(Pool *pool, Queue *selection, const char
14491580
if (name && dep)
14501581
return 0;
14511582

1583+
if ((flags & SELECTION_MATCH_SOLVABLE) != 0)
1584+
return selection_make_matchsolvable_common_limited(pool, selection, (Queue *)name, dep, flags, keyname, marker, limiter);
1585+
14521586
if ((flags & SELECTION_MATCH_DEPSTR) != 0)
14531587
flags &= ~SELECTION_REL;
14541588

@@ -1558,7 +1692,8 @@ selection_make_matchdeps_common_limited(Pool *pool, Queue *selection, const char
15581692
queue_push(selection, p);
15591693
continue;
15601694
}
1561-
queue_empty(&q);
1695+
if (q.count)
1696+
queue_empty(&q);
15621697
repo_lookup_deparray(s->repo, p, keyname, &q, marker);
15631698
if (!q.count)
15641699
continue;
@@ -1708,6 +1843,18 @@ selection_make_matchdepid(Pool *pool, Queue *selection, Id dep, int flags, int k
17081843
return selection_make_matchdeps_common(pool, selection, 0, dep, flags, keyname, marker);
17091844
}
17101845

1846+
int
1847+
selection_make_matchsolvable(Pool *pool, Queue *selection, Id solvid, int flags, int keyname, int marker)
1848+
{
1849+
return selection_make_matchdeps_common(pool, selection, 0, solvid, flags | SELECTION_MATCH_SOLVABLE, keyname, marker);
1850+
}
1851+
1852+
int
1853+
selection_make_matchsolvablelist(Pool *pool, Queue *selection, Queue *solvidq, int flags, int keyname, int marker)
1854+
{
1855+
return selection_make_matchdeps_common(pool, selection, (const char *)solvidq, 0, flags | SELECTION_MATCH_SOLVABLE, keyname, marker);
1856+
}
1857+
17111858
static inline int
17121859
pool_is_kind(Pool *pool, Id name, Id kind)
17131860
{

src/selection.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,16 +52,20 @@ extern "C" {
5252
#define SELECTION_SUBTRACT (2 << 28)
5353
#define SELECTION_FILTER (3 << 28)
5454

55-
#define SELECTION_MODEBITS (3 << 28) /* internal */
5655

5756
/* extra SELECTION_FILTER bits */
5857
#define SELECTION_FILTER_KEEP_IFEMPTY (1 << 30)
5958
#define SELECTION_FILTER_SWAPPED (1 << 31)
6059

60+
/* internal */
61+
#define SELECTION_MATCH_SOLVABLE (1 << 27)
62+
#define SELECTION_MODEBITS (3 << 28)
6163

6264
extern int selection_make(Pool *pool, Queue *selection, const char *name, int flags);
6365
extern int selection_make_matchdeps(Pool *pool, Queue *selection, const char *name, int flags, int keyname, int marker);
6466
extern int selection_make_matchdepid(Pool *pool, Queue *selection, Id dep, int flags, int keyname, int marker);
67+
extern int selection_make_matchsolvable(Pool *pool, Queue *selection, Id solvid, int flags, int keyname, int marker);
68+
extern int selection_make_matchsolvablelist(Pool *pool, Queue *selection, Queue *solvidq, int flags, int keyname, int marker);
6569

6670
extern void selection_filter(Pool *pool, Queue *sel1, Queue *sel2);
6771
extern void selection_add(Pool *pool, Queue *sel1, Queue *sel2);

0 commit comments

Comments
 (0)