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