#!/usr/bin/env perl

# the following #defined macros are really used as data types, and should
# be converted to typedefs.
my @type_macros = qw(CHARTYPE ENCODING STRING
                     Parrot_CharType Parrot_Encoding Parrot_String);

die "Usage: $0 <c source files>\n" unless @ARGV;

$|=1;
use strict;
use lib 'lib';

use Parrot::Config;
use C::Scan;

my @incdirs;
my $cc_inc  = $PConfig{'cc_inc'};
my $ccflags = $PConfig{'ccflags'};
while ($cc_inc  =~ s/-I(\S+)//g) { push @incdirs, $1; }
while ($ccflags =~ s/-I(\S+)//g) { push @incdirs, $1; }
my $i_flags = join ' ', map { "-I$_" } @incdirs;

my %all_errors;
foreach my $file (@ARGV) {
    next unless ($file =~ /\.[ch]$/);
    
    print STDERR "Scanning $file..";
    my $c = new C::Scan 'filename' => $file,
                        'add_cppflags' => $ccflags;
    $c->set('includeDirs' => \@incdirs);
    $/="\n";  # i don't know why, but this is necessary.
    
    my $errors = 0;
    local $SIG{__WARN__} = sub { $errors++; $all_errors{"@_"}=1; };
    my $typedefs = $c->get('typedef_hash');

#    my $defines = $c->get('defines_no_args_full');
#    foreach (keys %$defines) {
#	next unless (length($defines->{$_}) >= 3 &&
#		     $defines->{$_} !~ /\n/);
#	  
#	$typedefs->{$_}="maybe";	    
#    }
    
    foreach (@type_macros) {
        $typedefs->{$_}="#defined";
    }   
    
    # now a little trick.  Weed out the ones we know aren't used.
    open(F, "<$file") || die "Can't read $file: $!\n";
    {
        local $/=undef;
        my $contents = <F>;

	foreach (keys %$typedefs) {
            delete $typedefs->{$_} unless ($contents =~ /\Q$_\E/);	    
	}
    }
    close(F);
    
    print STDERR "$errors parse errors.  " if ($errors);
    print STDERR "Found " . scalar(keys %$typedefs) . " typedefs.\n";
    my $cmd = "indent -kr -nce -sc -cp0 -l79 -lc79 -psl -nut -cdw -ncs -lps";
    foreach (sort keys %$typedefs) {
        $cmd .= " -T $_";
    }
    $cmd .= " $file";
    
    print "Running \"$cmd\"\n";
    system($cmd);
}   

#if (%all_errors) {
#    print STDERR "The following parse errors occurred:\n";
#    foreach (sort keys %all_errors) {
#        print;
#    }
#}
