File: CParse.pm

package info (click to toggle)
icheck 0.9.7-9
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 2,352 kB
  • sloc: perl: 12,152; makefile: 202; ansic: 100
file content (74 lines) | stat: -rw-r--r-- 1,492 bytes parent folder | download | duplicates (6)
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;