xref: /freebsd/contrib/unifdef/unifdef.1 (revision 6137b5f7b8c183ee8806d79b3f1d8e5e3ddb3df3)
1.\" Copyright (c) 1985, 1991, 1993
2.\"	The Regents of the University of California.  All rights reserved.
3.\" Copyright (c) 2002 - 2015 Tony Finch <dot@dotat.at>.  All rights reserved.
4.\"
5.\" This code is derived from software contributed to Berkeley by
6.\" Dave Yost. It was rewritten to support ANSI C by Tony Finch.
7.\"
8.\" Redistribution and use in source and binary forms, with or without
9.\" modification, are permitted provided that the following conditions
10.\" are met:
11.\" 1. Redistributions of source code must retain the above copyright
12.\"    notice, this list of conditions and the following disclaimer.
13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\"    notice, this list of conditions and the following disclaimer in the
15.\"    documentation and/or other materials provided with the distribution.
16.\" 3. Neither the name of the University nor the names of its contributors
17.\"    may be used to endorse or promote products derived from this software
18.\"    without specific prior written permission.
19.\"
20.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30.\" SUCH DAMAGE.
31.\"
32.Dd December 3, 2015
33.Dt UNIFDEF 1 PRM
34.Os " "
35.Sh NAME
36.Nm unifdef , unifdefall
37.Nd remove preprocessor conditionals from code
38.Sh SYNOPSIS
39.Nm
40.Op Fl bBcdehKkmnsStV
41.Op Fl I Ns Ar path
42.Op Fl [i]D Ns Ar sym Ns Op = Ns Ar val
43.Op Fl [i]U Ns Ar sym
44.Ar ...
45.Op Fl f Ar defile
46.Op Fl x Bro Ar 012 Brc
47.Op Fl M Ar backext
48.Op Fl o Ar outfile
49.Op Ar infile ...
50.Nm unifdefall
51.Op Fl I Ns Ar path
52.Ar ...
53.Ar file
54.Sh DESCRIPTION
55The
56.Nm
57utility selectively processes conditional
58.Xr cpp 1
59directives.
60It removes from a file
61both the directives
62and any additional text that they specify should be removed,
63while otherwise leaving the file alone.
64.Pp
65The
66.Nm
67utility acts on
68.Ic #if , #ifdef , #ifndef ,
69.Ic #elif , #else ,
70and
71.Ic #endif
72lines,
73using macros specified in
74.Fl D
75and
76.Fl U
77command line options or in
78.Fl f
79definitions files.
80A directive is processed
81if the macro specifications are sufficient to provide
82a definite value for its control expression.
83If the result is false,
84the directive and the following lines under its control are removed.
85If the result is true,
86only the directive is removed.
87An
88.Ic #ifdef
89or
90.Ic #ifndef
91directive is passed through unchanged
92if its controlling macro is not specified.
93Any
94.Ic #if
95or
96.Ic #elif
97control expression that has an unknown value or that
98.Nm
99cannot parse is passed through unchanged.
100By default,
101.Nm
102ignores
103.Ic #if
104and
105.Ic #elif
106lines with constant expressions;
107it can be told to process them by specifying the
108.Fl k
109flag on the command line.
110.Pp
111It understands a commonly-used subset
112of the expression syntax for
113.Ic #if
114and
115.Ic #elif
116lines:
117integer constants,
118integer values of macros defined on the command line,
119the
120.Fn defined
121operator,
122the operators
123.Ic \&! , ~ , -
124(unary),
125.Ic * , / , % , + , - ,
126.Ic < , <= , > , >= , == , != , & , ^ , \&| ,
127.Ic && , || ,
128and parenthesized expressions.
129Division by zero is treated as an unknown value.
130A kind of
131.Dq "short circuit"
132evaluation is used for the
133.Ic &&
134operator:
135if either operand is definitely false then the result is false,
136even if the value of the other operand is unknown.
137Similarly,
138if either operand of
139.Ic ||
140is definitely true then the result is true.
141.Pp
142When evaluating an expression,
143.Nm
144does not expand macros first.
145The value of a macro must be a simple number,
146not an expression.
147A limited form of indirection is allowed,
148where one macro's value is the name of another.
149.Pp
150In most cases,
151.Nm
152does not distinguish between object-like macros
153(without arguments) and function-like macros (with arguments).
154A function-like macro invocation can appear in
155.Ic #if
156and
157.Ic #elif
158control expressions.
159If the macro is not explicitly defined,
160or is defined with the
161.Fl D
162flag on the command-line,
163or with
164.Ic #define
165in a
166.Fl f
167definitions file,
168its arguments are ignored.
169If a macro is explicitly undefined on the command line with the
170.Fl U
171flag,
172or with
173.Ic #undef
174in a
175.Fl f
176definitions file,
177it may not have any arguments since this leads to a syntax error.
178.Pp
179The
180.Nm
181utility understands just enough about C
182to know when one of the directives is inactive
183because it is inside
184a comment,
185or cannot be evaluated because it is split by a backslash-continued line.
186It spots unusually-formatted preprocessor directives
187and passes them through unchanged when the layout is too odd for it to handle.
188(See the
189.Sx BUGS
190section below.)
191.Pp
192A script called
193.Nm unifdefall
194can be used to remove all conditional
195.Xr cpp 1
196directives from a file.
197It uses
198.Nm Fl s
199and
200.Nm cpp Fl dM
201to get lists of all the controlling macros
202and their definitions (or lack thereof),
203then invokes
204.Nm
205with appropriate arguments to process the file.
206.Sh OPTIONS
207.Bl -tag -width indent -compact
208.It Fl D Ns Ar sym Ns = Ns Ar val
209Specify that a macro is defined to a given value.
210.Pp
211.It Fl D Ns Ar sym
212Specify that a macro is defined to the value 1.
213.Pp
214.It Fl U Ns Ar sym
215Specify that a macro is undefined.
216.Pp
217If the same macro appears in more than one argument,
218the last occurrence dominates.
219.Pp
220.It Fl iD Ns Ar sym Ns Op = Ns Ar val
221.It Fl iU Ns Ar sym
222C strings, comments,
223and line continuations
224are ignored within
225.Ic #ifdef
226and
227.Ic #ifndef
228blocks
229controlled by macros
230specified with these options.
231.Pp
232.It Fl f Ar defile
233The file
234.Ar defile
235contains
236.Ic #define
237and
238.Ic #undef
239preprocessor directives,
240which have the same effect as the corresponding
241.Fl D
242and
243.Fl U
244command-line arguments.
245You can have multiple
246.Fl f
247arguments and mix them with
248.Fl D
249and
250.Fl U
251arguments;
252later options override earlier ones.
253.Pp
254Each directive must be on a single line.
255Object-like macro definitions (without arguments)
256are set to the given value.
257Function-like macro definitions (with arguments)
258are treated as if they are set to 1.
259.Pp
260.Em Warning:
261string literals and character constants are not parsed correctly in
262.Fl f
263files.
264.Pp
265.It Fl b
266Replace removed lines with blank lines
267instead of deleting them.
268Mutually exclusive with the
269.Fl B
270option.
271.Pp
272.It Fl B
273Compress blank lines around a deleted section.
274Mutually exclusive with the
275.Fl b
276option.
277.Pp
278.It Fl c
279Complement,
280i.e., lines that would have been removed or blanked
281are retained and vice versa.
282.Pp
283.It Fl d
284Turn on printing of debugging messages.
285.Pp
286.It Fl e
287By default,
288.Nm
289will report an error if it needs to remove
290a preprocessor directive that spans more than one line,
291for example, if it has a multi-line
292comment hanging off its right hand end.
293The
294.Fl e
295flag makes it ignore the line instead.
296.Pp
297.It Fl h
298Print help.
299.Pp
300.It Fl I Ns Ar path
301Specifies to
302.Nm unifdefall
303an additional place to look for
304.Ic #include
305files.
306This option is ignored by
307.Nm
308for compatibility with
309.Xr cpp 1
310and to simplify the implementation of
311.Nm unifdefall .
312.Pp
313.It Fl K
314Always treat the result of
315.Ic &&
316and
317.Ic ||
318operators as unknown if either operand is unknown,
319instead of short-circuiting when unknown operands can't affect the result.
320This option is for compatibility with older versions of
321.Nm .
322.Pp
323.It Fl k
324Process
325.Ic #if
326and
327.Ic #elif
328lines with constant expressions.
329By default, sections controlled by such lines are passed through unchanged
330because they typically start
331.Dq Li "#if 0"
332and are used as a kind of comment to sketch out future or past development.
333It would be rude to strip them out, just as it would be for normal comments.
334.Pp
335.It Fl m
336Modify one or more input files in place.
337If an input file is not modified,
338the original is preserved instead of being overwritten with an identical copy.
339.Pp
340.It Fl M Ar backext
341Modify input files in place, and keep backups of the original files by
342appending the
343.Ar backext
344to the input filenames.
345A zero length
346.Ar backext
347behaves the same as the
348.Fl m
349option.
350.Pp
351.It Fl n
352Add
353.Li #line
354directives to the output following any deleted lines,
355so that errors produced when compiling the output file correspond to
356line numbers in the input file.
357.Pp
358.It Fl o Ar outfile
359Write output to the file
360.Ar outfile
361instead of the standard output when processing a single file.
362.Pp
363.It Fl s
364Instead of processing an input file as usual,
365this option causes
366.Nm
367to produce a list of macros that are used in
368preprocessor directive controlling expressions.
369.Pp
370.It Fl S
371Like the
372.Fl s
373option, but the nesting depth of each macro is also printed.
374This is useful for working out the number of possible combinations
375of interdependent defined/undefined macros.
376.Pp
377.It Fl t
378Disables parsing for C strings, comments,
379and line continuations,
380which is useful
381for plain text.
382This is a blanket version of the
383.Fl iD
384and
385.Fl iU
386flags.
387.Pp
388.It Fl V
389Print version details.
390.Pp
391.It Fl x Bro Ar 012 Brc
392Set exit status mode to zero, one, or two.
393See the
394.Sx EXIT STATUS
395section below for details.
396.El
397.Pp
398The
399.Nm
400utility takes its input from
401.Em stdin
402if there are no
403.Ar file
404arguments.
405You must use the
406.Fl m
407or
408.Fl M
409options if there are multiple input files.
410You can specify input from stdin or output to stdout with
411.Ql - .
412.Pp
413The
414.Nm
415utility works nicely with the
416.Fl D Ns Ar sym
417option of
418.Xr diff 1 .
419.Sh EXIT STATUS
420In normal usage the
421.Nm
422utility's exit status depends on the mode set using the
423.Fl x
424option.
425.Pp
426If the exit mode is zero (the default) then
427.Nm
428exits with status 0 if the output is an exact copy of the input,
429or with status 1 if the output differs.
430.Pp
431If the exit mode is one,
432.Nm
433exits with status 1 if the output is unmodified
434or 0 if it differs.
435.Pp
436If the exit mode is two,
437.Nm
438exits with status zero in both cases.
439.Pp
440In all exit modes,
441.Nm
442exits with status 2 if there is an error.
443.Pp
444The exit status is 0 if the
445.Fl h
446or
447.Fl V
448command line options are given.
449.Sh DIAGNOSTICS
450.Bl -item
451.It
452.Tn EOF
453in comment
454.It
455Inappropriate
456.Ic #elif ,
457.Ic #else
458or
459.Ic #endif
460.It
461Missing macro name in #define or #undef
462.It
463Obfuscated preprocessor control line
464.It
465Premature
466.Tn EOF
467(with the line number of the most recent unterminated
468.Ic #if )
469.It
470Too many levels of nesting
471.It
472Unrecognized preprocessor directive
473.It
474Unterminated char or string literal
475.El
476.Sh SEE ALSO
477.Xr cpp 1 ,
478.Xr diff 1
479.Pp
480The unifdef home page is
481.Pa http://dotat.at/prog/unifdef
482.Sh HISTORY
483The
484.Nm
485command appeared in
486.Bx 2.9 .
487.Tn ANSI\~C
488support was added in
489.Fx 4.7 .
490.Sh AUTHORS
491.An -nosplit
492The original implementation was written by
493.An Dave Yost Aq Mt Dave@Yost.com .
494.An Tony Finch Aq Mt dot@dotat.at
495rewrote it to support
496.Tn ANSI\~C .
497.Sh BUGS
498.Bl -bullet
499.It
500Expression evaluation is very limited.
501.It
502Character constants are not evaluated.
503String literals and character constants in
504.Fl f
505definition files are ignored rather than parsed as
506part of a macro's replacement tokens.
507.It
508Only the basic form of C++ raw string literals is recognized,
509like
510.Li R"(string)"
511without delimiters as in
512.Li R"delimiter(string)delimiter" .
513.It
514Source files are processed one line at a time,
515so preprocessor directives split across more than one physical line
516(because of comments or backslash-newline)
517cannot be handled in every situation.
518.It
519Trigraphs are not recognized.
520.It
521There is no support for macros with different definitions at
522different points in the source file.
523.It
524The text-mode and ignore functionality does not correspond to modern
525.Xr cpp 1
526behaviour.
527.El
528.Pp
529Please send bug reports by email to
530.Aq Mt dot@dotat.at .
531