Package: dpkg
Version: 1.13.9
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.9.email/scripts/controllib.pl dpkg-1.13.9.arch-alias/scripts/controllib.pl
--- dpkg-1.13.9.email/scripts/controllib.pl	2005-06-06 07:07:12.000000000 +0300
+++ dpkg-1.13.9.arch-alias/scripts/controllib.pl	2005-07-07 15:05:08.000000000 +0300
@@ -80,6 +80,44 @@
     $substvar{'Arch'}= $arch;
 }
 
+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;
+}
+
 sub substvars {
     my ($v) = @_;
     my ($lhs,$vn,$rhs,$count);
@@ -188,17 +226,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.9.email/scripts/dpkg-architecture.pl dpkg-1.13.9.arch-alias/scripts/dpkg-architecture.pl
--- dpkg-1.13.9.email/scripts/dpkg-architecture.pl	2005-06-19 19:42:29.000000000 +0300
+++ dpkg-1.13.9.arch-alias/scripts/dpkg-architecture.pl	2005-06-30 01:26:10.000000000 +0300
@@ -45,6 +45,7 @@
        -f                 force flag (override variables set in environment)
 Actions:
        -l                 list variables (default)
+       -e<alias-arch>     expand Debian architecture alias into real ones.
        -q<variable>       prints only the value of <variable>.
        -s                 print command to set environment variables
        -u                 print command to unset environment variables
@@ -78,6 +79,17 @@
     close OSTABLE;
 }
 
+sub fix_debian
+{
+    local ($os, $cpu) = @_;
+
+    if ($os eq "linux") {
+	return $cpu;
+    } else {
+	return "$os-$cpu";
+    }
+}
+
 sub split_debian {
     local ($_) = @_;
     
@@ -124,11 +136,37 @@
     }
 
     return undef if !defined($cpu) || !defined($os);
-    if ($os eq "linux") {
-	return $cpu;
+    return fix_debian($os, $cpu);
+}
+
+sub expand_debian
+{
+    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.fix_debian($os, $_cpu);
+	}
+    } elsif ($os eq 'any') {
+	foreach my $_os (@os) {
+	    push @list, $not.fix_debian($_os, $cpu);
+	}
     } else {
-	return "$os-$cpu";
+	push @list, $not.fix_debian($os, $cpu);
     }
+
+    return @list;
 }
 
 &read_cputable;
@@ -138,11 +176,7 @@
 if (grep { m/^-L$/ } @ARGV) {
     foreach $os (@os) {
 	foreach $cpu (@cpu) {
-	    if ($os eq "linux") {
-		print "$cpu\n"
-	    } else {
-		print "$os-$cpu\n";
-	    }
+	    print fix_debian($os, $cpu)."\n";
 	}
     }
     exit unless $#ARGV;
@@ -182,6 +216,7 @@
 $req_host_arch = '';
 $req_host_gnu_type = '';
 $req_build_gnu_type = '';
+$req_expand_arch = '';
 $action='l';
 $force=0;
 
@@ -191,6 +226,9 @@
 	$req_host_arch = "$'";
     } elsif (m/^-t/) {
 	$req_host_gnu_type = "$'";
+    } elsif (m/^-e/) {
+	$req_expand_arch = "$'";
+	$action = 'e';
     } elsif (m/^-[lsu]$/) {
 	$action = $_;
 	$action =~ s/^-//;
@@ -282,6 +320,9 @@
     print "export ".join(" ",@ordered)."\n";
 } elsif ($action eq 'u') {
     print "unset ".join(" ",@ordered)."\n";
+} elsif ($action eq 'e') {
+    @arch_list = expand_debian($req_expand_arch);
+    print "@arch_list\n";
 } elsif ($action eq 'c') {
     @ENV{keys %env} = values %env;
     exec @ARGV;
diff -aur dpkg-1.13.9.email/scripts/dpkg-genchanges.pl dpkg-1.13.9.arch-alias/scripts/dpkg-genchanges.pl
--- dpkg-1.13.9.email/scripts/dpkg-genchanges.pl	2005-06-06 07:07:12.000000000 +0300
+++ dpkg-1.13.9.arch-alias/scripts/dpkg-genchanges.pl	2005-06-19 21:29:38.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 (($a eq 'all' && !$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,7 +192,8 @@
 		$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') {
 			$v= '';
diff -aur dpkg-1.13.9.email/scripts/dpkg-gencontrol.pl dpkg-1.13.9.arch-alias/scripts/dpkg-gencontrol.pl
--- dpkg-1.13.9.email/scripts/dpkg-gencontrol.pl	2005-06-06 07:07:12.000000000 +0300
+++ dpkg-1.13.9.arch-alias/scripts/dpkg-gencontrol.pl	2005-06-19 19:17:31.000000000 +0300
@@ -135,11 +135,11 @@
         } elsif (m/^Architecture$/) {
             if ($v eq 'all') {
                 $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;
diff -aur dpkg-1.13.9.email/scripts/dpkg-source.pl dpkg-1.13.9.arch-alias/scripts/dpkg-source.pl
--- dpkg-1.13.9.email/scripts/dpkg-source.pl	2005-06-11 21:59:47.000000000 +0300
+++ dpkg-1.13.9.arch-alias/scripts/dpkg-source.pl	2005-07-07 15:05:29.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+/, `dpkg-architecture -e$_`),
+					 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');
