dpkg: Add new deppossi package iterator functions
authorGuillem Jover <guillem@debian.org>
Sat, 5 Nov 2011 13:24:08 +0000 (14:24 +0100)
committerGuillem Jover <guillem@debian.org>
Mon, 16 Jan 2012 07:15:40 +0000 (08:15 +0100)
Since a dependency now points to a pkgset, if you want to find the
correct instance of the package that satisfies the dependency, you
have to take into the account the arch affinity expressed by the
dependency.

The function deppossi_pkg_iter_next() now takes care of this. It
can return multiple packages when the dependency is a wildcard one
(foo:any), you just need to pass the iterator previously created
by deppossi_pkg_iter_new(), and free it with deppossi_pkg_iter_free().

Based-on-patch-by: Raphaël Hertzog <hertzog@debian.org>
Patch-sponsored-by: Linaro Limited
Signed-off-by: Guillem Jover <guillem@debian.org>
src/depcon.c
src/main.h

index 477d47a..1af1ca1 100644 (file)
@@ -3,6 +3,9 @@
  * depcon.c - dependency and conflict checking
  *
  * Copyright © 1994,1995 Ian Jackson <ian@chiark.greenend.org.uk>
+ * Copyright © 2006-2011 Guillem Jover <guillem@debian.org>
+ * Copyright © 2011 Linaro Limited
+ * Copyright © 2011 Raphaël Hertzog <hertzog@debian.org>
  *
  * This is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -26,6 +29,7 @@
 
 #include <assert.h>
 #include <errno.h>
+#include <stdlib.h>
 #include <unistd.h>
 
 #include <dpkg/i18n.h>
 #include "infodb.h"
 #include "main.h"
 
+struct deppossi_pkg_iterator {
+  struct deppossi *possi;
+  struct pkginfo *pkg_next;
+  enum which_pkgbin which_pkgbin;
+};
+
+struct deppossi_pkg_iterator *
+deppossi_pkg_iter_new(struct deppossi *possi, enum which_pkgbin wpb)
+{
+  struct deppossi_pkg_iterator *iter;
+
+  iter = m_malloc(sizeof(*iter));
+  iter->possi = possi;
+  iter->pkg_next = &possi->ed->pkg;
+  iter->which_pkgbin = wpb;
+
+  return iter;
+}
+
+struct pkginfo *
+deppossi_pkg_iter_next(struct deppossi_pkg_iterator *iter)
+{
+  struct pkginfo *pkg_cur;
+  struct pkgbin *pkgbin;
+
+  while ((pkg_cur = iter->pkg_next)) {
+    iter->pkg_next = pkg_cur->arch_next;
+
+    switch (iter->which_pkgbin) {
+    case wpb_installed:
+      pkgbin = &pkg_cur->installed;
+      break;
+    case wpb_available:
+      pkgbin = &pkg_cur->available;
+      break;
+    case wpb_by_istobe:
+      if (pkg_cur->clientdata->istobe == itb_installnew)
+        pkgbin = &pkg_cur->available;
+      else
+        pkgbin = &pkg_cur->installed;
+      break;
+    default:
+      internerr("bad value (%d) for wpb in deppossi_pkg_iter_next()",
+                iter->which_pkgbin);
+    }
+
+    if (archsatisfied(pkgbin, iter->possi))
+      return pkg_cur;
+  }
+
+  return NULL;
+}
+
+void
+deppossi_pkg_iter_free(struct deppossi_pkg_iterator *iter)
+{
+  free(iter);
+}
+
 struct cyclesofarlink {
   struct cyclesofarlink *prev;
   struct pkginfo *pkg;
index 583dedd..ff006f8 100644 (file)
@@ -270,6 +270,21 @@ void trig_activate_packageprocessing(struct pkginfo *pkg);
 
 /* from depcon.c */
 
+enum which_pkgbin {
+  wpb_installed,
+  wpb_available,
+  wpb_by_istobe,
+};
+
+struct deppossi_pkg_iterator;
+
+struct deppossi_pkg_iterator *
+deppossi_pkg_iter_new(struct deppossi *possi, enum which_pkgbin wpb);
+struct pkginfo *
+deppossi_pkg_iter_next(struct deppossi_pkg_iterator *iter);
+void
+deppossi_pkg_iter_free(struct deppossi_pkg_iterator *iter);
+
 bool depisok(struct dependency *dep, struct varbuf *whynot,
              struct pkginfo **fixbyrm, struct pkginfo **fixbytrigaw,
              bool allowunconfigd);