summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFlorian Festi <ffesti@redhat.com>2016-11-25 13:31:31 +0100
committerFlorian Festi <ffesti@redhat.com>2016-12-08 13:13:56 +0100
commitdecd7e619ee629b5bee0d2a597679cbf58457977 (patch)
tree13624734b82666642ff8bdbd0990fbfdaad50c88
parent61992a4b65c8e96f608fcca18b35cee83d342702 (diff)
downloadrpm-decd7e619ee629b5bee0d2a597679cbf58457977.tar.gz
Order by weak and reverse dependencies also
Add reversed param to add(Single)Relation() for Supplements and Enhances Also fix generation of reversed relations. As we generate all relations for one package (p) at once they are all the latest on the other packages. So we don't have to search through the list of relations there. But in the current package the relation might have been added before others. So we can check in package q if the relation is already there - using the proper list depending on the direction. So we can't reverse by just switching p and q before doing that.
-rw-r--r--lib/order.c84
1 files changed, 70 insertions, 14 deletions
diff --git a/lib/order.c b/lib/order.c
index 25f91cf10..f2f2aec27 100644
--- a/lib/order.c
+++ b/lib/order.c
@@ -67,7 +67,8 @@ static void rpmTSIFree(tsortInfo tsi)
static inline int addSingleRelation(rpmte p,
rpmte q,
- rpmsenseFlags dsflags)
+ rpmsenseFlags dsflags,
+ int reversed)
{
struct tsortInfo_s *tsi_p, *tsi_q;
relation rel;
@@ -80,9 +81,7 @@ static inline int addSingleRelation(rpmte p,
/* Erasures are reversed installs. */
if (teType == TR_REMOVED) {
- rpmte r = p;
- p = q;
- q = r;
+ reversed = ! reversed;
flags = isErasePreReq(dsflags);
} else {
flags = isInstallPreReq(dsflags);
@@ -94,14 +93,46 @@ static inline int addSingleRelation(rpmte p,
RPMSENSE_SCRIPT_PRE : RPMSENSE_SCRIPT_PREUN;
}
+
tsi_p = rpmteTSI(p);
tsi_q = rpmteTSI(q);
/* if relation got already added just update the flags */
- if (tsi_q->tsi_relations && tsi_q->tsi_relations->rel_suc == tsi_p) {
+ if (!reversed &&
+ tsi_q->tsi_relations && tsi_q->tsi_relations->rel_suc == tsi_p) {
+ /* must be latest one added to q as we add all rels to p at once */
tsi_q->tsi_relations->rel_flags |= flags;
- tsi_p->tsi_forward_relations->rel_flags |= flags;
- return 0;
+ /* search entry in p */
+ for (struct relation_s * tsi = tsi_p->tsi_forward_relations;
+ tsi; tsi = tsi->rel_next) {
+ if (tsi->rel_suc == tsi_q) {
+ tsi->rel_flags |= flags;
+ return 0;
+ }
+ }
+ assert(0);
+ }
+
+ /* if relation got already added just update the flags */
+ if (reversed && tsi_q->tsi_forward_relations &&
+ tsi_q->tsi_forward_relations->rel_suc == tsi_p) {
+ /* must be latest one added to q as we add all rels to p at once */
+ tsi_q->tsi_forward_relations->rel_flags |= flags;
+ /* search entry in p */
+ for (struct relation_s * tsi = tsi_p->tsi_relations;
+ tsi; tsi = tsi->rel_next) {
+ if (tsi->rel_suc == tsi_q) {
+ tsi->rel_flags |= flags;
+ return 0;
+ }
+ }
+ assert(0);
+ }
+
+ if (reversed) {
+ rpmte r = p;
+ p = q;
+ q = r;
}
/* Record next "q <- p" relation (i.e. "p" requires "q"). */
@@ -142,7 +173,8 @@ static inline int addSingleRelation(rpmte p,
static inline int addRelation(rpmts ts,
rpmal al,
rpmte p,
- rpmds requires)
+ rpmds requires,
+ int reversed)
{
rpmte q;
rpmsenseFlags dsflags;
@@ -158,18 +190,18 @@ static inline int addRelation(rpmts ts,
rpmrichOp op;
if (rpmdsParseRichDep(requires, &ds1, &ds2, &op, NULL) == RPMRC_OK) {
if (op != RPMRICHOP_ELSE)
- addRelation(ts, al, p, ds1);
+ addRelation(ts, al, p, ds1, reversed);
if (op == RPMRICHOP_IF) {
rpmds ds21, ds22;
rpmrichOp op2;
if (rpmdsParseRichDep(requires, &ds21, &ds22, &op2, NULL) == RPMRC_OK && op2 == RPMRICHOP_ELSE) {
- addRelation(ts, al, p, ds22);
+ addRelation(ts, al, p, ds22, reversed);
}
ds21 = rpmdsFree(ds21);
ds22 = rpmdsFree(ds22);
}
if (op == RPMRICHOP_AND || op == RPMRICHOP_OR)
- addRelation(ts, al, p, ds2);
+ addRelation(ts, al, p, ds2, reversed);
ds1 = rpmdsFree(ds1);
ds2 = rpmdsFree(ds2);
}
@@ -181,7 +213,7 @@ static inline int addRelation(rpmts ts,
if (q == NULL || q == p)
return 0;
- addSingleRelation(p, q, dsflags);
+ addSingleRelation(p, q, dsflags, reversed);
return 0;
}
@@ -559,16 +591,40 @@ int rpmtsOrder(rpmts ts)
rpmal al = (rpmteType(p) == TR_REMOVED) ?
erasedPackages : tsmem->addedPackages;
rpmds requires = rpmdsInit(rpmteDS(p, RPMTAG_REQUIRENAME));
+ rpmds recommends = rpmdsInit(rpmteDS(p, RPMTAG_RECOMMENDNAME));
+ rpmds suggests = rpmdsInit(rpmteDS(p, RPMTAG_SUGGESTNAME));
+ rpmds supplements = rpmdsInit(rpmteDS(p, RPMTAG_SUPPLEMENTNAME));
+ rpmds enhances = rpmdsInit(rpmteDS(p, RPMTAG_ENHANCENAME));
rpmds order = rpmdsInit(rpmteDS(p, RPMTAG_ORDERNAME));
while (rpmdsNext(requires) >= 0) {
/* Record next "q <- p" relation (i.e. "p" requires "q"). */
- (void) addRelation(ts, al, p, requires);
+ (void) addRelation(ts, al, p, requires, 0);
+ }
+
+ while (rpmdsNext(recommends) >= 0) {
+ /* Record next "q <- p" relation (i.e. "p" recommends "q"). */
+ (void) addRelation(ts, al, p, recommends, 0);
+ }
+
+ while (rpmdsNext(suggests) >= 0) {
+ /* Record next "q <- p" relation (i.e. "p" suggests "q"). */
+ (void) addRelation(ts, al, p, suggests, 0);
}
while (rpmdsNext(order) >= 0) {
/* Record next "q <- p" ordering request */
- (void) addRelation(ts, al, p, order);
+ (void) addRelation(ts, al, p, order, 0);
+ }
+
+ while (rpmdsNext(supplements) >= 0) {
+ /* Record next "p -> q" relation (i.e. "q" supplemented by "p"). */
+ (void) addRelation(ts, al, p, suggests, 1);
+ }
+
+ while (rpmdsNext(enhances) >= 0) {
+ /* Record next "p <- q" relation (i.e. "q" is enhanced by "p"). */
+ (void) addRelation(ts, al, p, suggests, 1);
}
}