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