#!/usr/bin/perl -w
# Merge several PCI ID lists to a single one. This script tries to be as agnostic
# of the details of the ID list as possible, so it should not break with future
# changes of the ID list format as long as they follow the same block structure.
# Greetings to Kurt Garloff who needed 300+ lines of code to give a wrong
# solution of the same problem.
#
# (c) 2007 Martin Mares <mj@ucw.cz>, GPLv2

use strict;

my %ids = ();
my %comments = ();
foreach our $file (@ARGV) {
	my $fn = ($file =~ /\.gz$/) ? "zcat $file |" : ($file =~ /\.bz2$/) ? "bzcat $file |" : $file;
	open F, $fn or die "Unable to open $file: $!";
	my @id = ();
	my $comm = "";
	sub err($) {
		print STDERR "Error in $file, line $.: @_\n";
		exit 1;
	}
	while (<F>) {
		if (/^(#.*)/) {
			$comm .= $_;
			next;
		}
		chomp;
		if (my ($indent, $id, $ignored, $name) = /^(\t*)(([0-9a-fA-Z]+ ?)*)((  |\t|$)\s*(.*))$/) {
			my $depth = length $indent;
			$depth <= @id or err "Mismatched indentation";
			@id = (@id[0..$depth-1], $id);
			my $i = join(":", @id);
			my $j = ($i =~ /[A-Z] /) ? "~$i" : $i;		# We want to sort special entries last
			if (exists $ids{$j} && $ids{$j} ne $name) {
				print STDERR "Warning: ID $i has two different definitions, using the one from $file\n";
			}
			$ids{$j} = $name;
			$comments{$j} = $comm if $comm;
		} elsif (!/^$/) {
			err "Parse error";
		}
		$comm = "";
	}
	close F;
}

print "# This file has been merged automatically from the following files:\n#\t", join("\n#\t", @ARGV), "\n\n";
foreach my $id (sort keys %ids) {
	my ($i, $j) = ($id, $id);
	$i =~ s/[^:]//g;
	$i =~ tr/:/\t/;
	$j =~ s/.*://g;	
	$j =~ s/^~//;
	print $comments{$id} if $comments{$id};
	print "$i$j$ids{$id}\n";
}
