- Change provide iterator from ID pointer to ID. Before, iterating
authorMichael Schroeder <mls@suse.de>
Wed, 17 Sep 2008 10:30:59 +0000 (10:30 +0000)
committerMichael Schroeder <mls@suse.de>
Wed, 17 Sep 2008 10:30:59 +0000 (10:30 +0000)
  was unsave as the whatprovides array can get relocated.

src/policy.c
src/pool.c
src/pool.h
src/solvable.c
src/solver.c
src/solver.h
src/solverdebug.c

index c6f9a10..176601b 100644 (file)
@@ -116,7 +116,7 @@ prune_to_recommended(Solver *solv, Queue *plist)
   Pool *pool = solv->pool;
   int i, j;
   Solvable *s;
-  Id p, *pp, rec, *recp, sug, *sugp;
+  Id p, pp, rec, *recp, sug, *sugp;
 
   if (solv->recommends_index < 0)
     {
@@ -241,7 +241,7 @@ prune_to_best_version(Solver *solv, Queue *plist)
   /* FIXME do not prune cycles */
   for (i = 0; i < plist->count; i++)
     {
-      Id p, *pp, obs, *obsp;
+      Id p, pp, obs, *obsp;
       s = pool->solvables + plist->elements[i];
       if (!s->obsoletes)
        continue;
@@ -401,7 +401,7 @@ policy_findupdatepackages(Solver *solv, Solvable *s, Queue *qs, int allow_all)
 {
   /* installed packages get a special upgrade allowed rule */
   Pool *pool = solv->pool;
-  Id p, *pp, n, p2, *pp2;
+  Id p, pp, n, p2, pp2;
   Id obs, *obsp;
   Solvable *ps;
 
@@ -467,7 +467,8 @@ policy_findupdatepackages(Solver *solv, Solvable *s, Queue *qs, int allow_all)
     return;
   if (solv->obsoletes && solv->obsoletes[n - solv->installed->start])
     {
-      for (pp = solv->obsoletes_data + solv->obsoletes[n - solv->installed->start]; (p = *pp++) != 0;)
+      Id *opp;
+      for (opp = solv->obsoletes_data + solv->obsoletes[n - solv->installed->start]; (p = *opp++) != 0;)
        {
          ps = pool->solvables + p;
          if (!allow_all && !solv->allowarchchange && s->arch != ps->arch && policy_illegal_archchange(solv, s, ps))
index 66bc3f7..042e049 100644 (file)
@@ -456,7 +456,7 @@ pool_match_nevr_rel(Pool *pool, Solvable *s, Id d)
  * 
  */
 
-Id *
+Id
 pool_addrelproviders(Pool *pool, Id d)
 {
   Reldep *rd = GETRELDEP(pool, d);
@@ -467,7 +467,7 @@ pool_addrelproviders(Pool *pool, Id d)
   Id evr = rd->evr;
   int flags = rd->flags;
   Id pid, *pidp;
-  Id p, *pp, *pp2, *pp3;
+  Id p, wp, *pp, *pp2, *pp3;
 
   d = GETRELID(d);
   queue_init_buffer(&plist, buf, sizeof(buf)/sizeof(*buf));
@@ -475,8 +475,8 @@ pool_addrelproviders(Pool *pool, Id d)
     {
     case REL_AND:
     case REL_WITH:
-      pp = pool_whatprovides(pool, name);
-      pp2 = pool_whatprovides(pool, evr);
+      pp = pool->whatprovidesdata + pool_whatprovides(pool, name);
+      pp2 = pool->whatprovidesdata + pool_whatprovides(pool, evr);
       while ((p = *pp++) != 0)
        {
          for (pp3 = pp2; *pp3;)
@@ -488,19 +488,19 @@ pool_addrelproviders(Pool *pool, Id d)
        }
       break;
     case REL_OR:
-      pp = pool_whatprovides(pool, name);
+      pp = pool->whatprovidesdata + pool_whatprovides(pool, name);
       while ((p = *pp++) != 0)
        queue_push(&plist, p);
-      pp = pool_whatprovides(pool, evr);
+      pp = pool->whatprovidesdata + pool_whatprovides(pool, evr);
       while ((p = *pp++) != 0)
        queue_pushunique(&plist, p);
       break;
     case REL_NAMESPACE:
       if (name == NAMESPACE_OTHERPROVIDERS)
        {
-         pp = pool_whatprovides(pool, evr);
-         pool->whatprovides_rel[d] = pp - pool->whatprovidesdata;
-         return pp;
+         wp = pool_whatprovides(pool, evr);
+         pool->whatprovides_rel[d] = wp;
+         return wp;
        }
       if (pool->nscallback)
        {
@@ -514,7 +514,7 @@ pool_addrelproviders(Pool *pool, Id d)
            {
              queue_free(&plist);
              pool->whatprovides_rel[d] = p;
-             return pool->whatprovidesdata + p;
+             return p;
            }
          if (p == 1)
            queue_push(&plist, SYSTEMSOLVABLE);
@@ -537,17 +537,21 @@ pool_addrelproviders(Pool *pool, Id d)
            }
          break;
        }
-      pp = pp2 = pool_whatprovides(pool, name);
+      wp = pool_whatprovides(pool, name);
+      pp = pool->whatprovidesdata + wp;
       while ((p = *pp++) != 0)
        {
          Solvable *s = pool->solvables + p;
          if (s->arch == evr)
            queue_push(&plist, p);
          else
-           pp2 = 0;
+           wp = 0;
+       }
+      if (wp)
+       {
+         pool->whatprovides_rel[d] = wp;
+         return wp;
        }
-      if (pp2)
-       return pp2;
       break;
     default:
       break;
@@ -559,7 +563,7 @@ pool_addrelproviders(Pool *pool, Id d)
 #endif
   if (flags && flags < 8)
     {
-      pp = pool_whatprovides(pool, name);
+      pp = pool->whatprovidesdata + pool_whatprovides(pool, name);
       while (ISRELDEP(name))
        {
           rd = GETRELDEP(pool, name);
@@ -635,7 +639,7 @@ pool_addrelproviders(Pool *pool, Id d)
   pool->whatprovides_rel[d] = pool_queuetowhatprovides(pool, &plist);
   queue_free(&plist);
 
-  return pool->whatprovidesdata + pool->whatprovides_rel[d];
+  return pool->whatprovides_rel[d];
 }
 
 /*************************************************************************/
@@ -1260,7 +1264,7 @@ pool_calc_duchanges(Pool *pool, Repo *oldinstalled, Map *installedmap, DUChanges
       repo_search(s->repo, sp, SOLVABLE_DISKUSAGE, 0, 0, solver_fill_DU_cb, &cbd);
       if (!cbd.hasdu && oldinstalled)
        {
-         Id op, *opp;
+         Id op, opp;
          /* no du data available, ignore data of all installed solvables we obsolete */
          if (!ignoredu.map)
            map_init(&ignoredu, oldinstalled->end - oldinstalled->start);
@@ -1343,7 +1347,7 @@ static inline Id dep2name(Pool *pool, Id dep)
 
 static inline int providedbyinstalled(Pool *pool, unsigned char *map, Id dep)
 {
-  Id p, *pp;
+  Id p, pp;
   int r = 0;
   FOR_PROVIDES(p, pp, dep)
     {
@@ -1387,7 +1391,7 @@ pool_trivial_installable(Pool *pool, Repo *oldinstalled, Map *installedmap, Queu
       conp = s->repo->idarraydata + s->conflicts;
       while ((con = *conp++) != 0)
        {
-         dp = pool_whatprovides(pool, con);
+         dp = pool->whatprovidesdata + pool_whatprovides(pool, con);
          for (; *dp; dp++)
            map[p] |= 2;        /* XXX: self conflict ? */
        }
index cd3d747..ac3ba51 100644 (file)
@@ -221,16 +221,16 @@ static inline int pool_installable(Pool *pool, Solvable *s)
   return 1;
 }
 
-extern Id *pool_addrelproviders(Pool *pool, Id d);
+extern Id pool_addrelproviders(Pool *pool, Id d);
 
-static inline Id *pool_whatprovides(Pool *pool, Id d)
+static inline Id pool_whatprovides(Pool *pool, Id d)
 {
   Id v;
   if (!ISRELDEP(d))
-    return pool->whatprovidesdata + pool->whatprovides[d];
+    return pool->whatprovides[d];
   v = GETRELID(d);
   if (pool->whatprovides_rel[v])
-    return pool->whatprovidesdata + pool->whatprovides_rel[v];
+    return pool->whatprovides_rel[v];
   return pool_addrelproviders(pool, d);
 }
 
@@ -273,7 +273,7 @@ void pool_trivial_installable(Pool *pool, struct _Repo *oldinstalled, Map *insta
 
 /* loop over all providers of d */
 #define FOR_PROVIDES(v, vp, d)                                                 \
-  for (vp = pool_whatprovides(pool, d) ; (v = *vp++) != 0; )
+  for (vp = pool_whatprovides(pool, d) ; (v = pool->whatprovidesdata[vp++]) != 0; )
 
 #define POOL_DEBUG(type, ...) do {if ((pool->debugmask & (type)) != 0) pool_debug(pool, (type), __VA_ARGS__);} while (0)
 #define IF_POOLDEBUG(type) if ((pool->debugmask & (type)) != 0)
index 2ca310c..f595f1c 100644 (file)
@@ -397,7 +397,7 @@ static inline Id dep2name(Pool *pool, Id dep)
 
 static inline int providedbyinstalled(Pool *pool, Map *installed, Id dep)
 {
-  Id p, *pp;
+  Id p, pp;
   FOR_PROVIDES(p, pp, dep)
     {
       if (p == SYSTEMSOLVABLE)
@@ -429,7 +429,7 @@ solvable_trivial_installable_map(Solvable *s, Map *installedmap, Map *conflictsm
 {
   Pool *pool = s->repo->pool;
   Solvable *s2;
-  Id p, *pp, *dp;
+  Id p, pp, *dp;
   Id *reqp, req;
   Id *conp, con;
   Id *obsp, obs;
@@ -503,7 +503,7 @@ solvable_trivial_installable_map(Solvable *s, Map *installedmap, Map *conflictsm
          conp = s2->repo->idarraydata + s2->conflicts;
          while ((con = *conp++) != 0)
            {
-             dp = pool_whatprovides(pool, con);
+             dp = pool->whatprovidesdata + pool_whatprovides(pool, con);
              for (; *dp; dp++)
                if (*dp == p)
                  return 0;
@@ -597,7 +597,7 @@ pool_create_state_maps(Pool *pool, Queue *installed, Map *installedmap, Map *con
       conp = s->repo->idarraydata + s->conflicts;
       while ((con = *conp++) != 0)
        {
-         dp = pool_whatprovides(pool, con);
+         dp = pool->whatprovidesdata + pool_whatprovides(pool, con);
          for (; *dp; dp++)
            MAPSET(conflictsmap, *dp);
        }
index 9970faf..6cfaf11 100644 (file)
@@ -25,8 +25,6 @@
 #include "policy.h"
 #include "solverdebug.h"
 
-#define CODE10 0 /* set to '1' to enable patch atoms */
-
 #define RULES_BLOCK 63
 
 /********************************************************************
@@ -43,7 +41,7 @@ int
 solver_splitprovides(Solver *solv, Id dep)
 {
   Pool *pool = solv->pool;
-  Id p, *pp;
+  Id p, pp;
   Reldep *rd;
   Solvable *s;
 
@@ -73,7 +71,7 @@ solver_dep_installed(Solver *solv, Id dep)
 {
 #if 0
   Pool *pool = solv->pool;
-  Id p, *pp;
+  Id p, pp;
 
   if (ISRELDEP(dep))
     {
@@ -108,7 +106,7 @@ static inline int
 dep_possible(Solver *solv, Id dep, Map *m)
 {
   Pool *pool = solv->pool;
-  Id p, *pp;
+  Id p, pp;
 
   if (ISRELDEP(dep))
     {
@@ -867,7 +865,7 @@ disableupdaterules(Solver *solv, Queue *job, int jobidx)
 {
   Pool *pool = solv->pool;
   int i, j;
-  Id how, select, what, p, *pp;
+  Id how, select, what, p, pp;
   Solvable *s;
   Repo *installed;
   Rule *r;
@@ -1057,7 +1055,7 @@ makemultiversionconflict(Solver *solv, Id n, Id con)
   Pool *pool = solv->pool;
   Solvable *s, *sn;
   Queue q;
-  Id p, *pp, qbuf[64];
+  Id p, pp, qbuf[64];
 
   sn = pool->solvables + n;
   queue_init_buffer(&q, qbuf, sizeof(qbuf)/sizeof(*qbuf));
@@ -1117,9 +1115,6 @@ addrpmrulesforsolvable(Solver *solv, Solvable *s, Map *m)
      * 0 = yes, 1 = no
      */
   int dontfix;
-#if CODE10
-  int patchatom;
-#endif
     /* Id var and pointer for each dependency
      * (not used in parallel)
      */
@@ -1129,7 +1124,7 @@ addrpmrulesforsolvable(Solver *solv, Solvable *s, Map *m)
   Id rec, *recp;
   Id sug, *sugp;
     /* var and ptr for loops */
-  Id p, *pp;
+  Id p, pp;
     /* ptr to 'whatprovides' */
   Id *dp;
     /* Id for current solvable 's' */
@@ -1185,18 +1180,11 @@ addrpmrulesforsolvable(Solver *solv, Solvable *s, Map *m)
                continue;
 
              /* find list of solvables providing 'req' */
-             dp = pool_whatprovides(pool, req);
+             dp = pool->whatprovidesdata + pool_whatprovides(pool, req);
 
              if (*dp == SYSTEMSOLVABLE)          /* always installed */
                continue;
 
-#if CODE10
-             if (patchatom)
-               {
-                 addpatchatomrequires(solv, s, dp, &workq, m);
-                 continue;
-               }
-#endif
              if (dontfix)
                {
                  /* the strategy here is to not insist on dependencies
@@ -1264,6 +1252,8 @@ addrpmrulesforsolvable(Solver *solv, Solvable *s, Map *m)
          /* we treat conflicts in patches a bit differen:
           * - nevr matching
           * - multiversion handling
+          * XXX: we should really handle this different, looking
+          * at the name is a bad hack
           */
          if (!strncmp("patch:", id2str(pool, s->name), 6))
            ispatch = 1;
@@ -2726,7 +2716,7 @@ run_solver(Solver *solv, int disablerules, int doweak)
              if (solv->decisionmap[i] > 0)
                {
                  /* installed, check for recommends */
-                 Id *recp, rec, *pp, p;
+                 Id *recp, rec, pp, p;
                  s = pool->solvables + i;
                  if (solv->ignorealreadyrecommended && s->repo == solv->installed)
                    continue;
@@ -3351,7 +3341,7 @@ solver_problemruleinfo(Solver *solv, Queue *job, Id rid, Id *depp, Id *sourcep,
   Rule *r;
   Solvable *s;
   int dontfix = 0;
-  Id p, d, w2, *pp, req, *reqp, con, *conp, obs, *obsp, *dp;
+  Id p, d, w2, pp, req, *reqp, con, *conp, obs, *obsp, *dp;
 
   assert(rid > 0);
   if (rid >= solv->jobrules && rid < solv->jobrules_end)
@@ -3401,7 +3391,7 @@ solver_problemruleinfo(Solver *solv, Queue *job, Id rid, Id *depp, Id *sourcep,
            {
              if (req == SOLVABLE_PREREQMARKER)
                continue;
-             dp = pool_whatprovides(pool, req);
+             dp = pool->whatprovidesdata + pool_whatprovides(pool, req);
              if (*dp == 0)
                break;
            }
@@ -3573,7 +3563,7 @@ solver_problemruleinfo(Solver *solv, Queue *job, Id rid, Id *depp, Id *sourcep,
        {
          if (req == SOLVABLE_PREREQMARKER)
            continue;
-         dp = pool_whatprovides(pool, req);
+         dp = pool->whatprovidesdata + pool_whatprovides(pool, req);
          if (d == 0)
            {
              if (*dp == r->w2 && dp[1] == 0)
@@ -3711,7 +3701,7 @@ create_obsolete_index(Solver *solv)
   Pool *pool = solv->pool;
   Solvable *s;
   Repo *installed = solv->installed;
-  Id p, *pp, obs, *obsp, *obsoletes, *obsoletes_data;
+  Id p, pp, obs, *obsp, *obsoletes, *obsoletes_data;
   int i, n;
 
   if (!installed || !installed->nsolvables)
@@ -3916,7 +3906,7 @@ solver_solve(Solver *solv, Queue *job)
   int oldnrules;
   Map addedmap;                       /* '1' == have rpm-rules for solvable */
   Map installcandidatemap;
-  Id how, what, select, name, weak, p, *pp, d;
+  Id how, what, select, name, weak, p, pp, d;
   Queue q, redoq;
   Solvable *s;
   int goterase;
@@ -4369,7 +4359,7 @@ solver_solve(Solver *solv, Queue *job)
    * solver run */
   if (redoq.count || solv->dontinstallrecommended || !solv->dontshowinstalledrecommended || solv->ignorealreadyrecommended)
     {
-      Id rec, *recp, p, *pp;
+      Id rec, *recp, p, pp;
 
       /* create map of all recommened packages */
       solv->recommends_index = -1;
@@ -4434,7 +4424,7 @@ solver_solve(Solver *solv, Queue *job)
     
   if (1)
     {
-      Id sug, *sugp, p, *pp;
+      Id sug, *sugp, p, pp;
 
       /* create map of all suggests that are still open */
       solv->recommends_index = -1;
@@ -4566,4 +4556,235 @@ solver_calc_installsizechange(Solver *solv)
   return change;
 }
 
+#define FIND_INVOLVED_DEBUG 0
+void
+solver_find_involved(Solver *solv, Queue *installedq, Solvable *ts, Queue *q)
+{
+  Pool *pool = solv->pool;
+  Map im;
+  Map installedm;
+  Solvable *s;
+  Queue iq;
+  Queue installedq_internal;
+  Id tp, ip, p, pp, req, *reqp, sup, *supp;
+  int i, count;
+
+  tp = ts - pool->solvables;
+  queue_init(&iq);
+  queue_init(&installedq_internal);
+  map_init(&im, pool->nsolvables);
+  map_init(&installedm, pool->nsolvables);
+
+  if (!installedq)
+    {
+      installedq = &installedq_internal;
+      if (solv->installed)
+       {
+         for (ip = solv->installed->start; ip < solv->installed->end; ip++)
+           {
+             s = pool->solvables + ip;
+             if (s->repo != solv->installed)
+               continue;
+             queue_push(installedq, ip);
+           }
+       }
+    }
+  for (i = 0; i < installedq->count; i++)
+    {
+      ip = installedq->elements[i];
+      MAPSET(&installedm, ip);
+      MAPSET(&im, ip);
+    }
+
+  queue_push(&iq, ts - pool->solvables);
+  while (iq.count)
+    {
+      ip = queue_shift(&iq);
+      if (!MAPTST(&im, ip))
+       continue;
+      if (!MAPTST(&installedm, ip))
+       continue;
+      MAPCLR(&im, ip);
+      s = pool->solvables + ip;
+#if FIND_INVOLVED_DEBUG
+      printf("hello %s\n", solvable2str(pool, s));
+#endif
+      if (s->requires)
+       {
+         reqp = s->repo->idarraydata + s->requires;
+         while ((req = *reqp++) != 0)
+           {
+             if (req == SOLVABLE_PREREQMARKER)
+               continue;
+             /* count number of installed packages that match */
+             count = 0;
+             FOR_PROVIDES(p, pp, req)
+               if (MAPTST(&installedm, p))
+                 count++;
+             if (count > 1)
+               continue;
+             FOR_PROVIDES(p, pp, req)
+               {
+                 if (MAPTST(&im, p))
+                   {
+#if FIND_INVOLVED_DEBUG
+                     printf("%s requires %s\n", solvable2str(pool, pool->solvables + ip), solvable2str(pool, pool->solvables + p));
+#endif
+                     queue_push(&iq, p);
+                   }
+               }
+           }
+       }
+      if (s->recommends)
+       {
+         reqp = s->repo->idarraydata + s->recommends;
+         while ((req = *reqp++) != 0)
+           {
+             count = 0;
+             FOR_PROVIDES(p, pp, req)
+               if (MAPTST(&installedm, p))
+                 count++;
+             if (count > 1)
+               continue;
+             FOR_PROVIDES(p, pp, req)
+               {
+                 if (MAPTST(&im, p))
+                   {
+#if FIND_INVOLVED_DEBUG
+                     printf("%s recommends %s\n", solvable2str(pool, pool->solvables + ip), solvable2str(pool, pool->solvables + p));
+#endif
+                     queue_push(&iq, p);
+                   }
+               }
+           }
+       }
+      if (!iq.count)
+       {
+         /* supplements pass */
+         for (i = 0; i < installedq->count; i++)
+           {
+             ip = installedq->elements[i];
+             s = pool->solvables + ip;
+             if (!s->supplements)
+               continue;
+             if (!MAPTST(&im, ip))
+               continue;
+             supp = s->repo->idarraydata + s->supplements;
+             while ((sup = *supp++) != 0)
+               if (!dep_possible(solv, sup, &im) && dep_possible(solv, sup, &installedm))
+                 break;
+             /* no longer supplemented, also erase */
+             if (sup)
+               {
+#if FIND_INVOLVED_DEBUG
+                 printf("%s supplemented\n", solvable2str(pool, pool->solvables + ip));
+#endif
+                 queue_push(&iq, ip);
+               }
+           }
+       }
+    }
+
+  for (i = 0; i < installedq->count; i++)
+    {
+      ip = installedq->elements[i];
+      if (MAPTST(&im, ip))
+       queue_push(&iq, ip);
+    }
+
+  while (iq.count)
+    {
+      ip = queue_shift(&iq);
+      if (!MAPTST(&installedm, ip))
+       continue;
+      s = pool->solvables + ip;
+#if FIND_INVOLVED_DEBUG
+      printf("bye %s\n", solvable2str(pool, s));
+#endif
+      if (s->requires)
+       {
+         reqp = s->repo->idarraydata + s->requires;
+         while ((req = *reqp++) != 0)
+           {
+             FOR_PROVIDES(p, pp, req)
+               {
+                 if (!MAPTST(&im, p))
+                   {
+                     if (p == tp)
+                       continue;
+#if FIND_INVOLVED_DEBUG
+                     printf("%s requires %s\n", solvable2str(pool, pool->solvables + ip), solvable2str(pool, pool->solvables + p));
+#endif
+                     MAPSET(&im, p);
+                     queue_push(&iq, p);
+                   }
+               }
+           }
+       }
+      if (s->recommends)
+       {
+         reqp = s->repo->idarraydata + s->recommends;
+         while ((req = *reqp++) != 0)
+           {
+             FOR_PROVIDES(p, pp, req)
+               {
+                 if (!MAPTST(&im, p))
+                   {
+                     if (p == tp)
+                       continue;
+#if FIND_INVOLVED_DEBUG
+                     printf("%s recommends %s\n", solvable2str(pool, pool->solvables + ip), solvable2str(pool, pool->solvables + p));
+#endif
+                     MAPSET(&im, p);
+                     queue_push(&iq, p);
+                   }
+               }
+           }
+       }
+      if (!iq.count)
+       {
+         /* supplements pass */
+         for (i = 0; i < installedq->count; i++)
+           {
+             ip = installedq->elements[i];
+             if (ip == tp)
+               continue;
+             s = pool->solvables + ip;
+             if (!s->supplements)
+               continue;
+             if (MAPTST(&im, ip))
+               continue;
+             supp = s->repo->idarraydata + s->supplements;
+             while ((sup = *supp++) != 0)
+               if (dep_possible(solv, sup, &im))
+                 break;
+             if (sup)
+               {
+#if FIND_INVOLVED_DEBUG
+                 printf("%s supplemented\n", solvable2str(pool, pool->solvables + ip));
+#endif
+                 MAPSET(&im, ip);
+                 queue_push(&iq, ip);
+               }
+           }
+       }
+    }
+    
+  queue_free(&iq);
+
+  /* convert map into result */
+  for (i = 0; i < installedq->count; i++)
+    {
+      ip = installedq->elements[i];
+      if (MAPTST(&im, ip))
+       continue;
+      if (ip == ts - pool->solvables)
+       continue;
+      queue_push(q, ip);
+    }
+  map_free(&im);
+  map_free(&installedm);
+  queue_free(&installedq_internal);
+}
+
 /* EOF */
index 13366a3..9c0dd05 100644 (file)
@@ -281,7 +281,7 @@ static inline int
 solver_dep_fulfilled(Solver *solv, Id dep)
 {
   Pool *pool = solv->pool;
-  Id p, *pp;
+  Id p, pp;
 
   if (ISRELDEP(dep))
     {
@@ -334,22 +334,28 @@ solver_is_enhancing(Solver *solv, Solvable *s)
 void solver_calc_duchanges(Solver *solv, DUChanges *mps, int nmps);
 int solver_calc_installsizechange(Solver *solv);
 
+void solver_find_involved(Solver *solv, Queue *installedq, Solvable *s, Queue *q);
+
 static inline void
 solver_create_state_maps(Solver *solv, Map *installedmap, Map *conflictsmap)
 {
   pool_create_state_maps(solv->pool, &solv->decisionq, installedmap, conflictsmap);
 }
 
+/* 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))
 
+/* iterate over all packages selected by a job */
 #define FOR_JOB_SELECT(p, pp, select, what) \
-    for (pp = (select == SOLVER_SOLVABLE ? pool->whatprovidesdata :    \
-               select == SOLVER_SOLVABLE_ONE_OF ? pool->whatprovidesdata + what : \
+    for (pp = (select == SOLVER_SOLVABLE ? 0 : \
+               select == SOLVER_SOLVABLE_ONE_OF ? what : \
                pool_whatprovides(pool, what)),                         \
-         p = (select == SOLVER_SOLVABLE ? what : *pp++) ; p ; p = *pp++) \
+         p = (select == SOLVER_SOLVABLE ? what : pool->whatprovidesdata[pp++]) ; p ; p = pool->whatprovidesdata[pp++]) \
       if (select != SOLVER_SOLVABLE_NAME || pool_match_nevr(pool, pool->solvables + p, what))
 
 #ifdef __cplusplus
index 2e314cf..42d48ba 100644 (file)
@@ -51,7 +51,7 @@ solver_create_decisions_obsoletesmap(Solver *solv)
     {
       for (i = 0; i < solv->decisionq.count; i++)
        {
-         Id *pp, n;
+         Id pp, n;
          int noobs;
 
          n = solv->decisionq.elements[i];
@@ -80,7 +80,7 @@ solver_create_decisions_obsoletesmap(Solver *solv)
       for (i = 0; i < solv->decisionq.count; i++)
        {
          Id obs, *obsp;
-         Id *pp, n;
+         Id pp, n;
 
          n = solv->decisionq.elements[i];
          if (n < 0)
@@ -301,7 +301,7 @@ solver_printdecisions(Solver *solv)
         }
       else
        {
-         Id xp, *xpp;
+         Id xp, xpp;
          FOR_PROVIDES(xp, xpp, s->name)
            {
              Solvable *s2 = pool->solvables + xp;