1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74
|
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;
|