+Sun, 14 Sep 2003 21:16:18 -0500 Adam Heath <doogie@debian.org>
+
+ * scripts/controllib.pl, scripts/dpkg-checkbuilddeps.pl: Moved dependency
+ parsing logic from dpkg-checkbuilddeps. The dpkg-checkbuilddeps parser
+ didn't support empty fields, while the controllib parser did.
+ * scripts/controllib.pl:
+ * Dependency fields are now parsed into a nested list structure.
+ * All dependency fields now support [arch] constructs. Those that
+ don't apply for the current host_arch are removed during parsing.
+ * Comment lines(those that start with '#') are ignored during parsing.
+ * Store the original field's casing with 'o:' prepended in %fi.
+ * scripts/dpkg-checkbuilddeps.pl: Because of the above controllib.pl
+ changes, this script is much simpler now.
+ * scripts/dpkg-gencontrol.pl:
+ * Use the original casing of field names when reporting unknown fields.
+ * scripts/dpkg-gencontrol.pl, scripts/controllib.pl: After opening files,
+ set binmode.
+
Sun Sep 14 17:24:20 CDT 2003 Adam Heath <doogie@debian.org>
* dselect/{Makefile.in,helpmsgs.{cc,h,src},mkhelpmsgs.pl,.cvsignore}:
* Updated config.sub and config.guess in cvs.
* Change use of strncpy in parsedb to memcpy. Closes: #160447
* No longer generate helpmsgs.{cc,h}.
+ * several controllib changes:
+ * Moved dependency parsing logic from dpkg-checkbuilddeps.
+ The dpkg-checkbuilddeps parser didn't support empty fields, while
+ the controllib parser did.
+ * All dependency fields parsed by controllib.pl support [arch]
+ specifiers. If the arch specifier doesn't apply for the current
+ arch, then the item will not be added to the internal list structure.
+ * Comment lines(that begin with '#') are removed during parsing.
+ * Store the original casing of field names, for use in error reporting.
+ * Store the original field's casing with 'o:' prepended in %fi.
+ * ballombe@merulo.debian.org:
+ dpkg-checkbuilddeps now handles empty fields. Closes: #111562
+ * Branden Robinson <branden@debian.org>:
+ support comments(first char on line begins with '#') in
+ debian/control. Closes: #191810
+ * Bastian Blank <waldi@debian.org>:
+ Allow for per-arch generated dependency fields. Closes: #170575
+ * Branden Robinson <branden@debian.org>:
+ Report the original casing of field names when they are unknown.
+ Closes: #177753
* Frank Lichtenheld <frank@lichtenheld.de>:
Apply patch, to handle missing infodir.bak, and empty files. Closes:
#196361
* Eduard Bloch <edi@gmx.de>:
Apply patch to check whether the target path exists on removing.
Closes: #37254
+ * Colin Walters <walters@debian.org>:
+ After opening files, set binmode. Closes: #175363
- -- Wichert Akkerman <debian@extern.wiggy.net> UNRELEASED
+ -- Wichert Akkerman <debian@extern.wiggy.net> Sun, 14 Sep 2003 20:15:31 -0500
dpkg (1.10.10) unstable; urgency=low
Origin: debian
Bugs: debbugs://bugs.debian.org
Standards-Version: 3.5.8
-Build-Depends: debiandoc-sgml, sgml-base (>= 1.9.1), sgmltools-lite, libncurses-dev, gettext (>= 0.12.1-3), zlib1g-dev (>= 1:1.1.3-19.1), autotools-dev
+Build-Depends: debiandoc-sgml, sgml-base (>= 1.9.1), sgmltools-lite, libncurses-dev, gettext (>= 0.12.1-3), zlib1g-dev (>= 1:1.1.3-19.1), autotools-dev, foo, bar
+# This is a comment
Uploaders: Wichert Akkerman <wakkerma@debian.org>, Adam Heath <doogie@debian.org>
+# And another comment
Package: dpkg
Architecture: any
-Essential: yes
+urce: yes
Pre-Depends: dselect, ${shlibs:Pre-Depends}
-Conflicts: sysvinit (<< 2.82-1), dpkg-iasearch (<< 0.11), dpkg-static, dpkg-dev (<< 1.9)
+Conflicts: sysvinit (<< 2.82-1), dpkg-iasearch (<< 0.11), dpkg-static, dpkg-dev (<< 1.9), foo [s390]
Replaces: dpkg-doc-ja, dpkg-static, manpages-de (<= 0.4-3)
Description: Package maintenance system for Debian
This package contains the programs which handle the installation and
grep($capit{lc $_}=$_, qw(Pre-Depends Standards-Version Installed-Size
Build-Depends Build-Depends-Indep
Build-Conflicts Build-Conflicts-Indep));
-
+@pkg_dep_fields = qw(Replaces Provides Depends Pre-Depends Recommends Suggests
+ Conflicts Enhances);
+@src_dep_fields = qw(Build-Depends Build-Depends-Indep
+ Build-Conflicts Build-Conflicts-Indep);
$substvar{'Format'}= 1.7;
$substvar{'Newline'}= "\n";
if (length($varlistfile) and $dosubstvars) {
$varlistfile="./$varlistfile" if $varlistfile =~ m/\s/;
if (open(SV,"< $varlistfile")) {
+ binmode(SV);
while (<SV>) {
next if m/^\#/ || !m/\S/;
s/\s*\n$//;
$controlfile="./$controlfile" if $controlfile =~ m/^\s/;
open(CDATA,"< $controlfile") || &error("cannot read control file $controlfile: $!");
+ binmode(CDATA);
$indices= &parsecdata('C',1,"control file $controlfile");
$indices >= 2 || &error("control file must have at least one binary package part");
defined($fi{"C$i Package"}) ||
&error("per-package paragraph $i in control info file is ".
"missing Package line");
+ foreach my $dep_field (@pkg_dep_fields) {
+ if (defined($fi{"C$i $dep_field"})) {
+ ($fi{"C$i $dep_field"} = parsedep($fi{"C$i $dep_field"}, 1, 1)) ||
+ &error("per-package paragraph $i in control info file ".
+ "invalid dependency field \`$dep_field'");
+ }
+ }
+ }
+ foreach my $dep_field (@src_dep_fields) {
+ if (defined($fi{"C $dep_field"})) {
+ ($fi{"C $dep_field"} = parsedep($fi{"C $dep_field"}, 1, 1)) ||
+ &error("source paragraph in control info file ".
+ "invalid dependency field \`$dep_field'");
+ }
+ }
+}
+
+sub parsedep {
+ my ($dep_line, $use_arch, $reduce_arch) = @_;
+ my @dep_list;
+ foreach my $dep_and (split(/,\s*/m, $dep_line)) {
+ my @or_list = ();
+ALTERNATE:
+ foreach my $dep_or (split(/\s*\|\s*/m, $dep_and)) {
+ my ($package, $relation, $version);
+ $package = $1 if ($dep_or =~ s/^(\S+)\s*//m);
+ ($relation, $version) = ($1, $2) if ($dep_or =~ s/^\((=|<=|>=|<<?|>>?)\s*([^)]+).*\)//m);
+ my @arches = split(/\s+/m, $1) if ($use_arch && $dep_or =~ s/^\[([^]]+)\]//m);
+ if ($reduce_arch && @arches) {
+
+ my $seen_arch='';
+ foreach my $arch (@arches) {
+ $arch=lc($arch);
+ if ($arch eq $host_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;
+ }
+ }
+ if (! $seen_arch) {
+ next;
+ }
+ }
+ return undef if (length($dep_or));
+ push @or_list, [ $package, $relation, $version, \@arches ];
+ }
+ push @dep_list, \@or_list;
+ }
+ \@dep_list;
+}
+
+sub showdep {
+ my ($dep_list, $show_arch) = @_;
+ my @and_list;
+ foreach my $dep_and (@$dep_list) {
+ my @or_list = ();
+ foreach my $dep_or (@$dep_and) {
+ my ($package, $relation, $version, $arch_list) = @$dep_or;
+ push @or_list, $package . ($relation && $version ? " ($relation $version)" : '') . ($show_arch && @$arch_list ? " [@$arch_list]" : '');
+ }
+ push @and_list, join(' | ', @or_list);
}
+ join(', ', @and_list);
}
sub parsechangelog {
defined($c=open(CDATA,"-|")) || &syserr("fork for parse changelog");
+ binmode(CDATA);
if (!$c) {
@al=($parsechangelog);
push(@al,"-F$changelogformat") if length($changelogformat);
while (<CDATA>) {
s/\s*\n$//;
next if (m/^$/ and $paraborder);
+ next if (m/^#/);
$paraborder=0;
if (m/^(\S+)\s*:\s*(.*)$/) {
$cf=$1; $v=$2;
$cf= &capit($cf);
$fi{"$source$index $cf"}= $v;
+ $fi{"o:$source$index $cf"}= $1;
if (lc $cf eq 'package') { $p2i{"$source $v"}= $index; }
} elsif (m/^\s+\S/) {
length($cf) || &syntax("continued value line not in field");
}
sub unknown {
- &warn("unknown information field $_ in input data in $_[0]");
+ &warn("unknown information field " . $fi{"o:$_"} . " in input data in $_[0]");
}
sub syntax {
-#!/usr/bin/perl -w
+#!/usr/bin/perl
# GPL copyright 2001 by Joey Hess <joeyh@debian.org>
-use strict;
+#use strict;
use Getopt::Long;
+my $dpkglibdir="/usr/lib/dpkg";
+push(@INC,$dpkglibdir);
+#my $controlfile;
+require 'controllib.pl';
+
sub usage {
print STDERR <<EOF;
Usage: dpkg-checkbuild [-B] [control-file]
}
my $control=shift || "debian/control";
+$controlfile=$control;
-open (CONTROL, $control) || die "$control: $!\n";
+&parsecontrolfile;
my @status=parse_status();
my (@unmet, @conflicts);
local $/='';
-my $cdata=<CONTROL>;
-close CONTROL;
-my $dep_regex=qr/\s*((.|\n\s+)*)\s/; # allow multi-line
-if ($cdata =~ /^Build-Depends:$dep_regex/mi) {
- push @unmet, build_depends($1, @status);
+my $dep_regex=qr/[ \t]*(([^\n]+|\n[ \t])*)\s/; # allow multi-line
+if (defined($fi{"C Build-Depends"})) {
+ push @unmet, build_depends($fi{"C Build-Depends"}, @status);
}
-if ($cdata =~ /^Build-Conflicts:$dep_regex/mi) {
- push @conflicts, build_conflicts($1, @status);
+if (defined($fi{"C Build-Conflicts"})) {
+ push @unmet, build_conflicts($fi{"C Build-Conflicts"}, @status);
}
-if (! $binary_only && $cdata =~ /^Build-Depends-Indep:$dep_regex/mi) {
- push @unmet, build_depends($1, @status);
+if (! $binary_only && defined($fi{"C Build-Depends-Indep"})) {
+ push @unmet, build_depends($fi{"C Build-Depends-Indep"}, @status);
}
-if (! $binary_only && $cdata =~ /^Build-Conflicts-Indep:$dep_regex/mi) {
- push @conflicts, build_conflicts($1, @status);
+if (! $binary_only && defined($fi{"C Build-Conflicts-Indep"})) {
+ push @unmet, build_conflicts($fi{"C Build-Conflicts-Indep"}, @status);
}
if (@unmet) {
# deps, and 0 to check build conflicts.
sub check_line {
my $build_depends=shift;
- my $line=shift;
+ my $dep_list=shift;
my %version=%{shift()};
my %providers=%{shift()};
my $host_arch=shift || `dpkg-architecture -qDEB_HOST_ARCH`;
chomp $host_arch;
my @unmet=();
- foreach my $dep (split(/,\s*/, $line)) {
+ foreach my $dep_and (@$dep_list) {
my $ok=0;
my @possibles=();
-ALTERNATE: foreach my $alternate (split(/\s*\|\s*/, $dep)) {
- my ($package, $rest)=split(/\s*(?=[[(])/, $alternate, 2);
- $package =~ s/\s*$//;
-
- # Check arch specifications.
- if (defined $rest && $rest=~m/\[(.*?)\]/) {
- my $arches=lc($1);
- my $seen_arch='';
- foreach my $arch (split(' ', $arches)) {
- if ($arch eq $host_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;
- }
- }
- if (! $seen_arch) {
- next;
- }
- }
-
+ALTERNATE: foreach my $alternate (@$dep_and) {
+ my ($package, $relation, $version, $arch_list)= @{$alternate};
+
# This is a possibile way to meet the dependency.
# Remove the arch stuff from $alternate.
- $alternate=~s/\s+\[.*?\]//;
- push @possibles, $alternate;
+ push @possibles, $package . ($relation && $version ? " ($relation $version)" : '') . (@$arch_list ? " [@$arch_list]" : '');
- # Check version.
- if (defined $rest && $rest=~m/\(\s*([<>=]{1,2})\s*(.*?)\s*\)/) {
- my $relation=$1;
- my $version=$2;
-
+ if ($relation && $version) {
if (! exists $version{$package}) {
# Not installed at all, so fail.
next;
# nothing provides it, so fail.
next;
}
-
# If we get to here, the dependency was met.
$ok=1;
}
#print STDERR "myindex $myindex\n";
+my %pkg_dep_fields = map { $_ => 1 } @pkg_dep_fields;
+
for $_ (keys %fi) {
$v= $fi{$_};
if (s/^C //) {
elsif (s/^X[CS]*B[CS]*-//i) { $f{$_}= $v; }
elsif (m/^X[CS]+-|^(Standards-Version|Uploaders)$|^Build-(Depends|Conflicts)(-Indep)?$/i) { }
elsif (m/^Section$|^Priority$/) { $spdefault{$_}= $v; }
- else { &unknown('general section of control info file'); }
+ else { $_ = "C $_"; &unknown('general section of control info file'); }
} elsif (s/^C$myindex //) {
#print STDERR "P key >$_< value >$v<\n";
- if (m/^(Package|Description|Essential|Pre-Depends|Depends)$/ ||
- m/^(Recommends|Suggests|Enhances|Optional|Conflicts|Provides|Replaces)$/) {
+ if (m/^(Package|Description|Essential|Optional)$/) {
$f{$_}= $v;
+ } elsif (exists($pkg_dep_fields{$_})) {
+ $f{$_}= showdep($v, 0);
} elsif (m/^Section$|^Priority$/) {
$spvalue{$_}= $v;
} elsif (m/^Architecture$/) {
} elsif (s/^X[CS]*B[CS]*-//i) {
$f{$_}= $v;
} elsif (!m/^X[CS]+-/i) {
- &unknown("package's section of control info file");
+ $_ = "C$myindex $_"; &unknown("package's section of control info file");
}
} elsif (m/^C\d+ /) {
#print STDERR "X key >$_< value not shown<\n";
} elsif (s/^X[CS]*B[CS]*-//i) {
$f{$_}= $v;
} elsif (!m/^X[CS]+-/i) {
- &unknown("parsed version of changelog");
+ $_ = "L $_"; &unknown("parsed version of changelog");
}
+ } elsif (m/o:/) {
} else {
&internerr("value from nowhere, with key >$_< and value >$v<");
}
$fileslistfile="./$fileslistfile" if $fileslistfile =~ m/^\s/;
open(Y,"> $fileslistfile.new") || &syserr("open new files list file");
+binmode(Y);
chown(@fowner, "$fileslistfile.new")
|| &syserr("chown new files list file");
if (open(X,"< $fileslistfile")) {
+ binmode(X);
while (<X>) {
chomp;
next if m/^([-+0-9a-z.]+)_[^_]+_(\w+)\.deb /
$cf= "./$cf" if $cf =~ m/^\s/;
open(STDOUT,"> $cf.new") ||
&syserr("cannot open new output control file \`$cf.new'");
+ binmode(STDOUT);
}
&outputclose(1);
if (!$stdout) {