Imported Upstream version 0.7.8
[platform/upstream/libsolv.git] / src / problems.c
index df751c4..b46d624 100644 (file)
@@ -64,12 +64,12 @@ solver_disableproblem(Solver *solv, Id v)
     }
   v = -(v + 1);
   jp = solv->ruletojob.elements;
-  if (solv->bestrules_pkg)
+  if (solv->bestrules_info)
     {
       int ni = solv->bestrules_up - solv->bestrules;
       for (i = 0; i < ni; i++)
        {
-         int j = solv->bestrules_pkg[i];
+         int j = solv->bestrules_info[i];
          if (j < 0 && jp[-j - solv->jobrules] == v)
            solver_disablerule(solv, solv->rules + solv->bestrules + i);
        }
@@ -131,12 +131,12 @@ solver_enableproblem(Solver *solv, Id v)
     }
   v = -(v + 1);
   jp = solv->ruletojob.elements;
-  if (solv->bestrules_pkg)
+  if (solv->bestrules_info)
     {
       int ni = solv->bestrules_up - solv->bestrules;
       for (i = 0; i < ni; i++)
        {
-         int j = solv->bestrules_pkg[i];
+         int j = solv->bestrules_info[i];
          if (j < 0 && jp[-j - solv->jobrules] == v)
            solver_enablerule(solv, solv->rules + solv->bestrules + i);
        }
@@ -155,8 +155,8 @@ solver_ruletoproblem(Solver *solv, Id rid)
 {
   if (rid >= solv->jobrules && rid < solv->jobrules_end)
     rid = -(solv->ruletojob.elements[rid - solv->jobrules] + 1);
-  else if (rid >= solv->bestrules && rid < solv->bestrules_up && solv->bestrules_pkg[rid - solv->bestrules] < 0)
-    rid = -(solv->ruletojob.elements[-solv->bestrules_pkg[rid - solv->bestrules] - solv->jobrules] + 1);
+  else if (rid >= solv->bestrules && rid < solv->bestrules_up && solv->bestrules_info[rid - solv->bestrules] < 0)
+    rid = -(solv->ruletojob.elements[-solv->bestrules_info[rid - solv->bestrules] - solv->jobrules] + 1);
   else if (rid > solv->infarchrules && rid < solv->infarchrules_end)
     {
       Pool *pool = solv->pool;
@@ -247,8 +247,23 @@ solver_autouninstall(Solver *solv, int start)
       if (v >= solv->updaterules && v < solv->updaterules_end)
        {
          Rule *r;
+         Id p = solv->installed->start + (v - solv->updaterules);
          if (m && !MAPTST(m, v - solv->updaterules))
            continue;
+         if (pool->considered && !MAPTST(pool->considered, p))
+           continue;   /* do not uninstalled disabled packages */
+         if (solv->bestrules_info && solv->bestrules_end > solv->bestrules)
+           {
+             int j;
+             for (j = start + 1; j < solv->problems.count - 1; j++)
+               {
+                 Id vv = solv->problems.elements[j];
+                 if (vv >= solv->bestrules && vv < solv->bestrules_end && solv->bestrules_info[vv - solv->bestrules] == p)
+                   break;
+               }
+             if (j < solv->problems.count - 1)
+               continue;       /* best rule involved, do not uninstall */
+           }
          /* check if identical to feature rule, we don't like that (except for orphans) */
          r = solv->rules + solv->featurerules + (v - solv->updaterules);
          if (!r->p)
@@ -260,7 +275,7 @@ solver_autouninstall(Solver *solv, int start)
              if (solv->keep_orphans)
                {
                  r = solv->rules + v;
-                 if (!r->d && !r->w2 && r->p == (solv->installed->start + (v - solv->updaterules)))
+                 if (!r->d && !r->w2 && r->p == p)
                    {
                      lastfeature = v;
                      lastupdate = 0;
@@ -663,7 +678,7 @@ convertsolution(Solver *solv, Id why, Queue *solutionq)
        if (p > 0 && solv->decisionmap[p] > 0)
          return;       /* false alarm */
       /* check update/feature rule */
-      p = solv->bestrules_pkg[why - solv->bestrules];
+      p = solv->bestrules_info[why - solv->bestrules];
       if (p < 0)
        {
          /* install job */
@@ -704,6 +719,12 @@ convertsolution(Solver *solv, Id why, Queue *solutionq)
        }
       return;
     }
+  if (why >= solv->blackrules && why < solv->blackrules_end)
+    {
+      queue_push(solutionq, SOLVER_SOLUTION_BLACK);
+      assert(solv->rules[why].p < 0);
+      queue_push(solutionq, -solv->rules[why].p);
+    }
 }
 
 /*
@@ -966,6 +987,8 @@ solver_solutionelement_extrajobflags(Solver *solv, Id problem, Id solution)
  *    -> add (SOLVER_INSTALL|SOLVER_SOLVABLE, rp) to the job
  *    SOLVER_SOLUTION_BEST          pkgid
  *    -> add (SOLVER_INSTALL|SOLVER_SOLVABLE, rp) to the job
+ *    SOLVER_SOLUTION_BLACK         pkgid
+ *    -> add (SOLVER_INSTALL|SOLVER_SOLVABLE, rp) to the job
  *    SOLVER_SOLUTION_JOB           jobidx
  *    -> remove job (jobidx - 1, jobidx) from job queue
  *    SOLVER_SOLUTION_POOLJOB       jobidx
@@ -1316,6 +1339,8 @@ solver_problemruleinfo2str(Solver *solv, SolverRuleinfo type, Id source, Id targ
       s = pool_tmpjoin(pool, "both package ", pool_solvid2str(pool, source), " and ");
       s = pool_tmpjoin(pool, s, pool_solvid2str(pool, target), " obsolete ");
       return pool_tmpappend(pool, s, pool_dep2str(pool, dep), 0);
+    case SOLVER_RULE_BLACK:
+      return pool_tmpjoin(pool, "package ", pool_solvid2str(pool, source), " can only be installed by a direct request");
     default:
       return "bad problem rule type";
     }
@@ -1370,6 +1395,11 @@ solver_solutionelement2str(Solver *solv, Id p, Id rp)
       else
         return pool_tmpjoin(pool, "install ", pool_solvable2str(pool, s), " despite the old version");
     }
+  else if (p == SOLVER_SOLUTION_BLACK)
+    {
+      Solvable *s = pool->solvables + rp;
+      return pool_tmpjoin(pool, "install ", pool_solvable2str(pool, s), 0);
+    }
   else if (p > 0 && rp == 0)
     return pool_tmpjoin(pool, "allow deinstallation of ", pool_solvid2str(pool, p), 0);
   else if (p > 0 && rp > 0)