SUNIFDEF(1) | User Commands | SUNIFDEF(1) |
sunifdef - simplify C preprocessor source files
sunifdef [-v | --version]
sunifdef [-h | --help]
sunifdef [OPTION...] [files...]
sunifdef is a more powerful successor of the FreeBSD unifdef 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 simplifications arising from the specified assumptions. 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 preprocessor 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 preprocessor complexities from a C or C++ source tree. See the EXAMPLES section.
Display a usage summary and exit.
Display version information and exit.
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.
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.
Assume that #define macro[=string] is in force for processing the input file(s).
Assume that #undef macro is in force for processing the input file(s).
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. Note that --recurse implies --replace.
If the names of the input files are read from stdin, the filenames are delimited by whitespace unless enclosed in double-quotes.
Recurse into directories to find input files. Implies --replace. The input files may include directories with this option: otherwise a directory provokes a non-fatal error.
All files within a directory (and within subdirectories) will be selected for input unless the --filter option is given: otherwise all files (including subdirectories) will be selected that match the --filter option.
When --recurse is in effect, sunifdef builds a graph of all unique input files once and for all as it parses the filenames that are explicitly supplied and before it processes any of them. New files that may later appear in input directories during execution will not be processed, and files that have disappeared from input directories when they are due to be processed will provoke fatal errors.
Process only input files that have one of the file extensions ext1,ext2... A file extension may be any terminal segment of a filename that follows a '.'.
Backup each input file before replacing it, the backup file having the same name as the input file with suffix appended to it.
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.
Suppress diagnostics no worse than [progress | info | warning | error | abend].
Suppress summary diagnostics at end of input.
Output all diagnostics,
If neither -V nor -garg is specified defaults are -gp -gi -gs.
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].
Ouput the lines that ought to be dropped and vice versa.
Write debugging information to stderr.
Select the policy for discarding lines from output:
d, drop: Drop discarded lines.
b, blank: Blank discarded lines.
c, comment: Comment out discarded lines.
If a parse error is encountered in an input file, continue processing subsequent input files. An event of severity abend will terminate processing regardless of --keepgoing.
Apart from CPP directives, input is to be treated as Plain Old Data. C/C++ comments and quotations will not be parsed.
Output #line directives in place of discarded lines to preserve the line numbers of retained lines.
Simplify the file foo.c assuming that the symbol UNIX is defined and the symbol WIN32 is undefined. Write the simplified file to stdout. By default diagnostic messages whose severity is warning or higher will be output and no summary diagnostics will be output. All diagnostics are written to stderr.
Like the previous example, but the symbol UNIX is defined as 1.
Like the first example, but suppress all diagnostics (--gag) whose severity is warning or lower that would otherwise be written to stderr.
Like the first example, but suppress all diagnostics (--gag) whose severity is warning or lower that would otherwise be written to stderr.
Like the previous example, but also suppress all summary diagnostics that would otherwise be written to stderr after processing is finished (--gag summary).
Like the previous example, but write all diagnostics at all severities to stderr, as well as summary diagnostics (--verbose).
Like the previous example, but write only the default diagnostics to stderr and read the input file from stdin (in this case redirected from bar.c)
Like the previous example, but --replace causes each input file to be replaced with the corresponding simplified output file. With this option multiple input files - foo.c, bar.c - can be supplied.
Like the previous example, but read the list of input filenames from stdin (in this case redirected from filelist.txt)
Like the previous example, but create a backup of each input file with the extension .bak (--backup ``.bak'').
The --recurse option implies --replace and causes sunifdef to find additional input files by searching recursively within the directories somedir and otherdir
Like the previous example, but select only input files that have one of the extensions .c or .h (--filter c,h).
Like the previous example, but keep going through parse errors (--keepgoing). Processing of the input file in error will be abandoned but subsequent input files will be processed.
Recursively select all the .c and .h files from foo.c, somedir, bar.h, otherdir and write on stderr a list of all the symbols that influence the truth-values of #if, #else, #elif conditions. Report only the first occurrence of each symbol.
Like the previous example, but report the file and line number of each reported symbol (--symbols first,locate)
Like the previous example, but report all occurrences of the symbols (--symbols first,locate)
Process the file data.txt with the assumptions --define UNIX and --undef WIN32 parsing the text (other than #-directives) as Plain Old Data, rather than C/C++ source. C/C++ comments and quotations will not be recognised.
Interprolate the contents of the file args.txt into the commandline, replacing --file args.txt and then execute the resulting command.
Substite the contents of the file args.txt for --file args.txt and then execute the resulting command.
0xXXXXX
that encodes its severity. The 5 severities are:
progress: Progress messages (0xXXXXX & 0x00800
is true)
info: Noteworthy information (0xXXXXX & 0x01000
is true)
warning: Indicating problematic input (0xXXXXX & 0x02000
is true)
error: Indicating invalid input (0xXXXXX & 0x04000
is true)
abend: Indicating a fatal environment or internal error (0xXXXXX & 0x08000
is true)
& 0x10000
is true. Even if --gag summary is not in force, a summary will not be written if its severity is suppressed by one of the specified or default --gag options. Since all summaries have severity info or warning, this means that by default no summaries will appear and to obtain all summaries you must specify --verbose. The summaries include:
info: The number of input files that were reached and the number that were not reached (due to abend).
info: The number of input files reached that were abandoned (due to errors).
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.
SC & 1
: Informational diagnostics accrued.
SC & 2
: Warnings diagnostics accrued.
SC & 4
: Error diagnostics accrued. (Input files provoking errors will be unchanged notwithstanding the --replace option.)
SC & 8
: An abend occurred. Some input files may not have been reached.
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 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
Mike Kinghan imk at strudl dot org
FreeBSD unifdef(1)
strudl.org | JANUARY 2008 | SUNIFDEF(1) |