[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

lintian: r126 - in trunk: checks debian testset



Author: djpig
Date: 2004-04-08 04:04:06 +0200 (Thu, 08 Apr 2004)
New Revision: 126

Modified:
   trunk/checks/fields
   trunk/checks/fields.desc
   trunk/debian/changelog
   trunk/testset/info_tags.empty
   trunk/testset/info_tags.foo++
   trunk/testset/info_tags.relations
   trunk/testset/tags.empty
   trunk/testset/tags.foo++
   trunk/testset/tags.relations
Log:
rewrite of checks/fields by HE, extensive testing and bug fixing by me:
 - bad-relation seems to work better now (Closes: #171763)
 - duplicate relations checking now works for different fields, too
   (Closes: #234978, #235356)


Modified: trunk/checks/fields
===================================================================
--- trunk/checks/fields	2004-04-07 22:44:58 UTC (rev 125)
+++ trunk/checks/fields	2004-04-08 02:04:06 UTC (rev 126)
@@ -1,8 +1,12 @@
-#!/usr/bin/perl -w
-# fields -- lintian check script
-
-# Copyright (C) 1998 Richard Braakman
+#!/usr/bin/perl -W
+# fields.new -- lintian check script (rewrite)
 #
+# Copyright (C) 2004 Marc Brockschmidt
+#
+# Parts of the code were taken from the old check script, which
+# was Copyright (C) 1998 Richard Braakman (also licensed under the
+# GPL 2 or higher)
+# 
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
 # the Free Software Foundation; either version 2 of the License, or
@@ -20,525 +24,391 @@
 # MA 02111-1307, USA.
 
 use strict;
+use lib "$ENV{'LINTIAN_ROOT'}/checks/";
+use common_data;
 
-($#ARGV == 1) or fail("syntax: field <pkg> <type>");
+($#ARGV == 1) or fail("syntax: fields.net <pkg> <type>");
 my $pkg = shift;
 my $type = shift;
+my $version;
 
+$/ = undef; #Read everything in one go
+
 unless (-d "fields") {
-    fail("directory in lintian laboratory for $type package $pkg missing: fields");
+	fail("directory in lintian laboratory for $type package $pkg missing: fields");
 }
 
-use lib "$ENV{'LINTIAN_ROOT'}/lib";
-use Dep;
-use lib "$ENV{'LINTIAN_ROOT'}/checks";
-use common_data; # my data in checks/
+#---- Package
 
-if ($type eq 'udeb') {
-    %known_sections = ( 'debian-installer' => 1 );
-    %known_non_us_parts = ();
-    %known_archive_parts = ();
+if ($type eq "binary"){
+	if (not open (FH, "fields/package")) {
+		print "E: $pkg $type: no-package-name\n";
+	} else {
+		my $name = <FH>;
+		close FH;
+
+		unfold("package", \$name);
+	
+		print "E: $pkg $type: bad-package-name\n" unless $name =~ /^[A-Z0-9][-+\.A-Z0-9]+$/i;
+		print "E: $pkg $type: package-not-lowercase\n" if ($name =~ /[A-Z]/)
+	}
 }
 
-# Complex regexps used more than once
-my $package_re = "[A-Za-z0-9][A-Za-z0-9+.-]+";
-my $version_re = "([0-9]+:)?([0-9a-zA-Z][0-9a-zA-Z+.:\-]*?)(-[0-9a-zA-Z+.]+)?";
-# lenient regexp also allows underlines to appear, which were once used
-# in package names and may still appear in Conflicts and Replaces lines
-my $lenient_package_re = "[A-Za-z0-9][_A-Za-z0-9+.-]+";
+#---- Version
 
-my @version;
-
-# In general, read entire files in one go
-undef $/;
-
-if (not open(IN, "fields/package")) {
-    if ($type eq 'binary') {
-	tag_error("no-package-name");
-    }
+if (not open (FH, "fields/version")) {
+	print "E: $pkg $type: no-version-field\n";
 } else {
-    chop(my $package = <IN>);
-    close(IN);
-    single_line('package', $package);
-    if ($package !~ m/^$package_re$/so) {
-	tag_error("bad-package-name", $_);
-    } elsif ($package =~ m/[A-Z]/) {
-	tag_error("package-not-lowercase", $_);
-    }
-}
+	$version = <FH>;
+	close FH;
 
-if (not open(IN, "fields/version")) {
-    tag_error("no-version-field");
-} else {
-    chop($_ = <IN>);
-    close(IN);
-    single_line('version', $_);
-    if (not (@version = m/^$version_re$/so)) {
-	tag_error("bad-version-number", $_);
-    } else {
-	# Could have more detailed tags here, but they would be pretty long.
-	if ($version[1] =~ m/:/ and not $version[0]) {
-	    tag_error("bad-version-number", $_);
-	} elsif ($version[1] =~ m/-/ and not $version[2]) {
-	    tag_error("bad-version-number", $_);
+	unfold("version", \$version);
+
+	if (my ($epoch, $upstream, $debian) = _valid_version($version)) {
+		if ($upstream !~ /^\d/i) {
+			print "W: $pkg $type: upstream-version-not-numeric\n";
+		}
+	} else {
+		print "E: $pkg $type: bad-version-number\n";
 	}
-	if ($version[1] !~ m/^\d/) {
-	    tag_error("upstream-version-not-numeric", $version[1]);
-	}
-    }
 }
 
-if (not open(IN, "fields/architecture")) {
-    tag_error("no-architecture-field");
+#---- Architecture
+
+if (not open (FH, "fields/architecture")) {
+	print "E: $pkg $type: no-architecture-field\n";
 } else {
-    # Policy Manual 5.6.7 says that multiple architectures should be
-    # separated by "spaces", not "whitespace".  But I'll allow any
-    # whitespace here anyway.  It's not important enough to check for.
-    chop($_ = <IN>);
-    my @archs = split;
-    close(IN);
+	my $archs = <FH>;
+	close FH;
 
-    single_line('architecture', $_);
+	unfold("architecture", \$archs);
 
-    if ($type eq 'source') {
-	# Special architectures "all" and "any" should only occur alone.
-	if ($#archs > 0 and grep {$_ eq 'all' or $_ eq 'any'} @archs) {
-	    tag_error("magic-arch-in-arch-list");
+	my @archs = split / /, $archs;
+
+	if (@archs > 1 && grep { $_ eq "any" || $_ eq "all" } @archs) {
+		print "E: $pkg $type: magic-arch-in-arch-list\n";
 	}
-	
-	foreach my $arch (@archs) {
-	    if (not exists $known_archs{$arch}) {
-		tag_warn("unknown-architecture", $arch);
-	    }
+
+	for my $arch (@archs) {
+		unless ($known_archs{$arch}) {
+			print "E: $pkg $type: unknown-architecture\n";
+		}
 	}
-    } else {
-	if ($#archs > 0) {
-	    tag_error("too-many-architectures");
+
+	if ($type eq "binary") {
+		print "E: $pkg $type: too-many-architectures\n" if (@archs > 1);
+		print "E: $pkg $type: arch-any-in-binary-pkg\n" if (grep { $_ eq "any" } @archs);
 	}
-	if ($archs[0] eq 'any') {
-	    tag_error("arch-any-in-binary-pkg");
-	}
-	if (not exists $known_archs{$archs[0]}) {
-	    tag_warn("unknown-architecture", $archs[0]);
-	}
-    }
 }
 
-if (open(IN, "fields/subarchitecture")) {
-    chop($_ = <IN>);
-    my @subarchs = split;
-    close(IN);
+#---- Subarchitecture (udeb)
 
-    single_line('subarchitecture', $_);
+if (open(FH, "fields/subarchitecture")) {
+    my $subarch = <FH>;
+    close(FH);
+
+    unfold("subarchitecture", \$subarch);
 }
 
-if (open(IN, "fields/installer-menu-item")) {
-    chop($_ = <IN>);
-    /^\d+$/ || tag_error("bad-menu-item");
-    close(IN);
+#---- Maintainer
+#---- Uploaders
 
-    single_line('installer-menu-item', $_);
-}
+for my $f (qw(maintainer uploaders)) {
+	if (not open (FH, "fields/$f")) {
+		print "E: $pkg $type: no-maintainer-field\n" if $f eq "maintainer";
+	} else {
+		my $maintainer = <FH>;
+		close FH;
 
-if (not open(IN, "fields/maintainer")) {
-    tag_error("no-maintainer-field");
-} else {
-    chop($_ = <IN>);
-    close(IN);
+		unfold($f, \$maintainer);
 
-    single_line('maintainer', $_);
+		$maintainer =~ s/^\s*(.+?)\s*$/$1/; #Remove leading and trailing whitespace
 
-    check_maint('maintainer', $_);
+		if ($f eq "uploaders") {
+			check_maint($_, "uploader") for (split /\s*,\s*/, $maintainer);
+		} else {
+			check_maint($maintainer, $f);
+		}
+	}
 }
 
+#---- Source
 
-if (open(IN, "fields/uploaders")) {
-    chop($_ = <IN>);
-    close(IN);
+if ($type eq "source") {
+	if (not open (FH, "fields/source")) {
+		print "E: $pkg $type: no-source-field\n";
+	} else {
+		my $source = <FH>;
+		close FH;
+	
+		unfold("source", \$source);
+	
+		if ($type eq 'source') {
+			if ($source ne $pkg) {
+				print "E: $pkg $type: source-field-does-not-match-pkg-name $_\n";
+			}
+		} else {
+			if ($source !~ /[A-Z0-9][-+\.A-Z0-9]+                      #Package name
+			                \s*                                        
+			                (?:\((?:\d+:)?(?:[-\.+:A-Z0-9]+?)(?:-[\.+A-Z0-9]+)?\))?\s*$/ix) { #Version
+				print "E: $pkg $type: source-field-malformed $source\n";
+			}
+		}	
+	}
+}
 
-    single_line('uploaders', $_);
+#---- Essential
 
-    # somehow doesn't catch the ', ,' case, where nothing is between comma's
-    # I don't get it...  --Jeroen
-    for (split /,/) {
-	check_maint('uploader', $_);
-    }
+if (open (FH, "fields/essential")) {
+	my $essential = <FH>;
+	close FH;
+
+	unfold("essential", \$essential);
+
+	print "E: $pkg $type: essential-in-source-package\n" if ($type eq "source");
+	print "E: $pkg $type: essential-no-not-needed\n" if ($essential eq "no");
+	print "E: $pkg $type: unknown-essential-value\n" if ($essential ne "no" and $essential ne "yes");
+	print "W: $pkg $type: new-essential-package\n" if ($essential eq "yes" and ! $known_essential{$pkg});
 }
 
-if (not open(IN, "fields/source")) {
-    if ($type eq 'source') {
-	tag_error("no-source-field");
-    }
+#---- Section
+
+if (not open (FH, "fields/section")) {
+	print "W: $pkg $type: no-section-field\n" if $type eq "binary";
 } else {
-    chop($_ = <IN>);
-    close(IN);
+	my $section = <FH>;
+	close FH;
 
-    single_line('source', $_);
+	unfold("section", \$section);
 
-    if ($type eq 'source') {
-	if ($_ ne $pkg) {
-	    tag_error("source-field-does-not-match-pkg-name", $_);
+	my @parts = split /\//, $section, 2;
+
+	if ($parts[0] =~ /non-US/i) {
+	    print "I: $pkg $type: non-us-spelling\n" if ($parts[0] ne "non-US");
+	    if ($parts[1] and not $known_non_us_parts{$parts[1]}) {
+		print "W: $pkg $type: unknown-section $section\n";
+	    }
+	} elsif (scalar @parts > 1) {
+	    print "W: $pkg $type: unknown-section $section\n" unless $known_archive_parts{$parts[0]};
+	    print "W: $pkg $type: unknown-section $section\n" unless $known_sections{$parts[1]};
+	} else {
+	    print "W: $pkg $type: unknown-section $section\n" unless $known_sections{$parts[0]};
 	}
-    } else {
-	if (not m/^($package_re)\s*(?:\(\s*($version_re)\s*\))?$/so) {
-	    tag_error("source-field-malformed", $_);
-	}
-    }
 }
 
-if (open(IN, "fields/essential")) {
-    chop($_ = <IN>);
-    close(IN);
+#---- Priority
 
-    single_line('essential', $_);
+if (not open (FH, "fields/priority")) {
+	print "W: $pkg $type: no-priority-field\n" if $type eq "binary";
+} else {
+	my $priority = <FH>;
+	close FH;
 
-    if ($type eq 'source') {
-	tag_error("essential-in-source-package");
-    } else {
-	if ($_ eq 'no') {
-	    tag_warn("essential-no-not-needed");
-	} elsif ($_ ne 'yes') {
-	    tag_error("unknown-essential-value", $_);
-	} elsif (not exists $known_essential{$pkg}) {
-	    tag_warn("new-essential-package");
-	}
-    }
+	unfold("priority", \$priority);
+
+	print "E: $pkg $type: unknown-priority $priority\n" if (! $known_prios{$priority});
 }
 
-if (not open(IN, "fields/section")) {
-    # The section and priority fields are mandatory in the debian/control
-    # files, but they are not copied to the .dsc files, so we can't check
-    # them for source packages unless we have a full-blown debian/control
-    # parser.
-    # It is an informational tag, because most packages do not yet use
-    # -isp when building packages, and it is not yet policy to do so.
-    tag_warn("no-section-field")
-	unless $type eq 'source';
-} else {
-    chop(my $section = <IN>);
-    close(IN);
+#---- Standards-Version
+# handled in checks/standards-version
 
-    my @foo;
+#---- Description
+# handled in checks/description
 
-    single_line('section', $section);
+#---- Installer-Menu-Item (udeb)
 
-    # Packages in the main distribution have a simple section field,
-    # but others have "non-free/section" or "contrib/section".
-    @foo = split(/\//, $section, 2);
-    if ( $foo[0] eq 'non-us' ) {
-	tag_info("non-us-spelling");
-    }
-    if ( $foo[0] =~ m/non-us/i ) {
-	if (defined $foo[1] and (not exists $known_non_us_parts{$foo[1]} or
-				 not defined $known_non_us_parts{$foo[1]})) {
-	    tag_warn("unknown-section", $section);
-	}
-    } elsif ($#foo > 0) {
-	if (not exists $known_archive_parts{$foo[0]} or
-	    not defined $known_archive_parts{$foo[0]}) {
-	    tag_warn("unknown-section", $section);
-	}
-	if (not exists $known_sections{$foo[1]}) {
-	    tag_warn("unknown-section", $section);
-	}
-    } else {
-    	if (not exists $known_sections{$foo[0]}) {
-	    tag_warn("unknown-section", $section);
-	}
-    }
+if (open(FH, "fields/installer-menu-item")) {
+    my $menu_item = <FH>;
+    close(FH);
+
+    unfold('installer-menu-item', \$menu_item);
+
+    $menu_item =~ /^\d+$/ or print "E: $pkg $type: bad-menu-item $menu_item\n";
 }
 
-if (not open(IN, "fields/priority")) {
-    tag_warn("no-priority-field")
-	unless $type eq 'source';
-} else {
-    chop($_ = <IN>);
-    close(IN);
 
-    single_line('priority', $_);
+#---- Package relations (binary package)
 
-    if (not exists $known_prios{$_} or not defined $known_prios{$_}) {
-	tag_error("unknown-priority", $_);
-    }
-}
+if (($type eq "binary") || ($type eq 'udeb')) {
+    my %deps;
+	for my $field (qw(depends pre-depends recommends suggests conflicts provides replaces)) {
+		if (open(FH, "fields/$field")) {
+			#Get data and clean it
+			my $data = <FH>;
+			unfold($field, \$data);
+			$data =~ s/^\s*(.+?)\s*$/$1/;
 
-# returns true, if the fieldname is one of 'depends', 'pre-depends',
-# 'recommends' or 'suggests' and false otherwise
-sub is_depends_relation {
-    if ($_[0]) {
-	return ($_[0] eq 'depends'
-	    or $_[0] eq 'pre-depends'
-	    or $_[0] eq 'recommends'
-	    or $_[0] eq 'suggests');
-    }
-    return 1;
-}
+			my (@seen_libstdcs, @seen_tcls, @seen_tclxs, @seen_tks, @seen_tkxs, @seen_libpngs);
 
-if (($type eq 'binary') || ($type eq 'udeb')) {
-    for my $fld ('depends', 'pre-depends', 'recommends', 'suggests',
-		 'conflicts', 'provides', 'replaces') {
-	next if not open(IN, "fields/$fld");
-	my @conjunctions;
-	my @seen_libstdcs;
-	my @seen_tcls;
-	my @seen_tclxs;
-	my @seen_tks;
-	my @seen_tkxs;
-	my @seen_libpngs;
-	chop($_ = <IN>);
-	close(IN);
-	
-	single_line($fld, $_);
-	
-	# zap whitespace at the edges
-	s/^\s+//;
-	s/\s+$//;
-	
-	@conjunctions = split(/\s*,\s*/);
-	my @seen_conjunctions;
-	for my $conj (@conjunctions) {
-	    my @alternates = split(/\s*\|\s*/, $conj);
-	    my $relpkg;
-	    my $relation;
-	    my $version;
-	    my $versioned;
+			my $is_dep_field = sub { grep { $_ eq $_[0] } qw(depends pre-depends recommends suggests) };
 
-	    if ($#alternates >= 1) {
-		unless (is_depends_relation($fld)) {
-		    tag_error("alternates-not-allowed", "$fld:", $conj);
-		}
-	    }
+			print "E: $pkg $type: alternates-not-allowed $field\n"
+			    if ($data =~ /\|/ && ! &$is_dep_field($field));
 
-	    if ($fld eq 'depends' and @alternates and
-		exists $known_virtual_packages{$alternates[0]} and
-	        defined $known_virtual_packages{$alternates[0]} and
-		$alternates[0] ne "awk") {
-		tag_warn("virtual-package-depends-without-real-package-depends", $conj);
-	    }
+			for my $dep (split /\s*,\s*/, $data) {
+				my @alternatives;
+				push @alternatives, [_split_dep($_), $_] for (split /\s*\|\s*/, $dep);
 
-	    my @seen_alternates;
-	    for my $alt (@alternates) {
-		# fill in blank
-		if ($alt =~ m/^(\S+)\s*\(\s*(<<|<=|=|>=|>>|<|>)\s*(\S+)\s*\)$/) {
-                    ($relpkg, $relation, $version) = ($1, $2, $3);
-                    tag_warn("obsolete-relation-form", "$fld:", $alt)
-		        if ($relation eq '<' or $relation eq '>');
+				push @seen_libstdcs, $alternatives[0]->[0] if defined $known_libstdcs{$alternatives[0]->[0]};
+				push @seen_tcls, $alternatives[0]->[0] if defined $known_tcls{$alternatives[0]->[0]};
+				push @seen_tclxs, $alternatives[0]->[0] if defined $known_tclxs{$alternatives[0]->[0]};
+				push @seen_tks, $alternatives[0]->[0] if defined $known_tks{$alternatives[0]->[0]};
+				push @seen_tkxs, $alternatives[0]->[0] if defined $known_tkxs{$alternatives[0]->[0]};
+				push @seen_libpngs, $alternatives[0]->[0] if defined $known_libpngs{$alternatives[0]->[0]};
 
-		    tag_warn("bad-version-in-relation", "$fld:", $alt)
-			unless $version =~ m/^$version_re$/so;
+				print "W: $pkg $type: virtual-package-depends-without-real-package-depends $field: $alternatives[0]->[0]\n"
+					if ($known_virtual_packages{$alternatives[0]->[0]} && &$is_dep_field($field));
 
-		    tag_error("versioned-provides",
-			      "$relpkg ($relation $version)")
-			if $fld eq 'provides';
+				for my $part_d (@alternatives) {
+					my ($d_pkg, $d_version, $d_arch, $rest, $part_d_orig) = @$part_d;
 
-		    $versioned = 1;
-		} else {
-		    $relpkg = $alt;
-		    $versioned = 0;
-		}
+					#Save the type of relationship (<<, <=, ...) and the field name:
+					if (&$is_dep_field($field) && scalar @alternatives == 1) {
+						$deps{$d_pkg} = [] if ! $deps{$d_pkg};
+						push @{$deps{$d_pkg}}, [$field, $d_version];
+					}
 
-		if (is_depends_relation($fld)) {
-		    if ($relpkg eq "libdb1-compat" and $pkg !~ /^libc(6|6.1|0.3)$/) {
-			tag_error("depends-on-libdb1-compat");
-		    }
+					print "E: $pkg $type: versioned-provides $part_d_orig\n"
+					    if ($field eq "provides" && $d_version->[0]);
 
-		    if ($relpkg eq "awk" and not $versioned) {
-			tag_error("needlessly-depends-on-awk");
-		    }
+					print "W: $pkg $type: obsolete-relation-form $field: $part_d_orig\n"
+					    if ($d_version && grep { $d_version->[0] eq $_ } ("<", ">"));
 
-		    if (not $versioned and exists $known_essential{$relpkg}) {
-			# exception for coreutils, as it is quite new,
-			# depending on coreutils is NOT a no-op. Bug#216536
-			tag_error("depends-on-essential-package-without-using-version", $relpkg)
-			    unless $relpkg eq 'coreutils';
-		    }
-		}
+					print "E: $pkg $type: bad-version-in-relation $field: $part_d_orig\n"
+					    if ($d_version->[0] && ! (_valid_version($d_version->[1]))[1]);
+					
+					print "W: $pkg $type: package-relation-with-self $field: $part_d_orig\n"
+					    if ($pkg eq $d_pkg) && ($field ne 'conflicts');
 
-		if (not $relpkg =~ m/^$package_re$/so) {
-		    tag_error("bad-relation", "$fld:", $alt)
-			unless (($fld eq 'conflicts' or $fld eq 'replaces')
-				and $relpkg =~ m/^$lenient_package_re$/so);
-		}
-		
-		if ($relpkg eq $pkg) {
-		    tag_warn("package-relation-with-self", "$fld:", $alt)
-			unless ($fld eq 'conflicts' and not $versioned);
-		}
-		
-		if ($pkg eq "$relpkg-doc" and $fld eq 'depends') {
-		    tag_warn("doc-package-depends-on-main-package", "$fld:",
-			     $alt);
-		}
-		
-		if (($fld eq 'depends' or $fld eq 'pre-depends') and
-		    ((exists $known_obsolete_packages{$relpkg} and
-		      defined $known_obsolete_packages{$relpkg}) or
-		     $relpkg =~ m/^libgtk1\.1/)) {
-		    tag_error("depends-on-obsolete-package", "$fld:", $alt)
-			unless $pkg eq "$relpkg-dev" or $pkg eq "$relpkg-dbg";
-		}
+					print "E: $pkg $type: bad-relation $field: $part_d_orig\n"
+					    if $rest;
 
-		if ($relpkg =~ /^xfont.*/ and $fld eq 'depends') {
-		    tag_warn("package-depends-on-an-x-font-package", $alt);
-		}
+					print "E: $pkg $type: depends-on-obsolete-package $field: $part_d_orig\n"
+					    if ($known_obsolete_packages{$d_pkg} && &$is_dep_field($field));
 
-		if ($#alternates == 0) {
-		    # just count the first alternative, others don't count as duplicates
-		    push @seen_libstdcs, $relpkg if exists $known_libstdcs{"$relpkg"};
-		    push @seen_tcls, $relpkg if exists $known_tcls{"$relpkg"};
-		    push @seen_tclxs, $relpkg if exists $known_tclxs{"$relpkg"};
-		    push @seen_tks, $relpkg if exists $known_tks{"$relpkg"};
-		    push @seen_tkxs, $relpkg if exists $known_tkxs{"$relpkg"};
-		    push @seen_libpngs, $relpkg if exists $known_libpngs{"$relpkg"};
-		}
+					print "E: $pkg $type: depends-on-essential-package-without-using-version $field: $part_d_orig\n"
+					    if ($d_pkg ne "coreutils" && $known_essential{$d_pkg} && ! $d_version->[0] && &$is_dep_field($field));
 
-                # Check if this implies or is implied by other alternates.
-                my $parsed_alt = Dep::parse($alt);
-		for my $seen_alt (@seen_alternates) {
-		    my $parsed_seen_alt = Dep::parse($seen_alt);
-		    if (Dep::implies($parsed_alt, $parsed_seen_alt) or
-			Dep::implies($parsed_seen_alt, $parsed_alt)) {
-			tag_error("package-has-a-duplicate-relation",
-				  "$seen_alt | $alt");
-		    }
-		}
-		push @seen_alternates, $alt;
-	    }
+					print "E: $pkg $type: package-depends-on-an-x-font-package $field: $part_d_orig\n"
+					    if ($field =~ /^(pre-)?depends$/ && $d_pkg =~ /^xfont.*/);
 
-            # Check if this implies or is implied by other elements in the
-            # conjunction.
-            my $parsed_conj = Dep::parse($conj);
-	    for my $seen_conj (@seen_conjunctions) {
-		my $parsed_seen_conj = Dep::parse($seen_conj);
-		if (Dep::implies($parsed_conj, $parsed_seen_conj) or
-		    Dep::implies($parsed_seen_conj, $parsed_conj)) {
-		    tag_error("package-has-a-duplicate-relation",
-			      "$seen_conj, $conj");
+					print "E: $pkg $type: needlessly-depends-on-awk $field\n"
+					    if ($d_pkg eq "awk" && ! $d_version->[0] && &$is_dep_field($field));
+
+					print "E: $pkg $type: depends-on-libdb1-compat $field\n"
+					    if ($d_pkg eq "libdb1-compat" && $pkg !~ /^libc(6|6.1|0.3)/ && $field =~ /^(pre-)depends$/);
+
+					print "W: $pkg $type: doc-package-depends-on-main-package $field\n"
+					    if ("$d_pkg-doc" eq $pkg && $field =~ /^(pre-)depends$/);
+				}
+			}
+			print "E: $pkg $type: package-depends-on-multiple-libstdc-versions ", join (" ", @seen_libstdcs), "\n"
+			    if (scalar @seen_libstdcs > 1);
+			print "E: $pkg $type: package-depends-on-multiple-tcl-versions ", join (" ", @seen_tcls), "\n"
+			    if (scalar @seen_tcls > 1);
+			print "E: $pkg $type: package-depends-on-multiple-tclx-versions ", join (" ", @seen_tclxs), "\n"
+			    if (scalar @seen_tclxs > 1);
+			print "E: $pkg $type: package-depends-on-multiple-tk-versions ", join (" ", @seen_tks), "\n"
+			    if (scalar @seen_tks > 1);
+			print "E: $pkg $type: package-depends-on-multiple-tkx-versions ", join (" ", @seen_tkxs), "\n"
+			    if (scalar @seen_tkxs > 1);
+			print "E: $pkg $type: package-depends-on-multiple-libpng-versions ", join (" ", @seen_libpngs), "\n"
+			    if (scalar @seen_libpngs > 1);
 		}
-	    }
-	    push @seen_conjunctions, $conj;
 	}
-	# for each dependency field, report multiple dependencies
-	tag_error("package-depends-on-multiple-libstdc-versions", @seen_libstdcs) if ($#seen_libstdcs > 0);
-	tag_error("package-depends-on-multiple-tcl-versions", @seen_tcls) if ($#seen_tcls > 0);
-	tag_error("package-depends-on-multiple-tclx-versions", @seen_tclxs) if ($#seen_tclxs > 0);
-	tag_error("package-depends-on-multiple-tk-versions", @seen_tks) if ($#seen_tks > 0);
-	tag_error("package-depends-on-multiple-tkx-versions", @seen_tkxs) if ($#seen_tkxs > 0);
-	tag_error("package-depends-on-multiple-libpng-versions", @seen_libpngs) if ($#seen_libpngs > 0);
-    }
-    for my $fld ('build-depends', 'build-depends-indep', 'build-conflicts',
-	      'build-conflicts-indep') {
-	next if not open(IN, "fields/$fld");
-	chop($_ = <IN>);
-	close(IN);
-	
-	single_line($fld, $_);
-	
-	# zap whitespace at the edges
-	s/^\s+//;
-	s/\s+$//;
 
-	my $dep = $_;
-	my $sentinel = 0;
-	my ($package, $version, $archs);
-	while ($dep =~ m/\G
-			  \s*([^\s]+?)      # the package
-                          (?:\s+\((.+?)\))? # the version
-		          (?:\s+(\[.+?\]))? # the arch(s)
-			  \s*
-                       /xgc) {
-	    $package = $1;
-	    $version = $2;
-	    $archs = $3;
-	    if (pos($dep) != length($dep) and not $dep =~ m/\G[,|]/gc) {
-		$sentinel = 1;
-	    }
-	    if ($archs =~ m/,/) {
-		tag_error("invalid-arch-string-in-source-relation",
-			  $fld, $archs);
-	    }
-	    if ($known_essential{$package} and not defined $version) {
-		    tag_error("depends-on-essential-package-without-using-version", $package);
-	    }
-	    if ($known_build_essential{$package} and not defined $version) {
-		    tag_error("depends-on-build-essential-package-without-using-version", $package);
-	    }
+	for my $d_pkg_name (keys %deps) {
+		my $d_pkg = $deps{$d_pkg_name};
+		if (scalar @$d_pkg > 1) {
+			#Allow things like Depends: package1 (>= 1.3), package1 (<= 5.2)
+			unless ((scalar @$d_pkg == 2) && 
+			        (($d_pkg->[0]->[1]->[0] =~ />=|>>|>/ && $d_pkg->[1]->[1]->[0] =~ /<=|<<|</) or
+					 ($d_pkg->[0]->[1]->[0] =~ /<=|<<|</ && $d_pkg->[1]->[1]->[0] =~ />=|>>|>/))) {
+			    print "E: $pkg $type: package-has-a-duplicate-relation ";
+			    my @relations;
+			    if ($d_pkg->[0][0] eq $d_pkg->[1][0]) {
+				print "$d_pkg->[0][0]: ";
+				for (@$d_pkg) {
+				    if ($_->[1][0]) {
+					push @relations, "$d_pkg_name (".$_->[1][0]." ".$_->[1][1].")";
+				    } else {
+					push @relations, "$d_pkg_name";
+				    }
+				}
+			    } else {
+				for (@$d_pkg) {
+				    if ($_->[1][0]) {
+					push @relations, "$_->[0]: $d_pkg_name (".$_->[1][0]." ".$_->[1][1].")";
+				    } else {
+					push @relations, "$_->[0]: $d_pkg_name";
+				    }
+				}
+			    }
+			    print join( ", ", @relations ),"\n";			    
+			}
+		}
 	}
-	if ($sentinel || pos($dep) != length($dep)) {
-	    tag_error("bad-relation", $fld, $dep);
-	}
-    }
 }
 
-if ($type eq 'source') {
-    my $num_arch_dep = 0;
-    my $num_arch_indep = 0;
+#---- Package relations (source package)
 
-    $/ = "\n";
+if ($type eq "source") {
+	
+	#Get number of arch-indep packages:
+	my $arch_indep_packages = 0;
+	if (open(CONTROL, "debfiles/control")) {
+		$arch_indep_packages = grep { /^Architecture: all/ } <CONTROL>;
+	} 
 
-    if (not open(IN, "debfiles/control")) {
-	fail("Can't open debfiles/control: $!");
-    }
+	print "E: $pkg $type: build-depends-indep-without-arch-indep\n"
+		if (-e "fields/build-depends-indep" && $arch_indep_packages == 0);
+	
+	for my $field (qw(build-depends build-depends-indep build-conflicts build-conflicts-indep)) {
+		if (open(FH, "fields/$field")) {
+			#Get data and clean it
+			my $data = <FH>;
+			unfold($field, \$data);
+			$data =~ s/^\s*(.+?)\s*$/$1/;
 
-    while (<IN>) {
-	if (/^Architecture:\s*(\S*)/) {
-	    if ($1 eq "all") {
-		$num_arch_indep++;
-	    }
-	    else {
-		$num_arch_dep++;
-	    }
-	}
-    }
-    close(IN);
+			for my $dep (split /\s*,\s*/, $data) {
+				my @alternatives;
+				push @alternatives, [_split_dep($_), $_] for (split /\s*\|\s*/, $dep);
 
-    if (-e "fields/build-depends-indep" && $num_arch_indep == 0) {
-	tag_error("build-depends-indep-without-arch-indep");
-    }
+				for my $part_d (@alternatives) {
+					my ($d_pkg, $d_version, $d_arch, $rest, $part_d_orig) = @$part_d;
 
-    undef $/;
-}
+					for my $arch (@{$d_arch->[0]}) {
+						print "E: $pkg $type: invalid-arch-string-in-source-relation $arch [$field: $part_d_orig]\n"
+						    unless ($known_archs{$arch} || $arch eq "any" || $arch eq "all");
+					}
 
-# Not really anything to check in the Binary field, except for the
-# syntax which I assume dpkg will get right.
+					print "E: $pkg $type: depends-on-build-essential-package-without-using-version $d_pkg [$field: $part_d_orig]\n"
+					    if ($known_build_essential{$d_pkg} && ! $d_version->[1]);
 
-# Not much to check about Installed-Size either.  It is generated by
-# dpkg-gencontrol automatically.  What could be checked in the future
-# is whether the figure matches the actual contents of the .deb.
+					print "E: $pkg $type: depends-on-essential-package-without-using-version $field: $part_d_orig\n"
+					    if ($d_pkg ne "coreutils" && $known_essential{$d_pkg} && ! $d_version->[0]);
 
-# The check for the Files field may be a good place to verify the
-# md5sums, but dinstall does that already.
+					print "E: $pkg $type: bad-relation $field: $part_d_orig\n"
+					    if $rest;
+				}
+			}
+		}
+	}
+}
 
-# Standards-Version is checked separately.
+#----- Field checks (without checking the value)
 
-# Description field is checked separately
+for my $field (glob("fields/*")) {
+	$field =~ s!^fields/!!;
 
-# Distribution, Urgency, Date, Format, Changes occur only in .changes files.
-# Filename, MSDOS-Filename, Size and MD5sum occur in Packages files but
-# not in the package control files themselves.
+	print "E: $pkg $type: obsolete-field $field\n"
+	    if $known_obsolete_fields{$field};
 
-# Status, Config-Version, and Conffiles occur only in status files.
+	print "N: $pkg $type: unknown-field-in-dsc $field\n"
+	    if ($type eq "source" && ! $known_source_fields{$field} && ! $known_obsolete_fields{$field});
 
-opendir(FIELDS, "fields") or fail("cannot open fields directory: $!");
-my @fields = readdir(FIELDS);
-closedir(FIELDS);
-
-foreach (@fields) {
-    if ($_ eq '.' or $_ eq '..') {
-	# skip
-    } elsif (exists $known_obsolete_fields{$_} and
-	     defined $known_obsolete_fields{$_}) {
-	tag_error("obsolete-field", $_);
-    } elsif ($type eq 'source' and (not exists $known_source_fields{$_} or
-	     not defined $known_source_fields{$_})) {
-	tag_info("unknown-field-in-dsc", $_);
-    } elsif ($type eq 'binary' and (not exists $known_binary_fields{$_} or
-	     not defined $known_binary_fields{$_})) {
-	tag_info("unknown-field-in-control", $_);
-    } elsif ($type eq 'udeb' and (not exists $known_udeb_fields{$_} or
-	     not defined $known_udeb_fields{$_})) {
-	tag_info("unknown-field-in-control", $_);
-    }
+	print "N: $pkg $type: unknown-field-in-changes $field\n"
+	    if ($type eq "binary" && ! $known_binary_fields{$field} && ! $known_obsolete_fields{$field});
 }
 
 exit 0;
@@ -546,115 +416,92 @@
 # -----------------------------------
 
 sub fail {
-    if ($_[0]) {
-	warn "internal error: $_[0]\n";
-    } elsif ($!) {
-	warn "internal error: $!\n";
-    } else {
-	warn "internal error.\n";
-    }
-    exit 1;
+	if ($_[0]) {
+		warn "internal error: $_[0]\n";
+	} elsif ($!) {
+		warn "internal error: $!\n";
+	} else {
+		warn "internal error.\n";
+	}
+	exit 1;
 }
 
-sub tag_error {
-    my $tag = shift;
-    if ($#_ >= 0) {
-	# We can't have newlines in a tag message, so turn them into \n
-	map { s,\n,\\n, } @_;
-	my $args = join(' ', @_);
-	print "E: $pkg $type: $tag $args\n";
-    } else {
-	print "E: $pkg $type: $tag\n";
-    }
-}
+# splits "foo (>= 1.2.3) [!i386 ia64]" into
+# ( "foo", [ ">=", "1.2.3" ], [ [ "i386", "ia64" ], 1 ], "" )
+#                                                  ^^^   ^^
+#                                 true, if ! was given   ||
+#           rest (should always be "" for valid dependencies)
+sub _split_dep {
+	my $dep = shift;
+	my ($pkg, $version, $darch) = ("", ["",""], [[],""]);
 
-sub tag_warn {
-    my $tag = shift;
-    if ($#_ >= 0) {
-	# We can't have newlines in a tag message, so turn them into \n
-	map { s,\n,\\n, } @_;
-	my $args = join(' ', @_);
-	print "W: $pkg $type: $tag $args\n";
-    } else {
-	print "W: $pkg $type: $tag\n";
-    }
+	$pkg = $1 if $dep =~ s/^\s*([^\s\[\(]+)\s*//;
+
+	if (length $dep) {
+		if ($dep =~ s/\s* \( \s* (<<|<=|<|=|>=|>>|>) \s* ([^(]+) \) \s*//x) {
+			@$version = ($1, $2);
+		}
+		if ($dep && $dep =~ s/\s*\[([^\]]+)\]\s*//) {
+			my $t = $1;
+			$darch->[1] = 1 if ($t =~ s/!//g);
+			$darch->[0] = [ split /\s+/, $t ];
+		}
+	}
+
+	return ($pkg, $version, $darch, $dep);
 }
 
-sub tag_info {
-    my $tag = shift;
-    if ($#_ >= 0) {
-	# We can't have newlines in a tag message, so turn them into \n
-	map { s,\n,\\n, } @_;
-	my $args = join(' ', @_);
-	print "I: $pkg $type: $tag $args\n";
-    } else {
-	print "I: $pkg $type: $tag\n";
-    }
+sub _valid_version {
+	my $ver = shift;
+
+	if ($ver =~ m/^(\d+:)?([-\.+:A-Z0-9]+?)(-[\.+A-Z0-9]+)?$/i) {
+		return ($1, $2, $3);
+	} else {
+		return undef;
+	}
 }
 
-sub single_line {
-    my $fieldname = shift;
-    my $fieldval = shift;
+sub unfold {
+	my $field = shift;
+	my $line = shift;
 
-    if ($fieldval =~ m/\n/) {
-	tag_error("multiline-field", $fieldname);
-	return undef;
-    }
+	$$line =~ s/\n$//;
 
-    return 1;
+	if ($$line =~ s/\n//g) {
+		print "E: $pkg $type: multiline-field $field\n";
+	}
 }
 
 sub check_maint {
-    my $type = shift;
-    $_ = shift;
+	my ($maintainer, $f) = @_;
+	$maintainer =~ /^([^<\s]*(?:\s+[^<\s]+)*)?(\s*)(?:<(.+)>)?(.*)$/, 
+	my ($name, $del, $mail, $crap) = ($1, $2, $3, $4);
 
-    # Zap leading and trailing whitespace
-    s/^\s+//;
-    s/\s+$//;
-
-    # Parse maintainer-address.  Policy Manual 5.6.2 says:
-    #   The package maintainer's name and email address. The name should
-    #   come first, then the email address inside angle brackets <> (in
-    #   RFC822 format).
-    # Note that it is _not_ necessary for the name to be in any particular
-    # format.  However, lintian will emit warnings if it doesn't look
-    # like a full name.
-    if (not m/(.*?)<(.*?)>(.*)/) {
-	if (m/@/) {
-	    # Name is missing and address does not have <> around it
-	    tag_error("$type-name-missing", $_);
-	} else {
-	    # address is missing
-	    tag_error("$type-address-missing", $_);
+	if (!$mail && $name =~ m/@/) { # name probably missing and address has no <>
+	    $mail = $name;
+	    $name = undef;
 	}
-    } else {
-	my ($name, $addr, $rest) = ($1, $2, $3);
-	# Check that there is something before the address and nothing
-	# after it, and that the address looks vaguely like user@domain.foo.
-	# Full RFC822 parsing is probably overkill.
-	if (not $name) {
-	    tag_error("$type-name-missing", $_);
-	} elsif ($rest or $addr !~ m/.+@.+\..+/) {
-	    tag_error("$type-address-malformed", $_);
-	} elsif ($name !~ m/\s\S/) {
-	    # Also complain if the maintainer name has no embedded spaces
-	    tag_warn("$type-not-full-name", $name);
-	} elsif ($name !~ m/\s$/) {
-	    # And complain if there is no whitespace between the
-	    # name and the address.
-	    tag_warn("$type-address-looks-weird", $_);
-	}
 
-	if ($addr =~ /localhost(?:\.localdomain)?$/) {
-	    tag_error("$type-address-is-on-localhost", $_);
+	print "E: $pkg $type: $f-address-malformed $maintainer\n" if $crap;
+	print "W: $pkg $type: $f-address-looks-weird $maintainer\n" if ! $del && $name && $mail;
+
+	if (! $name) {
+		print "E: $pkg $type: $f-name-missing $maintainer\n";
+	} elsif ($name !~ /^\S+\s+\S+/) {
+		print "W: $pkg $type: $f-not-full-name $name\n";
 	}
-	if ($type eq 'maintainer' 
-	    	and $addr eq 'debian-qa@lists.debian.org') {
-	    tag_error("wrong-debian-qa-address-set-as-maintainer", $_);
-	}
-    }
+			
+	#This should be done with Email::Valid:
+	if (!$mail) {
+	    print "E: $pkg $type: $f-address-missing $maintainer\n";
+	} else {
+	    print "E: $pkg $type: $f-address-malformed $maintainer\n" 
+		unless ($mail =~ /^[^()<>@,;:\\"[\]]+@(\S+\.)+\S+/); #"
+				    
+	    print "E: $pkg $type: $f-address-is-on-localhost $maintainer\n"
+	        if ($mail =~ /(?:localhost|\.localdomain|\.localnet)$/);
 
-    return 1;
+	    print "E: $pkg $type: wrong-debian-qa-address-set-as-maintainer $maintainer\n"
+	        if ($f eq "maintainer" && $mail eq 'debian-qa@lists.debian.org');
+	}
 }
-
-# vim: ts=8 sw=4

Modified: trunk/checks/fields.desc
===================================================================
--- trunk/checks/fields.desc	2004-04-07 22:44:58 UTC (rev 125)
+++ trunk/checks/fields.desc	2004-04-08 02:04:06 UTC (rev 126)
@@ -1,5 +1,5 @@
 Check-Script: fields
-Author: Richard Braakman <dark@xs4all.nl>
+Author: Marc 'HE' Brockschmidt <marc@marcbrockschmidt.de>
 Abbrev: fld
 Standards-Version: 3.6.1
 Type: binary, udeb, source

Modified: trunk/debian/changelog
===================================================================
--- trunk/debian/changelog	2004-04-07 22:44:58 UTC (rev 125)
+++ trunk/debian/changelog	2004-04-08 02:04:06 UTC (rev 126)
@@ -13,6 +13,11 @@
       (Closes: #236846)
   * checks/fields.desc:
     + [FL] Fix some wrong policy references
+  * checks/fields:
+    + [HE, FL] Nearly complete rewrite for clean up:
+      - bad-relation seems to work better now (Closes: #171763)
+      - duplicate relations checking now works for different fields, too
+        (Closes: #234978, #235356)
   * checks/files:
     + [HE] New check for compiled python files (*.pyc). Patch by David
       Kimdon <david@kimdon.org>, thanks. (Closes: #236606)

Modified: trunk/testset/info_tags.empty
===================================================================
--- trunk/testset/info_tags.empty	2004-04-07 22:44:58 UTC (rev 125)
+++ trunk/testset/info_tags.empty	2004-04-08 02:04:06 UTC (rev 126)
@@ -4,6 +4,11 @@
 N:   Please update your package to latest policy and set this control field
 N:   appropriately.
 N:
+W: empty source: maintainer-not-full-name empty
+N:
+N:   The `name' part of this maintainer field is just one word, so it might
+N:   not be a full name.
+N:
 E: empty source: maintainer-address-missing empty
 N:
 N:   The maintainer field should contain the package maintainer's name and
@@ -23,6 +28,7 @@
 N:
 N:   The binary package does not have a "Description:" control field.
 N:
+W: empty: maintainer-not-full-name empty
 E: empty: maintainer-address-missing empty
 W: empty: no-section-field
 N:
@@ -32,7 +38,7 @@
 N:   -is or -isp flags to dpkg-gencontrol when building the package. The
 N:   field is optional in binary packages.
 N:   
-N:   Refer to Policy Manual, section 5.6.4 for details.
+N:   Refer to Policy Manual, section 5.3 for details.
 N:
 W: empty: no-priority-field
 N:
@@ -42,5 +48,5 @@
 N:   -ip or -isp flags to dpkg-gencontrol when building the package. The
 N:   field is optional in binary packages.
 N:   
-N:   Refer to policy D.2.9 for details.
+N:   Refer to Policy Manual, section 5.3 for details.
 N:

Modified: trunk/testset/info_tags.foo++
===================================================================
--- trunk/testset/info_tags.foo++	2004-04-07 22:44:58 UTC (rev 125)
+++ trunk/testset/info_tags.foo++	2004-04-08 02:04:06 UTC (rev 126)
@@ -37,7 +37,7 @@
 N:   
 N:   Refer to Policy Manual, section 5.6.2 for details.
 N:
-W: foo++ source: uploader-not-full-name Frank 
+W: foo++ source: uploader-not-full-name Frank
 N:
 N:   The `name' part of this uploader field is just one word, so it might
 N:   not be a full name.
@@ -49,6 +49,14 @@
 N:   
 N:   Refer to Policy Manual, section 5.6.2 for details.
 N:
+E: foo++ source: uploader-address-malformed Yama@gotchi
+N:
+N:   The uploader field could not be parsed according to the rules in the
+N:   Policy Manual.
+N:   
+N:   Refer to Policy Manual, section 5.6.2 for details.
+N:
+W: foo++ source: uploader-not-full-name Josip
 E: foo++ source: uploader-address-missing Josip
 N:
 N:   The uploader field should contain the package uploader's name and
@@ -58,12 +66,6 @@
 N:   Refer to Policy Manual, section 5.6.2 for details.
 N:
 E: foo++ source: uploader-address-malformed I am afraid of spam and think this helps <no_spam_please AT debian.org>
-N:
-N:   The uploader field could not be parsed according to the rules in the
-N:   Policy Manual.
-N:   
-N:   Refer to Policy Manual, section 5.6.2 for details.
-N:
 E: foo++-helper: wrong-debian-qa-address-set-as-maintainer Lintian Maintainer <debian-qa@lists.debian.org>
 E: foo++: no-copyright-file
 N:

Modified: trunk/testset/info_tags.relations
===================================================================
--- trunk/testset/info_tags.relations	2004-04-07 22:44:58 UTC (rev 125)
+++ trunk/testset/info_tags.relations	2004-04-08 02:04:06 UTC (rev 126)
@@ -9,6 +9,13 @@
 N:   Standards-Version control field. However, please remember to update
 N:   this field next time you upload the package.
 N:
+E: relations source: bad-relation build-depends: foo (>> 2) bar baz bat
+N:
+N:   The package declares a relationship that could not be parsed according
+N:   to the rules given in the Policy Manual.
+N:   
+N:   Refer to Policy Manual, section 7.1 for details.
+N:
 E: relations-multiple-libs: no-copyright-file
 N:
 N:   Each binary package has to include a plain file
@@ -75,14 +82,8 @@
 N:   its package name doubles as a virtual package.
 N:
 W: relations: package-relation-with-self depends: relations (<< 3)
-E: relations: package-has-a-duplicate-relation relations, relations (<< 3)
+E: relations: depends-on-essential-package-without-using-version depends: dpkg
 N:
-N:   The package seems to declare a relation on another package which is
-N:   already implied by other relations it declares, and is therefore
-N:   redundant. This is not only sloppy but can break some tools.
-N:
-E: relations: depends-on-essential-package-without-using-version dpkg
-N:
 N:   The package declares a depends on an essential package i.e. dpkg
 N:   without using a versioned depends. In general a package should not
 N:   depend on essential packages but if it must do so, the depends should
@@ -90,7 +91,7 @@
 N:   
 N:   Refer to Policy Manual, section 3.5 for details.
 N:
-W: relations: virtual-package-depends-without-real-package-depends mail-transport-agent
+W: relations: virtual-package-depends-without-real-package-depends depends: mail-transport-agent
 N:
 N:   The package declares a depends on a virtual package without listing a
 N:   real package as an alternative first.
@@ -103,7 +104,7 @@
 N:   
 N:   Refer to Policy Manual, section 7.4 for details.
 N:
-E: relations: needlessly-depends-on-awk
+E: relations: needlessly-depends-on-awk depends
 N:
 N:   The package seems to declare a relation on awk. awk is a virtual
 N:   package, but it is special since it's de facto essential. If you don't
@@ -111,7 +112,7 @@
 N:   anyway, as dpkg doesn't support versioned provides), you should remove
 N:   the dependency on awk.
 N:
-W: relations: bad-version-in-relation conflicts: foobar (<< 5&5)
+E: relations: bad-version-in-relation conflicts: foobar (<< 5&5)
 N:
 N:   The version number used in this relationship does not match the
 N:   defined format of a version number.
@@ -119,6 +120,12 @@
 N:   Refer to Policy Manual, section 5.6.11 for details.
 N:
 W: relations: package-relation-with-self replaces: relations
+E: relations: package-has-a-duplicate-relation depends: relations, relations (<< 3)
+N:
+N:   The package seems to declare a relation on another package which is
+N:   already implied by other relations it declares, and is therefore
+N:   redundant. This is not only sloppy but can break some tools.
+N:
 E: relations: obsolete-field optional
 N:
 N:   This is one of the fields listed in Policy Manual as obsolete.

Modified: trunk/testset/tags.empty
===================================================================
--- trunk/testset/tags.empty	2004-04-07 22:44:58 UTC (rev 125)
+++ trunk/testset/tags.empty	2004-04-08 02:04:06 UTC (rev 126)
@@ -1,7 +1,9 @@
 E: empty source: no-standards-version-field
+W: empty source: maintainer-not-full-name empty
 E: empty source: maintainer-address-missing empty
 E: empty: no-copyright-file
 E: empty: package-has-no-description
+W: empty: maintainer-not-full-name empty
 E: empty: maintainer-address-missing empty
 W: empty: no-section-field
 W: empty: no-priority-field

Modified: trunk/testset/tags.foo++
===================================================================
--- trunk/testset/tags.foo++	2004-04-07 22:44:58 UTC (rev 125)
+++ trunk/testset/tags.foo++	2004-04-08 02:04:06 UTC (rev 126)
@@ -3,8 +3,10 @@
 E: foo++ source: multiline-field uploaders
 W: foo++ source: uploader-address-looks-weird Jeroen van Wolffelaar<jeroen@localhost.localdomain>
 E: foo++ source: uploader-address-is-on-localhost Jeroen van Wolffelaar<jeroen@localhost.localdomain>
-W: foo++ source: uploader-not-full-name Frank 
+W: foo++ source: uploader-not-full-name Frank
 E: foo++ source: uploader-name-missing Yama@gotchi
+E: foo++ source: uploader-address-malformed Yama@gotchi
+W: foo++ source: uploader-not-full-name Josip
 E: foo++ source: uploader-address-missing Josip
 E: foo++ source: uploader-address-malformed I am afraid of spam and think this helps <no_spam_please AT debian.org>
 E: foo++-helper: wrong-debian-qa-address-set-as-maintainer Lintian Maintainer <debian-qa@lists.debian.org>

Modified: trunk/testset/tags.relations
===================================================================
--- trunk/testset/tags.relations	2004-04-07 22:44:58 UTC (rev 125)
+++ trunk/testset/tags.relations	2004-04-08 02:04:06 UTC (rev 126)
@@ -1,4 +1,5 @@
 W: relations source: ancient-standards-version 3.1.1
+E: relations source: bad-relation build-depends: foo (>> 2) bar baz bat
 E: relations-multiple-libs: no-copyright-file
 W: relations-multiple-libs: description-synopsis-might-not-be-phrased-properly
 E: relations-multiple-libs: description-synopsis-is-duplicated
@@ -10,10 +11,10 @@
 E: relations: no-copyright-file
 W: relations: package-relation-with-self depends: relations
 W: relations: package-relation-with-self depends: relations (<< 3)
-E: relations: package-has-a-duplicate-relation relations, relations (<< 3)
-E: relations: depends-on-essential-package-without-using-version dpkg
-W: relations: virtual-package-depends-without-real-package-depends mail-transport-agent
-E: relations: needlessly-depends-on-awk
-W: relations: bad-version-in-relation conflicts: foobar (<< 5&5)
+E: relations: depends-on-essential-package-without-using-version depends: dpkg
+W: relations: virtual-package-depends-without-real-package-depends depends: mail-transport-agent
+E: relations: needlessly-depends-on-awk depends
+E: relations: bad-version-in-relation conflicts: foobar (<< 5&5)
 W: relations: package-relation-with-self replaces: relations
+E: relations: package-has-a-duplicate-relation depends: relations, relations (<< 3)
 E: relations: obsolete-field optional



Reply to: