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

lintian: r489 - in trunk: frontend lib



Author: djpig
Date: 2005-09-17 02:06:30 +0200 (Sat, 17 Sep 2005)
New Revision: 489

Modified:
   trunk/frontend/lintian
   trunk/lib/Tags.pm
Log:
Complete rewrite of lib/Tags.pm to be able to add new tag handling soon.
For now a little bit of compatibility code hides this all from the user
and the checks. Some little changes in frontend/lintian were required,
though.


Modified: trunk/frontend/lintian
===================================================================
--- trunk/frontend/lintian	2005-09-16 23:07:10 UTC (rev 488)
+++ trunk/frontend/lintian	2005-09-17 00:06:30 UTC (rev 489)
@@ -1203,7 +1203,7 @@
     }
 
     if ($action eq 'check') { 	# read override file
-	Tags::pkg_reset($long_type eq 'binary' ? $pkg : "$pkg $long_type");
+	Tags::set_pkg( $file, $pkg, "", "", $long_type );
 
 
 	unless ($no_override) 

Modified: trunk/lib/Tags.pm
===================================================================
--- trunk/lib/Tags.pm	2005-09-16 23:07:10 UTC (rev 488)
+++ trunk/lib/Tags.pm	2005-09-17 00:06:30 UTC (rev 489)
@@ -2,6 +2,7 @@
 # $Id$
 
 # Copyright (C) 1998-2004 Various authors
+# Copyright (C) 2005 Frank Lichtenheld <frank@lichtenheld.de>
 #
 # 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
@@ -22,24 +23,23 @@
 package Tags;
 use strict;
 
-use Util;
-
 use Exporter;
 our @ISA = qw(Exporter);
 our @EXPORT = qw(tag);
 
-my $LINTIAN_ROOT = $::LINTIAN_ROOT;
-
-# Can also be more precise later on (only verbose with lab actions) but for
-# now this will do --Jeroen
-my $verbose = $::verbose;
-my $debug = $::debug;
-
-# What to print between the "E:" and the tag, f.e. "package source"
-our $prefix = undef;
+# configuration variables and defaults
+our $verbose = $::verbose;
+our $debug = $::debug;
 our $show_info = 0;
+our $show_overrides = 0;
+our $output_format = 'default';
+our $min_severity = 1;
+our $max_severity = 99;
+our $min_significance = 1;
+our $max_significance = 99;
 
-# The master hash with all tag info. Key is a hash too, with these stuff:
+# The master hash with all tag info. Key is the tag name, value another hash
+# with the following keys:
 # - tag: short name
 # - type: error/warning/info/experimental
 # - info: Description in HTML
@@ -47,53 +47,229 @@
 # - experimental: experimental status (possibly undef)
 my %tags;
 
-our $show_overrides;
-# in the form overrides->tag or full thing
-my %overrides;
+# Statistics per file. Key is the filename, value another hash with the
+# following keys:
+# - overrides
+# - tags
+# - severity
+# - significance
+my %stats;
 
-my $codes = { 'error' => 'E' , 'warning' => 'W' , 'info' => 'I' };
+# Info about a specific file. Key is the the filename, value another hash
+# with the following keys:
+# - pkg: package name
+# - version: package version
+# - arch: package architecture
+# - type: one of 'binary', 'udeb' or 'source'
+# - overrides: hash with all overrides for this file as keys
+my %info;
 
+# Currently selected file (not package!)
+my $current;
 
-# TODO
-# - override support back in --> just the unused reporting
-# - be able to return whether any errors were there, better, full stats
+# Compatibility stuff
+my %codes = ( 'error' => 'E' , 'warning' => 'W' , 'info' => 'I' );
+my %type_to_sev = ( error => 3, warning => 1, info => 0 );
+my @sev_to_type = qw( info warning error error );
 
-# Call this function to add a certain tag, by supplying the info as a hash
+# Add a new tag, supplied as a hash reference
 sub add_tag {
 	my $newtag = shift;
-	fail("Duplicate tag: $newtag->{'tag'}")
-		if exists $tags{$newtag->{'tag'}};
-	
+	if (exists $tags{$newtag->{'tag'}}) {
+	    warn "Duplicate tag: $newtag->{'tag'}\n";
+	    return 0;
+	}
+
+	# smooth transition
+	$newtag->{type} = $sev_to_type[$newtag->{severity}]
+	    unless $newtag->{type};
+	$newtag->{significance} = 3 unless exists $newtag->{significance};
+	$newtag->{severity} = $type_to_sev{$newtag->{type}}
+	    unless exists $newtag->{severity};
 	$tags{$newtag->{'tag'}} = $newtag;
+	return 1;
 }
 
-# Used to reset the matched tags data
-sub pkg_reset {
-	$prefix = shift;
-	%overrides = ();
+# Add another file, will fail if there is already stored info about
+# the file
+sub set_pkg {
+    my ( $file, $pkg, $version, $arch, $type ) = @_;
+
+    if (exists $info{$file}) {
+	warn "File $file was already processed earlier\n";
+	return 0;
+    }
+
+    $current = $file;
+    $info{$file} = {
+	pkg => $pkg,
+	version => $version,
+	arch => $arch,
+	type => $type,
+	overrides => {},
+    };
+    $stats{$file} = {
+	severity => {},
+	significance => {},
+	tags => {},
+	overrides => {},
+    };
+
+    return 1;
 }
 
-# Add an override, string tag, string rest
+# select another file as 'current' without deleting or adding any information
+# the file must have been added with add_pkg
+sub select_pkg {
+    my ( $file ) = @_;
+
+    unless (exists $info{$file}) {
+	warn "Can't select package $file";
+	return 0;
+    }
+
+    $current = $file;
+    return 1;
+}
+
+# only delete the value of 'current' without deleting any stored information
+sub reset_pkg {
+    undef $current;
+    return 1;
+}
+
+# delete all the stored information (including tags)
+sub reset {
+    undef %stats;
+    undef %info;
+    undef %tags;
+    undef $current;
+    return 1;
+}
+
+# Add an override. If you specifiy two arguments, the first will be taken
+# as file to add the override to, otherwise 'current' will be assumed
 sub add_override {
-	my $tag = shift;
-	$overrides{$tag} = 0;
+    my ($tag, $file) = ( "", "" );
+    if (@_ > 1) {
+	($file, $tag) = @_;
+    } else {
+	($file, $tag) = ($current, @_);
+    }
+
+    unless ($file) {
+	warn "Don't know which package to add override $tag to";
+	return 0;
+    }
+
+    $info{$file}{overrides}{$tag}++;
+
+    return 1;
 }
 
+# Get the info hash for a tag back as a reference. The hash will be
+# copied first so that you can edit it safely
+sub get_tag_info {
+    my ( $tag ) = @_;
+    return { %{$tags{$tag}} } if exists $tags{$tag};
+    return undef;
+}
 
+sub check_range {
+    my ( $x, $min, $max ) = @_;
+
+    return -1 if $x < $min;
+    return 1 if $x > $max;
+    return 0;
+}
+
+# check if a certain tag has a override for the 'current' package
+sub check_overrides {
+    my ( $tag_info, $information ) = @_;
+
+    my $extra = '';
+    $extra = " @$information" if @$information;
+    $extra = '' if $extra eq ' ';
+    return $info{$current}{overrides}{$tag_info->{tag}}
+        if exists $info{$current}{overrides}{$tag_info->{tag}};
+    return $info{$current}{overrides}{"$tag_info->{tag}$extra"}
+        if exists $info{$current}{overrides}{"$tag_info->{tag}$extra"};
+
+    return '';
+}
+
+# sets all the overridden fields of a tag_info hash correctly
+sub check_need_to_show {
+    my ( $tag_info, $information ) = @_;
+    $tag_info->{overridden}{override} = check_overrides( $tag_info,
+							 $information );
+    my $min_sev = $show_info ? 0 : $min_severity; # compat hack
+    $tag_info->{overridden}{severity} = check_range( $tag_info->{severity},
+						     $min_sev,
+						     $max_severity );
+    $tag_info->{overridden}{significance} = check_range( $tag_info->{significance},
+							 $min_significance,
+							 $max_significance );
+}
+
+# records the stats for a given tag_info hash
+sub record_stats {
+    my ( $tag_info ) = @_;
+
+    for my $k (qw( severity significance tag )) {
+	$stats{$current}{$k}{$tag_info->{$k}}++;
+    }
+    for my $k (qw( severity significance override )) {
+	$stats{$current}{overrides}{$k}{$tag_info->{overridden}{$k}}++;
+    }
+}
+
+# get the statistics for a file (one argument) or for all files (no argument)
+sub get_stats {
+    my ( $file ) = @_;
+
+    return $stats{$file} if $file;
+    return \%stats;
+}
+
+sub print_tag {
+    my ( $pkg_info, $tag_info, $information ) = @_;
+
+    return if 
+	$tag_info->{overridden}{severity} != 0
+	|| $tag_info->{overridden}{significance} != 0
+	|| ( $tag_info->{overridden}{override} &&
+	     !$show_overrides);
+
+    my $extra = '';
+    $extra = " @$information" if @$information;
+    $extra = '' if $extra eq ' ';
+    my $code = $codes{$tag_info->{type}};
+    $code = 'O' if $tag_info->{overridden}{override};
+    my $type = '';
+    $type = " $pkg_info->{type}" if $pkg_info->{type} ne 'binary';
+
+    print "$code: $pkg_info->{pkg}$type: $tag_info->{tag}$extra\n";
+}
+
 sub tag {
-	my $tag = shift;
-	my $info = $tags{$tag};
-	return if not $show_info and $info->{'type'} eq 'info';
-	my $extra = '';
-	$extra = ' '.join(' ', @_) if $#_ >=0;
-	$extra = '' if $extra eq ' ';
-	my $code = $codes->{$info->{'type'}};
-	if (exists $overrides{$tag} or exists $overrides{"$tag$extra"}) {
-		return unless $show_overrides or $verbose;
-		$code = 'O';
-	}
+    my ( $tag, @information ) = @_;
+    unless ($current) {
+	warn "Tried to issue tag $tag without setting package\n";
+	return 0;
+    }
 
-	print "$code: $prefix: $tag$extra\n";
+    my $tag_info = get_tag_info( $tag );
+    unless ($tag_info) {
+	warn "Tried to issue unknown tag $tag\n";
+	return 0;
+    }
+    check_need_to_show( $tag_info, \@information );
+
+    record_stats( $tag_info );
+
+    print_tag( $info{$current}, $tag_info, \@information );
+    return 1;
 }
 
 1;



Reply to: