NAME 

sunifdef - simplify C Preprocessor source files

SYNOPSIS 

sunifdef -v | --version

sunifdef -h | --help

sunifdef (-s(f|a)[l] | --symbols (first | all) [,locate] ) [files...]

sunifdef [-fargfile | --file argfile] [-Dmacro[=string] | --define macro[=string]...] [-Umacro | --undef macro...] [-r | --replace] [-Bsuffix | --backup suffix] [-x(d|c|e) | --conflict ( delete | comment | error )] [-g(i|w|e|a) | --gag ( info | warning | error | abend )] [-gs | --gag summary] [-g0xXXXX | --gag 0xXXXX] [-V | --verbose] [-n(u|e[d]) | --constant ( unk | eval[,del])] [-c | --complement] [-d | --debug] [-o | --obfusc] [-k(d|b|c) | --discard ( drop | blank | comment)] [-P | --pod]

DESCRIPTION 

sunifdef is a more powerful successor of the FreeBSD unifdef(1) tool. sunifdef is a preprocessor of C or C++ preprocessor source files (or more briefly a preprocessor of C/C++ source files).

From the commandline arguments it takes a set of assumptions about the symbols to be defined, or undefined, for the CPP. From the commandline it also takes one or more source files. It parses these source files to pick out conditional preprocessor directives (#if,#ifdef,#ifndef,#else,#elif, #endif). It applies the specified assumptions to these directives in attempt to evaluate them. Directives that cannot be fully evaluated on the basis of the assumptions are simplified as much as possible. Directives that can be fully evaluated are eliminated, and the source text that they control is either retained or deleted in accordance with the evaluation, mimicking the behaviour of the CPP.

sunifdef also detects #define and #undef directives and checks them for consistency with the specified assumptions. If a #define or #undef directive repeats one of the assumptions it is deleted on output; if it conflicts with any of the assumptions then it may be deleted or replaced with a diagnostic comment or a diagnostic #error, depending on commandline options.

For each source file, an output file is generated that reflects the edits arising from the specified assumptions. The output file is a new and simpler CPP source file. The command

sunifdef -DFOO bar.c

will write on the standard output a revision of the file bar.c that has been purged as far as possible of CPP constructions controlled by the truth-value of defined(FOO). This revision is equivalent to bar.c on the assumption that FOO is defined. With appropriate options and inputs, you can use a sunifdef command to perform wholesale removal of redundant CPP complexities from a C or C++ source tree.

OPTIONS 

-h | --help
Display a usage summary and exit.
-v | --version
Display version information and exit.
-s(f|a)[l] | --symbols (first | all) [,locate]
Output a list of symbols that are determinative for the truth value of #if conditions.
f | first: List only the first occurrence of the symbol on input.

a | all: List all occurrences of the symbol on input.

l | locate: Report the file and line number of each listed occurrence.

-fargfile | --file argfile
Read (more) arguments from file argfile. Arguments may be written free-form, separated by whitespace, in argfile. These arguments will be parsed exactly as if they were listed on the commandline at the position of -fargfile.
-Dmacro[=string] | --define macro[=string]
Assume that #define macro[=string is in force for processing the input file(s).
-Umacro | --undef macro
Assume that #undef macro is in force for processing the input file(s).
-r | --replace
Replace each input file with the corresponding output file. You must specify this option to process multiple input files.

The option changes the default behaviour of the command when no input files are specified. In this case, input is acquired from the standard input. If -r is not specified, then a single input file is read from the standard input. If -r is specified then the names of the input files are read from the standard input.

If the names of the input files are read from stdin, the filenames are delimited by whitespace unless enclosed in double-quotes.

-Bsuffix | --backup suffix
Backup each input file before replacing it, the backup file having the same name as the input file with suffix appended to it.
-x(d|c|e) | --conflict ( delete | comment | error )
Select the action to be taken when a #define or #undef directive is encountered in an input file that conflicts with one of the -D or -U assumptions:
d | delete: Delete the conflicting directive.

c | comment: Replace the conflicting directive with a diagnostic comment (default).

e | error: Replace the conflicting directive with a diagnostic #error directive.

-g(i|w|e|a) | --gag ( info | warning | error | abend )
Suppress diagnostics no worse than ( info | warning | error | abend )
-gs | --gag summary.
Suppress summary diagnostics at end of input.
-g0xXXXX | --gag 0xXXXX
Suppress diagnostics with codes matching all the bits in 0xXXXX.
-v | --verbose
Output all diagnostics,
If neither -v nor -garg is specified defaults are -gi -gs.
-n(u|e[d]) | --constant ( unk | eval[,del])
Select the policy for processing constants in #if-directives:
u | unk: Treat constants as unknowns, i.e. like macros that are not subject to any assumptions (default).

e[d] | eval[,del]: Evaluate constants [and optionally eliminate them].

-c | --complement
Ouput the lines that ought to be dropped and vice versa.
-d | --debug
Write debugging information to stderr.
-o | --obfusc
Tolerate apparently obfuscated lines of input.
-k(d|b|c) | --discard ( drop | blank | comment)
Select the policy for discarding lines from output:

d | drop: Drop discarded lines.

b | blank: Blank discarded lines.

c | comment: Comment out discarded lines.

-P | --pod
Apart from CPP directives, input is to be treated as Plain Old Data. C/C++ comments and quotations will not be parsed.

DIAGNOSTICS 

Diagnostics written to stderr are classified by severity. Each diagnostic includes a distinct hexadecimal code of the form 0xXXXX that encodes its severity. The 4 severities are:
info: Infomational messages (0xXXXX & 0x0400 is true)

warning: Indicating problematic input (0xXXXX & 0x0800 is true)

error: Indicating invalid input (0xXXXX & 0x1000 is true)

abend: Indicating a fatal environment or internal error (0xXXXX & 0x2000 is true)

Unless --gag summary is in force, sunifdef writes summary diagnostics at the end of processing. These summaries report each of the following outcomes that has occurred:
info: Input lines were dropped on output.

info: Input lines were changed on output.

warning: Input lines were changed to #error directives.

warning: Unconditional #error directives were output.

sunifdef returns a system code SC of which the low order byte is meaningful:
SC & 1: Informational diagnostics accrued.

SC & 2: Warnings diagnostics accrued.

SC & 4: Error diagnostics accrued.

SC & 8: An abend occurred.

SC & 16: Input lines were dropped on output.

SC & 32: Input lines were changed on output.

SC & 64: Input lines were changed to #error directives.

SC & 128: Unconditional #error directives were output.

The system code reflects diagnostics that were provoked even if they were not actually output due to --gag options.

BUGS 

The conditional operator ?...:... is not parsed.

Trigraphs are not parsed.

#define and #undef directives that are found to be active are not factored into the evalation of subsequent #if directives.

Please report bugs to bugs dot sunifdef at strudl dot org

AUTHOR 

Mike Kinghan imk at strudl dot org

SEE ALSO 

FreeBSD unifdef(1)