From 6af795d324371210ff18ecd482eaf2153aebd9e3 Mon Sep 17 00:00:00 2001 From: Adam Heath Date: Mon, 15 Sep 2003 02:17:44 +0000 Subject: [PATCH] * 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, --- ChangeLog | 18 ++++++++ debian/changelog | 24 +++++++++- debian/control | 8 ++-- scripts/controllib.pl | 81 +++++++++++++++++++++++++++++++++- scripts/dpkg-checkbuilddeps.pl | 78 +++++++++++--------------------- scripts/dpkg-gencontrol.pl | 17 ++++--- 6 files changed, 162 insertions(+), 64 deletions(-) diff --git a/ChangeLog b/ChangeLog index 741f660d..130a3c3b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,21 @@ +Sun, 14 Sep 2003 21:16:18 -0500 Adam Heath + + * 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 * dselect/{Makefile.in,helpmsgs.{cc,h,src},mkhelpmsgs.pl,.cvsignore}: diff --git a/debian/changelog b/debian/changelog index c120017b..2811f128 100644 --- a/debian/changelog +++ b/debian/changelog @@ -6,6 +6,26 @@ dpkg (1.10.11) unstable; urgency=low * 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 : + support comments(first char on line begins with '#') in + debian/control. Closes: #191810 + * Bastian Blank : + Allow for per-arch generated dependency fields. Closes: #170575 + * Branden Robinson : + Report the original casing of field names when they are unknown. + Closes: #177753 * Frank Lichtenheld : Apply patch, to handle missing infodir.bak, and empty files. Closes: #196361 @@ -117,8 +137,10 @@ dpkg (1.10.11) unstable; urgency=low * Eduard Bloch : Apply patch to check whether the target path exists on removing. Closes: #37254 + * Colin Walters : + After opening files, set binmode. Closes: #175363 - -- Wichert Akkerman UNRELEASED + -- Wichert Akkerman Sun, 14 Sep 2003 20:15:31 -0500 dpkg (1.10.10) unstable; urgency=low diff --git a/debian/control b/debian/control index 1ac9e19d..52901951 100644 --- a/debian/control +++ b/debian/control @@ -6,14 +6,16 @@ Uploaders: Wichert Akkerman , Adam Heath = 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 , Adam Heath +# 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 diff --git a/scripts/controllib.pl b/scripts/controllib.pl index ade70071..45d27f28 100755 --- a/scripts/controllib.pl +++ b/scripts/controllib.pl @@ -16,7 +16,10 @@ $parsechangelog= 'dpkg-parsechangelog'; 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"; @@ -105,6 +108,7 @@ sub outputclose { if (length($varlistfile) and $dosubstvars) { $varlistfile="./$varlistfile" if $varlistfile =~ m/\s/; if (open(SV,"< $varlistfile")) { + binmode(SV); while () { next if m/^\#/ || !m/\S/; s/\s*\n$//; @@ -142,6 +146,7 @@ sub parsecontrolfile { $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"); @@ -149,11 +154,81 @@ sub parsecontrolfile { 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); @@ -186,11 +261,13 @@ sub parsecdata { while () { 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"); @@ -225,7 +302,7 @@ sub parsecdata { } sub unknown { - &warn("unknown information field $_ in input data in $_[0]"); + &warn("unknown information field " . $fi{"o:$_"} . " in input data in $_[0]"); } sub syntax { diff --git a/scripts/dpkg-checkbuilddeps.pl b/scripts/dpkg-checkbuilddeps.pl index 837856a0..9fbd5ade 100755 --- a/scripts/dpkg-checkbuilddeps.pl +++ b/scripts/dpkg-checkbuilddeps.pl @@ -1,9 +1,14 @@ -#!/usr/bin/perl -w +#!/usr/bin/perl # GPL copyright 2001 by Joey Hess -use strict; +#use strict; use Getopt::Long; +my $dpkglibdir="/usr/lib/dpkg"; +push(@INC,$dpkglibdir); +#my $controlfile; +require 'controllib.pl'; + sub usage { print STDERR <; -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) { @@ -117,55 +121,24 @@ sub build_conflicts { # 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; @@ -186,7 +159,6 @@ ALTERNATE: foreach my $alternate (split(/\s*\|\s*/, $dep)) { # nothing provides it, so fail. next; } - # If we get to here, the dependency was met. $ok=1; } diff --git a/scripts/dpkg-gencontrol.pl b/scripts/dpkg-gencontrol.pl index 4cfb2c23..da7099d3 100755 --- a/scripts/dpkg-gencontrol.pl +++ b/scripts/dpkg-gencontrol.pl @@ -112,6 +112,8 @@ if (length($oppackage)) { #print STDERR "myindex $myindex\n"; +my %pkg_dep_fields = map { $_ => 1 } @pkg_dep_fields; + for $_ (keys %fi) { $v= $fi{$_}; if (s/^C //) { @@ -121,12 +123,13 @@ for $_ (keys %fi) { 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$/) { @@ -144,7 +147,7 @@ for $_ (keys %fi) { } 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"; @@ -159,8 +162,9 @@ for $_ (keys %fi) { } 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<"); } @@ -211,9 +215,11 @@ if (length($substvar{'Installed-Size'})) { $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 () { chomp; next if m/^([-+0-9a-z.]+)_[^_]+_(\w+)\.deb / @@ -242,6 +248,7 @@ if (!$stdout) { $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) { -- 2.39.5