xref: /freebsd/contrib/unifdef/ifdef-how.pl (revision 2008043f386721d58158e37e0d7e50df8095942d)
1#!/usr/bin/perl
2
3use warnings;
4use strict;
5
6if (@ARGV != 2) {
7	die <<END;
8usage: ifdef-how <file> <line>
9
10Print the sequence of preprocessor conditionals which lead to the
11given line being retained after preprocessing. There is no output
12if the line is always retained. Conditionals that must be true are
13printed verbatim; conditionals that musy be false have their
14preprocessor keyword prefixed with NOT.
15
16Warning: this program does not parse comments or strings, so it will
17not handle tricky code correctly.
18END
19}
20
21my $file = shift;
22my $line = shift;
23
24open my $fh, '<', $file
25    or die "ifdef-how: open $file: $!\n";
26
27my @stack;
28while (<$fh>) {
29	last if $. == $line;
30	if (m{^\s*#\s*(if|ifdef|ifndef)\b}) {
31		push @stack, $_;
32	}
33	if (m{^\s*#\s*(elif|else)\b}) {
34		$stack[-1] =~ s{^(\s*#\s*)(?!NOT)\b}{${1}NOT}gm;
35		$stack[-1] .= $_;
36	}
37	if (m{^\s*#\s*endif\b}) {
38		pop @stack;
39	}
40}
41
42print @stack;
43