]> git.ipfire.org Git - thirdparty/libsolv.git/commitdiff
Add pool_whatmatchessolvable() function to match against the provides of a solvable
authorMichael Schroeder <mls@suse.de>
Thu, 4 Oct 2018 15:22:43 +0000 (17:22 +0200)
committerMichael Schroeder <mls@suse.de>
Thu, 4 Oct 2018 15:22:43 +0000 (17:22 +0200)
examples/solv/solv.c
src/libsolv.ver
src/pool.c
src/pool.h

index 42ab751bf9f3be7a554bdc39c4fb980806c60ce9..c35cc2fa91bd2acf7221c4b20fcd62c6c9220c3c 100644 (file)
@@ -169,6 +169,40 @@ find_repo(const char *name, Pool *pool, struct repoinfo *repoinfos, int nrepoinf
   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
@@ -227,6 +261,7 @@ main(int argc, char **argv)
   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;
@@ -316,9 +351,15 @@ main(int argc, char **argv)
          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++;
        }
@@ -541,6 +582,8 @@ main(int argc, char **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)
@@ -554,6 +597,8 @@ main(int argc, char **argv)
          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)
index d31d902cf01374117bff3dfbec37dc4aa36c04f9..c2acc137f0f11d1ea4fa1b7ca28e6a239f73b5e7 100644 (file)
@@ -120,6 +120,7 @@ SOLV_1.0 {
                pool_trivial_installable_multiversionmap;
                pool_vendor2mask;
                pool_whatmatchesdep;
+               pool_whatmatchessolvable;
                pool_whatcontainsdep;
                queue_alloc_one;
                queue_alloc_one_head;
index 3ff5bd20d2561638f5a877b2206bbefc68b8d49f..aa994cc7660da273e05c806ec01d634a95ed665a 100644 (file)
@@ -1485,6 +1485,77 @@ pool_whatcontainsdep(Pool *pool, Id keyname, Id dep, Queue *q, int marker)
   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
index e6d1700ca622249c1c0be89619aa4d8a3742aa73..7b1474327f0411177ea2b143aee14f58fedfbe1a 100644 (file)
@@ -348,6 +348,7 @@ static inline Id *pool_whatprovides_ptr(Pool *pool, Id d)
 
 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);