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

[SCM] Debian package checker branch, master, updated. 2.2.0-40-gd8f9e52



The following commit has been merged in the master branch:
commit 01dc51eea9022a713f12edae36eda70881acb7ec
Author: Russ Allbery <rra@debian.org>
Date:   Sat Jan 31 16:21:10 2009 -0800

    Replace Manual_refs and Read_taginfo with Lintian::Tag::Info
    
    * data/output/manual-references:
      + [RA] Manual reference data used for formatting tag descriptions.
        Moved from lib/manual_refs.
    * frontend/lintian-info:
      + [RA] Use Lintian::Tag::Info instead of Read_taginfo.
    * lib/Lintian/Output.pm
      + [RA] Use Lintian::Tag::Info instead of Read_taginfo.
      + [RA] Force early exporting of functions to be more robust in the
        face of circular library dependencies.  The circular dependencies
        had already existed but not previously caused problems.
    * lib/Lintian/Output/LetterQualifier.pm:
      + [RA] Use Lintian::Tag::Info instead of Read_taginfo.
    * lib/Lintian/Tag/Info.pm:
      + [RA] New module providing an interface to tag metadata.  Currently,
        this only supports formatting the tag description, merging the
        actions previously done by Manual_refs.pm and Read_taginfo.pm.  It
        defers loading of manual references until they're needed, which
        removes the requirement that LINTIAN_ROOT be already set in the
        environment before running the reporting harness.  It also saves a
        small amount of time in runs without -I.
    * lib/Manual_refs.pm:
      + [RA] Removed, merged into Lintian::Tag::Info.
    * lib/manual_refs:
      + [RA] Moved to data/output/manual-references.
    * lib/Read_taginfo.pm:
      + [RA] Removed, merged into Lintian::Tag::Info.
    * lib/Util.pm:
      + [RA] Force early exporting of functions to be more robust in the
        face of circular library dependencies.
    * reporting/html_reports:
      + [RA] Use Lintian::Tag::Info instead of Read_taginfo.

diff --git a/lib/manual_refs b/data/output/manual-references
similarity index 100%
rename from lib/manual_refs
rename to data/output/manual-references
diff --git a/debian/changelog b/debian/changelog
index c845dbb..f72e7e9 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -35,6 +35,13 @@ lintian (2.2.1) UNRELEASED; urgency=low
     + [RA] Use binary_field() to read control fields for binary packages.
       Patch from Raphael Geissert.
 
+  * data/output/manual-references:
+    + [RA] Manual reference data used for formatting tag descriptions.
+      Moved from lib/manual_refs.
+
+  * frontend/lintian-info:
+    + [RA] Use Lintian::Tag::Info instead of Read_taginfo.
+
   * lib/Lintian/Collect/Source.pm:
     + [RA] Add binary_field() method to return a binary package field from
       debian/control for a source package.  Based on a patch by Raphael
@@ -45,8 +52,34 @@ lintian (2.2.1) UNRELEASED; urgency=low
     + [ADB] Add a colour for pedantic tags to avoid warnings when colourised
       output is used and make the combination more useful.  Thanks, gregor
       herrmann.  (Closes: #513132)
+    + [RA] Use Lintian::Tag::Info instead of Read_taginfo.
+    + [RA] Force early exporting of functions to be more robust in the
+      face of circular library dependencies.  The circular dependencies
+      had already existed but not previously caused problems.
   * lib/Lintian/Output/LetterQualifier.pm:
     + [ADB] Add support for pedantic tags.
+    + [RA] Use Lintian::Tag::Info instead of Read_taginfo.
+  * lib/Lintian/Tag/Info.pm:
+    + [RA] New module providing an interface to tag metadata.  Currently,
+      this only supports formatting the tag description, merging the
+      actions previously done by Manual_refs.pm and Read_taginfo.pm.  It
+      defers loading of manual references until they're needed, which
+      removes the requirement that LINTIAN_ROOT be already set in the
+      environment before running the reporting harness.  It also saves a
+      small amount of time in runs without -I.
+  * lib/Manual_refs.pm:
+    + [RA] Removed, merged into Lintian::Tag::Info.
+  * lib/manual_refs:
+    + [RA] Moved to data/output/manual-references.
+  * lib/Read_taginfo.pm:
+    + [RA] Removed, merged into Lintian::Tag::Info.
+  * lib/Util.pm:
+    + [RA] Force early exporting of functions to be more robust in the
+      face of circular library dependencies.
+
+  * man/lintian.1:
+    + [ADB] Fix the spelling of "pedantic".  Thanks, Michal Čihař.
+      (Closes: #513083)
 
   * reporting/config:
     + [RA] Set a bin directory and disable signature checks by default.
@@ -55,10 +88,8 @@ lintian (2.2.1) UNRELEASED; urgency=low
       /bin/true if signature checks are disabled.  This is a hack to work
       with the etch version of dpkg-source.  In lenny, the --no-check flag
       will be used instead.  Patch from Raphael Geissert.
-
-  * man/lintian.1:
-    + [ADB] Fix the spelling of "pedantic".  Thanks, Michal Čihař.
-      (Closes: #513083)
+  * reporting/html_reports:
+    + [RA] Use Lintian::Tag::Info instead of Read_taginfo.
 
   * t/runtests:
     + [RA] Add support for selecting a different test package skeleton.
diff --git a/frontend/lintian-info b/frontend/lintian-info
index 80d6ae9..c4e0595 100755
--- a/frontend/lintian-info
+++ b/frontend/lintian-info
@@ -36,13 +36,11 @@ BEGIN {
 
 # import perl libraries
 use lib "$ENV{'LINTIAN_ROOT'}/lib";
-use Read_taginfo;
+use Lintian::Tag::Info ();
 use Text_utils;
 
 my %already_displayed = ();
 
-my %tag_info = %{read_tag_info()};
-
 my ($annotate, $tags);
 Getopt::Long::config('bundling', 'no_getopt_compat', 'no_auto_abbrev');
 GetOptions('annotate|a' => \$annotate, 'tags|t' => \$tags)
@@ -54,15 +52,16 @@ GetOptions('annotate|a' => \$annotate, 'tags|t' => \$tags)
 my $unknown;
 if ($tags) {
     for my $tag (@ARGV) {
-        print "N: $tag\n";
-        print "N:\n";
-        if (exists $tag_info{$tag}) {
-            print wrap_paragraphs('N:   ', $tag_info{$tag});
-        } else {
-            print "N:   Unknown tag.\n";
-            $unknown = 1;
-        }
-        print "N:\n";
+	print "N: $tag\n";
+	print "N:\n";
+	my $info = Lintian::Tag::Info->new($tag);
+	if ($info) {
+	    print $info->description('text', 'N:   ');
+	} else {
+	    print "N:	Unknown tag.\n";
+	    $unknown = 1;
+	}
+	print "N:\n";
     }
     exit ($unknown ? 1 : 0);
 }
@@ -92,9 +91,11 @@ while (<>) {
 	next if not defined $tag;
 	($tag) = split(/\s+/, $tag, 2);
 
-	next if not exists $tag_info{$tag} or $already_displayed{$tag}++;
+	next if $already_displayed{$tag}++;
+	my $info = Lintian::Tag::Info->new($tag);
+	next unless $info;
 	print "N:\n";
-	print wrap_paragraphs('N:   ',$tag_info{$tag});
+	print $info->description('text', 'N:   ');
 	print "N:\n";
     }
 }
diff --git a/lib/Lintian/Output.pm b/lib/Lintian/Output.pm
index 0670f34..edb3878 100644
--- a/lib/Lintian/Output.pm
+++ b/lib/Lintian/Output.pm
@@ -22,6 +22,20 @@ use strict;
 use warnings;
 
 use v5.8.0; # for PerlIO
+use base qw(Class::Accessor Exporter);
+
+# Force export as soon as possible, since some of the modules we load also
+# depend on us and the sequencing can cause things not to be exported
+# otherwise.
+our (@EXPORT, %EXPORT_TAGS, @EXPORT_OK);
+BEGIN {
+    @EXPORT = ();
+    %EXPORT_TAGS = ( messages => [qw(msg v_msg warning debug_msg delimiter)],
+		     util => [qw(_global_or_object)]);
+    @EXPORT_OK = (@{$EXPORT_TAGS{messages}},
+		  @{$EXPORT_TAGS{util}},
+		  'string');
+}
 
 =head1 NAME
 
@@ -61,8 +75,8 @@ $Lintian::Output::GLOBAL unless their first argument C<isa('Lintian::Output')>.
 
 # support for ANSI color output via colored()
 use Term::ANSIColor ();
+use Lintian::Tag::Info ();
 use Tags ();
-use Read_taginfo qw(format_tag_description);
 
 =head1 ACCESSORS
 
@@ -114,17 +128,9 @@ Hash containing the names of tags which have been issued.
 
 =cut
 
-use base qw(Class::Accessor Exporter);
 Lintian::Output->mk_accessors(qw(verbose debug quiet color colors stdout
     stderr showdescription issuedtags));
 
-our @EXPORT = ();
-our %EXPORT_TAGS = ( messages => [qw(msg v_msg warning debug_msg delimiter)],
-		     util => [qw(_global_or_object)]);
-our @EXPORT_OK = (@{$EXPORT_TAGS{messages}},
-		  @{$EXPORT_TAGS{util}},
-		  'string');
-
 # for the non-OO interface
 my %default_colors = ( 'E' => 'red' , 'W' => 'yellow' , 'I' => 'cyan',
 		       'P' => 'green' );
@@ -299,9 +305,13 @@ sub print_tag {
 
     $self->_print('', "$code: $pkg_info->{pkg}$type", "$tag$information");
     if (!$self->issued_tag($tag_info->{tag}) and $self->showdescription) {
-	$self->_print('', 'N', '');
-	$self->_print('', 'N', split("\n", format_tag_description($tag_info, 3)));
-	$self->_print('', 'N', '');
+	my $info = Lintian::Tag::Info->new($tag_info->{tag});
+	if ($info) {
+	    my $description = $info->description('text', '   ');
+	    $self->_print('', 'N', '');
+	    $self->_print('', 'N', split("\n", $description));
+	    $self->_print('', 'N', '');
+	}
     }
 }
 
@@ -471,3 +481,9 @@ Originally written by Frank Lichtenheld <djpig@debian.org> for Lintian.
 lintian(1)
 
 =cut
+
+# Local Variables:
+# indent-tabs-mode: t
+# cperl-indent-level: 4
+# End:
+# vim: syntax=perl sw=4 ts=8 noet shiftround
diff --git a/lib/Lintian/Output/LetterQualifier.pm b/lib/Lintian/Output/LetterQualifier.pm
index 2f20dc6..825da55 100644
--- a/lib/Lintian/Output/LetterQualifier.pm
+++ b/lib/Lintian/Output/LetterQualifier.pm
@@ -21,8 +21,8 @@ package Lintian::Output::LetterQualifier;
 use strict;
 use warnings;
 
-use Read_taginfo qw(format_tag_description);
 use Term::ANSIColor qw(colored);
+use Lintian::Tag::Info ();
 use Tags ();
 
 use Lintian::Output qw(:util);
@@ -129,12 +129,20 @@ sub print_tag {
 
     $self->_print('', "$code\[$lq\]: $pkg$type", "$tag$information");
     if (!$self->issued_tag($tag_info->{tag}) and $self->showdescription) {
-	$self->_print('', 'N', '');
-	$self->_print('', 'N', split("\n", format_tag_description($tag_info, 3)));
-	$self->_print('', 'N', '');
+        my $info = Lintian::Tag::Info->new($tag_info->{tag});
+        if ($info) {
+            my $description = $info->description('text', '   ');
+            $self->_print('', 'N', '');
+            $self->_print('', 'N', split("\n", $description));
+            $self->_print('', 'N', '');
+        }
     }
 }
 
 1;
 
-# vim: sw=4 sts=4 ts=4 et sr
+# Local Variables:
+# indent-tabs-mode: nil
+# cperl-indent-level: 4
+# End:
+# vim: syntax=perl sw=4 sts=4 ts=8 et shiftround
diff --git a/lib/Lintian/Tag/Info.pm b/lib/Lintian/Tag/Info.pm
new file mode 100644
index 0000000..5d358df
--- /dev/null
+++ b/lib/Lintian/Tag/Info.pm
@@ -0,0 +1,353 @@
+# -*- perl -*-
+# Lintian::Tag::Info -- interface to tag metadata
+
+# Copyright (C) 1998 Christian Schwarz and Richard Braakman
+# Copyright (C) 2009 Russ Allbery
+#
+# 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 (at your option)
+# any later version.
+#
+# This program is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+# more details.
+#
+# You should have received a copy of the GNU General Public License along with
+# this program.  If not, see <http://www.gnu.org/licenses/>.
+
+package Lintian::Tag::Info;
+
+use strict;
+use warnings;
+
+use Carp qw(croak);
+
+use Lintian::Output qw(debug_msg);
+use Text_utils qw(dtml_to_html dtml_to_text split_paragraphs wrap_paragraphs);
+use Util qw(fail read_dpkg_control);
+
+# The URL to a web man page service.  NAME is replaced by the man page
+# name and SECTION with the section to form a valid URL.  This is used
+# when formatting references to manual pages into HTML to provide a link
+# to the manual page.
+our $MANURL
+    = 'http://manpages.debian.net/cgi-bin/man.cgi?query=NAME&sektion=SECTION';
+
+# Stores the parsed tag information for all known tags.  Loaded the first
+# time new() is called.
+our %INFO;
+
+# Stores the parsed manual reference data.  Loaded the first time info()
+# is called.
+our %MANUALS;
+
+=head1 NAME
+
+Lintian::Tag::Info - Lintian interface to tag metadata
+
+=head1 SYNOPSIS
+
+    my $tag = Lintian::Tag::Info->new('some-tag');
+    print "Tag info is:\n";
+    print $tag_info->description('text', '   ');
+    print "\nTag info in HTML is:\n";
+    print $tag_info->description('html', '   ');
+
+=head1 DESCRIPTION
+
+This module provides an interface to tag metadata as gleaned from the
+*.desc files describing the checks.  Currently, it is only used to format
+and return the tag description, but it provides a framework that can be
+used to retrieve other metadata about tags.
+
+=head1 CLASS METHODS
+
+=over 4
+
+=item new(TAG)
+
+Creates a new Lintian::Tag::Info object for the given TAG.  Returns undef
+if the tag is unknown and throws an exception if there is a parse error
+reading the check description files or if TAG is not specified.
+
+The first time this method is called, all tag metadata will be loaded into
+a memory cache.  This information will be used to satisfy all subsequent
+Lintian::Tag::Info object creation, avoiding multiple file reads.  This
+however means that a running Lintian process will not notice changes to
+tag metadata on disk.
+
+=cut
+
+# Load all tag data into the %INFO hash.  Called by new() if %INFO is
+# empty and hence called the first time new() is called.
+sub _load_tag_data {
+    my $root = $ENV{LINTIAN_ROOT} || '/usr/share/lintian';
+    for my $desc (<$root/checks/*.desc>) {
+        debug_msg(2, "Reading checker description file $desc ...");
+        my ($header, @tags) = read_dpkg_control($desc);
+        unless ($header->{'check-script'}) {
+            fail("missing Check-Script field in $desc");
+        }
+        for my $tag (@tags) {
+            unless ($tag->{tag}) {
+                fail("missing Tag field in $desc");
+            }
+            $tag->{info} = '' unless exists($tag->{info});
+            $INFO{$tag->{tag}} = $tag;
+        }
+    }
+}
+
+# Create a new object for the given tag.  We just use the hash created by
+# read_dpkg_control as the object, which means we slowly bless the objects
+# in %INFO as we return them.
+sub new {
+    my ($class, $tag) = @_;
+    croak('no tag specified') unless $tag;
+    _load_tag_data() unless %INFO;
+    if ($INFO{$tag}) {
+        my $self = $INFO{$tag};
+        bless($self, $class) unless ref($self) eq $class;
+        return $self;
+    } else {
+        return;
+    }
+}
+
+=back
+
+=head1 INSTANCE METHODS
+
+=over 4
+
+=item description([FORMAT [, INDENT]])
+
+Returns the formatted description (the Info field) for a tag.  FORMAT must
+be either C<text> or C<html> and defaults to C<text> if no format is
+specified.  If C<text>, returns wrapped paragraphs formatted in plain text
+with a right margin matching the Text::Wrap default, preserving as
+verbatim paragraphs that begin with whitespace.  If C<html>, return
+paragraphs formatted in HTML.
+
+If INDENT is specified, the string INDENT is prepended to each line of the
+formatted output.
+
+=cut
+
+# Load manual reference data into %MANUALS.  This information doesn't have
+# a single unique key and has multiple data values per key, so we don't
+# try to use the Lintian::Data interface.  Instead, we read a file
+# delimited by double colons.  We do use a path similar to Lintian::Data
+# to keep such files in the same general location.
+sub _load_manual_data {
+    my $root = $ENV{LINTIAN_ROOT} || '/usr/share/lintian';
+    open(REFS, '<', "$root/data/output/manual-references")
+        or fail("can't open $root/data/output/manual-references: $!");
+    local $_;
+    while (<REFS>) {
+        chomp;
+        next if /^\#/;
+        next if /^\s*$/;
+        next unless /^(.+?)::(.*?)::(.+?)::(.*?)$/;
+        my ($manual, $section, $title, $url) = split('::');
+        $MANUALS{$manual}{$section}{title} = $title;
+        $MANUALS{$manual}{$section}{url} = $url;
+    }
+    close REFS;
+}
+
+# Format a reference to a manual in the HTML that Lintian uses internally
+# for tag descriptions and return the result.  Takes the name of the
+# manual and the name of the section.  Returns an empty string if the
+# argument isn't a known manual.
+sub _manual_reference {
+    my ($manual, $section) = @_;
+    _load_manual_data unless %MANUALS;
+    return '' unless exists $MANUALS{$manual}{''};
+
+    # Start with the reference to the overall manual.
+    my $title = $MANUALS{$manual}{''}{title};
+    my $url   = $MANUALS{$manual}{''}{url};
+    my $text  = $url ? qq(<a href="$url">$title</a>) : $title;
+
+    # Add the section information, if present, and a direct link to that
+    # section of the manual where possible.
+    if ($section and $section =~ /^[A-Z]+$/) {
+        $text .= " appendix $section";
+    } elsif ($section and $section =~ /^\d+$/) {
+        $text .= " chapter $section";
+    } elsif ($section and $section =~ /^[A-Z\d.]+$/) {
+        $text .= " section $section";
+    }
+    if ($section and exists $MANUALS{$manual}{$section}) {
+        my $title = $MANUALS{$manual}{$section}{title};
+        my $url   = $MANUALS{$manual}{$section}{url};
+        $text .= qq[ (<a href="$url">$title</a>)];
+    }
+
+    return $text;
+}
+
+# Format the contents of the Ref attribute of a tag.  Handles manual
+# references in the form <keyword> <section>, manpage references in the
+# form <manpage>(<section>), and URLs.
+sub _format_reference {
+    my ($field) = @_;
+    my @refs;
+    for my $ref (split(/,\s*/, $field)) {
+        my $text;
+        if ($ref =~ /^([\w-]+)\s+(.+)$/) {
+            $text = _manual_reference($1, $2);
+        } elsif ($ref =~ /^([\w_-]+)\((\d\w*)\)$/) {
+            my ($name, $section) = ($1, $2);
+            my $url = $MANURL;
+            $url =~ s/NAME/$name/g;
+            $url =~ s/SECTION/$section/g;
+            $text = qq(the <a href="$url">$ref</a> manual page);
+        } elsif ($ref =~ m,^(ftp|https?)://,) {
+            $text = qq(<a href="$ref">$ref</a>);
+        }
+        push (@refs, $text) if $text;
+    }
+
+    # Now build an English list of the results with appropriate commas and
+    # conjunctions.
+    my $text = '';
+    if ($#refs >= 2) {
+        $text = join(', ', splice(@refs, 0, $#refs));
+        $text = "Refer to $text, and @refs for details.";
+    } elsif ($#refs >= 0) {
+        $text = 'Refer to ' . join(' and ', @refs) . ' for details.';
+    }
+    return $text;
+}
+
+# Returns the formatted tag description.
+sub description {
+    my ($self, $format, $indent) = @_;
+    $indent = '' unless defined($indent);
+    $format = 'text' unless defined($format);
+    if ($format ne 'text' and $format ne 'html') {
+        croak("unknown output format $format");
+    }
+
+    # Build the tag description.
+    my @text = split_paragraphs($self->{info});
+    if ($self->{ref}) {
+        push(@text, '', _format_reference($self->{ref}));
+    }
+    if ($self->{severity} and $self->{certainty}) {
+        my $severity = $self->{severity};
+        my $certainty = $self->{certainty};
+        push(@text, '', "Severity: $severity, Certainty: $certainty");
+    }
+    if ($self->{experimental}) {
+        push(@text, '',
+             'This tag is marked experimental, which means that the code that'
+             . ' generates it is not as well-tested as the rest of Lintian'
+             . ' and might still give surprising results.  Feel free to'
+             . ' ignore experimental tags that do not seem to make sense,'
+             . ' though of course bug reports are always welcomed.');
+    }
+
+    # Format and return the output.
+    if ($format eq 'text') {
+        return wrap_paragraphs($indent, dtml_to_text(@text));
+    } elsif ($format eq 'html') {
+        return wrap_paragraphs('HTML', $indent, dtml_to_html(@text));
+    }
+}
+
+=back
+
+=head1 DIAGNOSTICS
+
+The following exceptions may be thrown:
+
+=over 4
+
+=item no tag specified
+
+The Lintian::Tag::Info::new constructor was called without passing a tag
+as an argument.
+
+=item unknown output format %s
+
+An unknown output format was passed as the FORMAT argument of
+description().  FORMAT must be either C<text> or C<html>.
+
+=back
+
+The following fatal internal errors may be reported:
+
+=over 4
+
+=item can't open %s: %s
+
+The specified file, which should be part of the standard Lintian data
+files, could not be opened.  The file may be missing or have the wrong
+permissions.
+
+=item missing Check-Script field in %s
+
+The specified check description file has no Check-Script field in its
+header section.  This probably indicates the file doesn't exist or has
+some significant formatting error.
+
+=item missing Tag field in %s
+
+The specified check description file has a tag section that has no Tag
+field.
+
+=back
+
+=head1 FILES
+
+=over 4
+
+=item LINTIAN_ROOT/checks/*.desc
+
+The tag description files, from which tag metadata is read.  All files
+matching this shell glob expression will be read looking for tag data.
+
+=item LINTIAN_ROOT/data/output/manual-references
+
+Information about manual references.  Each non-comment, non-empty line of
+this file contains four fields separated by C<::>.  The first field is the
+name of the manual, the second field is the section or empty for data
+about the whole manual, the third field is the title, and the fourth field
+is the URL.  The URL is optional.
+
+=back
+
+=head1 ENVIRONMENT
+
+=over 4
+
+=item LINTIAN_ROOT
+
+This variable specifies Lintian's root directory.  It defaults to
+F</usr/share/lintian> if not set.  The B<lintian> program normally takes
+care of setting it.
+
+=back
+
+=head1 AUTHOR
+
+Originally written by Russ Allbery <rra@debian.org> for Lintian.
+
+=head1 SEE ALSO
+
+lintian(1)
+
+=cut
+
+1;
+
+# Local Variables:
+# indent-tabs-mode: nil
+# cperl-indent-level: 4
+# End:
+# vim: syntax=perl sw=4 sts=4 ts=4 et shiftround
diff --git a/lib/Manual_refs.pm b/lib/Manual_refs.pm
deleted file mode 100644
index 8dd3708..0000000
--- a/lib/Manual_refs.pm
+++ /dev/null
@@ -1,42 +0,0 @@
-# Copyright (C) 1998 Christian Schwarz
-#
-# 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
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program.  If not, you can find it on the World Wide
-# Web at http://www.gnu.org/copyleft/gpl.html, or write to the Free
-# Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
-# MA 02110-1301, USA.
-
-use strict;
-
-our %refs;
-
-my $lib = defined $ENV{LINTIAN_ROOT} ?  "$ENV{LINTIAN_ROOT}/" : "";
-
-open (REFS, '<', "${lib}lib/manual_refs")
-    or die "Could not open manual_refs: $!";
-
-while(<REFS>) {
-    chomp;
-    next if not m/^(.+?)::(.*?)::(.+?)::(.*?)$/;
-
-    my ($man, $section, $title, $u) = split('::');
-    $section = '0' if $section eq "";
-    $refs{$man}{$section}{title} = $title;
-    $refs{$man}{$section}{url} = $u;
-}
-
-close REFS;
-
-1;
-
-# vim: sw=4 sts=4 ts=4 et sr
diff --git a/lib/Read_taginfo.pm b/lib/Read_taginfo.pm
deleted file mode 100644
index 0aaa6c7..0000000
--- a/lib/Read_taginfo.pm
+++ /dev/null
@@ -1,167 +0,0 @@
-# Hey emacs! This is a -*- Perl -*- script!
-# Read_taginfo -- Perl utility function to read Lintian's tag information
-
-# Copyright (C) 1998 Christian Schwarz and Richard Braakman
-#
-# 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
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program.  If not, you can find it on the World Wide
-# Web at http://www.gnu.org/copyleft/gpl.html, or write to the Free
-# Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
-# MA 02110-1301, USA.
-
-package Read_taginfo;
-
-use Exporter;
-our @ISA    = qw(Exporter);
-our @EXPORT = qw(read_tag_info format_tag_description);
-
-my $LINTIAN_ROOT = $ENV{'LINTIAN_ROOT'} || '/usr/share/lintian';
-my $debug = $ENV{'LINTIAN_DEBUG'} || 0;
-
-use lib "$ENV{'LINTIAN_ROOT'}/lib";
-use Util;
-use Text_utils;
-use Manual_refs;
-
-use strict;
-
-srand;
-
-our %refs; # from Manual_refs
-
-# load information about checker scripts
-sub read_tag_info {
-    my ($type) = @_;
-
-    my $dtml_convert;
-    my %tag_info;
-    if (defined $type && $type eq 'html') {
-	$dtml_convert = \&dtml_to_html;
-    }
-
- #   $debug = 2;
-    for my $f (<$LINTIAN_ROOT/checks/*.desc>) {
-	print "N: Reading checker description file $f ...\n" if $debug >= 2;
-
-	my @secs = Util::read_dpkg_control($f);
-	$secs[0]->{'check-script'} or fail("error in description file $f: `Check-Script:' not defined");
-
-	for (my $i=1; $i<=$#secs; $i++) {
-	    (my $tag = $secs[$i]->{'tag'}) or fail("error in description file $f: section $i does not have a `Tag:'");
-	    $tag_info{$tag} = format_tag_description($secs[$i], 0, $dtml_convert);
-	}
-    }
-
-    return \%tag_info;
-}
-
-sub format_tag_description {
-    my $tag=shift;
-    my $indent=shift;
-    my $dtml_convert=shift;
-
-    if (not defined $dtml_convert) {
-	$dtml_convert = \&dtml_to_text;
-    }
-
-    my @foo = split_paragraphs($tag->{'info'});
-    if ($tag->{'ref'}) {
-	push(@foo,"");
-	push(@foo,format_ref($tag->{'ref'}));
-    }
-
-    if ($tag->{'severity'} and $tag->{'certainty'}) {
-	push(@foo, "");
-	push(@foo, "Severity: $tag->{'severity'}; " .
-	           "Certainty: $tag->{'certainty'}");
-    }
-
-    if ($tag->{'experimental'}) {
-	push(@foo,"");
-	push(@foo,"Please note that this tag is marked Experimental, which "
-	     . "means that the code that generates it is not as well tested "
-	     . "as the rest of Lintian, and might still give surprising "
-	     . "results.  Feel free to ignore Experimental tags that do not "
-	     . "seem to make sense, though of course bug reports are always "
-	     . "welcomed.");
-    }
-
-    if ($indent) {
-	return wrap_paragraphs(" " x $indent, join("\n",&$dtml_convert(@foo)));
-    } else {
-	return join("\n",&$dtml_convert(@foo));
-    }
-}
-
-sub manual_ref {
-    my ($man, $sub) = @_;
-    my $numbered = ($sub =~ /[A-Z\d\.]+/) ? 1 : 0;
-    my $chapter = ($sub =~ /^[\d]+$/) ? 1 : 0;
-    my $appendix = ($sub =~ /^[A-Z]+$/) ? 1 : 0;
-
-    return "" if not exists $refs{$man}{0};
-
-    my $man_title = $refs{$man}{0}{title};
-    my $man_url = $refs{$man}{0}{url};
-    my $text = "<a href='$man_url'>$man_title</a>";
-
-    my $div = '';
-    $div = "section $sub " if $numbered;
-    $div = "chapter $sub " if $chapter;
-    $div = "appendix $sub " if $appendix;
-
-    if (exists $refs{$man}{$sub}) {
-        my $sub_title = $refs{$man}{$sub}{title};
-        my $sub_url = $refs{$man}{$sub}{url};
-        $text .= " $div(<a href='$sub_url'>$sub_title</a>)";
-    }
-
-    if (not $man_url) {
-        my @arr = ( $text );
-        $text = join('', dtml_to_text(@arr));
-    }
-
-    return $text;
-}
-
-sub format_ref {
-    my ($header) = @_;
-    my $text = '';
-    my @list;
-
-    foreach my $ref (split(/,\s?/, $header)) {
-        if ($ref =~ /^([\w-]+)\s(.+)$/) {
-            $text = manual_ref($1, $2);
-        } elsif ($ref =~ /^([\w_-]+)\((\d)\)$/) {
-            $text = "the <a href='http://manpages.debian.net/cgi-bin/";.
-                    "man.cgi?query=$1&sektion=$2'>$ref</a> manual page";
-        } elsif ($ref =~ /^(?:ftp|https?):\/\//) {
-            $text = "<a href='$ref'>$ref</a>";
-        }
-        push(@list, $text) if $text;
-    }
-
-    if ($#list >= 2) {
-        $text = join(', ', splice(@list , 0, $#list));
-        $text = "Refer to $text, and @list for details.";
-    } elsif ($#list >= 0) {
-        $text = join(' and ', @list);
-        $text = "Refer to $text for details.";
-    }
-
-    return $text;
-}
-
-1;
-
-# vim: sw=4 sts=4 ts=4 et sr
diff --git a/lib/Util.pm b/lib/Util.pm
index bea8da5..3f5e06d 100644
--- a/lib/Util.pm
+++ b/lib/Util.pm
@@ -23,8 +23,14 @@ package Util;
 use strict;
 
 use Exporter;
-our @ISA = qw(Exporter);
-our @EXPORT = qw(parse_dpkg_control
+
+# Force export as soon as possible, since some of the modules we load also
+# depend on us and the sequencing can cause things not to be exported
+# otherwise.
+our (@ISA, @EXPORT);
+BEGIN {
+    @ISA = qw(Exporter);
+    @EXPORT = qw(parse_dpkg_control
 	read_dpkg_control
 	get_deb_info
 	get_dsc_info
@@ -38,6 +44,7 @@ our @EXPORT = qw(parse_dpkg_control
 	gunzip_file
 	touch_file
 	perm2oct);
+}
 
 use FileHandle;
 use Lintian::Command qw(spawn);
diff --git a/reporting/html_reports b/reporting/html_reports
index 818bfc6..7c67d24 100755
--- a/reporting/html_reports
+++ b/reporting/html_reports
@@ -22,6 +22,7 @@
 # MA 02110-1301, USA.
 
 use strict;
+
 use File::Copy qw(copy);
 use URI::Escape;
 use Text::Template ();
@@ -52,8 +53,8 @@ $ENV{'LINTIAN_ROOT'} = $LINTIAN_ROOT;
 
 # Import Lintian Perl libraries.
 use lib "$ENV{LINTIAN_ROOT}/lib";
+use Lintian::Tag::Info ();
 use Read_pkglists;
-use Read_taginfo;
 use Text_utils;
 use Util;
 
@@ -61,9 +62,6 @@ use Util;
 # FIXME: Read_pkglists should return this information instead.
 our (%binary_info, %source_info, %udeb_info, %bin_src_ref);
 
-# Get the tag information from the Lintian *.desc files.
-our %tag_info = %{ read_tag_info('html') };
-
 # Get additional tag information.
 our %tag_extra = ();
 
@@ -428,9 +426,10 @@ for my $id (keys %clean) {
 # Create the pages for each tag.  Each page shows the extended description for
 # the tag and all the packages for which that tag was issued.
 for my $tag (sort keys %by_tag) {
+    my $info = Lintian::Tag::Info->new($tag);
     my $description;
-    if ($tag_info{$tag}) {
-        $description = wrap_paragraphs('HTML', '    ', $tag_info{$tag});
+    if ($info) {
+        $description = $info->description('html', '    ');
     } else {
         $description = "    <p>Can't find description of tag $tag.</p>";
     }

-- 
Debian package checker


Reply to: