tags 547724 + patch
thanks

* Sebastian Andrzej Siewior | 2010-06-23 21:37:26 [+0200]:

>-i$arch" while resolving deps. So I guess I sneak some informations
>during the build-process and hack the compare into
>debListParser::ParseDepends().

The patch attached does the work.

Sebastian
>From 2ee48393a1d0b70ac3dbc562b526c68c91671e72 Mon Sep 17 00:00:00 2001
From: Sebastian Andrzej Siewior <sebast...@breakpoint.cc>
Date: Sat, 26 Jun 2010 11:26:08 +0200
Subject: [PATCH] Add debarch_is()

debarch_is() is cloned after the debarch_is() which is included in
libdpkg-perl as a Perl module. The clone should behave like the original. The
included perl script creates a header file which holds the current tripplet
informations.
The debarch_is() is able to match against architectual wildcards like
linux-any or any-powerpc.

Signed-off-by: Sebastian Andrzej Siewior <sebast...@breakpoint.cc>
---
 apt-pkg/create_tripplet_header.pl |  104 +++++++++++++++++++++++++
 apt-pkg/deb/deblistparser.cc      |  153 ++++++++++++++++++++++++++++++++++++-
 apt-pkg/makefile                  |    6 +-
 3 files changed, 260 insertions(+), 3 deletions(-)
 create mode 100755 apt-pkg/create_tripplet_header.pl

diff --git a/apt-pkg/create_tripplet_header.pl 
b/apt-pkg/create_tripplet_header.pl
new file mode 100755
index 0000000..a6920ad
--- /dev/null
+++ b/apt-pkg/create_tripplet_header.pl
@@ -0,0 +1,104 @@
+#!/usr/bin/perl
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+use strict;
+use warnings;
+
+# This piece is from /usr/share/perl5/Dpkg/Arch.pm
+
+my $pkgdatadir="/usr/share/dpkg";
+
+my (@cpu, @os);
+my (%cputable, %ostable);
+my (%cputable_re, %ostable_re);
+my (%cpubits, %cpuendian);
+
+my %debtriplet_to_debarch;
+my %debarch_to_debtriplet;
+
+
+sub read_cputable
+{
+       local $_;
+       local $/ = "\n";
+
+       open CPUTABLE, "$pkgdatadir/cputable"
+               or syserr(_g("cannot open %s"), "cputable");
+       while (<CPUTABLE>) {
+               if (m/^(?!\#)(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)/) {
+                       $cputable{$1} = $2;
+                       $cputable_re{$1} = $3;
+                       $cpubits{$1} = $4;
+                       $cpuendian{$1} = $5;
+                       push @cpu, $1;
+               }
+       }
+       close CPUTABLE;
+}
+
+sub read_triplettable()
+{
+       read_cputable() if (!...@cpu);
+
+       local $_;
+       local $/ = "\n";
+
+       open TRIPLETTABLE, "$pkgdatadir/triplettable"
+               or syserr(_g("cannot open %s"), "triplettable");
+       while (<TRIPLETTABLE>) {
+               if (m/^(?!\#)(\S+)\s+(\S+)/) {
+                       my $debtriplet = $1;
+                       my $debarch = $2;
+
+                       if ($debtriplet =~ /<cpu>/) {
+                               foreach my $_cpu (@cpu) {
+                                       (my $dt = $debtriplet) =~ 
s/<cpu>/$_cpu/;
+                                       (my $da = $debarch) =~ s/<cpu>/$_cpu/;
+
+                                       $debarch_to_debtriplet{$da} = $dt;
+                                       $debtriplet_to_debarch{$dt} = $da;
+                               }
+                       } else {
+                               $debarch_to_debtriplet{$2} = $1;
+                               $debtriplet_to_debarch{$1} = $2;
+                       }
+               }
+       }
+       close TRIPLETTABLE;
+}
+
+{
+       my $k;
+
+       # create the hash
+       read_triplettable();
+
+       # and now dump it into a header file
+
+       print "#ifndef __dpkg_arch__h_\n";
+       print "#define __dpkg_arch__h_\n";
+       print "struct trip_info {\n";
+       print " const char *key;\n";
+       print " const char *val;\n";
+       print "};\n";
+       print "\n";
+
+       print "static struct trip_info debarch_to_triplet[] = {\n";
+       foreach $k (sort (keys(%debarch_to_debtriplet))) {
+               print " { \"" . $k . "\", \"" . $debarch_to_debtriplet{$k} . 
"\" },\n";
+       }
+       print "};\n";
+       print "#define debarch_to_triplet_num " .  keys(%debarch_to_debtriplet);
+       print "\n#endif\n";
+}
diff --git a/apt-pkg/deb/deblistparser.cc b/apt-pkg/deb/deblistparser.cc
index 25b0953..5fd4728 100644
--- a/apt-pkg/deb/deblistparser.cc
+++ b/apt-pkg/deb/deblistparser.cc
@@ -17,6 +17,7 @@
 #include <apt-pkg/crc-16.h>
 #include <apt-pkg/md5.h>
 #include <apt-pkg/macros.h>
+#include <apt-pkg/dpkg_tripplet.h>
 
 #include <ctype.h>
                                                                        /*}}}*/
@@ -376,6 +377,154 @@ const char *debListParser::ConvertRelation(const char 
*I,unsigned int &Op)
    return I;
 }
 
+static int trip_key_cmp(const void *a, const void *b)
+{
+       struct trip_info *h1 = (struct trip_info *)a;
+       struct trip_info *h2 = (struct trip_info *)b;
+
+       return strcmp(h1->key, h2->key);
+}
+
+static const char *search_array(const char *key)
+{
+       struct trip_info k;
+       struct trip_info *ret;
+
+       k.key = key;
+       ret = (struct trip_info *)bsearch((const void *)&k,
+                       (const void *)debarch_to_triplet,
+                       debarch_to_triplet_num, sizeof(struct trip_info),
+                       trip_key_cmp);
+       if (!ret)
+               return NULL;
+       return ret->val;
+}
+
+static const char *debarch_to_debtriplet(const char *arch)
+{
+       const char *s;
+
+       s = arch;
+       if (!strncmp(s, "linux-", sizeof("linux-") - 1))
+               s += sizeof("linux-") - 1;
+       return search_array(s);
+}
+
+static unsigned int count_dashes(const char *wild)
+{
+       unsigned int num = 0;
+
+       while (*wild) {
+               if (*wild == '-')
+                       num++;
+               wild++;
+       }
+       return num;
+}
+
+static char *debwildcard_to_debtriplet(const char *wild)
+{
+       unsigned int num;
+       unsigned int len;
+       char *ret;
+
+       if (!strstr(wild, "any")) {
+               const char *ret_c;
+
+               ret_c = debarch_to_debtriplet(wild);
+               if (!ret_c)
+                       return NULL;
+               return strdup(ret_c);
+       }
+
+       num = count_dashes(wild);
+       switch(num) {
+       case 2:
+               /* gnu-linux-amd64 */
+               ret = strdup(wild);
+               break;
+
+       case 1:
+               /* linux-any */
+               len = strlen(wild);
+
+               /* any- */
+               len += 4 + 1;
+               ret = (char *)malloc(len);
+               if (!ret)
+                       return ret;
+               snprintf(ret, len, "any-%s\n", wild);
+               break;
+
+       default:
+               len = strlen(wild);
+               /* wild-wild-wild */
+               len = len * 3 + 2 + 1;
+               ret = (char *)malloc(len);
+               if (!ret)
+                       return ret;
+
+               snprintf(ret, len, "%s-%s-%s\n", wild, wild, wild);
+               break;
+       }
+       return ret;
+}
+
+static int debarch_is(const char *arch, const char *alias_long, unsigned int 
alen)
+{
+       const char *deb_tripplet_c;
+       char *alias;
+       char *deb_tripplet;
+       char *alias_tripplet;
+       char *deb_parts[3];
+       char *alias_parts[3];
+       char *step;
+       int ret = 0;
+       int i;
+
+       if (!strncmp(arch, alias_long, alen))
+               return 1;
+       if (!strncmp(alias_long, "any", alen))
+               return 1;
+
+       deb_tripplet_c = debarch_to_debtriplet(arch);
+       if (!deb_tripplet_c)
+               return 0;
+       alias = (char *)malloc(alen + 1);
+       if (!alias)
+               return 0;
+       strncpy(alias, alias_long, alen);
+       alias[alen] = '\0';
+
+       deb_tripplet = strdup(deb_tripplet_c);
+       alias_tripplet = debwildcard_to_debtriplet(alias);
+
+       if (!deb_tripplet || !alias_tripplet)
+               goto out;
+
+       step = deb_tripplet;
+       for (i = 0; i < 3; i++)
+               deb_parts[i] = strsep(&step, "-");
+
+       step = alias_tripplet;
+       for (i = 0; i < 3; i++)
+               alias_parts[i] = strsep(&step, "-");
+
+       for (i = 0; i < 3; i++) {
+               if (!deb_parts[i] || !alias_parts[i])
+                       goto out;
+
+               if (strcmp(alias_parts[i], deb_parts[i]) &&
+                       strcmp(alias_parts[i], "any"))
+                       goto out;
+       }
+
+       ret = 1;
+out:
+       free(deb_tripplet);
+       free(alias_tripplet);
+       return ret;
+}
                                                                        /*}}}*/
 // ListParser::ParseDepends - Parse a dependency element               /*{{{*/
 // ---------------------------------------------------------------------
@@ -468,9 +617,9 @@ const char *debListParser::ParseDepends(const char 
*Start,const char *Stop,
               I++;
             }
 
-           if (stringcmp(arch,I,End) == 0)
+           if (debarch_is(arch.c_str(), I, End - I))
               Found = true;
-           
+
            if (*End++ == ']') {
               I = End;
               break;
diff --git a/apt-pkg/makefile b/apt-pkg/makefile
index bdd49c0..575b44f 100644
--- a/apt-pkg/makefile
+++ b/apt-pkg/makefile
@@ -50,8 +50,12 @@ SOURCE+= deb/deblistparser.cc deb/debrecords.cc 
deb/dpkgpm.cc \
          deb/debsrcrecords.cc deb/debversion.cc deb/debsystem.cc \
         deb/debindexfile.cc deb/debindexfile.cc deb/debmetaindex.cc
 HEADERS+= debversion.h debsrcrecords.h dpkgpm.h debrecords.h \
-         deblistparser.h debsystem.h debindexfile.h debmetaindex.h
+         deblistparser.h debsystem.h debindexfile.h debmetaindex.h \
+         dpkg_tripplet.h
 
 HEADERS := $(addprefix apt-pkg/,$(HEADERS))
 
+dpkg_tripplet.h:
+       ./create_tripplet_header.pl >$@
+
 include $(LIBRARY_H)
-- 
1.7.1

Reply via email to