The following commit has been merged in the master branch:
commit 64fb693c7628bd21d9bc79ecbf8171f9f7a38450
Author: Steve Langasek <[email protected]>
Date:   Sun Aug 30 01:31:27 2009 -0700

    libdpkg: Allow pkg:arch syntax in package relationship fields
    
    Implement support for the packagename:archname syntax in package
    relationships, required for multiarch.
    
    Also, the only architecture value currently allowed is “any”, consistent
    with round one of <https://wiki.ubuntu.com/MultiarchSpec>. This may be
    relaxed before the wheezy release to allow for arch-specific cross
    dependencies in the next release, but should probably not be relaxed
    for package generation in order to avoid accidental archive uploads of
    uninstallable packages.
    
    [[email protected]:
     - Rearrange struct deppossi for better memory alignment.
     - Do not print the arch qualifier if arch_none instead of NULL.
     - Check against arch_wildcard instead of the literal string.
     - Check archlength == 0 instead of arch[0] being NUL. ]
    
    Signed-off-by: Guillem Jover <[email protected]>

diff --git a/lib/dpkg/dpkg-db.h b/lib/dpkg/dpkg-db.h
index 727d78b..7f2b125 100644
--- a/lib/dpkg/dpkg-db.h
+++ b/lib/dpkg/dpkg-db.h
@@ -72,8 +72,10 @@ struct deppossi {
   struct dependency *up;
   struct pkgset *ed;
   struct deppossi *next, *rev_next, *rev_prev;
+  const struct dpkg_arch *arch;
   struct versionrevision version;
   enum depverrel verrel;
+  bool arch_is_implicit;
   bool cyclebreak;
 };
 
diff --git a/lib/dpkg/dump.c b/lib/dpkg/dump.c
index 86b3dff..4f4c733 100644
--- a/lib/dpkg/dump.c
+++ b/lib/dpkg/dump.c
@@ -283,6 +283,10 @@ void varbufdependency(struct varbuf *vb, struct dependency 
*dep) {
     varbuf_add_str(vb, possdel);
     possdel = " | ";
     varbuf_add_str(vb, dop->ed->name);
+    if (!dop->arch_is_implicit && dop->arch->type != arch_none) {
+      varbuf_add_char(vb, ':');
+      varbuf_add_str(vb, dop->arch->name);
+    }
     if (dop->verrel != dvr_none) {
       varbuf_add_str(vb, " (");
       switch (dop->verrel) {
diff --git a/lib/dpkg/fields.c b/lib/dpkg/fields.c
index 6b4a0f9..8d6e9bf 100644
--- a/lib/dpkg/fields.c
+++ b/lib/dpkg/fields.c
@@ -5,6 +5,7 @@
  * Copyright © 1995 Ian Jackson <[email protected]>
  * Copyright © 2001 Wichert Akkerman
  * Copyright © 2006-2011 Guillem Jover <[email protected]>
+ * Copyright © 2009 Canonical Ltd.
  * Copyright © 2011 Linaro Limited
  * Copyright © 2011 Raphaël Hertzog <[email protected]>
  *
@@ -32,6 +33,7 @@
 #include <dpkg/i18n.h>
 #include <dpkg/dpkg.h>
 #include <dpkg/dpkg-db.h>
+#include <dpkg/arch.h>
 #include <dpkg/path.h>
 #include <dpkg/parsedump.h>
 #include <dpkg/triglib.h>
@@ -386,9 +388,9 @@ f_dependency(struct pkginfo *pigp, struct pkgbin *pifp,
     for (;;) {
       depnamestart= p;
       /* Skip over package name characters. */
-      while (*p && !isspace(*p) && *p != '(' && *p != ',' && *p != '|') {
-       p++;
-      }
+      while (*p && !isspace(*p) && *p != ':' && *p != '(' && *p != ',' &&
+             *p != '|')
+        p++;
       depnamelength= p - depnamestart ;
       if (depnamelength == 0)
         parse_error(ps,
@@ -420,6 +422,48 @@ f_dependency(struct pkginfo *pigp, struct pkgbin *pifp,
 
       dop->cyclebreak = false;
 
+      /* See if we have an architecture qualifier. */
+      if (*p == ':') {
+        static struct varbuf arch;
+        const char *archstart;
+        int archlength;
+
+        archstart = ++p;
+        while (*p && !isspace(*p) && *p != '(' && *p != ',' && *p != '|')
+          p++;
+        archlength = p - archstart;
+        if (archlength == 0)
+          parse_error(ps, _("'%s' field, missing architecture name, or garbage 
"
+                            "where architecture name expected"), fip->name);
+
+        varbuf_reset(&arch);
+        varbuf_add_buf(&arch, archstart, archlength);
+        varbuf_end_str(&arch);
+
+        dop->arch_is_implicit = false;
+        dop->arch = dpkg_arch_find(arch.buf);
+
+        if (dop->arch->type == arch_illegal)
+          emsg = dpkg_arch_name_is_illegal(arch.buf);
+        else if (dop->arch->type != arch_wildcard)
+          emsg = _("a value different from 'any' is currently not allowed");
+        if (emsg)
+          parse_error(ps, _("'%s' field, reference to '%.255s': "
+                            "invalid architecture name '%.255s': %s"),
+                      fip->name, depname.buf, arch.buf, emsg);
+      } else if (fip->integer == dep_conflicts || fip->integer == dep_breaks ||
+                 fip->integer == dep_replaces) {
+        /* Conflics/Breaks/Replaces get an implicit "any" arch qualifier. */
+        dop->arch_is_implicit = true;
+        dop->arch = dpkg_arch_find("any");
+      } else {
+        /* Otherwise use the pkgbin architecture, which will be assigned to
+         * later on by parse.c, once we can guarantee we have parsed it from
+         * the control stanza. */
+        dop->arch_is_implicit = true;
+        dop->arch = NULL;
+      }
+
       /* Skip whitespace after package name. */
       while (isspace(*p)) p++;
 
diff --git a/lib/dpkg/parse.c b/lib/dpkg/parse.c
index c84f6b4..4611356 100644
--- a/lib/dpkg/parse.c
+++ b/lib/dpkg/parse.c
@@ -170,6 +170,9 @@ static void
 pkg_parse_verify(struct parsedb_state *ps,
                  struct pkginfo *pkg, struct pkgbin *pkgbin)
 {
+  struct dependency *dep;
+  struct deppossi *dop;
+
   parse_must_have_field(ps, pkg->set->name, "package name");
 
   /* XXX: We need to check for status != stat_halfinstalled as while
@@ -204,6 +207,12 @@ pkg_parse_verify(struct parsedb_state *ps,
     parse_error(ps, _("package has field '%s' but is architecture all"),
                 "Multi-Arch: same");
 
+  /* Initialize deps to be arch-specific unless stated otherwise. */
+  for (dep = pkgbin->depends; dep; dep = dep->next)
+    for (dop = dep->list; dop; dop = dop->next)
+      if (!dop->arch)
+        dop->arch = pkgbin->arch;
+
   /* Check the Config-Version information:
    * If there is a Config-Version it is definitely to be used, but
    * there shouldn't be one if the package is ‘installed’ (in which case
diff --git a/src/processarc.c b/src/processarc.c
index cfda85e..802e9a2 100644
--- a/src/processarc.c
+++ b/src/processarc.c
@@ -1091,6 +1091,8 @@ void process_archive(const char *filename) {
       newpossi->ed= possi->ed;
       newpossi->next = NULL;
       newpossi->rev_next = newpossi->rev_prev = NULL;
+      newpossi->arch_is_implicit = possi->arch_is_implicit;
+      newpossi->arch = possi->arch;
       newpossi->verrel= possi->verrel;
       if (possi->verrel != dvr_none)
         newpossi->version= possi->version;

-- 
dpkg's main repository


-- 
To UNSUBSCRIBE, email to [email protected]
with a subject of "unsubscribe". Trouble? Contact [email protected]

Reply via email to