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