4
# script takes the output of cpp -dD and a header name and
5
# trims the cpp output to only include output that came from
8
# This program treats the output of cpp as a state machine
9
# inputs and only outputs lines that exist while the state
10
# machine is in the state that represents the given header.
14
my $compress_functions = 0;
17
for (my $i = 0; $i <= $#ARGV; $i++) {
18
if ($ARGV[$i] eq '-m') {
20
} if ($ARGV[$i] eq '-f') {
21
$compress_functions = 1;
28
printf "Need the name of a header!\n";
37
# check for lines beginning with '# <number> \"'
39
if ($line =~ m/^# \d+ \"*/) {
41
# If the line matches this pattern CPP switched
42
# state to the given header from another or this
43
# header, and we will print output until state
46
# if the line does not match this pattern CPP
47
# switched state away from this header or state
48
# remains away from this header.
50
if ($line =~ m/^# \d+ \"$header\"*/) {
51
#printf "state $state_on to 1 because of $line";
54
#printf "state $state_on to 0 because of $line";
62
# cpp already compresses multi-line macros down to a single
63
# line for us so we don't have to handle multi-line macros here.
65
if ($line =~ m/^\s*#/) {
70
# detect and print multi-line functions as a single line
71
# so that we can do simple grep filtering later.
73
if ($compress_functions) {
77
if (! ($line =~ m/^\s*#/)) {
79
# ensure line wrapping won't occur.
81
#print "function line $line";
84
if ($line =~ m/^.*;.*$/) {
85
my $last_terminated = ($line =~ m/^.*;$/) ? 1 : 0;
86
@line = split(";", $line);
87
for (my $i = 0; $i <= $#line; $i++) {
88
#print "\nindex $i terminated? $last_terminated token $line[$i]\n";
90
if ($last_terminated) {
91
print $line[$i] . ";\n";
97
print $line[$i] . ";\n";