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