From decd7e619ee629b5bee0d2a597679cbf58457977 Mon Sep 17 00:00:00 2001 From: Florian Festi Date: Fri, 25 Nov 2016 13:31:31 +0100 Subject: [PATCH] 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. --- lib/order.c | 84 ++++++++++++++++++++++++++++++++++++++++++++--------- 1 file 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); } }