Imported Upstream version 0.7.2
[platform/upstream/libsolv.git] / src / solver_util.c
index bd5d4b4..fb17bf4 100644 (file)
@@ -181,84 +181,91 @@ solver_dep_fulfilled_cplx(Solver *solv, Reldep *rd)
   return 0;
 }
 
-
-/* mirrors solver_dep_fulfilled, but returns 2 if a new package
- * was involved */
 static int
-solver_dep_fulfilled_alreadyinstalled(Solver *solv, Id dep)
+solver_dep_fulfilled_complex_func(Solver *solv, Reldep *rd, int (*dep_fullfilled)(Solver *, Id))
 {
   Pool *pool = solv->pool;
-  Id p, pp;
-  int r;
-
-  if (ISRELDEP(dep))
+  int r1, r2;
+  if (rd->flags == REL_COND)
     {
-      Reldep *rd = GETRELDEP(pool, dep);
-      if (rd->flags == REL_COND)
+      if (ISRELDEP(rd->evr))
        {
-         int r1, r2;
-         if (ISRELDEP(rd->evr))
+         Reldep *rd2 = GETRELDEP(pool, rd->evr);
+         if (rd2->flags == REL_ELSE)
            {
-             Reldep *rd2 = GETRELDEP(pool, rd->evr);
-             if (rd2->flags == REL_ELSE)
+             r1 = dep_fullfilled(solv, rd2->name);
+             if (r1)
                {
-                 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);
+                 r2 = dep_fullfilled(solv, rd->name);
+                 return r2 && r1 == 2 ? 2 : r2;
                }
+             return dep_fullfilled(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_UNLESS)
+      r1 = dep_fullfilled(solv, rd->name);
+      r2 = !dep_fullfilled(solv, rd->evr);
+      if (!r1 && !r2)
+       return 0;
+      return r1 == 2 ? 2 : 1;
+    }
+  if (rd->flags == REL_UNLESS)
+    {
+      if (ISRELDEP(rd->evr))
        {
-         int r1, r2;
-         if (ISRELDEP(rd->evr))
+         Reldep *rd2 = GETRELDEP(pool, rd->evr);
+         if (rd2->flags == REL_ELSE)
            {
-             Reldep *rd2 = GETRELDEP(pool, rd->evr);
-             if (rd2->flags == REL_ELSE)
+             r1 = dep_fullfilled(solv, rd2->name);
+             if (r1)
                {
-                 r1 = solver_dep_fulfilled_alreadyinstalled(solv, rd2->name);
-                 if (r1)
-                   {
-                     r2 = solver_dep_fulfilled_alreadyinstalled(solv, rd2->evr);
-                     return r2 && r1 == 2 ? 2 : r2;
-                   }
-                 return solver_dep_fulfilled_alreadyinstalled(solv, rd->name);
+                 r2 = dep_fullfilled(solv, rd2->evr);
+                 return r2 && r1 == 2 ? 2 : r2;
                }
+             return dep_fullfilled(solv, rd->name);
            }
-         /* A AND NOT(B) */
-         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);
-          if (!r1)
-            return 0;
-         r2 = solver_dep_fulfilled_alreadyinstalled(solv, rd->evr);
-         if (!r2)
-           return 0;
-          return r1 == 2 || r2 == 2 ? 2 : 1;
-        }
-      if (rd->flags == REL_OR)
-       {
-         int r2, r1 = solver_dep_fulfilled_alreadyinstalled(solv, rd->name);
-         r2 = solver_dep_fulfilled_alreadyinstalled(solv, rd->evr);
-         if (!r1 && !r2)
-           return 0;
-          return r1 == 2 || r2 == 2 ? 2 : 1;
        }
+      /* A AND NOT(B) */
+      r1 = dep_fullfilled(solv, rd->name);
+      r2 = !dep_fullfilled(solv, rd->evr);
+      if (!r1 || !r2)
+       return 0;
+      return r1 == 2 ? 2 : 1;
+    }
+  if (rd->flags == REL_AND)
+    {
+      r1 = dep_fullfilled(solv, rd->name);
+      if (!r1)
+       return 0;
+      r2 = dep_fullfilled(solv, rd->evr);
+      if (!r2)
+       return 0;
+      return r1 == 2 || r2 == 2 ? 2 : 1;
+    }
+  if (rd->flags == REL_OR)
+    {
+      r1 = dep_fullfilled(solv, rd->name);
+      r2 = dep_fullfilled(solv, rd->evr);
+      if (!r1 && !r2)
+       return 0;
+      return r1 == 2 || r2 == 2 ? 2 : 1;
+    }
+  return 0;
+}
+
+/* mirrors solver_dep_fulfilled, but returns 2 if a new package
+ * was involved */
+static int
+solver_dep_fulfilled_alreadyinstalled(Solver *solv, Id dep)
+{
+  Pool *pool = solv->pool;
+  Id p, pp;
+  int r;
+
+  if (ISRELDEP(dep))
+    {
+      Reldep *rd = GETRELDEP(pool, dep);
+      if (rd->flags == REL_COND || rd->flags == REL_UNLESS || rd->flags == REL_AND || rd->flags == REL_OR)
+       return solver_dep_fulfilled_complex_func(solv, rd, solver_dep_fulfilled_alreadyinstalled);
       if (rd->flags == REL_NAMESPACE && rd->name == NAMESPACE_SPLITPROVIDES)
         return solver_splitprovides(solv, rd->evr, 0) ? 2 : 0;
       if (rd->flags == REL_NAMESPACE && solv->installsuppdepq)
@@ -282,16 +289,61 @@ solver_dep_fulfilled_alreadyinstalled(Solver *solv, Id dep)
   return r;
 }
 
+static int
+solver_dep_fulfilled_namespace(Solver *solv, Id dep)
+{
+  Pool *pool = solv->pool;
+  Id p, pp;
+  int r = 1;
+
+  if (ISRELDEP(dep))
+    {
+      Reldep *rd = GETRELDEP(pool, dep);
+      if (rd->flags == REL_COND || rd->flags == REL_UNLESS || rd->flags == REL_AND || rd->flags == REL_OR)
+       return solver_dep_fulfilled_complex_func(solv, rd, solver_dep_fulfilled_namespace);
+      if (rd->flags == REL_NAMESPACE && rd->name == NAMESPACE_SPLITPROVIDES)
+        return solver_splitprovides(solv, rd->evr, 0) ? 2 : 0;
+      if (rd->flags == REL_NAMESPACE)
+       r = 2;
+    }
+  FOR_PROVIDES(p, pp, dep)
+    if (solv->decisionmap[p] > 0)
+      return r;
+  return 0;
+}
+
 int
 solver_is_supplementing_alreadyinstalled(Solver *solv, Solvable *s)
 {
   Id sup, *supp;
   supp = s->repo->idarraydata + s->supplements;
   while ((sup = *supp++) != 0)
-    if (solver_dep_fulfilled_alreadyinstalled(solv, sup) == 2)
+    {
+      if (!solv->addalreadyrecommended && solver_dep_fulfilled_alreadyinstalled(solv, sup) != 2)
+       continue;
+      if (solv->only_namespace_recommended && solver_dep_fulfilled_namespace(solv, sup) != 2)
+       continue;
       return 1;
+    }
   return 0;
 }
+
+int
+solver_is_namespace_dep_slow(Solver *solv, Reldep *rd)
+{
+  Pool *pool = solv->pool;
+  for (;;)
+    {
+      if (rd->flags == REL_NAMESPACE)
+       return 1;
+      if (ISRELDEP(rd->name) && solver_is_namespace_dep_slow(solv, GETRELDEP(pool, rd->name)))
+       return 1;
+      if (!ISRELDEP(rd->evr))
+       return 0;
+      rd = GETRELDEP(pool, rd->evr);
+    }
+}
+
 /*
  * add all installed packages that package p obsoletes to Queue q.
  * Package p is not installed. Also, we know that if