package CParse;

use 5.6.0;
use strict;
use warnings;

use Exporter;

use CParse::Parser::Perl;
use CParse::Parser::PerlXS;

our @ISA = qw/Exporter/;
our @EXPORT = qw/parse_file/;

our $current_location = undef;

$::RD_HINT = 1 if $ENV{RD_HINT};
$::RD_TRACE = 1 if $ENV{RD_TRACE};

my $parser = $ENV{ICHECK_PARSER_XSUB} ? new CParse::Parser::PerlXS : new CParse::Parser::Perl;
die "Couldn't create parser" unless $parser;

sub parse_file
  {
    my $filename = shift;
    my @args = @_;

    my $fh;
    open($fh, "-|", "gcc", @args, "-E", "-x", "c-header", $filename) or die "Failed to spawn gcc: $!";

    my %line_map;

    my $current_line = 1;
    my $current_file = $filename;
    my @data;
    while (<$fh>)
      {
        chomp;
        if (/^#/)
          {
            if (/^# (\d+) "(.*)"((?: \d+)*)/)
              {
                ($current_line, $current_file, my $flags) = ($1, $2, $3);
                my %flags = map {$_=>1} split / /, $flags;
                next;
              }
          }
        else
          {
            my $data_line = scalar @data;
            $line_map{$data_line} = {file => $current_file, line => $current_line};
            push @data, $_;
          }
        $current_line++;
      }
    close $fh;

    if ($?)
      {
        exit 1;
      }

    my $unit = $parser->unit(\@data, \%line_map);

    unless (defined $unit)
      {
        print STDERR "Failed to parse file $filename\n";
        exit 1;
      }

    return $unit;
  }

1;
