- also check obsoletes when disabling update rules
[platform/upstream/libsolv.git] / src / solver.c
index 1abfad7..f3826e4 100644 (file)
@@ -380,7 +380,7 @@ addrule(Solver *solv, Id p, Id d)
     }
 #endif
 
-  if (n == 1 && p > d)
+  if (n == 1 && p > d && !solv->rpmrules_end)
     {
       /* smallest literal first so we can find dups */
       n = p; p = d; d = n;             /* p <-> d */
@@ -838,7 +838,7 @@ enabledisablelearntrules(Solver *solv)
  * 
  */
 
-void
+static void
 enableweakrules(Solver *solv)
 {
   int i;
@@ -910,9 +910,23 @@ disableupdaterules(Solver *solv, Queue *job, int jobidx)
          s = pool->solvables + what;
          if (solv->noobsoletes.size && MAPTST(&solv->noobsoletes, what))
            break;
+         if (s->obsoletes)
+           {
+             Id obs, *obsp;
+             obsp = s->repo->idarraydata + s->obsoletes;
+             while ((obs = *obsp++) != 0)
+               FOR_PROVIDES(p, pp, obs)
+                 {
+                   if (pool->solvables[p].repo != installed)
+                     continue;
+                   if (!solv->obsoleteusesprovides && !pool_match_nevr(pool, pool->solvables + p, obs))
+                     continue;
+                   MAPSET(&solv->noupdate, p - installed->start);
+                 }
+           }
          FOR_PROVIDES(p, pp, s->name)
            {
-             if (pool->solvables[p].name != s->name)
+             if (!solv->implicitobsoleteusesprovides && pool->solvables[p].name != s->name)
                continue;
              if (pool->solvables[p].repo == installed)
                MAPSET(&solv->noupdate, p - installed->start);
@@ -949,9 +963,33 @@ disableupdaterules(Solver *solv, Queue *job, int jobidx)
        {
        case SOLVER_INSTALL_SOLVABLE:
          s = pool->solvables + what;
+         if (s->obsoletes)
+           {
+             Id obs, *obsp;
+             obsp = s->repo->idarraydata + s->obsoletes;
+             while ((obs = *obsp++) != 0)
+               FOR_PROVIDES(p, pp, obs)
+                 {
+                   if (pool->solvables[p].repo != installed)
+                     continue;
+                   if (!solv->obsoleteusesprovides && !pool_match_nevr(pool, pool->solvables + p, obs))
+                     continue;
+                   if (MAPTST(&solv->noupdate, p - installed->start))
+                     continue;
+                   r = solv->rules + solv->updaterules + (p - installed->start);
+                   if (r->d >= 0)
+                     continue;
+                   enablerule(solv, r);
+                   IF_POOLDEBUG (SAT_DEBUG_SOLUTIONS)
+                     {
+                       POOL_DEBUG(SAT_DEBUG_SOLUTIONS, "@@@ re-enabling ");
+                       solver_printrule(solv, SAT_DEBUG_SOLUTIONS, r);
+                     }
+                 }
+           }
          FOR_PROVIDES(p, pp, s->name)
            {
-             if (pool->solvables[p].name != s->name)
+             if (!solv->implicitobsoleteusesprovides && pool->solvables[p].name != s->name)
                continue;
              if (pool->solvables[p].repo != installed)
                continue;
@@ -1022,50 +1060,6 @@ disableupdaterules(Solver *solv, Queue *job, int jobidx)
     }
 }
 
-#if CODE10
-/*-------------------------------------------------------------------
- * add patch atom requires
- */
-
-static void
-addpatchatomrequires(Solver *solv, Solvable *s, Id *dp, Queue *q, Map *m)
-{
-  Pool *pool = solv->pool;
-  Id fre, *frep, p, *pp, ndp;
-  Solvable *ps;
-  Queue fq;
-  Id qbuf[64];
-  int i, used = 0;
-
-  queue_init_buffer(&fq, qbuf, sizeof(qbuf)/sizeof(*qbuf));
-  queue_push(&fq, -(s - pool->solvables));
-  for (; *dp; dp++)
-    queue_push(&fq, *dp);
-  ndp = pool_queuetowhatprovides(pool, &fq);
-  frep = s->repo->idarraydata + s->freshens;
-  while ((fre = *frep++) != 0)
-    {
-      FOR_PROVIDES(p, pp, fre)
-       {
-         ps = pool->solvables + p;
-         addrule(solv, -p, ndp);
-         used = 1;
-         if (!MAPTST(m, p))
-           queue_push(q, p);
-       }
-    }
-  if (used)
-    {
-      for (i = 1; i < fq.count; i++)
-       {
-         p = fq.elements[i];
-         if (!MAPTST(m, p))
-           queue_push(q, p);
-       }
-    }
-  queue_free(&fq);
-}
-#endif
 
 
 /*-------------------------------------------------------------------
@@ -1158,15 +1152,6 @@ addrpmrulesforsolvable(Solver *solv, Solvable *s, Map *m)
          POOL_DEBUG(SAT_DEBUG_RULE_CREATION, "package %s [%d] is not installable\n", solvable2str(pool, s), (Id)(s - pool->solvables));
          addrule(solv, -n, 0);            /* uninstallable */
        }
-#if CODE10
-      patchatom = 0;
-      if (s->freshens && !s->supplements)
-       {
-         const char *name = id2str(pool, s->name);
-         if (name[0] == 'a' && !strncmp(name, "atom:", 5))
-           patchatom = 1;
-       }
-#endif
 
       /*-----------------------------------------
        * check requires of s
@@ -1377,17 +1362,6 @@ addrpmrulesforweak(Solver *solv, Map *m)
              break;
        }
 
-       /* if nothing found, check for freshens
-        * (patterns use this)
-        */
-      if (!sup && s->freshens)
-       {
-         supp = s->repo->idarraydata + s->freshens;
-         while ((sup = *supp++) != ID_NULL)
-           if (dep_possible(solv, sup, m))
-             break;
-       }
-
        /* if nothing found, check for enhances */
       if (!sup && s->enhances)
        {
@@ -1396,7 +1370,7 @@ addrpmrulesforweak(Solver *solv, Map *m)
            if (dep_possible(solv, sup, m))
              break;
        }
-       /* if notthing found, goto next solvables */
+       /* if nothing found, goto next solvables */
       if (!sup)
        continue;
       addrpmrulesforsolvable(solv, s, m);
@@ -2414,6 +2388,60 @@ run_solver(Solver *solv, int disablerules, int doweak)
            }
        }
 
+     if (level < systemlevel)
+       {
+         POOL_DEBUG(SAT_DEBUG_STATS, "resolving job rules\n");
+         for (i = solv->jobrules, r = solv->rules + i; i < solv->jobrules_end; i++, r++)
+           {
+             Id l;
+             if (r->d < 0)             /* ignore disabled rules */
+               continue;
+             queue_empty(&dq);
+             FOR_RULELITERALS(l, dp, r)
+               {
+                 if (l < 0)
+                   {
+                     if (solv->decisionmap[-l] <= 0)
+                       break;
+                   }
+                 else
+                   {
+                     if (solv->decisionmap[l] > 0)
+                       break;
+                     if (solv->decisionmap[l] == 0)
+                       queue_push(&dq, l);
+                   }
+               }
+             if (l || !dq.count)
+               continue;
+             if (!solv->updatesystem && solv->installed && dq.count > 1)
+               {
+                 int j, k;
+                 for (j = k = 0; j < dq.count; j++)
+                   {
+                     Solvable *s = pool->solvables + dq.elements[j];
+                     if (s->repo == solv->installed)
+                       dq.elements[k++] = dq.elements[j];
+                   }
+                 if (k)
+                   dq.count = k;
+               }
+             olevel = level;
+             level = selectandinstall(solv, level, &dq, 0, disablerules);
+             if (level == 0)
+               {
+                 queue_free(&dq);
+                 return;
+               }
+             if (level <= olevel)
+               break;
+           }
+         systemlevel = level + 1;
+         if (i < solv->jobrules_end)
+           continue;
+       }
+
+
       /*
        * installed packages
        */
@@ -2521,11 +2549,14 @@ run_solver(Solver *solv, int disablerules, int doweak)
              if (level <= olevel)
                break;
            }
+         systemlevel = level + 1;
          if (i < solv->installed->end)
            continue;
-         systemlevel = level;
        }
 
+      if (level < systemlevel)
+        systemlevel = level;
+
       /*
        * decide
        */
@@ -2658,7 +2689,7 @@ run_solver(Solver *solv, int disablerules, int doweak)
              else
                {
                  s = pool->solvables + i;
-                 if (!s->supplements && !s->freshens)
+                 if (!s->supplements)
                    continue;
                  if (!pool_installable(pool, s))
                    continue;
@@ -2687,7 +2718,7 @@ run_solver(Solver *solv, int disablerules, int doweak)
                {
                  p = dqs.elements[i];
                  s = pool->solvables + p;
-                 if (!s->supplements && !s->freshens)
+                 if (!s->supplements)
                    continue;
                  if (!solver_is_supplementing(solv, s))
                    queue_pushunique(&dq, p);
@@ -3896,7 +3927,7 @@ solver_solve(Solver *solv, Queue *job)
   oldnrules = solv->nrules;
     
     /*
-     * add rules for suggests, [freshens,] enhances
+     * add rules for suggests, enhances
      */
   addrpmrulesforweak(solv, &addedmap);
   POOL_DEBUG(SAT_DEBUG_STATS, "added %d rpm rules because of weak dependencies\n", solv->nrules - oldnrules);
@@ -3953,17 +3984,6 @@ solver_solve(Solver *solv, Queue *job)
              addrule(solv, 0, 0);      /* create dummy rule */
              continue;
            }
-#if CODE10
-         if (s->freshens && !s->supplements)
-           {
-             const char *name = id2str(pool, s->name);
-             if (name[0] == 'a' && !strncmp(name, "atom:", 5))
-               {
-                 addrule(solv, 0, 0);
-                 continue;
-               }
-           }
-#endif
          addupdaterule(solv, s, 1);    /* allow s to be updated */
        }
        /*
@@ -3998,18 +4018,6 @@ solver_solve(Solver *solv, Queue *job)
              continue;
            }
 
-#if CODE10
-         /* no update rules for patch atoms */
-         if (s->freshens && !s->supplements)
-           {
-             const char *name = id2str(pool, s->name);
-             if (name[0] == 'a' && !strncmp(name, "atom:", 5))
-               {
-                 addrule(solv, 0, 0);
-                 continue;
-               }
-           }
-#endif
          addupdaterule(solv, s, 0);    /* allowall = 0: downgrades allowed */
 
            /*
@@ -4250,7 +4258,7 @@ solver_solve(Solver *solv, Queue *job)
     
   /* if redoq.count == 0 we already found all recommended in the
    * solver run */
-  if (redoq.count || solv->dontinstallrecommended || !solv->dontshowinstalledrecommended)
+  if (redoq.count || solv->dontinstallrecommended || !solv->dontshowinstalledrecommended || solv->ignorealreadyrecommended)
     {
       Id rec, *recp, p, *pp;