From c44510ade109455a6771f00b2c537d9a1068b659 Mon Sep 17 00:00:00 2001 From: Werner Almesberger Date: Sun, 21 Nov 2010 23:51:35 -0300 Subject: [PATCH] qpkg: detect conflicts with installed packages - prereq.c (installed_conflicts, free_conflicts, prereq): collect list of pre-existing conflicts in installed packages - prereq.c (prereq): check if package being requested already conflicts - test/instconf: regression test for conflicts with installed packages - TODO: updated for full support of conflicts. Mention that we're not terribly efficient with handling conflicts. --- qpkg/TODO | 15 ++++++++------ qpkg/prereq.c | 47 ++++++++++++++++++++++++++++++++++++++++--- qpkg/test/instconf | 50 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 103 insertions(+), 9 deletions(-) create mode 100755 qpkg/test/instconf diff --git a/qpkg/TODO b/qpkg/TODO index f95cc41..f3cf69f 100644 --- a/qpkg/TODO +++ b/qpkg/TODO @@ -1,12 +1,8 @@ Still left to do ================ -- check whether introducing a new package would cause a conflict - - Update: conflicts among the packages considered for installation are now - checked. - -- compile the list of conflicts of installed packages +- consider reducing the size of the lists of conflicts, e.g., by making + them unique via a red-black tree - handle Provides: @@ -53,3 +49,10 @@ Done 1172642 calls to comp_id, or 102% of the predicted "good case". - if there are multiple choices, try to prefer more recent versions + +- check whether introducing a new package would cause a conflict + + Update: conflicts among the packages considered for installation are now + checked. + +- compile the list of conflicts of installed packages diff --git a/qpkg/prereq.c b/qpkg/prereq.c index d7e330a..f00e9f6 100644 --- a/qpkg/prereq.c +++ b/qpkg/prereq.c @@ -16,9 +16,9 @@ #include #include +#include "util.h" #include "id.h" #include "qpkg.h" -#include "util.h" #include "prereq.h" @@ -221,6 +221,42 @@ static void resolve(struct list *next_dep, const struct ref *dep, } +static struct list *installed_conflicts(void) +{ + struct list *list = NULL, *new; + const struct jrb *n; + const struct pkg *pkg; + + for (n = jrb_first(packages->root); n != jrb_nil(packages->root); + n = jrb_next(n)) { + pkg = n->val; + if (!pkg) + continue; + if (!(pkg->flags & QPKG_INSTALLED)) + continue; + if (!pkg->conflicts) /* optimization */ + continue; + new = alloc_type(struct list); + new->refs = pkg->conflicts; + new->next = list; + list = new; + } + return list; +} + + +static void free_conflicts(struct list *conf) +{ + struct list *next; + + while (conf) { + next = conf->next; + free(conf); + conf = next; + } +} + + struct pkg **prereq(struct pkg *pkg) { struct stack stack = { @@ -229,13 +265,18 @@ struct pkg **prereq(struct pkg *pkg) }; struct list conf = { .refs = pkg->conflicts, - .next = NULL + .next = installed_conflicts() }; - /* @@@ make list of pre-existing conflicts */ + if (conflicts(pkg, &conf)) { + fprintf(stderr, "%.*s conflicts with installed packages\n", + ID2PF(pkg->id)); + exit(1); + } pkg->flags |= QPKG_ADDING; resolve(NULL, pkg->depends, &stack, &conf); pkg->flags &= ~QPKG_ADDING; free(installs); + free_conflicts(conf.next); return best; } diff --git a/qpkg/test/instconf b/qpkg/test/instconf new file mode 100755 index 0000000..853528f --- /dev/null +++ b/qpkg/test/instconf @@ -0,0 +1,50 @@ +#!/bin/sh +. ./Common + +############################################################################### + +qpkg_fail "installed package conflicts with dependency" prereq A <