Blame modversions

Bernhard M. Wiedemann 6ebc4a
#! /usr/bin/perl -w
Bernhard M. Wiedemann 6ebc4a
Bernhard M. Wiedemann 6ebc4a
use File::Basename;
Bernhard M. Wiedemann 6ebc4a
use File::Path;
Bernhard M. Wiedemann 6ebc4a
use File::Find;
Bernhard M. Wiedemann 6ebc4a
use Getopt::Long;
Bernhard M. Wiedemann 6ebc4a
use strict;
Bernhard M. Wiedemann 6ebc4a
Bernhard M. Wiedemann 6ebc4a
my %symbol_type_name = (
Bernhard M. Wiedemann 6ebc4a
    n => 'normal', t => 'typedef', e => 'enum', s => 'struct', u => 'union',
Bernhard M. Wiedemann 6ebc4a
    E => 'enum constant'
Bernhard M. Wiedemann 6ebc4a
);
Bernhard M. Wiedemann 6ebc4a
Bernhard M. Wiedemann 6ebc4a
my %definitions;
Bernhard M. Wiedemann 6ebc4a
my %override;
Bernhard M. Wiedemann 6ebc4a
my %override_locally;
Bernhard M. Wiedemann 6ebc4a
my %locally_unknown;
Bernhard M. Wiedemann 6ebc4a
my %locally_defined;
Bernhard M. Wiedemann 6ebc4a
Bernhard M. Wiedemann 6ebc4a
sub expand_types($);
Bernhard M. Wiedemann 6ebc4a
sub expand_types($) {
Bernhard M. Wiedemann 6ebc4a
    my ($definition) = @_;
Bernhard M. Wiedemann 6ebc4a
    local ($_, $1, $2);
Bernhard M. Wiedemann 6ebc4a
Bernhard M. Wiedemann 6ebc4a
    my @defn = split ' ', $definition;
Bernhard M. Wiedemann 6ebc4a
    for (@defn[1..$#defn]) {
Bernhard M. Wiedemann 6ebc4a
	if (/^(.)#(.*)/) {
Bernhard M. Wiedemann 6ebc4a
	    #print "<<$defn[0] : $_>>\n";
Bernhard M. Wiedemann 6ebc4a
	    next if exists $locally_defined{$_};
Bernhard M. Wiedemann 6ebc4a
	    $locally_defined{$_} = 1;
Bernhard M. Wiedemann 6ebc4a
Bernhard M. Wiedemann 6ebc4a
	    if ($locally_unknown{$_}) {
Bernhard M. Wiedemann 6ebc4a
                print "override " if $override_locally{$_};
Bernhard M. Wiedemann 6ebc4a
		print "$_ $symbol_type_name{$1} $2 { UNKNOWN } \n";
Bernhard M. Wiedemann 6ebc4a
	    } else {
Bernhard M. Wiedemann 6ebc4a
		if (!exists $definitions{$_}) {
Bernhard M. Wiedemann 6ebc4a
		    die "Missing definition of $symbol_type_name{$1} $2\n";
Bernhard M. Wiedemann 6ebc4a
		}
Bernhard M. Wiedemann 6ebc4a
		expand_types("$_ $definitions{$_}");
Bernhard M. Wiedemann 6ebc4a
	    }
Bernhard M. Wiedemann 6ebc4a
	}
Bernhard M. Wiedemann 6ebc4a
    }
Bernhard M. Wiedemann 6ebc4a
    print "override " if $override_locally{$defn[0]};
Bernhard M. Wiedemann 6ebc4a
    print "$definition\n";
Bernhard M. Wiedemann 6ebc4a
}
Bernhard M. Wiedemann 6ebc4a
Bernhard M. Wiedemann 6ebc4a
sub pack_dump($$) {
Bernhard M. Wiedemann 6ebc4a
    my ($dir, $ext) = @_;
Bernhard M. Wiedemann 6ebc4a
    my @files;
Bernhard M. Wiedemann 6ebc4a
Bernhard M. Wiedemann 6ebc4a
    $ext = ".symtypes" unless defined $ext;
Bernhard M. Wiedemann 6ebc4a
    $dir =~ s/\/+$//;
Bernhard M. Wiedemann 6ebc4a
Bernhard M. Wiedemann 6ebc4a
    find(sub ($) { /\Q$ext\E$/ && push @files, $File::Find::name}, $dir);
Bernhard M. Wiedemann 6ebc4a
    map { s/^\Q$dir\E\/(.*)\Q$ext\E$/$1/ } @files;
Bernhard M. Wiedemann 6ebc4a
Bernhard M. Wiedemann 6ebc4a
    foreach my $file (sort @files) {
Bernhard M. Wiedemann 6ebc4a
	print "/* $file.o */\n";
Bernhard M. Wiedemann 6ebc4a
Bernhard M. Wiedemann 6ebc4a
	local *FD;
Bernhard M. Wiedemann 6ebc4a
	open FD, "< $dir/$file$ext"
Bernhard M. Wiedemann 6ebc4a
	    or die "$dir/$file$ext: $!\n";
Bernhard M. Wiedemann 6ebc4a
	while (<FD>) {
Bernhard M. Wiedemann 6ebc4a
	    chomp;
Bernhard M. Wiedemann 6ebc4a
Bernhard M. Wiedemann 6ebc4a
	    my $override = "";
Bernhard M. Wiedemann 6ebc4a
	    if (s/^override //) {
Bernhard M. Wiedemann 6ebc4a
		$override = $&;
Bernhard M. Wiedemann 6ebc4a
	    }
Bernhard M. Wiedemann 6ebc4a
Bernhard M. Wiedemann 6ebc4a
	    if (/^(\S)#(\S+)\s*(.*)/) {
Bernhard M. Wiedemann 6ebc4a
		my $sym = "$1#$2";
Bernhard M. Wiedemann 6ebc4a
		my $definition = $3;
Bernhard M. Wiedemann 6ebc4a
Bernhard M. Wiedemann 6ebc4a
		if (/^$sym\s+$symbol_type_name{$1}\s+$2\s+{\s+UNKNOWN\s+}\s*$/) {
Bernhard M. Wiedemann 6ebc4a
		    $_ = $override . substr($sym, 0, 1) . "##" . substr($sym, 2);
Bernhard M. Wiedemann 6ebc4a
		} else {
Bernhard M. Wiedemann 6ebc4a
		    if (exists $definitions{$sym} && $definitions{$sym} eq $definition) {
Bernhard M. Wiedemann 6ebc4a
			if (($override ne "") == (exists $override{$sym})) {
Bernhard M. Wiedemann 6ebc4a
			    next;
Bernhard M. Wiedemann 6ebc4a
			}
Bernhard M. Wiedemann 6ebc4a
			$_ = "$override$sym";
Bernhard M. Wiedemann 6ebc4a
		    } else {
Bernhard M. Wiedemann 6ebc4a
			$definitions{$sym} = $definition;
Bernhard M. Wiedemann 6ebc4a
			if ($override eq "") {
Bernhard M. Wiedemann 6ebc4a
			    delete $override{$sym};
Bernhard M. Wiedemann 6ebc4a
			} else {
Bernhard M. Wiedemann 6ebc4a
			    $override{$sym} = 1;
Bernhard M. Wiedemann 6ebc4a
			    $_ = "$override$_";
Bernhard M. Wiedemann 6ebc4a
			}
Bernhard M. Wiedemann 6ebc4a
		    }
Bernhard M. Wiedemann 6ebc4a
		}
Bernhard M. Wiedemann 6ebc4a
	    } elsif ($override) {
Bernhard M. Wiedemann 6ebc4a
		    $_ = "$override$_";
Bernhard M. Wiedemann 6ebc4a
	    }
Bernhard M. Wiedemann 6ebc4a
	    print "$_\n";
Bernhard M. Wiedemann 6ebc4a
	}
Bernhard M. Wiedemann 6ebc4a
	close FD;
Bernhard M. Wiedemann 6ebc4a
	print "\n";
Bernhard M. Wiedemann 6ebc4a
    }
Bernhard M. Wiedemann 6ebc4a
}
Bernhard M. Wiedemann 6ebc4a
Bernhard M. Wiedemann 6ebc4a
sub unpack_dump($$) {
Bernhard M. Wiedemann 6ebc4a
    my ($dir, $ext) = @_;
Bernhard M. Wiedemann 6ebc4a
Bernhard M. Wiedemann 6ebc4a
    $ext = ".symref" unless defined $ext;
Bernhard M. Wiedemann 6ebc4a
Bernhard M. Wiedemann 6ebc4a
    while (<STDIN>) {
Bernhard M. Wiedemann 6ebc4a
	next if /^$/;
Bernhard M. Wiedemann 6ebc4a
	chomp;
Bernhard M. Wiedemann 6ebc4a
Bernhard M. Wiedemann 6ebc4a
	if (/^\/\* (.*)\.o \*\//) {
Bernhard M. Wiedemann 6ebc4a
	    close STDOUT;
Bernhard M. Wiedemann 6ebc4a
	    mkpath(dirname("$dir/$1$ext"));
Bernhard M. Wiedemann 6ebc4a
	    open STDOUT, "> $dir/$1$ext"
Bernhard M. Wiedemann 6ebc4a
		or die "$dir/$1$ext: $!\n";
Bernhard M. Wiedemann 6ebc4a
	    %locally_defined = ();
Bernhard M. Wiedemann 6ebc4a
	    %locally_unknown = ();
Bernhard M. Wiedemann 6ebc4a
	    %override_locally = %override;
Bernhard M. Wiedemann 6ebc4a
	    next;
Bernhard M. Wiedemann 6ebc4a
	}
Bernhard M. Wiedemann 6ebc4a
Bernhard M. Wiedemann 6ebc4a
	my $override = /^override\s/;
Bernhard M. Wiedemann 6ebc4a
	s/^override\s//;
Bernhard M. Wiedemann 6ebc4a
Bernhard M. Wiedemann 6ebc4a
	if (/^([^ ])#(#?)([^ ]+) *(.*)$/) {
Bernhard M. Wiedemann 6ebc4a
	    my $sym = "$1#$3";
Bernhard M. Wiedemann 6ebc4a
Bernhard M. Wiedemann 6ebc4a
	    if ($4 ne "") {
Bernhard M. Wiedemann 6ebc4a
		if (/\s+{\s+UNKNOWN\s+}\s*$/) {
Bernhard M. Wiedemann 6ebc4a
		    $locally_unknown{$sym} = 1;
Bernhard M. Wiedemann 6ebc4a
		    $override_locally{$sym} = $override;
Bernhard M. Wiedemann 6ebc4a
		} else {
Bernhard M. Wiedemann 6ebc4a
		    $definitions{$sym} = $4;
Bernhard M. Wiedemann 6ebc4a
		    $locally_unknown{$sym} = 0;
Bernhard M. Wiedemann 6ebc4a
		    $override{$sym} = $override;
Bernhard M. Wiedemann 6ebc4a
		    $override_locally{$sym} = $override;
Bernhard M. Wiedemann 6ebc4a
		}
Bernhard M. Wiedemann 6ebc4a
	    } else {
Bernhard M. Wiedemann 6ebc4a
		$locally_unknown{$sym} = ($2 ne "");
Bernhard M. Wiedemann 6ebc4a
		$override_locally{$sym} = $override;
Bernhard M. Wiedemann 6ebc4a
	    }
Bernhard M. Wiedemann 6ebc4a
	    next;
Bernhard M. Wiedemann 6ebc4a
	} elsif (/^([^# ]*)/) {
Bernhard M. Wiedemann 6ebc4a
		$override_locally{$1} = $override;
Bernhard M. Wiedemann 6ebc4a
	}
Bernhard M. Wiedemann 6ebc4a
	expand_types($_);
Bernhard M. Wiedemann 6ebc4a
    }
Bernhard M. Wiedemann 6ebc4a
}
Bernhard M. Wiedemann 6ebc4a
Bernhard M. Wiedemann 6ebc4a
my ($pack, $unpack, $ext);
Bernhard M. Wiedemann 6ebc4a
GetOptions("pack" => \$pack, "unpack" => \$unpack, "ext:s" => \$ext)
Bernhard M. Wiedemann 6ebc4a
    && ($pack || $unpack) && @ARGV == 1
Bernhard M. Wiedemann 6ebc4a
    or die "USAGE:\t$0 [--ext extension] --pack {dir} > file\n" .
Bernhard M. Wiedemann 6ebc4a
		 "\t$0 [--ext extension] --unpack {dir} < file\n";
Bernhard M. Wiedemann 6ebc4a
Bernhard M. Wiedemann 6ebc4a
pack_dump($ARGV[0], $ext) if $pack;
Bernhard M. Wiedemann 6ebc4a
unpack_dump($ARGV[0], $ext) if $unpack;