#define RARRAY_LEN(ary) (RARRAY(ary)->len)
#endif
-#define SOLVER_SOLUTION_ERASE -100
-#define SOLVER_SOLUTION_REPLACE -101
-#define SOLVER_SOLUTION_REPLACE_DOWNGRADE -102
-#define SOLVER_SOLUTION_REPLACE_ARCHCHANGE -103
-#define SOLVER_SOLUTION_REPLACE_VENDORCHANGE -104
-#define SOLVER_SOLUTION_REPLACE_NAMECHANGE -105
-
typedef void *AppObjectPtr;
typedef Id DepId;
Solver *solv;
Id problemid;
Id solutionid;
- Id id;
Id type;
Id p;
Solver *const solv;
Id const problemid;
Id const solutionid;
- Id const id;
Id const type;
} Solutionelement;
Id const type;
Id const dep_id;
Id const chosen_id;
- int level;
+ int const level;
} Alternative;
%nodefaultctor Transaction;
int element_count() {
return solver_solutionelement_count($self->solv, $self->problemid, $self->id);
}
-
- %typemap(out) Queue elements Queue2Array(Solutionelement *, 4, new_Solutionelement(arg1->solv, arg1->problemid, arg1->id, id, idp[1], idp[2], idp[3]));
+ %typemap(out) Queue elements Queue2Array(Solutionelement *, 3, new_Solutionelement(arg1->solv, arg1->problemid, arg1->id, id, idp[1], idp[2]));
%newobject elements;
Queue elements(bool expandreplaces=0) {
Queue q;
- int i, cnt;
queue_init(&q);
- cnt = solver_solutionelement_count($self->solv, $self->problemid, $self->id);
- for (i = 1; i <= cnt; i++)
- {
- Id p, rp, type;
- solver_next_solutionelement($self->solv, $self->problemid, $self->id, i - 1, &p, &rp);
- if (p > 0) {
- type = rp ? SOLVER_SOLUTION_REPLACE : SOLVER_SOLUTION_ERASE;
- } else {
- type = p;
- p = rp;
- rp = 0;
- }
- if (type == SOLVER_SOLUTION_REPLACE && expandreplaces) {
- int illegal = policy_is_illegal(self->solv, self->solv->pool->solvables + p, self->solv->pool->solvables + rp, 0);
- if (illegal) {
- if ((illegal & POLICY_ILLEGAL_DOWNGRADE) != 0) {
- queue_push2(&q, i, SOLVER_SOLUTION_REPLACE_DOWNGRADE);
- queue_push2(&q, p, rp);
- }
- if ((illegal & POLICY_ILLEGAL_ARCHCHANGE) != 0) {
- queue_push2(&q, i, SOLVER_SOLUTION_REPLACE_ARCHCHANGE);
- queue_push2(&q, p, rp);
- }
- if ((illegal & POLICY_ILLEGAL_VENDORCHANGE) != 0) {
- queue_push2(&q, i, SOLVER_SOLUTION_REPLACE_VENDORCHANGE);
- queue_push2(&q, p, rp);
- }
- if ((illegal & POLICY_ILLEGAL_NAMECHANGE) != 0) {
- queue_push2(&q, i, SOLVER_SOLUTION_REPLACE_NAMECHANGE);
- queue_push2(&q, p, rp);
- }
- continue;
- }
- }
- queue_push2(&q, i, type);
- queue_push2(&q, p, rp);
- }
+ solver_all_solutionelements($self->solv, $self->problemid, $self->id, expandreplaces, &q);
return q;
}
}
%extend Solutionelement {
- Solutionelement(Solver *solv, Id problemid, Id solutionid, Id id, Id type, Id p, Id rp) {
+ Solutionelement(Solver *solv, Id problemid, Id solutionid, Id type, Id p, Id rp) {
Solutionelement *e;
e = solv_calloc(1, sizeof(*e));
e->solv = solv;
e->problemid = problemid;
e->solutionid = solutionid;
- e->id = id;
e->type = type;
e->p = p;
e->rp = rp;
return e;
}
const char *str() {
- Id p = $self->type;
- Id rp = $self->p;
- int illegal = 0;
- if (p == SOLVER_SOLUTION_ERASE)
- {
- p = rp;
- rp = 0;
- }
- else if (p == SOLVER_SOLUTION_REPLACE)
- {
- p = rp;
- rp = $self->rp;
- }
- else if (p == SOLVER_SOLUTION_REPLACE_DOWNGRADE)
- illegal = POLICY_ILLEGAL_DOWNGRADE;
- else if (p == SOLVER_SOLUTION_REPLACE_ARCHCHANGE)
- illegal = POLICY_ILLEGAL_ARCHCHANGE;
- else if (p == SOLVER_SOLUTION_REPLACE_VENDORCHANGE)
- illegal = POLICY_ILLEGAL_VENDORCHANGE;
- else if (p == SOLVER_SOLUTION_REPLACE_NAMECHANGE)
- illegal = POLICY_ILLEGAL_NAMECHANGE;
- if (illegal)
- return pool_tmpjoin($self->solv->pool, "allow ", policy_illegal2str($self->solv, illegal, $self->solv->pool->solvables + $self->p, $self->solv->pool->solvables + $self->rp), 0);
- return solver_solutionelement2str($self->solv, p, rp);
- }
- %typemap(out) Queue replaceelements Queue2Array(Solutionelement *, 1, new_Solutionelement(arg1->solv, arg1->problemid, arg1->solutionid, arg1->id, id, arg1->p, arg1->rp));
+ return solver_solutionelementtype2str($self->solv, $self->type, $self->p, $self->rp);
+ }
+ %typemap(out) Queue replaceelements Queue2Array(Solutionelement *, 1, new_Solutionelement(arg1->solv, arg1->problemid, arg1->solutionid, id, arg1->p, arg1->rp));
%newobject replaceelements;
Queue replaceelements() {
Queue q;
}
%}
Queue choices_raw() {
- Queue r;
- queue_init_clone(&r, &$self->choices);
- return r;
+ Queue q;
+ queue_init_clone(&q, &$self->choices);
+ return q;
}
%typemap(out) Queue choices Queue2Array(XSolvable *, 1, new_XSolvable(arg1->solv->pool, id));
Queue choices() {
int i;
- Queue r;
- queue_init_clone(&r, &$self->choices);
- for (i = 0; i < r.count; i++)
- if (r.elements[i] < 0)
- r.elements[i] = -r.elements[i];
- return r;
+ Queue q;
+ queue_init_clone(&q, &$self->choices);
+ for (i = 0; i < q.count; i++)
+ if (q.elements[i] < 0)
+ q.elements[i] = -q.elements[i];
+ return q;
}
#if defined(SWIGPERL) || defined(SWIGTCL)
%rename("str") __str__;
for (problem = 1; problem <= pcnt; problem++)
{
int take = 0;
+ Id rid;
printf("Problem %d/%d:\n", problem, pcnt);
- solver_printprobleminfo(solv, problem);
+ rid = solver_findproblemrule(solv, problem);
+ if (rid)
+ {
+ Id source, target, dep;
+ SolverRuleinfo type = solver_ruleinfo(solv, rid, &source, &target, &dep);
+ printf("%s\n", solver_problemruleinfo2str(solv, type, source, target, dep));
+ }
printf("\n");
scnt = solver_solution_count(solv, problem);
for (solution = 1; solution <= scnt; solution++)
{
+ Queue sq;
printf("Solution %d:\n", solution);
- solver_printsolution(solv, problem, solution);
+ queue_init(&sq);
+ solver_all_solutionelements(solv, problem, solution, 1, &sq);
+ for (i = 0; i < sq.count; i += 3)
+ printf(" - %s\n", solver_solutionelementtype2str(solv, sq.elements[i], sq.elements[i + 1], sq.elements[i + 2]));
+ queue_free(&sq);
printf("\n");
}
for (;;)
solvable_trivial_installable_queue;
solvable_trivial_installable_repo;
solvable_unset;
+ solver_all_solutionelements;
solver_allruleinfos;
solver_allweakdepinfos;
solver_alternative2str;
solver_set_flag;
solver_solution_count;
solver_solutionelement2str;
+ solver_solutionelementtype2str;
solver_solutionelement_count;
solver_solutionelement_internalid;
solver_solutionelement_extrajobflags;
#include "pool.h"
#include "util.h"
#include "evr.h"
+#include "policy.h"
#include "solverdebug.h"
/**********************************************************************************/
return solv->solutions.elements[solidx + 2 * solv->solutions.elements[solidx] + 3];
}
+/* currently just SOLVER_CLEANDEPS */
Id
solver_solutionelement_extrajobflags(Solver *solv, Id problem, Id solution)
{
return element + 1;
}
+static inline void
+queue_push3(Queue *q, Id id1, Id id2, Id id3)
+{
+ queue_push(q, id1);
+ queue_push2(q, id2, id3);
+}
+
+static void
+add_expanded_replace(Solver *solv, Id p, Id rp, Queue *q)
+{
+ int illegal = policy_is_illegal(solv, solv->pool->solvables + p, solv->pool->solvables + rp, 0);
+ if ((illegal & POLICY_ILLEGAL_DOWNGRADE) != 0)
+ queue_push3(q, SOLVER_SOLUTION_REPLACE_DOWNGRADE, p, rp);
+ if ((illegal & POLICY_ILLEGAL_ARCHCHANGE) != 0)
+ queue_push3(q, SOLVER_SOLUTION_REPLACE_ARCHCHANGE, p, rp);
+ if ((illegal & POLICY_ILLEGAL_VENDORCHANGE) != 0)
+ queue_push3(q, SOLVER_SOLUTION_REPLACE_VENDORCHANGE, p, rp);
+ if ((illegal & POLICY_ILLEGAL_NAMECHANGE) != 0)
+ queue_push3(q, SOLVER_SOLUTION_REPLACE_NAMECHANGE, p, rp);
+ if (!illegal || (illegal & ~(POLICY_ILLEGAL_DOWNGRADE | POLICY_ILLEGAL_ARCHCHANGE | POLICY_ILLEGAL_VENDORCHANGE | POLICY_ILLEGAL_NAMECHANGE)))
+ queue_push3(q, SOLVER_SOLUTION_REPLACE, p, rp);
+}
+
+/* solutionelements are (type, p, rp) triplets */
+void
+solver_all_solutionelements(Solver *solv, Id problem, Id solution, int expandreplaces, Queue *q)
+{
+ int i, cnt;
+ Id solidx = solv->problems.elements[problem * 2 - 1];
+ solidx = solv->solutions.elements[solidx + solution];
+ queue_empty(q);
+ if (!solidx)
+ return;
+ cnt = solv->solutions.elements[solidx++];
+ for (i = 0; i < cnt; i++)
+ {
+ Id p = solv->solutions.elements[solidx++];
+ Id rp = solv->solutions.elements[solidx++];
+ if (p > 0)
+ {
+ if (rp && expandreplaces)
+ add_expanded_replace(solv, p, rp, q);
+ else
+ queue_push3(q, rp ? SOLVER_SOLUTION_REPLACE : SOLVER_SOLUTION_ERASE, p, rp);
+ }
+ else
+ queue_push3(q, p, rp, 0);
+ }
+}
+
void
solver_take_solutionelement(Solver *solv, Id p, Id rp, Id extrajobflags, Queue *job)
{
job->elements[rp] = 0;
return;
}
+ if (p == SOLVER_SOLUTION_ERASE)
+ {
+ p = rp;
+ rp = 0;
+ }
if (rp <= 0 && p <= 0)
return; /* just in case */
if (rp > 0)
}
const char *
-solver_solutionelement2str(Solver *solv, Id p, Id rp)
+solver_solutionelementtype2str(Solver *solv, int type, Id p, Id rp)
{
Pool *pool = solv->pool;
- if (p == SOLVER_SOLUTION_JOB || p == SOLVER_SOLUTION_POOLJOB)
- {
- Id how, what;
- if (p == SOLVER_SOLUTION_JOB)
- rp += solv->pooljobcnt;
- how = solv->job.elements[rp - 1];
- what = solv->job.elements[rp];
- return pool_tmpjoin(pool, "do not ask to ", pool_job2str(pool, how, what, 0), 0);
- }
- else if (p == SOLVER_SOLUTION_INFARCH)
+ Solvable *s;
+ const char *str;
+
+ switch (type)
{
- Solvable *s = pool->solvables + rp;
+ case SOLVER_SOLUTION_JOB:
+ case SOLVER_SOLUTION_POOLJOB:
+ if (type == SOLVER_SOLUTION_JOB)
+ p += solv->pooljobcnt;
+ return pool_tmpjoin(pool, "do not ask to ", pool_job2str(pool, solv->job.elements[p - 1], solv->job.elements[p], 0), 0);
+ case SOLVER_SOLUTION_INFARCH:
+ s = pool->solvables + p;
if (solv->installed && s->repo == solv->installed)
return pool_tmpjoin(pool, "keep ", pool_solvable2str(pool, s), " despite the inferior architecture");
else
return pool_tmpjoin(pool, "install ", pool_solvable2str(pool, s), " despite the inferior architecture");
- }
- else if (p == SOLVER_SOLUTION_DISTUPGRADE)
- {
- Solvable *s = pool->solvables + rp;
+ case SOLVER_SOLUTION_DISTUPGRADE:
+ s = pool->solvables + p;
if (solv->installed && s->repo == solv->installed)
return pool_tmpjoin(pool, "keep obsolete ", pool_solvable2str(pool, s), 0);
else
return pool_tmpjoin(pool, "install ", pool_solvable2str(pool, s), " from excluded repository");
- }
- else if (p == SOLVER_SOLUTION_BEST)
- {
- Solvable *s = pool->solvables + rp;
+ case SOLVER_SOLUTION_BEST:
+ s = pool->solvables + p;
if (solv->installed && s->repo == solv->installed)
return pool_tmpjoin(pool, "keep old ", pool_solvable2str(pool, s), 0);
else
return pool_tmpjoin(pool, "install ", pool_solvable2str(pool, s), " despite the old version");
+ case SOLVER_SOLUTION_BLACK:
+ return pool_tmpjoin(pool, "install ", pool_solvid2str(pool, p), 0);
+ case SOLVER_SOLUTION_STRICTREPOPRIORITY:
+ return pool_tmpjoin(pool, "install ", pool_solvid2str(pool, p), " despite the repo priority");
+
+ /* replace types: p -> rp */
+ case SOLVER_SOLUTION_ERASE:
+ return pool_tmpjoin(pool, "allow deinstallation of ", pool_solvid2str(pool, p), 0);
+ case SOLVER_SOLUTION_REPLACE:
+ str = pool_tmpjoin(pool, "allow replacement of ", pool_solvid2str(pool, p), 0);
+ return pool_tmpappend(pool, str, " with ", pool_solvid2str(pool, rp));
+ case SOLVER_SOLUTION_REPLACE_DOWNGRADE:
+ return pool_tmpjoin(pool, "allow ", policy_illegal2str(solv, POLICY_ILLEGAL_DOWNGRADE, pool->solvables + p, pool->solvables + rp), 0);
+ case SOLVER_SOLUTION_REPLACE_ARCHCHANGE:
+ return pool_tmpjoin(pool, "allow ", policy_illegal2str(solv, POLICY_ILLEGAL_ARCHCHANGE, pool->solvables + p, pool->solvables + rp), 0);
+ case SOLVER_SOLUTION_REPLACE_VENDORCHANGE:
+ return pool_tmpjoin(pool, "allow ", policy_illegal2str(solv, POLICY_ILLEGAL_VENDORCHANGE, pool->solvables + p, pool->solvables + rp), 0);
+ case SOLVER_SOLUTION_REPLACE_NAMECHANGE:
+ return pool_tmpjoin(pool, "allow ", policy_illegal2str(solv, POLICY_ILLEGAL_NAMECHANGE, pool->solvables + p, pool->solvables + rp), 0);
+ default:
+ break;
}
- 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 == SOLVER_SOLUTION_STRICTREPOPRIORITY)
- {
- Solvable *s = pool->solvables + rp;
- return pool_tmpjoin(pool, "install ", pool_solvable2str(pool, s), " despite the repo priority");
- }
- else if (p > 0 && rp > 0)
- {
- const char *sp = pool_solvid2str(pool, p);
- const char *srp = pool_solvid2str(pool, rp);
- const char *str = pool_tmpjoin(pool, "allow replacement of ", sp, 0);
- return pool_tmpappend(pool, str, " with ", srp);
- }
- else
- return "bad solution element";
+ return "bad solution element";
}
+const char *
+solver_solutionelement2str(Solver *solv, Id p, Id rp)
+{
+ if (p > 0)
+ return solver_solutionelementtype2str(solv, rp ? SOLVER_SOLUTION_REPLACE : SOLVER_SOLUTION_ERASE, p, rp);
+ return solver_solutionelementtype2str(solv, p, rp, 0);
+}
#define SOLVER_SOLUTION_POOLJOB (-4)
#define SOLVER_SOLUTION_BLACK (-5)
#define SOLVER_SOLUTION_STRICTREPOPRIORITY (-6)
+/* replace solution types */
+#define SOLVER_SOLUTION_ERASE (-100)
+#define SOLVER_SOLUTION_REPLACE (-101)
+#define SOLVER_SOLUTION_REPLACE_DOWNGRADE (-102)
+#define SOLVER_SOLUTION_REPLACE_ARCHCHANGE (-103)
+#define SOLVER_SOLUTION_REPLACE_VENDORCHANGE (-104)
+#define SOLVER_SOLUTION_REPLACE_NAMECHANGE (-105)
void solver_recordproblem(struct s_Solver *solv, Id rid);
void solver_fixproblem(struct s_Solver *solv, Id rid);
Id solver_solutionelement_internalid(struct s_Solver *solv, Id problem, Id solution);
Id solver_solutionelement_extrajobflags(struct s_Solver *solv, Id problem, Id solution);
Id solver_next_solutionelement(struct s_Solver *solv, Id problem, Id solution, Id element, Id *p, Id *rp);
+void solver_all_solutionelements(struct s_Solver *solv, Id problem, Id solution, int expandreplaces, Queue *q);
void solver_take_solutionelement(struct s_Solver *solv, Id p, Id rp, Id extrajobflags, Queue *job);
void solver_take_solution(struct s_Solver *solv, Id problem, Id solution, Queue *job);
extern const char *solver_problemruleinfo2str(struct s_Solver *solv, SolverRuleinfo type, Id source, Id target, Id dep);
extern const char *solver_problem2str(struct s_Solver *solv, Id problem);
extern const char *solver_solutionelement2str(struct s_Solver *solv, Id p, Id rp);
+extern const char *solver_solutionelementtype2str(struct s_Solver *solv, int type, Id p, Id rp);
#ifdef __cplusplus
}
queue_free(&q);
}
-static int illegals[] = {
- POLICY_ILLEGAL_DOWNGRADE,
- POLICY_ILLEGAL_NAMECHANGE,
- POLICY_ILLEGAL_ARCHCHANGE,
- POLICY_ILLEGAL_VENDORCHANGE,
- 0
-};
-
void
solver_printsolution(Solver *solv, Id problem, Id solution)
{
Pool *pool = solv->pool;
- Id p, rp, element;
-
- element = 0;
- while ((element = solver_next_solutionelement(solv, problem, solution, element, &p, &rp)) != 0)
- {
- if (p > 0 && rp > 0)
- {
- /* for replacements we want to know why it was illegal */
- Solvable *s = pool->solvables + p, *rs = pool->solvables + rp;
- int illegal = policy_is_illegal(solv, s, rs, 0);
- if (illegal)
- {
- int i;
- for (i = 0; illegals[i]; i++)
- if ((illegal & illegals[i]) != 0)
- {
- POOL_DEBUG(SOLV_DEBUG_RESULT, " - allow %s\n", policy_illegal2str(solv, illegals[i], s, rs));
- illegal ^= illegals[i];
- }
- if (!illegal)
- continue;
- }
- }
- POOL_DEBUG(SOLV_DEBUG_RESULT, " - %s\n", solver_solutionelement2str(solv, p, rp));
- }
+ Queue q;
+ int i;
+ queue_init(&q);
+ solver_all_solutionelements(solv, problem, solution, 1, &q);
+ for (i = 0; i < q.count; i += 3)
+ POOL_DEBUG(SOLV_DEBUG_RESULT, " - %s\n", solver_solutionelementtype2str(solv, q.elements[i], q.elements[i + 1], q.elements[i + 2]));
+ queue_free(&q);
}
void