86eea914a7
Fix a long-standing cpp compatibility bug: The -DFOO argument (without an explicit value) should define FOO to 1 not to the empty string. Add support for CRLF newlines, based on a suggestion from Mark Rushakoff. Obtained from: http://dotat.at/prog/unifdef/
408 lines
9.5 KiB
Groff
408 lines
9.5 KiB
Groff
.\" Copyright (c) 1985, 1991, 1993
|
|
.\" The Regents of the University of California. All rights reserved.
|
|
.\" Copyright (c) 2002 - 2010 Tony Finch <dot@dotat.at>. All rights reserved.
|
|
.\"
|
|
.\" This code is derived from software contributed to Berkeley by
|
|
.\" Dave Yost. It was rewritten to support ANSI C by Tony Finch.
|
|
.\"
|
|
.\" Redistribution and use in source and binary forms, with or without
|
|
.\" modification, are permitted provided that the following conditions
|
|
.\" are met:
|
|
.\" 1. Redistributions of source code must retain the above copyright
|
|
.\" notice, this list of conditions and the following disclaimer.
|
|
.\" 2. Redistributions in binary form must reproduce the above copyright
|
|
.\" notice, this list of conditions and the following disclaimer in the
|
|
.\" documentation and/or other materials provided with the distribution.
|
|
.\" 3. Neither the name of the University nor the names of its contributors
|
|
.\" may be used to endorse or promote products derived from this software
|
|
.\" without specific prior written permission.
|
|
.\"
|
|
.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
|
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
|
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
.\" SUCH DAMAGE.
|
|
.\"
|
|
.\" @(#)unifdef.1 8.2 (Berkeley) 4/1/94
|
|
.\" $dotat: unifdef/unifdef.1,v 1.63 2010/02/19 16:41:15 fanf2 Exp $
|
|
.\" $FreeBSD$
|
|
.\"
|
|
.Dd January 19, 2010
|
|
.Dt UNIFDEF 1
|
|
.Os
|
|
.Sh NAME
|
|
.Nm unifdef , unifdefall
|
|
.Nd remove preprocessor conditionals from code
|
|
.Sh SYNOPSIS
|
|
.Nm
|
|
.Op Fl BbcdeKknst
|
|
.Op Fl I Ns Ar path
|
|
.Op Fl D Ns Ar sym Ns Op = Ns Ar val
|
|
.Op Fl U Ns Ar sym
|
|
.Op Fl iD Ns Ar sym Ns Op = Ns Ar val
|
|
.Op Fl iU Ns Ar sym
|
|
.Ar ...
|
|
.Op Fl o Ar outfile
|
|
.Op Ar infile
|
|
.Nm unifdefall
|
|
.Op Fl I Ns Ar path
|
|
.Ar ...
|
|
.Ar file
|
|
.Sh DESCRIPTION
|
|
The
|
|
.Nm
|
|
utility selectively processes conditional
|
|
.Xr 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.
|
|
.Pp
|
|
The
|
|
.Nm
|
|
utility acts on
|
|
.Ic #if , #ifdef , #ifndef , #elif , #else ,
|
|
and
|
|
.Ic #endif
|
|
lines.
|
|
A directive is only processed
|
|
if the symbols specified on the command line are sufficient to allow
|
|
.Nm
|
|
to get a definite value for its control expression.
|
|
If the result is false,
|
|
the directive and the following lines under its control are removed.
|
|
If the result is true,
|
|
only the directive is removed.
|
|
An
|
|
.Ic #ifdef
|
|
or
|
|
.Ic #ifndef
|
|
directive is passed through unchanged
|
|
if its controlling symbol is not specified on the command line.
|
|
Any
|
|
.Ic #if
|
|
or
|
|
.Ic #elif
|
|
control expression that has an unknown value or that
|
|
.Nm
|
|
cannot parse is passed through unchanged.
|
|
By default,
|
|
.Nm
|
|
ignores
|
|
.Ic #if
|
|
and
|
|
.Ic #elif
|
|
lines with constant expressions;
|
|
it can be told to process them by specifying the
|
|
.Fl k
|
|
flag on the command line.
|
|
.Pp
|
|
It understands a commonly-used subset
|
|
of the expression syntax for
|
|
.Ic #if
|
|
and
|
|
.Ic #elif
|
|
lines:
|
|
integer constants,
|
|
integer values of symbols defined on the command line,
|
|
the
|
|
.Fn defined
|
|
operator,
|
|
the operators
|
|
.Ic \&! , < , > , <= , >= , == , != , && , || ,
|
|
and parenthesized expressions.
|
|
A kind of
|
|
.Dq "short circuit"
|
|
evaluation is used for the
|
|
.Ic &&
|
|
operator:
|
|
if either operand is definitely false then the result is false,
|
|
even if the value of the other operand is unknown.
|
|
Similarly,
|
|
if either operand of
|
|
.Ic ||
|
|
is definitely true then the result is true.
|
|
.Pp
|
|
In most cases, the
|
|
.Nm
|
|
utility does not distinguish between object-like macros
|
|
(without arguments) and function-like arguments (with arguments).
|
|
If a macro is not explicitly defined, or is defined with the
|
|
.Fl D
|
|
flag on the command-line, its arguments are ignored.
|
|
If a macro is explicitly undefined on the command line with the
|
|
.Fl U
|
|
flag, it may not have any arguments since this leads to a syntax error.
|
|
.Pp
|
|
The
|
|
.Nm
|
|
utility 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 for it to handle.
|
|
.Pp
|
|
A script called
|
|
.Nm unifdefall
|
|
can be used to remove all conditional
|
|
.Xr cpp 1
|
|
directives from a file.
|
|
It uses
|
|
.Nm Fl s
|
|
and
|
|
.Nm cpp Fl dM
|
|
to get lists of all the controlling symbols
|
|
and their definitions (or lack thereof),
|
|
then invokes
|
|
.Nm
|
|
with appropriate arguments to process the file.
|
|
.Sh OPTIONS
|
|
.Pp
|
|
.Bl -tag -width indent -compact
|
|
.It Fl D Ns Ar sym Ns = Ns Ar val
|
|
Specify that a symbol is defined to a given value
|
|
which is used when evaluating
|
|
.Ic #if
|
|
and
|
|
.Ic #elif
|
|
control expressions.
|
|
.Pp
|
|
.It Fl D Ns Ar sym
|
|
Specify that a symbol is defined to the value 1.
|
|
.Pp
|
|
.It Fl U Ns Ar sym
|
|
Specify that a symbol is undefined.
|
|
If the same symbol appears in more than one argument,
|
|
the last occurrence dominates.
|
|
.Pp
|
|
.It Fl B
|
|
Compress blank lines around a deleted section.
|
|
Mutually exclusive with the
|
|
.Fl b
|
|
option.
|
|
.Pp
|
|
.It Fl b
|
|
Replace removed lines with blank lines
|
|
instead of deleting them.
|
|
Mutually exclusive with the
|
|
.Fl B
|
|
option.
|
|
.Pp
|
|
.It Fl c
|
|
If the
|
|
.Fl c
|
|
flag is specified,
|
|
then the operation of
|
|
.Nm
|
|
is complemented,
|
|
i.e., the lines that would have been removed or blanked
|
|
are retained and vice versa.
|
|
.Pp
|
|
.It Fl d
|
|
Turn on printing of degugging messages.
|
|
.Pp
|
|
.It Fl e
|
|
Because
|
|
.Nm
|
|
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
|
|
.Nm
|
|
has to process such a directive,
|
|
it will complain that the line is too obfuscated.
|
|
The
|
|
.Fl e
|
|
option changes the behaviour so that,
|
|
where possible,
|
|
such lines are left unprocessed instead of reporting an error.
|
|
.Pp
|
|
.It Fl K
|
|
Always treat the result of
|
|
.Ic &&
|
|
and
|
|
.Ic ||
|
|
operators as unknown if either operand is unknown,
|
|
instead of short-circuiting when unknown operands can't affect the result.
|
|
This option is for compatibility with older versions of
|
|
.Nm .
|
|
.Pp
|
|
.It Fl k
|
|
Process
|
|
.Ic #if
|
|
and
|
|
.Ic #elif
|
|
lines with constant expressions.
|
|
By default, sections controlled by such lines are passed through unchanged
|
|
because they typically start
|
|
.Dq Li "#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.
|
|
.Pp
|
|
.It Fl n
|
|
Add
|
|
.Li #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.
|
|
.Pp
|
|
.It Fl o Ar outfile
|
|
Write output to the file
|
|
.Ar outfile
|
|
instead of the standard output.
|
|
If
|
|
.Ar outfile
|
|
is the same as the input file,
|
|
the output is written to a temporary file
|
|
which is renamed into place when
|
|
.Nm
|
|
completes successfully.
|
|
.Pp
|
|
.It Fl s
|
|
Instead of processing the input file as usual,
|
|
this option causes
|
|
.Nm
|
|
to produce a list of symbols that appear in expressions
|
|
that
|
|
.Nm
|
|
understands.
|
|
It is useful in conjunction with the
|
|
.Fl dM
|
|
option of
|
|
.Xr cpp 1
|
|
for creating
|
|
.Nm
|
|
command lines.
|
|
.Pp
|
|
.It Fl t
|
|
Disables parsing for C comments
|
|
and line continuations,
|
|
which is useful
|
|
for plain text.
|
|
.Pp
|
|
.It Fl iD Ns Ar sym Ns Op = Ns Ar val
|
|
.It Fl iU Ns Ar sym
|
|
Ignore
|
|
.Ic #ifdef Ns s .
|
|
If your C code uses
|
|
.Ic #ifdef Ns s
|
|
to delimit non-C lines,
|
|
such as comments
|
|
or code which is under construction,
|
|
then you must tell
|
|
.Nm
|
|
which symbols are used for that purpose so that it will not try to parse
|
|
comments
|
|
and line continuations
|
|
inside those
|
|
.Ic #ifdef Ns s .
|
|
You can specify ignored symbols with
|
|
.Fl iD Ns Ar sym Ns Oo = Ns Ar val Oc
|
|
and
|
|
.Fl iU Ns Ar sym
|
|
similar to
|
|
.Fl D Ns Ar sym Ns Op = Ns Ar val
|
|
and
|
|
.Fl U Ns Ar sym
|
|
above.
|
|
.Pp
|
|
.It Fl I Ns Ar path
|
|
Specifies to
|
|
.Nm unifdefall
|
|
an additional place to look for
|
|
.Ic #include
|
|
files.
|
|
This option is ignored by
|
|
.Nm
|
|
for compatibility with
|
|
.Xr cpp 1
|
|
and to simplify the implementation of
|
|
.Nm unifdefall .
|
|
.El
|
|
.Pp
|
|
The
|
|
.Nm
|
|
utility copies its output to
|
|
.Em stdout
|
|
and will take its input from
|
|
.Em stdin
|
|
if no
|
|
.Ar file
|
|
argument is given.
|
|
.Pp
|
|
The
|
|
.Nm
|
|
utility works nicely with the
|
|
.Fl D Ns Ar sym
|
|
option of
|
|
.Xr diff 1 .
|
|
.Sh EXIT STATUS
|
|
The
|
|
.Nm
|
|
utility exits 0 if the output is an exact copy of the input,
|
|
1 if not, and 2 if in trouble.
|
|
.Sh DIAGNOSTICS
|
|
.Bl -item
|
|
.It
|
|
Too many levels of nesting.
|
|
.It
|
|
Inappropriate
|
|
.Ic #elif ,
|
|
.Ic #else
|
|
or
|
|
.Ic #endif .
|
|
.It
|
|
Obfuscated preprocessor control line.
|
|
.It
|
|
Premature
|
|
.Tn EOF
|
|
(with the line number of the most recent unterminated
|
|
.Ic #if ) .
|
|
.It
|
|
.Tn EOF
|
|
in comment.
|
|
.El
|
|
.Sh SEE ALSO
|
|
.Xr cpp 1 ,
|
|
.Xr diff 1
|
|
.Sh HISTORY
|
|
The
|
|
.Nm
|
|
command appeared in
|
|
.Bx 2.9 .
|
|
.Tn ANSI\~C
|
|
support was added in
|
|
.Fx 4.7 .
|
|
.Sh AUTHORS
|
|
The original implementation was written by
|
|
.An Dave Yost Aq Dave@Yost.com .
|
|
.An Tony Finch Aq dot@dotat.at
|
|
rewrote it to support
|
|
.Tn ANSI\~C .
|
|
.Sh BUGS
|
|
Expression evaluation is very limited.
|
|
.Pp
|
|
Preprocessor control lines split across more than one physical line
|
|
(because of comments or backslash-newline)
|
|
cannot be handled in every situation.
|
|
.Pp
|
|
Trigraphs are not recognized.
|
|
.Pp
|
|
There is no support for symbols with different definitions at
|
|
different points in the source file.
|
|
.Pp
|
|
The text-mode and ignore functionality does not correspond to modern
|
|
.Xr cpp 1
|
|
behaviour.
|