Package: dpkg
Version: 1.13.10
Author: Guillem Jover <guillem@debian.org>
Status: fixed
Debbug: 291939
Description:
 Implement Debian architecture alias support, and export an equality and
 identity operators via the new dpkg-architecture -e and -i actions.
 .
 Will take a virtual arch like <kernel>-any or any-<cpu> and expand to all
 available arches. And will also normalize linux-<cpu> to <cpu> for
 consistency.

diff -aur dpkg-1.13.10.orig/scripts/controllib.pl dpkg-1.13.10/scripts/controllib.pl
--- dpkg-1.13.10.orig/scripts/controllib.pl	2005-06-06 07:07:12.000000000 +0300
+++ dpkg-1.13.10/scripts/controllib.pl	2005-07-23 23:52:17.000000000 +0300
@@ -12,6 +12,8 @@
 #                     "S key" where S is the source and key is the packagename
 # %substvar         - map with substitution variables
 
+$pkgdatadir=".";
+
 $parsechangelog= 'dpkg-parsechangelog';
 
 grep($capit{lc $_}=$_, qw(Pre-Depends Standards-Version Installed-Size
@@ -80,6 +82,114 @@
     $substvar{'Arch'}= $arch;
 }
 
+sub read_cputable {
+    open CPUTABLE, "$pkgdatadir/cputable"
+	or &syserr("unable to open cputable");
+    while (<CPUTABLE>) {
+	if (m/^(?!\#)(\S+)\s+(\S+)\s+(\S+)/) {
+	    $cputable{$1} = $2;
+	    $cputable_re{$1} = $3;
+	    push @cpu, $1;
+	}
+    }
+    close CPUTABLE;
+}
+
+sub read_ostable {
+    open OSTABLE, "$pkgdatadir/ostable"
+	or &syserr("unable to open ostable");
+    while (<OSTABLE>) {
+	if (m/^(?!\#)(\S+)\s+(\S+)\s+(\S+)/) {
+	    $ostable{$1} = $2;
+	    $ostable_re{$1} = $3;
+	    push @os, $1;
+	}
+    }
+    close OSTABLE;
+}
+
+sub debian_arch_fix
+{
+    local ($os, $cpu) = @_;
+
+    if ($os eq "linux") {
+	return $cpu;
+    } else {
+	return "$os-$cpu";
+    }
+}
+
+sub debian_arch_split {
+    local ($_) = @_;
+
+    if (/^([^-]*)-(.*)/) {
+	return ($1, $2);
+    } elsif (/any/ || /all/) {
+	return ($_, $_);
+    } else {
+	return ("linux", $_);
+    }
+}
+
+sub debian_arch_eq {
+    my ($a, $b) = @_;
+    my ($a_os, $a_cpu) = debian_arch_split($a);
+    my ($b_os, $b_cpu) = debian_arch_split($b);
+
+    return ("$a_os-$a_cpu" eq "$b_os-$b_cpu");
+}
+
+sub debian_arch_is {
+    my ($real, $alias) = @_;
+    my ($real_os, $real_cpu) = debian_arch_split($real);
+    my ($alias_os, $alias_cpu) = debian_arch_split($alias);
+
+    if ("$real_os-$real_cpu" eq "$alias_os-$alias_cpu") {
+	return 1;
+    } elsif ("$alias_os-$alias_cpu" eq "any-any") {
+	return 1;
+    } elsif ("$alias_os-$alias_cpu" eq "any-$real_cpu") {
+	return 1;
+    } elsif ("$alias_os-$alias_cpu" eq "$real_os-any") {
+	return 1;
+    }
+
+    return 0;
+}
+
+&read_cputable;
+&read_ostable;
+
+sub debian_arch_expand
+{
+    local ($_) = @_;
+
+    /^(!)?(.*)/;
+
+    local $not = $1;
+    local $arch = $2;
+    local ($os, $cpu) = debian_arch_split($arch);
+    local @list;
+
+    if ("$os-$cpu" eq 'any-any') {
+	@list = 'any';
+    } elsif ($os eq 'all' or $cpu eq 'all') {
+	@list = 'all';
+    } elsif ($cpu eq 'any') {
+	foreach my $_cpu (@cpu) {
+	    push @list, $not.debian_arch_fix($os, $_cpu);
+	}
+    } elsif ($os eq 'any') {
+	foreach my $_os (@os) {
+	    push @list, $not.debian_arch_fix($_os, $cpu);
+	}
+    } else {
+	push @list, $not.debian_arch_fix($os, $cpu);
+    }
+
+    return @list;
+}
+
 sub substvars {
     my ($v) = @_;
     my ($lhs,$vn,$rhs,$count);
@@ -188,17 +298,21 @@
                 my $seen_arch='';
                 foreach my $arch (@arches) {
                     $arch=lc($arch);
-                    if ($arch eq $host_arch) {
+                    if (debian_arch_is($host_arch, $arch)) {
                         $seen_arch=1;
                         next;
-                    } elsif ($arch eq "!$host_arch") {
-                        next ALTERNATE;
-                    } elsif ($arch =~ /!/) {
-                        # This is equivilant to
-                        # having seen the current arch,
-                        # unless the current arch
-                        # is also listed..
-                        $seen_arch=1;
+                    } elsif ($arch =~ /^!/) {
+			($not_arch = $arch) =~ s/^!//;
+
+			if (debian_arch_is($host_arch, $not_arch)) {
+			    next ALTERNATE;
+			} else {
+			    # This is equivilant to
+			    # having seen the current arch,
+			    # unless the current arch
+			    # is also listed..
+			    $seen_arch=1;
+			}
                     }
                 }
                 if (! $seen_arch) {
diff -aur dpkg-1.13.10.orig/scripts/dpkg-architecture.pl dpkg-1.13.10/scripts/dpkg-architecture.pl
--- dpkg-1.13.10.orig/scripts/dpkg-architecture.pl	2005-07-23 23:52:33.000000000 +0300
+++ dpkg-1.13.10/scripts/dpkg-architecture.pl	2005-07-24 00:33:02.000000000 +0300
@@ -26,8 +26,6 @@
 push(@INC,$dpkglibdir);
 require 'controllib.pl';
 
-$pkgdatadir=".";
-
 sub usageversion {
     print STDERR
 "Debian $0 $version.
@@ -39,12 +37,14 @@
 Usage:
   $0 [<option> ...] [<action>]
 Options:
-       -a<debian-arch>    set Debian architecture
-       -t<gnu-system>     set GNU system type 
+       -a<debian-arch>    set current Debian architecture
+       -t<gnu-system>     set current GNU system type
        -L                 list valid architectures
        -f                 force flag (override variables set in environment)
 Actions:
        -l                 list variables (default)
+       -e<debian-arch>    compare the current Debian architecture with the one given
+       -i<arch-alias>     check if current Debian architecture is part of the arch-alias
        -q<variable>       prints only the value of <variable>.
        -s                 print command to set environment variables
        -u                 print command to unset environment variables
@@ -52,32 +52,6 @@
 ";
 }
 
-sub read_cputable {
-    open CPUTABLE, "$pkgdatadir/cputable"
-	or &syserr("unable to open cputable");
-    while (<CPUTABLE>) {
-	if (m/^(?!\#)(\S+)\s+(\S+)\s+(\S+)/) {
-	    $cputable{$1} = $2;
-	    $cputable_re{$1} = $3;
-	    push @cpu, $1;
-	}
-    }
-    close CPUTABLE;
-}
-
-sub read_ostable {
-    open OSTABLE, "$pkgdatadir/ostable"
-	or &syserr("unable to open ostable");
-    while (<OSTABLE>) {
-	if (m/^(?!\#)(\S+)\s+(\S+)\s+(\S+)/) {
-	    $ostable{$1} = $2;
-	    $ostable_re{$1} = $3;
-	    push @os, $1;
-	}
-    }
-    close OSTABLE;
-}
-
 sub split_debian {
     local ($_) = @_;
     
@@ -124,25 +98,14 @@
     }
 
     return undef if !defined($cpu) || !defined($os);
-    if ($os eq "linux") {
-	return $cpu;
-    } else {
-	return "$os-$cpu";
-    }
+    return debian_arch_fix($os, $cpu);
 }
 
-&read_cputable;
-&read_ostable;
-
 # Check for -L
 if (grep { m/^-L$/ } @ARGV) {
     foreach $os (@os) {
 	foreach $cpu (@cpu) {
-	    if ($os eq "linux") {
-		print "$cpu\n"
-	    } else {
-		print "$os-$cpu\n";
-	    }
+	    print debian_arch_fix($os, $cpu)."\n";
 	}
     }
     exit unless $#ARGV;
@@ -182,6 +145,8 @@
 $req_host_arch = '';
 $req_host_gnu_type = '';
 $req_build_gnu_type = '';
+$req_eq_arch = '';
+$req_is_arch = '';
 $action='l';
 $force=0;
 
@@ -191,6 +156,12 @@
 	$req_host_arch = "$'";
     } elsif (m/^-t/) {
 	$req_host_gnu_type = "$'";
+    } elsif (m/^-e/) {
+	$req_eq_arch = "$'";
+	$action = 'e';
+    } elsif (m/^-i/) {
+	$req_is_arch = "$'";
+	$action = 'i';
     } elsif (m/^-[lsu]$/) {
 	$action = $_;
 	$action =~ s/^-//;
@@ -282,6 +253,10 @@
     print "export ".join(" ",@ordered)."\n";
 } elsif ($action eq 'u') {
     print "unset ".join(" ",@ordered)."\n";
+} elsif ($action eq 'e') {
+    exit !debian_arch_eq($deb_host_arch, $req_eq_arch);
+} elsif ($action eq 'i') {
+    exit !debian_arch_is($deb_host_arch, $req_is_arch);
 } elsif ($action eq 'c') {
     @ENV{keys %env} = values %env;
     exec @ARGV;
diff -aur dpkg-1.13.10.orig/scripts/dpkg-genchanges.pl dpkg-1.13.10/scripts/dpkg-genchanges.pl
--- dpkg-1.13.10.orig/scripts/dpkg-genchanges.pl	2005-06-06 07:07:12.000000000 +0300
+++ dpkg-1.13.10/scripts/dpkg-genchanges.pl	2005-07-12 20:57:52.000000000 +0300
@@ -168,8 +168,9 @@
     } elsif (s/^C(\d+) //) {
 	$i=$1; $p=$fi{"C$i Package"}; $a=$fi{"C$i Architecture"};
 	if (!defined($p2f{$p}) && not $sourceonly) {
-	    if ($a eq 'any' || ($a eq 'all' && !$archspecific) ||
-		grep($_ eq $substvar{'Arch'}, split(/\s+/, $a))) {
+	    if ((debian_arch_eq('all', $a) && !$archspecific) ||
+		debian_arch_is($arch, $a) ||
+		grep(debian_arch_is($arch, $_), split(/\s+/, $a))) {
 		&warn("package $p in control file but not in files list");
 		next;
 	    }
@@ -191,9 +192,10 @@
 		$f{$_}= $v;
 	    } elsif (m/^Architecture$/) {
 		if (not $sourceonly) {
-		    if ($v eq 'any' || grep($_ eq $arch, split(/\s+/, $v))) {
+		    if (debian_arch_is($arch, $v) ||
+			grep(debian_arch_is($arch, $_), split(/\s+/, $v))) {
 			$v= $arch;
-		    } elsif ($v ne 'all') {
+		    } elsif (!debian_arch_eq('all', $v)) {
 			$v= '';
 		    }
 		} else {
@@ -315,7 +317,7 @@
 
 $f{'Files'}= '';
 for $f (@sourcefiles,@fileslistfiles) {
-    next if ($archspecific && ($p2arch{$f2p{$f}} eq 'all'));
+    next if ($archspecific && debian_arch_eq('all', $p2arch{$f2p{$f}}));
     next if $filedone{$f}++;
     $uf= "$uploadfilesdir/$f";
     open(STDIN,"< $uf") || &syserr("cannot open upload file $uf for reading");
diff -aur dpkg-1.13.10.orig/scripts/dpkg-gencontrol.pl dpkg-1.13.10/scripts/dpkg-gencontrol.pl
--- dpkg-1.13.10.orig/scripts/dpkg-gencontrol.pl	2005-06-06 07:07:12.000000000 +0300
+++ dpkg-1.13.10/scripts/dpkg-gencontrol.pl	2005-07-12 20:57:52.000000000 +0300
@@ -133,13 +133,13 @@
         } elsif (m/^Section$|^Priority$/) {
             $spvalue{$_}= $v;
         } elsif (m/^Architecture$/) {
-            if ($v eq 'all') {
+            if (debian_arch_eq('all', $v)) {
                 $f{$_}= $v;
-            } elsif ($v eq 'any') {
+            } elsif (debian_arch_is($arch, $v)) {
                 $f{$_}= $arch;
             } else {
                 @archlist= split(/\s+/,$v);
-                grep($arch eq $_, @archlist) ||
+                grep(debian_arch_is($arch, $_), @archlist) ||
                     &error("current build architecture $arch does not".
                            " appear in package's list (@archlist)");
                 $f{$_}= $arch;
@@ -243,7 +243,8 @@
     while (<X>) {
         chomp;
         next if m/^([-+0-9a-z.]+)_[^_]+_([\w-]+)\.deb /
-                && ($1 eq $oppackage) && ($2 eq $arch || $2 eq 'all');
+                && ($1 eq $oppackage)
+                && (debian_arch_eq($2, $arch) || debian_arch_eq($2, 'all'));
         print(Y "$_\n") || &syserr("copy old entry to new files list file");
     }
     close(X) || &syserr("close old files list file");
diff -aur dpkg-1.13.10.orig/scripts/dpkg-source.pl dpkg-1.13.10/scripts/dpkg-source.pl
--- dpkg-1.13.10.orig/scripts/dpkg-source.pl	2005-06-13 20:47:34.000000000 +0300
+++ dpkg-1.13.10/scripts/dpkg-source.pl	2005-07-12 21:25:03.000000000 +0300
@@ -161,9 +161,9 @@
             $i=$1; $p=$fi{"C$i Package"};
             push(@binarypackages,$p) unless $packageadded{$p}++;
             if (m/^Architecture$/) {
-                if ($v eq 'any') {
+                if (debian_arch_eq($v, 'any')) {
                     @sourcearch= ('any');
-                } elsif ($v eq 'all') {
+                } elsif (debian_arch_eq($v, 'all')) {
                     if (!@sourcearch || $sourcearch[0] eq 'all') {
                         @sourcearch= ('all');
                     } else {
@@ -173,7 +173,10 @@
 		    if (grep($sourcearch[0] eq $_, 'any','all'))  {
 			@sourcearch= ('any');
 		    } else {
-                        for $a (split(/\s+/,$v)) {
+			my @arches = map(split(/\s+/, debian_arch_expand($_)),
+					 split(/\s+/, $v));
+			chomp @arches;
+			for $a (@arches) {
                             &error("architecture $a only allowed on its own".
                                    " (list for package $p is `$a')")
                                    if grep($a eq $_, 'any','all');
diff -aur dpkg-1.13.10.orig/scripts/Makefile.am dpkg-1.13.10/scripts/Makefile.am
--- dpkg-1.13.10.orig/scripts/Makefile.am	2005-06-06 07:07:12.000000000 +0300
+++ dpkg-1.13.10/scripts/Makefile.am	2005-07-24 01:18:03.000000000 +0300
@@ -70,6 +70,11 @@
 	$(do_perl_subst) <$< >$@
 	chmod +x $@
 
+%.pl: %.pl.in Makefile
+	@test -d `dirname $@` || $(mkdir_p) `dirname $@`
+	$(do_perl_subst) <$< >$@
+	chmod +x $@
+
 %: %.sh Makefile
 	@test -d `dirname $@` || $(mkdir_p) `dirname $@`
 	$(do_shell_subst) <$< >$@
