]> git.ipfire.org Git - thirdparty/libsolv.git/commitdiff
Fix REL_COND for weak deps corner cases
authorMichael Schroeder <mls@suse.de>
Tue, 25 Aug 2015 10:48:05 +0000 (12:48 +0200)
committerMichael Schroeder <mls@suse.de>
Tue, 25 Aug 2015 10:48:05 +0000 (12:48 +0200)
src/cplxdeps.c
src/cplxdeps.h
src/rules.c
src/solver.c

index 2248b8b8205d4f43902857c7ae7d85c937c13746..aadbc48e5b870b321494b12112d3db21af6e5618 100644 (file)
@@ -417,5 +417,38 @@ pool_normalize_complex_dep(Pool *pool, Id dep, Queue *bq, int flags)
   return i;
 }
 
+void
+pool_add_pos_literals_complex_dep(Pool *pool, Id dep, Queue *q, Map *m, int neg)
+{
+  while (ISRELDEP(dep))
+    {
+      Reldep *rd = GETRELDEP(pool, dep);
+      if (rd->flags != REL_AND && rd->flags != REL_OR && rd->flags != REL_COND)
+       break;
+      pool_add_pos_literals_complex_dep(pool, rd->name, q, m, neg);
+      dep = rd->evr;
+      if (rd->flags == REL_COND)
+       {
+         neg = !neg;
+         if (ISRELDEP(dep))
+           {
+             Reldep *rd2 = GETRELDEP(pool, rd->evr);
+             if (rd2->flags == REL_ELSE)
+               {
+                 pool_add_pos_literals_complex_dep(pool, rd2->evr, q, m, !neg);
+                 dep = rd2->name;
+               }
+           }
+       }
+    }
+  if (!neg)
+    {
+      Id p, pp;
+      FOR_PROVIDES(p, pp, dep)
+       if (!MAPTST(m, p))
+         queue_push(q, p);
+    }
+}
+
 #endif /* ENABLE_COMPLEX_DEPS */
 
index 1cda760e66a3f151187c57e0125b20656d3a4b3c..798b485a3076d77941d283903af9d661791780f3 100644 (file)
@@ -27,6 +27,7 @@ pool_is_complex_dep(Pool *pool, Id dep)
 }
 
 extern int pool_normalize_complex_dep(Pool *pool, Id dep, Queue *bq, int flags);
+extern void pool_add_pos_literals_complex_dep(Pool *pool, Id dep, Queue *q, Map *m, int neg);
 
 #define CPLXDEPS_TODNF   (1 << 0)
 #define CPLXDEPS_EXPAND  (1 << 1)
index 7a6d7fdee84c4077033d7d47012612bfdd7861cb..3264e9b86f82f76e31a451481506fa43b8274497 100644 (file)
@@ -968,13 +968,20 @@ solver_addpkgrulesforsolvable(Solver *solv, Solvable *s, Map *m)
        }
 
       /*-----------------------------------------
-       * add recommends to the work queue
+       * add recommends/suggests to the work queue
        */
       if (s->recommends && m)
        {
          recp = s->repo->idarraydata + s->recommends;
          while ((rec = *recp++) != 0)
            {
+#ifdef ENABLE_COMPLEX_DEPS
+             if (pool_is_complex_dep(pool, rec))
+               {
+                 pool_add_pos_literals_complex_dep(pool, rec, &workq, m, 0);
+                   continue;
+               }
+#endif
              FOR_PROVIDES(p, pp, rec)
                if (!MAPTST(m, p))
                  queue_push(&workq, p);
@@ -985,6 +992,13 @@ solver_addpkgrulesforsolvable(Solver *solv, Solvable *s, Map *m)
          sugp = s->repo->idarraydata + s->suggests;
          while ((sug = *sugp++) != 0)
            {
+#ifdef ENABLE_COMPLEX_DEPS
+             if (pool_is_complex_dep(pool, sug))
+               {
+                 pool_add_pos_literals_complex_dep(pool, sug, &workq, m, 0);
+                   continue;
+               }
+#endif
              FOR_PROVIDES(p, pp, sug)
                if (!MAPTST(m, p))
                  queue_push(&workq, p);
index f5517311777a404c984b7292c5269e2183ced1fa..b89e0d17ed863a560c5d3c946586bda4816d8b3e 100644 (file)
@@ -117,6 +117,29 @@ solver_dep_fulfilled_alreadyinstalled(Solver *solv, Id dep)
   if (ISRELDEP(dep))
     {
       Reldep *rd = GETRELDEP(pool, dep);
+      if (rd->flags == REL_COND)
+       {
+         int r1, r2;
+         if (ISRELDEP(rd->evr))
+           {
+             Reldep *rd2 = GETRELDEP(pool, rd->evr);
+             if (rd2->flags == REL_ELSE)
+               {
+                 r1 = solver_dep_fulfilled_alreadyinstalled(solv, rd2->name);
+                 if (r1)
+                   {
+                     r2 = solver_dep_fulfilled_alreadyinstalled(solv, rd->name);
+                     return r2 && r1 == 2 ? 2 : r2;
+                   }
+                 return solver_dep_fulfilled_alreadyinstalled(solv, rd2->evr);
+               }
+           }
+         r1 = solver_dep_fulfilled_alreadyinstalled(solv, rd->name);
+         r2 = !solver_dep_fulfilled_alreadyinstalled(solv, rd->evr);
+         if (!r1 && !r2)
+           return 0;
+          return r1 == 2 ? 2 : 1;
+       }
       if (rd->flags == REL_AND)
         {
          int r2, r1 = solver_dep_fulfilled_alreadyinstalled(solv, rd->name);