make FOR_RULELITERALS safe against whatprovides realloc
authorMichael Schroeder <mls@suse.de>
Tue, 27 Nov 2012 10:26:32 +0000 (11:26 +0100)
committerMichael Schroeder <mls@suse.de>
Tue, 27 Nov 2012 10:26:32 +0000 (11:26 +0100)
Should only make iterating a tiny bit slower, but is more safe and
brings the macro in line with the other iterater macros.

src/problems.c
src/rules.c
src/solver.c
src/solver.h

index afb6639..78911f9 100644 (file)
@@ -431,12 +431,12 @@ convertsolution(Solver *solv, Id why, Queue *solutionq)
   if (why >= solv->updaterules && why < solv->updaterules_end)
     {
       /* update rule, find replacement package */
-      Id p, *dp, rp = 0;
+      Id p, pp, rp = 0;
       Rule *rr;
 
       /* check if this is a false positive, i.e. the update rule is fulfilled */
       rr = solv->rules + why;
-      FOR_RULELITERALS(p, dp, rr)
+      FOR_RULELITERALS(p, pp, rr)
        if (p > 0 && solv->decisionmap[p] > 0)
          return;       /* false alarm */
 
@@ -456,7 +456,7 @@ convertsolution(Solver *solv, Id why, Queue *solutionq)
       if (rr->w2)
        {
          int mvrp = 0;         /* multi-version replacement */
-         FOR_RULELITERALS(rp, dp, rr)
+         FOR_RULELITERALS(rp, pp, rr)
            {
              if (rp > 0 && solv->decisionmap[rp] > 0 && pool->solvables[rp].repo != solv->installed)
                {
@@ -480,11 +480,11 @@ convertsolution(Solver *solv, Id why, Queue *solutionq)
   if (why >= solv->bestrules && why < solv->bestrules_end)
     {
       int mvrp;
-      Id p, *dp, rp = 0;
+      Id p, pp, rp = 0;
       Rule *rr;
       /* check false positive */
       rr = solv->rules + why;
-      FOR_RULELITERALS(p, dp, rr)
+      FOR_RULELITERALS(p, pp, rr)
        if (p > 0 && solv->decisionmap[p] > 0)
          return;       /* false alarm */
       /* check update/feature rule */
@@ -507,7 +507,7 @@ convertsolution(Solver *solv, Id why, Queue *solutionq)
       if (!rr->p)
        rr = solv->rules + solv->updaterules + (p - solv->installed->start);
       mvrp = 0;                /* multi-version replacement */
-      FOR_RULELITERALS(rp, dp, rr)
+      FOR_RULELITERALS(rp, pp, rr)
        if (rp > 0 && solv->decisionmap[rp] > 0 && pool->solvables[rp].repo != solv->installed)
          {
            mvrp = rp;
index 12be39b..d16c423 100644 (file)
@@ -2202,7 +2202,7 @@ void
 solver_ruleliterals(Solver *solv, Id rid, Queue *q)
 {
   Pool *pool = solv->pool;
-  Id p, *pp;
+  Id p, pp;
   Rule *r;
 
   queue_empty(q);
@@ -2246,7 +2246,7 @@ solver_addchoicerules(Solver *solv)
   Rule *r;
   Queue q, qi;
   int i, j, rid, havechoice;
-  Id p, d, *pp;
+  Id p, d, pp;
   Id p2, pp2;
   Solvable *s, *s2;
   Id lastaddedp, lastaddedd;
@@ -2428,7 +2428,7 @@ solver_addchoicerules(Solver *solv)
 void
 solver_disablechoicerules(Solver *solv, Rule *r)
 {
-  Id rid, p, *pp;
+  Id rid, p, pp;
   Pool *pool = solv->pool;
   Map m;
   Rule *or;
@@ -2515,7 +2515,7 @@ solver_addbestrules(Solver *solv, int havebestinstalljobs)
          if ((solv->job.elements[i] & (SOLVER_JOBMASK | SOLVER_FORCEBEST)) == (SOLVER_INSTALL | SOLVER_FORCEBEST))
            {
              int j;
-             Id p2, *pp2;
+             Id p2, pp2;
              for (j = 0; j < solv->ruletojob.count; j++)
                if (solv->ruletojob.elements[j] == i)
                  break;
@@ -2544,7 +2544,7 @@ solver_addbestrules(Solver *solv, int havebestinstalljobs)
     {
       FOR_REPO_SOLVABLES(installed, p, s)
        {
-         Id d, p2, *pp2;
+         Id d, p2, pp2;
          if (!solv->updatemap_all && (!solv->updatemap.size || !MAPTST(&solv->updatemap, p - installed->start)))
            continue;
          if (!solv->bestupdatemap_all && (!solv->bestupdatemap.size || !MAPTST(&solv->bestupdatemap, p - installed->start)))
@@ -2694,7 +2694,7 @@ solver_createcleandepsmap(Solver *solv, Map *cleandepsmap, int unneeded)
   Map installedm;
   Rule *r;
   Id rid, how, what, select;
-  Id p, pp, ip, *jp;
+  Id p, pp, ip, jp;
   Id req, *reqp, sup, *supp;
   Solvable *s;
   Queue iq;
index a1dec92..ae0ddcf 100644 (file)
@@ -1544,7 +1544,7 @@ cleandeps_check_mistakes(Solver *solv, int level)
 {
   Pool *pool = solv->pool;
   Rule *r;
-  Id p, *dp;
+  Id p, pp;
   int i;
   int mademistake = 0;
 
@@ -1557,37 +1557,34 @@ cleandeps_check_mistakes(Solver *solv, int level)
        continue;
       r = solv->rules + solv->featurerules + (i - solv->installed->start);
       /* a mistake is when the featurerule is true but the updaterule is false */
-      if (r->p)
-       {
-         FOR_RULELITERALS(p, dp, r)
-           if (p > 0 && solv->decisionmap[p] > 0)
-             break;
-         if (p)
-           {
-             r = solv->rules + solv->updaterules + (i - solv->installed->start);
-             if (!r->p)
-               continue;
-             FOR_RULELITERALS(p, dp, r)
-               if (p > 0 && solv->decisionmap[p] > 0)
-                 break;
-             if (!p)
-               {
-                 POOL_DEBUG(SOLV_DEBUG_SOLVER, "cleandeps mistake: ");
-                 solver_printruleclass(solv, SOLV_DEBUG_SOLVER, r);
-                 POOL_DEBUG(SOLV_DEBUG_SOLVER, "feature rule: ");
-                 solver_printruleclass(solv, SOLV_DEBUG_SOLVER, solv->rules + solv->featurerules + (i - solv->installed->start));
-                 if (!solv->cleandeps_mistakes)
-                   {
-                     solv->cleandeps_mistakes = solv_calloc(1, sizeof(Queue));
-                     queue_init(solv->cleandeps_mistakes);
-                   }
-                 queue_push(solv->cleandeps_mistakes, i);
-                 MAPCLR(&solv->cleandepsmap, i - solv->installed->start);
-                 solver_reenablepolicyrules_cleandeps(solv, i);
-                 mademistake = 1;
-               }
-           }
-       }
+      if (!r->p)
+       continue;
+      FOR_RULELITERALS(p, pp, r)
+       if (p > 0 && solv->decisionmap[p] > 0)
+         break;
+      if (!p)
+       continue;       /* feature rule is not true */
+      r = solv->rules + solv->updaterules + (i - solv->installed->start);
+      if (!r->p)
+       continue;
+      FOR_RULELITERALS(p, pp, r)
+       if (p > 0 && solv->decisionmap[p] > 0)
+         break;
+      if (p)
+       continue;       /* update rule is true */
+      POOL_DEBUG(SOLV_DEBUG_SOLVER, "cleandeps mistake: ");
+      solver_printruleclass(solv, SOLV_DEBUG_SOLVER, r);
+      POOL_DEBUG(SOLV_DEBUG_SOLVER, "feature rule: ");
+      solver_printruleclass(solv, SOLV_DEBUG_SOLVER, solv->rules + solv->featurerules + (i - solv->installed->start));
+      if (!solv->cleandeps_mistakes)
+       {
+         solv->cleandeps_mistakes = solv_calloc(1, sizeof(Queue));
+         queue_init(solv->cleandeps_mistakes);
+       }
+      queue_push(solv->cleandeps_mistakes, i);
+      MAPCLR(&solv->cleandepsmap, i - solv->installed->start);
+      solver_reenablepolicyrules_cleandeps(solv, i);
+      mademistake = 1;
     }
   if (mademistake)
     solver_reset(solv);
@@ -1631,7 +1628,7 @@ solver_run_sat(Solver *solv, int disablerules, int doweak)
   int i, j, n;
   Solvable *s;
   Pool *pool = solv->pool;
-  Id p, *dp;
+  Id p, pp, *dp;
   int minimizationsteps;
   int installedpos = solv->installed ? solv->installed->start : 0;
 
@@ -1694,7 +1691,7 @@ solver_run_sat(Solver *solv, int disablerules, int doweak)
              if (r->d < 0)             /* ignore disabled rules */
                continue;
              queue_empty(&dq);
-             FOR_RULELITERALS(l, dp, r)
+             FOR_RULELITERALS(l, pp, r)
                {
                  if (l < 0)
                    {
@@ -1824,7 +1821,7 @@ solver_run_sat(Solver *solv, int disablerules, int doweak)
                      else
                        {
                          /* update to best package */
-                         FOR_RULELITERALS(p, dp, rr)
+                         FOR_RULELITERALS(p, pp, rr)
                            {
                              if (solv->decisionmap[p] > 0)
                                {
index 7ba1f51..5e3a162 100644 (file)
@@ -266,7 +266,6 @@ typedef struct _Solver Solver;
  * you will get problem reported if the best package is
  * not installable. This can be used with INSTALL, UPDATE
  * and DISTUPGRADE */
-/* Also, it's not implemented yet ;) */
 #define SOLVER_FORCEBEST               0x100000
 
 #define SOLVER_SETEV                   0x01000000
@@ -340,12 +339,13 @@ void pool_job2solvables(Pool *pool, Queue *pkgs, Id how, Id what);
 int  pool_isemptyupdatejob(Pool *pool, Id how, Id what);
 
 /* iterate over all literals of a rule */
-/* WARNING: loop body must not relocate whatprovidesdata, e.g. by
- * looking up the providers of a dependency */
-#define FOR_RULELITERALS(l, dp, r)                             \
-    for (l = r->d < 0 ? -r->d - 1 : r->d,                      \
-         dp = !l ? &r->w2 : pool->whatprovidesdata + l,                \
-         l = r->p; l; l = (dp != &r->w2 + 1 ? *dp++ : 0))
+#define FOR_RULELITERALS(l, pp, r)                             \
+    for (pp = r->d < 0 ? -r->d - 1 : r->d,                     \
+         l = r->p; l; l = (pp <= 0 ? (pp-- ? 0 : r->w2) :      \
+         pool->whatprovidesdata[pp++]))
+
+
+
 
 /* XXX: this currently doesn't work correctly for SOLVER_SOLVABLE_REPO and
    SOLVER_SOLVABLE_ALL */