[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Compute the complexity of source code not just with a
path-through-the-code count, but also amplifying line counts
by logic level nesting.
complexity
ignores all cpp preprocessor directives -
calculating the complexity of the appearance of the code,
rather than the complexity after the preprocessor manipulates the
code. getchar(3)
, for example, will expand into quite
complicated code.
This chapter was generated by AutoGen,
using the agtexi-cmd
template and the option descriptions for the complexity
program.
This software is released under the GNU General Public License.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
This is the automatically generated usage text for complexity:
complexity (GNU Complexity) - Measure complexity of C source - Ver. 0.4 USAGE: complexity [ -<flag> [<val>] | --<name>[{=| }<val>] ]... \ [ <file-name> ... ] -t, --threshold=num Reporting threshold --horrid-threshold=num zero exit threshold -n, --nesting-penalty=str score multiplier for nested code --demi-nesting-penalty=str score multiplier for nested expressions -s, --scale=num complexity scaling factor -h, --histogram Display histogram of complexity numbers - disabled as --no-histogram - may not be preset -c, --scores Display the score for each procedure - disabled as --no-scores - may not be preset -I, --ignore=str procedure name to be ignored - may appear multiple times -H, --no-header do not print scoring header - may not be preset -u, --unifdef=str Run the source(s) through unifdef(1BSD) - may appear multiple times --unif-exe=str Specify the unifdef program -i, --input=str file of file list --trace=str trace output file -v, --version[=arg] Output version information and exit -?, --help Display extended usage information and exit ->, --save-opts[=arg] Save the option state to a config file -<, --load-opts=str Load options from a config file - disabled as --no-load-opts - may appear multiple times Options are specified by doubled hyphens and their name or by a single hyphen and the flag character. Compute the complexity of source code not just with a path-through-the-code count, but also amplifying line counts by logic level nesting. If no arguments are provided, input arguments are read from stdin, one per line; blank and '#'-prefixed lines are comments. 'stdin' may not be a terminal (tty). The following option preset mechanisms are supported: - reading file $@/complex.conf - reading file $HOME/.complexityrc - reading file $PROJECT_ROOT/complex.conf - reading file ./.complexityrc - examining environment variables named COMPLEXITY_* ``complexity'' ignores all cpp preprocessor directives - calculating the complexity of the appearance of the code, rather than the complexity after the preprocessor manipulates the code. ``getchar(3)'', for example, will expand into quite complicated code. please send bug reports to: bkorb@gnu.org |
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
This is the “score multiplier for nested expressions” option. By default, this value is halfway between 1.0 and the nesting penalty (specifically, the square root of the nesting penalty). It refers to a parenthesized sub-expression. e.g.
((a > b) && (c > d)) |
contains two parenthesized sub-expressions. This would count 3.5 points. On the other hand, this:
(a > b && c > d) |
contains two relation operators and a logical operator at the same level.
These nested counts will be multiplied together and yield
2.5 * 2.5
, or 6.25
. Don’t do that. It gets even worse
if you have logical ands and ors at the same level.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
This is the “display histogram of complexity numbers” option.
This option has some usage constraints. It:
Instead of printing out each function’s score, a summary is printed
at the end showing how many functions had particular ranges of scores.
Unless --scores
is specifically called out, the scores will not
print with this option specified. The minimum scoring threshold will
also be reduced to zero (0), unless --threshold
is specified.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
This is the “zero exit threshold” option.
If any procedures score higher than this threshold, then the
program will exit non-zero. (4/COMPLEX_EXIT_HORRID_FUNCTION
,
if no other problems are encountered.) By default, this program exits
zero unless one function exceeds the horrid score of 100.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
This is the “procedure name to be ignored” option.
This option has some usage constraints. It:
Some code has macros defined that confuse the lexical analysis. This will cause them to be ignored. Other ways to cause functions to be ignored are:
Generally speaking, anything you do that alters normal C syntax will confuse the lexical analysis. If a procedure is not seen, then it will not get counted. If code within a procedure is incomprehensible, you will likely get inappropriate results.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
This is the “file of file list” option. Instead of either a command line list of input files or reading them from standard input, read the list of files from this file.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
This is the “score multiplier for nested code” option. Linguistic constructs weigh more heavily the more deeply nested they are. By default, each layer penalizes by a factor of 2.0. The option argument is a floating point number. The penalty may be 1, but not less.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
This is the “do not print scoring header” option.
This option has some usage constraints. It:
If a script is going to process the scoring output, parsing is easier without a header. The histogram output will always have a header.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
This is the “complexity scaling factor” option.
By default, the scaling is 20 which divides the raw score by 20.
This was normalized to roughly correspond to the pmccabe
scores:
Easily maintained code.
Maintained with little trouble.
Maintained with some effort.
Difficult to maintain code.
Hard to maintain code.
Unmaintainable code.
Crazy making difficult code.
I only wish I were kidding.
Score | ln-ct | nc-lns| file-name(line): proc-name 4707 3815 2838 lib/vasnprintf.c(1747): VASNPRINTF |
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
This is the “display the score for each procedure” option.
This option has some usage constraints. It:
If you specify --histogram
, individual scores will not be
displayed, unless this option is specified.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
This is the “reporting threshold” option. Ignore any procedures with a complexity measure below this threshold. By default, a complexity score of under 30 is not printed. However, if a histogram and statistics are to be printed, but not individual procedure scores, then the default is set to zero. Procedures below this limit are not counted in the statistics.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
This is the “trace output file” option. Print intermediate scores to a trace file.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
This is the “specify the unifdef program” option. Alternate program to use for unifdef-ing the input.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
This is the “run the source(s) through unifdef(1bsd)” option.
This option has some usage constraints. It:
Strip out sections of code surrounded by #if/#endif
directives.
The option argument is passed as an argument to the ‘unifdef(1BSD)’
program. For example:
complexity -u-Dsymbol |
would cause symbol
to be defined and remove sections of code
preceded by #ifndef symbol
directives.
Please see the ‘unifdef’ documentation for more information.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Any option that is not marked as not presettable may be preset by
loading values from configuration ("rc" or "ini") files, and values from environment variables named COMPLEXITY
and COMPLEXITY_<OPTION_NAME>
. “<OPTION_NAME>
” must be one of
the options listed above in upper case and segmented with underscores.
The COMPLEXITY
variable will be tokenized and parsed like
the command line. The remaining variables are tested for existence and their
values are treated like option arguments.
libopts
will search in 4 places for configuration files:
The value for $(pkgdatadir)
is recorded at package configure time
and replaced by ‘libopts’ when ‘complexity’ runs.
The environment variables HOME
, PROJECT_ROOT
, and PWD
are expanded and replaced when ‘complexity’ runs.
For any of these that are plain files, they are simply processed.
For any that are directories, then a file named ‘.complexityrc’ is searched for
within that directory and processed.
Configuration files may be in a wide variety of formats. The basic format is an option name followed by a value (argument) on the same line. Values may be separated from the option name with a colon, equal sign or simply white space. Values may be continued across multiple lines by escaping the newline with a backslash.
Multiple programs may also share the same initialization file. Common options are collected at the top, followed by program specific segments. The segments are separated by lines like:
[COMPLEXITY] |
or by
<?program complexity> |
Do not mix these within one configuration file.
Compound values and carefully constructed string values may also be specified using XML syntax:
<option-name> <sub-opt>...<...>...</sub-opt> </option-name> |
yielding an option-name.sub-opt
string value of
"...<...>..." |
AutoOpts
does not track suboptions. You simply note that it is a
hierarchicly valued option. AutoOpts
does provide a means for searching
the associated name/value pair list (see: optionFindValue).
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
One of the following exit values will be returned:
Successful program execution.
The operation failed or the command syntax was not valid.
insufficient memory to run program
One or more functions scored over 100
No qualifying procedures were found.
one or more input files were unreadable or empty.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
The weight of each statement is the number of lines the statement uses. This value is multiplied by the nested logic weighting (2.0 by default) for each layer of logic. For example, this snippet:
if (foo) { if (bar) { bumble; baz; } } |
will score 11. This score is then scaled to approximate pmccabe
results by dividing by 20 and rounding. This scores "1" at the end.
pmccabe
scores higher on simple procedures and complexity
scores higher with more deeply nested logic.
The scoring can be tweaked by adjusting the --nesting-penalty
and --scale
-ing factors. The default values were calibrated
by comparing the average results of millions of lines of code with
the results of pmccabe
.
For the purposes of this program, a procedure is identified by a name followed by a parenthesized expression and then an opening curly brace. It ends with a closing curly brace in column 1.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
This program does not recognize K&R procedure headers.
Some procedures still get missed. Usually, these are procedures that use the C pre-processor to extend the C language in some way.
[ << ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
This document was generated by Bruce Korb on May 15, 2011 using texi2html 1.82.