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