NAME
unifdef , unifdefall - remove preprocessor
conditionals from code
SYNOPSIS
[-cdeklnst ] [-I path ]
[-D sym [= val ] ] [-U sym ]
[-iD sym [= val ] ] [-iU sym ]
... [file ]
unifdefall [-I path ] ... file
DESCRIPTION
The utility selectively processes conditional
cpp(1)
directives. It removes from a file both the directives and any
additional text that they specify should be removed, while
otherwise leaving the file alone.
The utility acts on #if , #ifdef , #ifndef , #elif ,
#else and #endif lines, and it understands only the
commonly-used subset of the expression syntax for #if and
#elif lines. It handles integer values of symbols defined on
the command line, the Fn defined operator applied to symbols
defined or undefined on the command line, the operators ! , <
, > , <= , >= , == , != , && , || and
parenthesized expressions. Anything that it does not understand is
passed through unharmed. It only processes #ifdef and
#ifndef directives if the symbol is specified on the command
line, otherwise they are also passed through unchanged. By default,
it ignores #if and #elif lines with constant
expressions, or they may be processed by specifying the -k
flag on the command line.
The utility also understands just enough about C to know when
one of the directives is inactive because it is inside a comment,
or affected by a backslash-continued line. It spots
unusually-formatted preprocessor directives and knows when the
layout is too odd to handle.
A script called unifdefall can be used to remove all
conditional cpp(1) directives
from a file. It uses -s and cpp -dM to get lists of
all the controlling symbols and their definitions (or lack
thereof), then invokes with appropriate arguments to process the
file.
Available options:
- -D sym [= val ]
- Specify that a symbol is defined, and optionally specify what
value to give it for the purpose of handling #if and
#elif directives.
- -U sym
- Specify that a symbol is undefined. If the same symbol appears
in more than one argument, the last occurrence dominates.
- -c
- If the -c flag is specified, then the operation of is
complemented, i.e., the lines that would have been removed or
blanked are retained and vice versa.
- -d
- Turn on printing of degugging messages.
- -e
- Because processes its input one line at a time, it cannot
remove preprocessor directives that span more than one line. The
most common example of this is a directive with a multi-line
comment hanging off its right hand end. By default, if has to
process such a directive, it will complain that the line is too
obfuscated. The -e option changes the behaviour so that,
where possible, such lines are left unprocessed instead of
reporting an error.
- -k
- Process #if and #elif lines with constant
expressions. By default, sections controlled by such lines are
passed through unchanged because they typically start ``#if
0 '' and are used as a kind of comment to sketch out future or
past development. It would be rude to strip them out, just as it
would be for normal comments.
- -l
- Replace removed lines with blank lines instead of deleting
them.
- -n
- Add #line directives to the output following any deleted
lines, so that errors produced when compiling the output file
correspond to line numbers in the input file.
- -s
- Instead of processing the input file as usual, this option
causes to produce a list of symbols that appear in expressions that
understands. It is useful in conjunction with the -dM option
of cpp(1)
for creating command lines.
- -t
- Disables parsing for C comments and line continuations, which
is useful for plain text.
- -iD sym [= val ]
- -iU sym
- Ignore #ifdef s If your C code uses #ifdef s to
delimit non-C lines, such as comments or code which is under
construction, then you must tell which symbols are used for that
purpose so that it will not try to parse comments and line
continuations inside those #ifdef s One specifies ignored
symbols with -iD sym [= val ] and -iU
sym similar to -D sym [= val ] and
-U sym above.
- -I path
- Specifies to unifdefall an additional place to look for
#include files. This option is ignored by for compatibility
with cpp(1) and to
simplify the implementation of unifdefall
The utility copies its output to stdout and will take its
input from stdin if no file argument is given.
The utility works nicely with the -D sym option of
diff(1).
EXIT STATUS
The utility exits 0 if the output is an exact
copy of the input, 1 if not, and 2 if in trouble.
DIAGNOSTICS
- Too many levels of nesting.
- Inappropriate
- #elif #else or #endif
- Obfuscated preprocessor control line.
- Premature
- EOF (with the line number of the most recent
unterminated #if )
- EOF
- in comment.
SEE ALSO
cpp(1), diff(1)
HISTORY
The command appeared in BSD 4.3 ANSI~C
support was added in Fx 4.7 .
BUGS
Expression evaluation is very limited.
Preprocessor control lines split across more than one physical
line (because of comments or backslash-newline) cannot be handled
in every situation.
Trigraphs are not recognized.
There is no support for symbols with different definitions at
different points in the source file.
The text-mode and ignore functionality does not correspond to
modern cpp(1) behaviour.