tags 291939 patch
retitle 291939 [ARCH] Add support for Architecture aliases/wildcards
thanks

Hi Scott,

I've finally had the time to finish this patch. I've polished the
initial version I showed you at Debconf, moved the read_{cpu,os}table
functions to controllib.pl, thus eliminating the need to expand the
arches externally through dpkg-architecture.

Those aliases will only affect the debian/control file, so will not
change the debian source (.dsc, .changes) or binary format (.deb).
Once the new dpkg source format is introduced the source format
could use the new aliases instead.

The new aliases are:

  <kernel>-any
  linux-<cpu>
  any-<cpu>
  any-any
  all-all

I've not added "all-any" and "any-all" because they do not make
sense right now, but maybe would be nice to have, just for
consistency.

I've added two new commands to dpkg-architecture so other programs
can use the same logic w/o having to reimplement it, also that will
allow adding aliases there and everyone will benefit automagically.
Those are -e<debian-arch> for equality (eq) and -i<arch-alias> for
identity (is). The only problem is that when you set the current
arch with -a it spews a warning, so it's a bit annoying (maybe that
could be removed?).

So you can ask things like:

  - "current arch" eq i386?
    dpkg-architecture -ei386 && echo yes
  - alpha eq linux-alpha?
    dpkg-architecture -aalpha -elinux-alpha 2>/dev/null && echo yes
  - "current arch" is any-sparc?
    dpkg-architecture -iany-sparc && echo yes
  - alpha is linux-any?
    dpkg-architecture -aalpha -ilinux-any 2>/dev/null && echo yes
  - kfreebsd-i386 is any-i386?
    dpkg-architecture -akfreebsd-i386 -iany-i386 2>/dev/null && echo yes

Once this patch is accepted, bug #112325 can be closed as well as
it can be handled with the new wildcards.

Patch attached, apply, rename "scripts/controllib.pl" to
"scripts/controllib.pl.in" and autoreconf. I've included as well two
hackish source packages to test the new stuff, the test-source is for
dpkg-checkbuilddeps and dpkg-source and test-binary for the remaning
stuff, just debuild and check.

regards,
guillem
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 ([EMAIL PROTECTED] || $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 [EMAIL PROTECTED] || $(mkdir_p) `dirname [EMAIL 
PROTECTED]
+       $(do_perl_subst) <$< >$@
+       chmod +x $@
+
 %: %.sh Makefile
        @test -d `dirname [EMAIL PROTECTED] || $(mkdir_p) `dirname [EMAIL 
PROTECTED]
        $(do_shell_subst) <$< >$@

Attachment: dpkg-arch-alias-tests.tgz
Description: GNU Unix tar archive

Reply via email to