- Pool *pool = solv->pool;
- int i, j;
- Id name, how, what, p, *pp;
- Solvable *s;
- Repo *installed;
- Rule *r;
- Id lastjob = -1;
-
- installed = solv->installed;
- if (!installed)
- return;
-
- if (jobidx != -1)
- {
- how = job->elements[jobidx] & ~SOLVER_WEAK;
- switch(how)
- {
- case SOLVER_INSTALL_SOLVABLE:
- case SOLVER_ERASE_SOLVABLE:
- case SOLVER_ERASE_SOLVABLE_NAME:
- case SOLVER_ERASE_SOLVABLE_PROVIDES:
- break;
- default:
- return;
- }
- }
- /* go through all enabled job rules */
- MAPZERO(&solv->noupdate);
- for (i = solv->jobrules; i < solv->updaterules; i++)
- {
- r = solv->rules + i;
- if (!r->w1) /* disabled? */
- continue;
- j = solv->ruletojob.elements[i - solv->jobrules];
- if (j == lastjob)
- continue;
- lastjob = j;
- how = job->elements[j] & ~SOLVER_WEAK;
- what = job->elements[j + 1];
- switch(how)
- {
- case SOLVER_INSTALL_SOLVABLE: /* install specific solvable */
- s = pool->solvables + what;
- FOR_PROVIDES(p, pp, s->name)
- {
- if (pool->solvables[p].name != s->name)
- continue;
- if (pool->solvables[p].repo == installed)
- MAPSET(&solv->noupdate, p - installed->start);
- }
- break;
- case SOLVER_ERASE_SOLVABLE:
- s = pool->solvables + what;
- if (s->repo == installed)
- MAPSET(&solv->noupdate, what - installed->start);
- break;
- case SOLVER_ERASE_SOLVABLE_NAME: /* remove by capability */
- case SOLVER_ERASE_SOLVABLE_PROVIDES:
- name = (how == SOLVER_ERASE_SOLVABLE_NAME) ? what : 0;
- while (ISRELDEP(name))
- {
- Reldep *rd = GETRELDEP(pool, name);
- name = rd->name;
- }
- FOR_PROVIDES(p, pp, what)
- {
- if (name && pool->solvables[p].name != name)
- continue;
- if (pool->solvables[p].repo == installed)
- MAPSET(&solv->noupdate, p - installed->start);
- }
- break;
- default:
- break;
- }
- }
-
- /* fixup update rule status */
- if (solv->allowuninstall)
- return; /* no update rules at all */
-
- if (jobidx != -1)
- {
- /* we just disabled job #jobidx. enable all update rules
- * that aren't disabled by the remaining job rules */
- how = job->elements[jobidx] & ~SOLVER_WEAK;
- what = job->elements[jobidx + 1];
- switch(how)
- {
- case SOLVER_INSTALL_SOLVABLE:
- s = pool->solvables + what;
- FOR_PROVIDES(p, pp, s->name)
- {
- if (pool->solvables[p].name != s->name)
- continue;
- if (pool->solvables[p].repo != installed)
- continue;
- if (MAPTST(&solv->noupdate, p - installed->start))
- continue;
- r = solv->rules + solv->updaterules + (p - installed->start);
- if (r->w1)
- continue;
- enablerule(solv, r);
- IF_POOLDEBUG (SAT_DEBUG_SOLUTIONS)
- {
- POOL_DEBUG(SAT_DEBUG_SOLUTIONS, "@@@ re-enabling ");
- solver_printrule(solv, SAT_DEBUG_SOLUTIONS, r);
- }
- }
- break;
- case SOLVER_ERASE_SOLVABLE:
- s = pool->solvables + what;
- if (s->repo != installed)
- break;
- if (MAPTST(&solv->noupdate, what - installed->start))
- break;
- r = solv->rules + solv->updaterules + (what - installed->start);
- if (r->w1)
- break;
- enablerule(solv, r);
- IF_POOLDEBUG (SAT_DEBUG_SOLUTIONS)
- {
- POOL_DEBUG(SAT_DEBUG_SOLUTIONS, "@@@ re-enabling ");
- solver_printrule(solv, SAT_DEBUG_SOLUTIONS, r);
- }
- break;
- case SOLVER_ERASE_SOLVABLE_NAME: /* remove by capability */
- case SOLVER_ERASE_SOLVABLE_PROVIDES:
- name = (how == SOLVER_ERASE_SOLVABLE_NAME) ? what : 0;
- while (ISRELDEP(name))
- {
- Reldep *rd = GETRELDEP(pool, name);
- name = rd->name;
- }
- FOR_PROVIDES(p, pp, what)
- {
- if (name && pool->solvables[p].name != name)
- continue;
- if (pool->solvables[p].repo != installed)
- continue;
- if (MAPTST(&solv->noupdate, p - installed->start))
- continue;
- r = solv->rules + solv->updaterules + (p - installed->start);
- if (r->w1)
- continue;
- enablerule(solv, r);
- IF_POOLDEBUG (SAT_DEBUG_SOLUTIONS)
- {
- POOL_DEBUG(SAT_DEBUG_SOLUTIONS, "@@@ re-enabling ");
- solver_printrule(solv, SAT_DEBUG_SOLUTIONS, r);
- }
- }
- break;
- default:
- break;
- }
- return;
- }
-
- for (i = 0; i < installed->nsolvables; i++)
- {
- r = solv->rules + solv->updaterules + i;
- if (r->w1 && MAPTST(&solv->noupdate, i))
- disablerule(solv, r); /* was enabled, need to disable */
- r = solv->rules + solv->featurerules + i;
- if (r->w1 && MAPTST(&solv->noupdate, i))
- disablerule(solv, r); /* was enabled, need to disable */
- }
-}
-
-#if 0
-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
-
-
-/*
- * add (install) rules for solvable
- * for unfulfilled requirements, conflicts, obsoletes,....
- * add a negative assertion for solvables that are not installable
- */
-
-static void
-addrpmrulesforsolvable(Solver *solv, Solvable *s, Map *m)
-{
- Pool *pool = solv->pool;
- Repo *installed = solv->installed;
- Queue q;
- Id qbuf[64];
- int i;
- int dontfix;
- int patchatom;
- Id req, *reqp;
- Id con, *conp;
- Id obs, *obsp;
- Id rec, *recp;
- Id sug, *sugp;
- Id p, *pp;
- Id *dp;
- Id n;
-
- POOL_DEBUG(SAT_DEBUG_SCHUBI, "----- addrpmrulesforsolvable -----\n");
-
- queue_init_buffer(&q, qbuf, sizeof(qbuf)/sizeof(*qbuf));
- queue_push(&q, s - pool->solvables); /* push solvable Id */
-
- while (q.count)
- {
- /*
- * n: Id of solvable
- * s: Pointer to solvable
- */
-
- n = queue_shift(&q);
- if (MAPTST(m, n)) /* continue if already done */
- continue;
-
- MAPSET(m, n);
- s = pool->solvables + n; /* s = Solvable in question */
-
- dontfix = 0;
- if (installed /* Installed system available */
- && !solv->fixsystem /* NOT repair errors in rpm dependency graph */
- && s->repo == installed) /* solvable is installed? */
- {
- dontfix = 1; /* dont care about broken rpm deps */
- }
-
- if (!dontfix && s->arch != ARCH_SRC && s->arch != ARCH_NOSRC && !pool_installable(pool, s))
- {
- 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 */
- }
-
- patchatom = 0;
- if (s->freshens && !s->supplements)
- {
- const char *name = id2str(pool, s->name);
- if (name[0] == 'a' && !strncmp(name, "atom:", 5))
- patchatom = 1;
- }
-
- /*-----------------------------------------
- * check requires of s
- */
-
- if (s->requires)
- {
- reqp = s->repo->idarraydata + s->requires;
- while ((req = *reqp++) != 0) /* go throw all requires */
- {
- if (req == SOLVABLE_PREREQMARKER) /* skip the marker */
- continue;
-
- dp = pool_whatprovides(pool, req);
-
- if (*dp == SYSTEMSOLVABLE) /* always installed */
- continue;
-
-#if 0
- if (patchatom)
- {
- addpatchatomrequires(solv, s, dp, &q, m);
- continue;
- }
-#endif
- if (dontfix)
- {
- /* the strategy here is to not insist on dependencies
- * that are already broken. so if we find one provider
- * that was already installed, we know that the
- * dependency was not broken before so we enforce it */
- for (i = 0; (p = dp[i]) != 0; i++) /* for all providers */
- {
- if (pool->solvables[p].repo == installed)
- break; /* provider was installed */
- }
- if (!p) /* previously broken dependency */
- {
- POOL_DEBUG(SAT_DEBUG_RULE_CREATION, "ignoring broken requires %s of installed package %s\n", dep2str(pool, req), solvable2str(pool, s));
- continue;
- }
- }
-
- if (!*dp)
- {
- /* nothing provides req! */
- POOL_DEBUG(SAT_DEBUG_RULE_CREATION, "package %s [%d] is not installable (%s)\n", solvable2str(pool, s), (Id)(s - pool->solvables), dep2str(pool, req));
- addrule(solv, -n, 0); /* mark requestor as uninstallable */
- continue;
- }
-
- IF_POOLDEBUG (SAT_DEBUG_RULE_CREATION)
- {
- POOL_DEBUG(SAT_DEBUG_RULE_CREATION," %s requires %s\n", solvable2str(pool, s), dep2str(pool, req));
- for (i = 0; dp[i]; i++)
- POOL_DEBUG(SAT_DEBUG_RULE_CREATION, " provided by %s\n", solvable2str(pool, pool->solvables + dp[i]));
- }
-
- /* add 'requires' dependency */
- /* rule: (-requestor|provider1|provider2|...|providerN) */
- addrule(solv, -n, dp - pool->whatprovidesdata);
-
- /* descend the dependency tree */
- for (; *dp; dp++) /* loop through all providers */
- {
- if (!MAPTST(m, *dp))
- queue_push(&q, *dp);
- }
-
- } /* while, requirements of n */
-
- } /* if, requirements */
-
- /* that's all we check for src packages */
- if (s->arch == ARCH_SRC || s->arch == ARCH_NOSRC)
- continue;
-
- /*-----------------------------------------
- * check conflicts of s
- */
-
- if (s->conflicts)
- {
- conp = s->repo->idarraydata + s->conflicts;
- while ((con = *conp++) != 0)
- {
- FOR_PROVIDES(p, pp, con)
- {
- /* dontfix: dont care about conflicts with already installed packs */
- if (dontfix && pool->solvables[p].repo == installed)
- continue;
- if (p == n && !solv->allowselfconflicts)
- p = 0; /* make it a negative assertion */
- /* rule: -n|-p: either solvable _or_ provider of conflict */
- addrule(solv, -n, -p);
- }
- }
- }
-
- /*-----------------------------------------
- * check obsoletes if not installed
- */
- if (!installed || pool->solvables[n].repo != installed)
- { /* not installed */
- if (s->obsoletes)
- {
- obsp = s->repo->idarraydata + s->obsoletes;
- while ((obs = *obsp++) != 0)
- {
- FOR_PROVIDES(p, pp, obs)
- addrule(solv, -n, -p);
- }
- }
- FOR_PROVIDES(p, pp, s->name)
- {
- if (s->name == pool->solvables[p].name)
- addrule(solv, -n, -p);
- }
- }
-
- /*-----------------------------------------
- * add recommends to the rule list
- */
- if (s->recommends)
- {
- recp = s->repo->idarraydata + s->recommends;
- while ((rec = *recp++) != 0)
- {
- FOR_PROVIDES(p, pp, rec)
- if (!MAPTST(m, p))
- queue_push(&q, p);
- }
- }
- if (s->suggests)
- {
- sugp = s->repo->idarraydata + s->suggests;
- while ((sug = *sugp++) != 0)
- {
- FOR_PROVIDES(p, pp, sug)
- if (!MAPTST(m, p))
- queue_push(&q, p);
- }
- }
- }
- queue_free(&q);
- POOL_DEBUG(SAT_DEBUG_SCHUBI, "----- addrpmrulesforsolvable end -----\n");
-}
-
-static void
-addrpmrulesforweak(Solver *solv, Map *m)
-{
- Pool *pool = solv->pool;
- Solvable *s;
- Id sup, *supp;
- int i, n;
-
- POOL_DEBUG(SAT_DEBUG_SCHUBI, "----- addrpmrulesforweak -----\n");
- for (i = n = 1; n < pool->nsolvables; i++, n++)
- {
- if (i == pool->nsolvables)
- i = 1;
- if (MAPTST(m, i))
- continue;
- s = pool->solvables + i;
- if (!pool_installable(pool, s))
- continue;
- sup = 0;
- if (s->supplements)
- {
- supp = s->repo->idarraydata + s->supplements;
- while ((sup = *supp++) != ID_NULL)
- if (dep_possible(solv, sup, m))
- break;
- }
- if (!sup && s->freshens)
- {
- supp = s->repo->idarraydata + s->freshens;
- while ((sup = *supp++) != ID_NULL)
- if (dep_possible(solv, sup, m))
- break;
- }
- if (!sup && s->enhances)
- {
- supp = s->repo->idarraydata + s->enhances;
- while ((sup = *supp++) != ID_NULL)
- if (dep_possible(solv, sup, m))
- break;
- }
- if (!sup)
- continue;
- addrpmrulesforsolvable(solv, s, m);
- n = 0;
- }
- POOL_DEBUG(SAT_DEBUG_SCHUBI, "----- addrpmrulesforweak end -----\n");
-}
-
-static void
-addrpmrulesforupdaters(Solver *solv, Solvable *s, Map *m, int allowall)
-{
- Pool *pool = solv->pool;
- int i;
- Queue qs;
- Id qsbuf[64];
-
- POOL_DEBUG(SAT_DEBUG_SCHUBI, "----- addrpmrulesforupdaters -----\n");
-
- queue_init_buffer(&qs, qsbuf, sizeof(qsbuf)/sizeof(*qsbuf));
- policy_findupdatepackages(solv, s, &qs, allowall);
- if (!MAPTST(m, s - pool->solvables)) /* add rule for s if not already done */
- addrpmrulesforsolvable(solv, s, m);
- for (i = 0; i < qs.count; i++)
- if (!MAPTST(m, qs.elements[i]))
- addrpmrulesforsolvable(solv, pool->solvables + qs.elements[i], m);
- queue_free(&qs);
-
- POOL_DEBUG(SAT_DEBUG_SCHUBI, "----- addrpmrulesforupdaters -----\n");
-}
-
-/*
- * add rule for update
- * (A|A1|A2|A3...) An = update candidates for A
- *
- * s = (installed) solvable
- */
-
-static void
-addupdaterule(Solver *solv, Solvable *s, int allowall)
-{
- /* installed packages get a special upgrade allowed rule */
- Pool *pool = solv->pool;
- Id d;
- Queue qs;
- Id qsbuf[64];
-
- POOL_DEBUG(SAT_DEBUG_SCHUBI, "----- addupdaterule -----\n");
-
- queue_init_buffer(&qs, qsbuf, sizeof(qsbuf)/sizeof(*qsbuf));
- policy_findupdatepackages(solv, s, &qs, allowall);
- if (qs.count == 0) /* no updaters found */
- d = 0;
- else
- d = pool_queuetowhatprovides(pool, &qs); /* intern computed queue */
- queue_free(&qs);
- addrule(solv, s - pool->solvables, d); /* allow update of s */
- POOL_DEBUG(SAT_DEBUG_SCHUBI, "----- addupdaterule end -----\n");
-}
-
-
-/*-----------------------------------------------------------------*/
-/* watches */
-
-
-/*
- * makewatches
- *
- * initial setup for all watches
- */
-
-static void
-makewatches(Solver *solv)
-{
- Rule *r;
- int i;
- int nsolvables = solv->pool->nsolvables;
-
- sat_free(solv->watches);
- /* lower half for removals, upper half for installs */
- solv->watches = sat_calloc(2 * nsolvables, sizeof(Id));
-#if 1
- /* do it reverse so rpm rules get triggered first (XXX: obsolete?) */
- for (i = 1, r = solv->rules + solv->nrules - 1; i < solv->nrules; i++, r--)
-#else
- for (i = 1, r = solv->rules + 1; i < solv->nrules; i++, r++)
-#endif
- {
- if (!r->w1 /* rule is disabled */
- || !r->w2) /* rule is assertion */
- continue;
-
- /* see addwatches(solv, r) */
- r->n1 = solv->watches[nsolvables + r->w1];
- solv->watches[nsolvables + r->w1] = r - solv->rules;
-
- r->n2 = solv->watches[nsolvables + r->w2];
- solv->watches[nsolvables + r->w2] = r - solv->rules;
- }
-}
-
-
-/*
- * add watches (for rule)
- */
-
-static void
-addwatches(Solver *solv, Rule *r)
-{
- int nsolvables = solv->pool->nsolvables;