return 0;
}
+static int
+selection_alldeps(Pool *pool, Queue *selection, const char *name, int flags, int keyname, int marker)
+{
+ int i, j, r;
+ Queue pkgs, q;
+
+ queue_empty(selection);
+ queue_init(&q);
+ r = selection_make(pool, &q, name, flags);
+ if (!q.count)
+ {
+ queue_free(&q);
+ return 0;
+ }
+ queue_init(&pkgs);
+ selection_solvables(pool, &q, &pkgs);
+ 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++)
+ if (q.elements[j] != pkgs.elements[i])
+ queue_pushunique(selection, q.elements[j]);
+ }
+ queue_free(&q);
+ 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];
+ }
+ return j ? r : 0;
+}
#define MODE_LIST 0
#define MODE_INSTALL 1
char *rootdir = 0;
char *keyname = 0;
int keyname_depstr = 0;
+ int keyname_alldeps = 0; /* dnf repoquesy --alldeps */
int debuglevel = 0;
int answer, acnt = 0;
char *testcase = 0;
argc--;
argv++;
}
+ else if (argc > 1 && !strcmp(argv[1], "--alldeps"))
+ {
+ keyname_alldeps = 1; /* dnf repoquesy --alldeps */
+ argc--;
+ argv++;
+ }
else if (argc > 1 && !strcmp(argv[1], "--depstr"))
{
- keyname_depstr = 1;
+ keyname_depstr = 1; /* do literal matching instead of dep intersection */
argc--;
argv++;
}
flags |= SELECTION_MATCH_DEPSTR;
if (!keyname)
rflags = selection_make(pool, &job2, argv[i], flags);
+ else if (keyname_alldeps)
+ rflags = selection_alldeps(pool, &job2, argv[i], flags, pool_str2id(pool, keyname, 1), 0);
else
rflags = selection_make_matchdeps(pool, &job2, argv[i], flags, pool_str2id(pool, keyname, 1), 0);
if (repofilter.count)
flags |= SELECTION_NOCASE;
if (!keyname)
rflags = selection_make(pool, &job2, argv[i], flags);
+ else if (keyname_alldeps)
+ rflags = selection_alldeps(pool, &job2, argv[i], flags, pool_str2id(pool, keyname, 1), 0);
else
rflags = selection_make_matchdeps(pool, &job2, argv[i], flags, pool_str2id(pool, keyname, 1), 0);
if (repofilter.count)
queue_free(&qq);
}
+/* intersect dependencies in keyname with all provides of solvable solvid,
+ * return list of matching packages */
+/* this currently only works for installable packages */
+void
+pool_whatmatchessolvable(Pool *pool, Id keyname, Id solvid, Queue *q, int marker)
+{
+ Id p, *wp;
+ Queue qq;
+ int i;
+ Map missc; /* cache for misses */
+ int reloff, boff;
+
+ queue_empty(q);
+ queue_init(&qq);
+ reloff = pool->ss.nstrings;
+ map_init(&missc, reloff + pool->nrels);
+ FOR_POOL_SOLVABLES(p)
+ {
+ Solvable *s = pool->solvables + p;
+ if (p == solvid)
+ continue; /* filter out self-matches */
+ if (s->repo->disabled)
+ continue;
+ if (s->repo != pool->installed && !pool_installable(pool, s))
+ continue;
+ if (qq.count)
+ queue_empty(&qq);
+ solvable_lookup_deparray(s, keyname, &qq, marker);
+ for (i = 0; i < qq.count; i++)
+ {
+ Id dep = qq.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);
+ 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);
+ for (wp = pool_whatprovides_ptr(pool, dep); *wp; wp++)
+ if (*wp == solvid)
+ break;
+ if (*wp)
+ {
+ queue_push(q, p);
+ break;
+ }
+ MAPSET(&missc, boff);
+ }
+ }
+ map_free(&missc);
+ queue_free(&qq);
+}
+
/*************************************************************************/
void
void pool_whatmatchesdep(Pool *pool, Id keyname, Id dep, Queue *q, int marker);
void pool_whatcontainsdep(Pool *pool, Id keyname, Id dep, Queue *q, int marker);
+void pool_whatmatchessolvable(Pool *pool, Id keyname, Id solvid, Queue *q, int marker);
void pool_set_whatprovides(Pool *pool, Id id, Id providers);