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