return 0;
}
-static void
-selection_alldeps(Pool *pool, Queue *selection, int keyname, int marker)
-{
- Queue pkgs, q;
- int i, j;
-
- queue_init(&pkgs);
- queue_init(&q);
- selection_solvables(pool, selection, &pkgs);
- queue_empty(selection);
- for (i = 0; i < pkgs.count; i++)
- {
- queue_empty(&q);
- pool_whatmatchessolvable(pool, keyname, pkgs.elements[i], &q, marker);
- for (j = 0; j < q.count; j++)
- queue_pushunique(selection, q.elements[j]);
- }
- queue_free(&q);
- queue_free(&pkgs);
- j = selection->count;
- queue_insertn(selection, 0, j, 0);
- for (i = 0; i < j; i++)
- {
- selection->elements[2 * i] = SOLVER_SOLVABLE | SOLVER_NOAUTOSET;
- selection->elements[2 * i + 1] = selection->elements[i + j];
- }
-}
-
#define MODE_LIST 0
#define MODE_INSTALL 1
#define MODE_ERASE 2
if (rflags & SELECTION_PROVIDES)
printf("[using capability match for '%s']\n", argv[i]);
if (keyname && keyname_alldeps)
- selection_alldeps(pool, &job2, pool_str2id(pool, keyname, 1), 0);
+ {
+ Queue q;
+ queue_init(&q);
+ selection_solvables(pool, &job2, &q);
+ selection_make_matchsolvablelist(pool, &job2, &q, 0, pool_str2id(pool, keyname, 1), 0);
+ queue_free(&q);
+ }
queue_insertn(&job, job.count, job2.count, job2.elements);
queue_free(&job2);
}
return matchdep_str(rname, pool_id2str(pool, id), flags);
}
+static int
+selection_make_matchsolvable_common_limited(Pool *pool, Queue *selection, Queue *solvidq, Id solvid, int flags, int keyname, int marker, struct limiter *limiter)
+{
+ Id *wp;
+ Map m, missc;
+ int reloff, boff;
+ int li, i, j;
+ Id p;
+ Queue q;
+
+ if (solvidq)
+ {
+ map_init(&m, pool->nsolvables);
+ for (i = 0; i < solvidq->count; i++)
+ MAPSET(&m, solvidq->elements[i]);
+ }
+ queue_init(&q);
+ reloff = pool->ss.nstrings;
+ map_init(&missc, reloff + pool->nrels);
+ for (li = limiter->start; li < limiter->end; li++)
+ {
+ Solvable *s;
+ p = limiter->mapper ? limiter->mapper[li] : li;
+ if (solvidq && MAPTST(&m, p))
+ continue;
+ if (!solvidq && p == solvid)
+ continue;
+ s = pool->solvables + p;
+ if (!s->repo || (limiter->repofilter && s->repo != limiter->repofilter))
+ continue;
+ if (s->arch == ARCH_SRC || s->arch == ARCH_NOSRC)
+ {
+ if (!(flags & SELECTION_SOURCE_ONLY) && !(flags & SELECTION_WITH_SOURCE))
+ continue;
+ if (!(flags & SELECTION_WITH_DISABLED) && pool_disabled_solvable(pool, s))
+ continue;
+ }
+ else
+ {
+ if ((flags & SELECTION_SOURCE_ONLY) != 0)
+ continue;
+ if (s->repo != pool->installed)
+ {
+ if (!(flags & SELECTION_WITH_DISABLED) && pool_disabled_solvable(pool, s))
+ continue;
+ if (!(flags & SELECTION_WITH_BADARCH) && pool_badarch_solvable(pool, s))
+ continue;
+ }
+ }
+ if (q.count)
+ queue_empty(&q);
+ repo_lookup_deparray(s->repo, p, keyname, &q, marker);
+ if (!q.count)
+ continue;
+ for (i = 0; i < q.count; i++)
+ {
+ Id dep = q.elements[i];
+ boff = ISRELDEP(dep) ? reloff + GETRELID(dep) : dep;
+ if (MAPTST(&missc, boff))
+ continue;
+ if (ISRELDEP(dep))
+ {
+ Reldep *rd = GETRELDEP(pool, dep);
+ if (!ISRELDEP(rd->name) && rd->flags < 8)
+ {
+ /* do pre-filtering on the base */
+ if (MAPTST(&missc, rd->name))
+ continue;
+ wp = pool_whatprovides_ptr(pool, rd->name);
+ if (solvidq)
+ {
+ for (wp = pool_whatprovides_ptr(pool, dep); *wp; wp++)
+ if (MAPTST(&m, *wp))
+ break;
+ }
+ else
+ {
+ for (wp = pool_whatprovides_ptr(pool, dep); *wp; wp++)
+ if (*wp == solvid)
+ break;
+ }
+ if (!*wp)
+ {
+ /* the base does not include solvid, no need to check the complete dep */
+ MAPSET(&missc, rd->name);
+ MAPSET(&missc, boff);
+ continue;
+ }
+ }
+ }
+ wp = pool_whatprovides_ptr(pool, dep);
+ if (solvidq)
+ {
+ for (wp = pool_whatprovides_ptr(pool, dep); *wp; wp++)
+ if (MAPTST(&m, *wp))
+ break;
+ }
+ else
+ {
+ for (wp = pool_whatprovides_ptr(pool, dep); *wp; wp++)
+ if (*wp == solvid)
+ break;
+ }
+ if (*wp)
+ {
+ queue_push(selection, p);
+ break;
+ }
+ MAPSET(&missc, boff);
+ }
+ }
+ queue_free(&q);
+ map_free(&missc);
+ if (solvidq)
+ map_free(&m);
+ if (!selection->count)
+ return 0;
+
+ /* convert package list to selection */
+ j = selection->count;
+ queue_insertn(selection, 0, selection->count, 0);
+ for (i = 0; i < selection->count; )
+ {
+ selection->elements[i++] = SOLVER_SOLVABLE | SOLVER_NOAUTOSET;
+ selection->elements[i++] = selection->elements[j++];
+ }
+ if ((flags & SELECTION_FLAT) != 0)
+ selection_flatten(pool, selection);
+ return SELECTION_PROVIDES;
+}
+
static int
selection_make_matchdeps_common_limited(Pool *pool, Queue *selection, const char *name, Id dep, int flags, int keyname, int marker, struct limiter *limiter)
{
if (name && dep)
return 0;
+ if ((flags & SELECTION_MATCH_SOLVABLE) != 0)
+ return selection_make_matchsolvable_common_limited(pool, selection, (Queue *)name, dep, flags, keyname, marker, limiter);
+
if ((flags & SELECTION_MATCH_DEPSTR) != 0)
flags &= ~SELECTION_REL;
queue_push(selection, p);
continue;
}
- queue_empty(&q);
+ if (q.count)
+ queue_empty(&q);
repo_lookup_deparray(s->repo, p, keyname, &q, marker);
if (!q.count)
continue;
return selection_make_matchdeps_common(pool, selection, 0, dep, flags, keyname, marker);
}
+int
+selection_make_matchsolvable(Pool *pool, Queue *selection, Id solvid, int flags, int keyname, int marker)
+{
+ return selection_make_matchdeps_common(pool, selection, 0, solvid, flags | SELECTION_MATCH_SOLVABLE, keyname, marker);
+}
+
+int
+selection_make_matchsolvablelist(Pool *pool, Queue *selection, Queue *solvidq, int flags, int keyname, int marker)
+{
+ return selection_make_matchdeps_common(pool, selection, (const char *)solvidq, 0, flags | SELECTION_MATCH_SOLVABLE, keyname, marker);
+}
+
static inline int
pool_is_kind(Pool *pool, Id name, Id kind)
{
#define SELECTION_SUBTRACT (2 << 28)
#define SELECTION_FILTER (3 << 28)
-#define SELECTION_MODEBITS (3 << 28) /* internal */
/* extra SELECTION_FILTER bits */
#define SELECTION_FILTER_KEEP_IFEMPTY (1 << 30)
#define SELECTION_FILTER_SWAPPED (1 << 31)
+/* internal */
+#define SELECTION_MATCH_SOLVABLE (1 << 27)
+#define SELECTION_MODEBITS (3 << 28)
extern int selection_make(Pool *pool, Queue *selection, const char *name, int flags);
extern int selection_make_matchdeps(Pool *pool, Queue *selection, const char *name, int flags, int keyname, int marker);
extern int selection_make_matchdepid(Pool *pool, Queue *selection, Id dep, int flags, int keyname, int marker);
+extern int selection_make_matchsolvable(Pool *pool, Queue *selection, Id solvid, int flags, int keyname, int marker);
+extern int selection_make_matchsolvablelist(Pool *pool, Queue *selection, Queue *solvidq, int flags, int keyname, int marker);
extern void selection_filter(Pool *pool, Queue *sel1, Queue *sel2);
extern void selection_add(Pool *pool, Queue *sel1, Queue *sel2);