home *** CD-ROM | disk | FTP | other *** search
- .PA
- .K
- .RM 65
-
- .HL COMMAND FORMAT
-
- .LT
-
-
- -- MCCABE : Calculate the McCabe complexity measures.
- -- Version 3.01-1.1
-
-
- subtype FILE_NAME is STRING;
- subtype MAX_VALUE is INTEGER range 1 .. 99;
-
- procedure MCCABE(
- SOURCE_FILE : in FILE_NAME;
- OUTPUT_FILE : in FILE_NAME := "";
- MAX_COMPLEXITY : in MAX_VALUE := 20
- );
-
- -- SOURCE_FILE : Input file name.
- -- OUTPUT_FILE : Name of the report file (defaults to standard output).
- -- MAX_COMPLEXITY : Greatest complexity not flagged in output listing
- -- (range: 1 .. 99, default: 20).
-
- .EL
-
-
- .HL MCCABE DESCRIPTION AND USE
-
- The McCabe measure computes complexity based on the control
- structure (or "flow graph") of the program. The tool takes the name
- of an Ada source program text file and computes the cyclomatic
- complexity for every subprogram body contained
- in the file. Specifications do not have a complexity associated
- with them. The tool also takes an output file name and a number,
- MAX_COMPLEXITY, which is the maximum complexity allowed for a
- program. If a procedure is found to have a complexity greater than
- the specified value, it will be flagged on the output listing.
- .P
- The McCabe tool builds the flow graph and computes the cyclomatic number
- for each program unit in the source file. In addition, it sums the number
- of nodes and edges in all program units and computes a cyclomatic number
- for the entire file.
- .P
- The tool assumes that a source program text is correct ADA (i.e., it is
- compiled cleanly); otherwise it terminates with a syntax error.
-
- .HL MOTIVATION
-
- The McCabe complexity measure is principally useful in two ways:
- as an aid in testing and as a numeric guidline for management purposes.
- In testing, the complexity number corresponds to the number of control
- paths through a subprogram and therefore the number of test cases
- required to test them all. If the number of test cases is less than
- the complexity, then at least one of three conditions is true:
- .LS
- .LE
- more testing is required;
- .LE
- decision points can be removed;
- .LE
- in-line code can replace decision points.
- .ELS
- (See [McC] for a full explanation.) As a programming and management
- guidline the tool provides a simple way of flagging subprograms which
- might cause problems. The general method for keeping subprograms
- simple is to establish a size limit, e.g., 50 lines or 2 pages.
- This is really a surrogate for the lack af any good way of measuring
- simplicity. The McCabe metric is just such a simplicity measure.
- The measure is only a guideline since a large CASE statement will
- have a correspondingly large complexity but it may only be the
- equivalent of a jump table.
- .P
- Each user will have to determine through experience how best to use
- the information provided by the tool. The McCabe complexity number
- is just one measure of program complexity. Although it can help to
- identify program units that may require further scrutiny, it is
- not at all reasonable to require that all program units have a
- cyclomatic complexity below a certain value. A case statement for
- example is well structured, but can have a high complexity (on the order
- of the number of branches in the statement). This does not mean that
- the program is poorly structured, only that each branch of the case
- statement must be tested.
-
- .HL THEORY OF THE MCCABE METRIC
- .P
- The McCabe metric is based on the flow graph of a program. The
- flow graph is a directed graph where the nodes represent basic
- blocks and the edges represent control flow between basic blocks.
- A basic block is a sequence of consecutive statements which may
- only be entered at the beginning and exited at the end. When
- entered the instructions are executed in sequence without
- branching except at the end [Aho]. Figure 1 shows some flow
- graphs for different programming structures.
- .TP 10
- .LT
-
- if expression do while expression loop
- then S1;
- S1 end loop;
- else
- S2
- endif;
-
- .EL
- .TP 12
- .LT
-
- if do while
- / \ | | ^
- V V | V |
- S1 S2 | S1
- \ / V
- V V end loop
- endif
-
-
- FIGURE 1
-
- .EL
-
- McCabe's cyclomatic complexity is defined as:
- .LT
-
- V(G) = e - n + 2p
-
- .EL
- .NAP
- where 'e' is the number of edges in the flow graph, 'n' is the number
- of nodes, and 'p' is the number of connected components. Ignoring
- the direction from the edges of the flow graph, if there exists a
- path between each pair of vertices I and J then we say the graph
- is a connected component. Since there is a path from the entry
- node to every other node in the flow graph then (ignoring the
- directions of the edges) we will be able to get from any node I to
- any other node J by going through the entry node. Therefore, in
- our case of computing the cyclomatic complexity for an individual
- subprogram p is always 1. The number of
- connected components becomes interesting when we would like to
- calcultate the cyclomatic complexity of a program that has a
- number of different subprograms. McCabe defines the cyclomatic
- complexity of a system as the sum of the cyclomatic complexities
- of all the modules. In this case p, the number of connected
- components would be the number of different modules.
- .AP
- .P
- If a subprogram has some unreachable code then McCabe's cyclomatic
- complexity formular does not make a lot of sense. In some cases
- the tool discovers such subprograms and flags them in the output
- with the message "unreachable code".
-
- .HL INTERPRETATION OF ADA STATEMENTS
- .P
- There is a number of ADA statements which generate flow but building
- a flow graph for them is not obvious. Sometimes it happens because
- the flow of a statement can be interpreted in a number of ways
- (as for case and select statements); sometimes it happens because
- of the tool limits (as for a raise statement - the flow could go
- to an exception handler belonging to a same subprogram as the raise
- statement or it could go to a different subprogram in which case
- the tool does not have enough information to track the flow).
- .P
- This is a list of such statements with their corresponding
- interpretations.
- .LS
- .LE
- The complexity of an exception handler is added to the complexity
- of a containing subprogram.
- .LE
- Case, select statements and exception handlers are interpreted
- as if statement [McC]. For a case statement a corresponding
- if statement always has an else clause. Two forms of select
- statements - conditional entry call and timed entry call
- are always interpreted as if...then...else...end if.
- .LE
- Return, raise and terminate statements are ignored (as a stop
- statement in [McC]).
- .ELS
-
- .HL OUTPUT FORMAT
- .P
- The output of the tool is a list of names of all the subprograms
- in the input file. Each name is preceeded by
- its cyclomatic complexity, the number of nodes and the number
- of edges in the flow graph.
- If any subprogram or function has a cyclomatic complexity above the
- specified value, it is flagged. A sample output follows:
-
- .LT
-
-
- MCCABE CYCLOMATIC COMPLEXITY:
- SOURCE_FILE "EXAMPLE" - WITH MAX_COMPLEXITY 9
-
- COMPLEXITY NUMBER OF
- CYCLOMATIC EDGES NODES SUBPROGRAM NAME
-
- 4 10 8 subprog1
- 3 9 8 subprog2
- 14 37 25 *** subprog3
- . . . .
- . . . .
- . . . .
-
- 32 90 48 Total for 5 program units
-
- .EL
- .PG
- .HL REFERENCES
-
- .LS 2
- .LE
- [Aho] Aho, A.V., Ullman, J.D., Principles of Compiler
- Design, Addision-wesley Publishing Company, pp 412-413, 1977.
- .LE
- [McC] McCabe, T. J., "A Complexity Measure", IEEE Transactions on
- Software Engineering, Vol. SE-2, pp 308-320, December, 1976.
- .ELS
- .PG
- .RM 80
- .HL Appendix A: Installation and Modification
- .NF
- .REQUIRE "[-]read.me"
- .F
-