# Hey emacs! This is a -*- Perl -*- script!
# Lintian::Parser::Copyright -- debian copyright parser

# Copyright © 1998 Christian Schwarz
# Copyright © 2008 Mathieu Parent <math.parent@gmail.com>
#
# 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 Lintian::Parser::Copyright;
use strict;

use Exporter;
use Util;
our @ISA = qw(Exporter);
our @EXPORT = qw(parse_dpkg_copyright
	read_dpkg_copyright);

use FileHandle;

# general function to read dpkg copyright files
# arguments:
#    $filehandle 
# output:
#    list of hashes
#    (a hash contains one sections,
#    keys in hash are lower case letters of control fields
#    errors are sections also)
sub parse_dpkg_copyright {
    my ($COPYRIGHT) = @_;

    my @errors;
    my $cur_error = 0;
    my @data;
    my $cur_section = 0;
    my $open_section = 0;
    my $last_tag;
    my $line_number = 0;

    while (<$COPYRIGHT>) {
	chomp;
	$line_number++;

	# empty line? -> force new section
	if (m/^$/) {
	    if ($open_section) { # end of current section
		$cur_section++;
		$open_section = 0;
	    }
	}
	# new field?
	elsif (m/^(\S+):\s*(.*)$/o) {
	    my ($tag,$value) = (lc $1,$2);
	    #format-specification, files and notice always start a section
	    if($tag =~ /format-specification|files|notice/) {
		$cur_section++ if $open_section;
	    #license only start a section if the current section already have a license field
	    } elsif ($tag =~ /license/ and $data[$cur_section]->{'license'}) {
		$cur_section++ if $open_section;
	    #other known fields
	    } elsif($tag =~ /debianized-by|debianized-date|original-source-location|upstream-author|copyright|license/) {
		#do nothing
	    #unknown fields
	    } else {
		$errors[$cur_error]->{error} = 'unknown-field';
	        $errors[$cur_error]->{info} = "$tag";
		$cur_error++;
	    }
	    #fields already parsed for current section
	    if($data[$cur_section]->{$tag}) {
		$errors[$cur_error]->{error} = 'duplicate-field';
	        $errors[$cur_error]->{info} = "$tag in section $cur_section line $line_number";
		$cur_error++;
	    }
	    $open_section = 1;
	    $data[$cur_section]->{$tag} = $value;
	    $last_tag = $tag;
	}
	# continued field?
	elsif (m/^ (.*)$/o and $open_section) {
	    $data[$cur_section]->{$last_tag} .= "\n".$1;
	}
	#everything else	
	else {
	    $errors[$cur_error]->{error} = 'extra-line';
	    $errors[$cur_error]->{info} = "line $line_number";
	    $cur_error++;
	}
    }
    return (@errors,@data);
}

sub read_dpkg_copyright {
    my ($file) = @_;

    if (not Util::_ensure_file_is_sane($file)) {
	return undef;
    }

    my $COPYRIGHT = FileHandle->new;
    open($COPYRIGHT, '<', $file)
	or Util::fail("cannot open copyright file $file for reading: $!");
    my @data = parse_dpkg_copyright($COPYRIGHT);
    close($COPYRIGHT)
	or Util::fail("pipe for copyright file $file exited with status: $?");
    return @data;
}

1;
