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