xref: /freebsd/contrib/unifdef/ifdef-how.pl (revision 09e32b2fddf5f673f76e2fffa415a73d99a6f309)
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