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