COAN(1)User CommandsCOAN(1)

NAME

coan - C/C++ configuration analyser

SYNOPSIS

coan COMMAND [OPTION...] [file...] [directory...]

Where no files or directories are specified, input will be read from the standard input. The output of a command is written either to the standard output or to new files, depending upon the command and the options.

DESCRIPTION

Coan is a tool for investigating configurations of C or C++ source code. A configuration is a (possibly empty) list of assumptions about the status of some preprocessor symbols when the source code is compiled. It may be assumed that a symbol is defined for the preprocessor, possibly with formal parameters and possibly with a specified definition, or it may be assumed that a symbol is undefined.

It is important to understand that coan shall consider a symbol to be undefined only if there is an assumption to that effect, or if you use the --implicit option. By default, a symbol that is not mentioned in any assumption is considered to be undetermined.

A configuration may be thought of as list of #define and/or #undef directives that are applied to every file in the source code to observe their effects. The source files might themselves contain #define or #undef directives that are active under the given configuration and which may influence its effects. To capture that influence, Coan temporarily adds each active #define or #undef directive to the configuration just for the duration of the source file in which it is found.

Given a configuration and some source code, coan can answer a range of questions about how the source code would appear to the C/C++ preprocessor if that configuration of preprocessor symbols had been applied in advance.

The most useful of the questions that coan can answer is: What would the source code look like if re-written with all of the simplifications that follow from the given configuration? Coan can produce the simplified re-write that answers this question. So, if the source code contains redundant preprocessor complexities that depend on the status of some preprocessor symbols, coan can be given a configuration that specifies the status of those symbols, and it will output an new version of the source code from which those redundant complexities have been eliminated. Or, if the source code is obscured by preprocessor logic that differentiates several variants by reference to preprocessor symbols, coan can be given a configuration that specifies any of these variants and will be able to generate a simpler version of the source code that represents only the specifed variant.

Source code re-written by coan is not pre-processed code as produced by the preprocessor. It still contains comments, macro-invocations, and #-directives. It is still source code, but simplified.

Other questions that coan can answer include ones about the preprocessor symbols that are invoked in the source code and their properties under a given configuration. For example: What symbol references would appear within active preprocessor directives under a given configuration, and could thus influence the preprocessor under that configuration? What are the macro-expansions of symbol references? How are those macro-expansions derived? What integer values would accrue to the symbol references that can be evaluated under a given configuration?

Coan can also answer a range of questions about any category of preprocessor directive that might appear in the source code, e.g. What #include directives that import system header files would be active under a given configuration? When coan is invoked to identify the symbol references or directives that satisfy certain criteria, it will output a list of the references or directives of interest, and optionally their locations in the source code.

COMMANDS

help

Display a usage summary and exit.

version

Display version information and exit.

source [OPTION...] [file...] [directory...]

Read the input files and rewrite them in accordance with the options.

spin [OPTION...] [file...] [directory...]

Like the source, with all output files organised beneath a specified directory mirroring their original structure.

symbols [OPTION...] [file...] [directory...]

Select references of preprocessor symbols from the input files in accordance with the options and report them on the standard output in accordance with the options.

includes [OPTION...] [file...] [directory...]

Select #include directives from the input files in accordance with the options and report them on the standard output in accordance with the options.

defs [OPTION...] [file...] [directory...]

Select #define and #undef directives from the input files in accordance with the options and report them on the standard output in accordance with the options.

pragmas [OPTION...] [file...] [directory...]

Select #pragma directives from the input files in accordance with the options and report them on the standard output in accordance with the options.

errors [OPTION...] [file...] [directory...]

Select #error directives from the input files in accordance with the options and report them on the standard output in accordance with the options.

lines [OPTION...] [file...] [directory...]

Select #line directives from the input files in accordance with the options and report them on the standard output in accordance with the options.

directives [OPTION...] [file...] [directory...]

Select preprocessor directives from the input files in accordance with the options and report them on the standard output in accordance with the options.

OPTIONS

GENERAL OPTIONS

These options may be given with any command.

-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.

-Dsymbol[(param1[,param2...])]=definition, --define symbol[(param1[,param2...])]=definition

Assume that the macro definition symbol[(param1[,param2...])]=definition is in force for processing the input file(s). If =definition is unspecified then string defaults to the empty string.

-Usymbol, --undef symbol

Assume that the macro symbol is undefined for processing the input file(s).

-m, --implicit

Assume that any symbol that is not --define-ed is implicitly --undef-ed.

This option is not allowed to have the perverse effect that an initial invocation, with arguments, of an unconfigured symbol, e.g. sym(a,b), is expanded as 0(a,b) to provoke a syntax error. The invocation is taken to imply that sym has a conforming but unknown definition and is passed through unresolved. However, once sym has been invoked either with arguments or without then subsequent invocations are expected to be of the same form unless sym is redefined or undefined in the meanwhile.

-R, --recurse

Recurse into directories to find input files. (With the source command, --recurse implies --replace). With --recurse, the input files may include directories: otherwise a directory provokes a non-fatal error.

All files beneath a directory will be selected for input unless the --filter option is given: otherwise all files will be selected that match the --filter option.

When --recurse is in effect, coan 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.

-Fext1[,ext2...], --filter ext1[,ext2...]

Process only input files that have one of the file extensions ext1,ext2... A file extension is the terminal segment of a filename that immediately follows the final '.'.

-g[p|i|w|e|a], --gag [progress | info | warning | error | abend]

Suppress diagnostics no worse than [progress | info | warning | error | abend].

-gs, --gag summary.

Suppress summary diagnostics at end of input.

-V, --verbose

Output all diagnostics,

If neither -V nor -garg is specified defaults are -gp -gi -gs.

-E, --evalconsts

Constants occurring as truth-functional operands in #if expressions shall be evaluated and eliminated. By default constants as truth-functional operands are treated as unknowns, i.e. like macros that are not subject to any assumptions. Constants are always evaluated and eliminated when they are arithmetic or bitwise operands.

The default behaviour preserves "work-in-progress" directives such as #if 1 and #if 0 along with the code they control. With --evalconsts these directives are evaluated.

-K, --keepgoing

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.

--no-transients

By default an in-source #define SYM or #undef SYM directive is transiently treated as a -DSYM or -USYM option within the source file where it is found. This option suppresses the default behaviour at your own risk.

-P, --pod

Apart from #-directives, input is to be treated as Plain Old Data. C or C++ comments and quotations will not be parsed.

OPTIONS FOR THE source COMMAND

-r, --replace

Replace each input file with the corresponding output file. This option must be specified to process multiple input files.

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

If you wish to preserve the original files with the --replace option, use the --backup option as well.

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.

-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.

--line

Output #line directives in place of discarded lines to preserve the line numbers of retained lines.

-c, --complement

Ouput the lines that ought to be dropped and vice versa.

OPTIONS FOR THE spin COMMAND

The --recurse and --replace options are implied for this command.

-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.

-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.

--line

Output #line directives in place of discarded lines to preserve the line numbers of retained lines.

-c, --complement

Ouput the lines that ought to be dropped and vice versa.

--dir dirname

Generate a spin under the directory dirname. The output files are generated relative to dirname, mirroring their original structure. dirname and subdirectories will be created as required. Pre-existing output files will be overwritten. A fatal error is given if dirname includes, or is included by or is identical with any input directory.

-ppathame, --prefix pathname

In organising output files beneath the spin directory dir, dir will equated with the path prefix pathname of any input file. This enables any common prefix of all input files to be deleted from all the outout files under dir if desired.

OPTIONS FOR THE symbols COMMAND

-i, --ifs

List symbol references that occur in #if, #if[n]def and #elif directives.

-d, --defs

List symbol references that occur in #define directives.

-u, --undefs

List symbol references that occur in #undef directives.

--includes

List symbol references that occur in #include directives.

--lns

List symbol references that occur in #line directives.

If none of -i, -d, -u, --includes or --lns is given then they are all defaults.

-o, --once-only

List only the first ocurrence of each distinct reference of a symbol.

--once-per-file

List only the first ocurrence per input file of each distinct reference of a symbol.

If neither --once-only nor --once-per-file is given then all of a symbol's references are listed.

-A, --active

List only references from operative directives.

-I, --inactive

List only references from inoperative directives.

-L, --locate

Report the source file and line number of each listed reference.

-e, --expand

Report the macro expansion of each reported symbol reference, and the integer to which it evaluates, if any. An expansion will be reported for a reference of the symbol symbol if symbol is configured by a -Doption or a -U option, or transiently configured by a #define or #undef directive in the current file.

In the case -Dsymbol, the expansion of symbol is the empty string (since that is the C preprocessor's default definition for defined symbols).

In the case -Usymbol, the expansion of symbol is the numeral 0 (since 0 is the value assigned by the preprocessor to an undefined symbol).

In the case -Dsymbol[(param1[,param2...])]=definition, the expansion of the reference is the string that results by, first, substituting the arguments of the references, if any, for the corresponding formal parameters of the symbol in its definition and then recursively replacing each symbol reference in the result with its expansion.

If a symbol is not configured then its references are reported as insoluble. Likewise if it is configured but a reference has a circular expansion.

--explain

Report the successive steps of macro expansion for each reported symbol reference. Implies --expand

--select name1[*][,name2[*]...]

Select by name the symbols to be reported. A symbol reference will be reported only if its name matches one of the comma-separated names or *-terminated names. A *-terminated name is interpreted as a wildcard name prefix. If not specified then --select * is the default.

OPTIONS FOR THE includes COMMAND

-s, --system

List system headers, e.g. <header.h>

-l, --local

List local headers, e.g. "header.h"

If neither -s or -L is given then both are defaults.

-o, --once-only

List only the first occurrence of each header.

--once-per-file

List only the first occurrence per input file of each header.

If neither --once-only nor --once-per-file is given then all occurrences of a header are listed.

-A, --active

List only headers from operative directives.

-I, --inactive

List only headers from inoperative directives.

-L, --locate

Report the source file and line number of each listed occurrence

OPTIONS FOR THE defs COMMAND

-o, --once-only

List only the first occurrence of each distinct #define or #undef directive.

--once-per-file

List only the first occurrence per input file of each distinct #define or #undef directive.

For the purpose of determining whether two occurrences express the same directive or not, coan reduces the text of each occurrence to a canonical form, i.e. all comments are stripped out, all whitespace sequences are collapsed to a single space and all tokens are separated by a single space. This applies for all commands that accept the --once-only or --once-per-file option.

If neither --once-only nor --once-per-file is given then all occurrences of a distinct #define or #undef directive are listed.

-A, --active

List only operative #define and #undef directives.

-I, --inactive

List only inoperative #define and #undef directives.

-L, --locate

Report the source file and line number of each listed occurrence.

OPTIONS FOR THE pragmas COMMAND

-o, --once-only

List only the first occurrence of each distinct pragma.

--once-per-file

List only the first occurrence per input file of each distinct pragma.

If neither --once-only nor --once-per-file is given then all occurrences of a pragma are listed.

-A, --active

List only operative pragmas.

-I, --inactive

List only inoperative pragmas.

-L, --locate

Report the source file and line number of each listed occurrence.

OPTIONS FOR THE errors COMMAND

-o, --once-only

List only the first occurrence of each #error directive.

--once-per-file

List only the first occurrence per input file of each #error directive.

If neither --once-only nor --once-per-file is given then all occurrences of a distinct #error directive are listed.

-A, --active

List only operative #error directives.

-I, --inactive

List only inoperative #error directives.

-L, --locate

Report the source file and line number of each listed occurrence.

OPTIONS FOR THE directives COMMAND

-o, --once-only

List only the first occurrence of each distinct directive.

--once-per-file

List only the first occurrence per input file of each distinct directive.

If neither --once-only nor --once-per-file is given then all occurrences of a distinct directive are listed.

-A, --active

List only operative directives.

-I, --inactive

List only inoperative directives.

-L, --locate

Report the source file and line number of each listed occurrence.

DIAGNOSTICS

Diagnostics written to stderr are classified by severity. Each diagnostic includes a distinct hexadecimal code of the form 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)

If --gag summary is not in force, coan can write summary diagnostics at the end of processing. A summary diagnostic has a hexadecimal code S that encodes one of the severities and in addition S & 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, and since the --gag defaults are info, warning and summary, you should specify --gag info to see only warning summaries, and to see all summaries you should 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).

If there was no abend or error, then additional summaries are written (unless suppressed) indicating each of the following outcomes that has occurred:

info: Input lines were dropped through simplification.

info: Input lines were changed through simplification. If the option --discard comment is in effect, causing discarded lines to be commented out, then discarded lines are counted as changed, not dropped.

warning: Input lines were changed to #error directives.

warning: #error directives were operative (either in the input source or as a result of simplification).

Coan returns a system code SC of which the low order half of the low order byte is always meaningful:

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.

If no error or abend is indicated, then the high order half of the low order byte is also meaningful:

SC & 16: Input lines were dropped through simplification.

SC & 32: Input lines were changed through simplification.

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

SC & 128: #error directives were operative.

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

BUGS

Trigraphs are not parsed.

Files that are #include-ed by input files are not parsed, hence any #define or #undef directives they contain will not be factored into the evaluation of the file.

Please report bugs to bugs dot coan at burroingroingjoing dot com

AUTHOR

Mike Kinghan imk at burroingroingjoing dot com

burroingroingjoing.comAUGUST 2014COAN(1)