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