XTRAN Example — Analyze Cyclomatic Complexity of C, C++, Java, or C#

The following example uses an XTRAN rules file comprising about 200 non-comment lines of XTRAN's rules language ("meta-code") to analyze C, C++, Java, or C# code and show the cyclomatic complexity of each function.

Cyclomatic complexity is essentially a count of the different logic paths through a function's body.  It is regarded by many programming managers as a good measure of code maintainability (the lower the better).

Note that the analysis output shows not only the complexity measure for each function, but also the logic flow from which it was determined, eliding "straight line code" that doesn't affect the measure.

The XTRAN rules themselves are not particularly specific to C / C++ / Java / C#; they can easily be adapted to analyze any 3GL language.

The input to and output from XTRAN are untouched.




Process Flowchart

Here is a flowchart for this process, in which the elements are color coded:

process flowchart

Input to XTRAN:

short func(short i, long j)
{
	short k = 0;

	if (i < j)				/*predicate node 1*/
	    {
	    for ( ; i < j; i++)			/*predicate node 2*/
		k++;
	    }
	return;
}

int main(int numarg, char **pp_args_txt)
{
	short i, j, k;

	i = 1;
	if (i < 2)				/*predicate node 1*/
	    {
	    i = 2;
	    for (j = 1; j < i; j++)		/*predicate node 2*/
		k = j;
	    if (j < i)				/*predicate node 3*/
		{
		j = i;
		k = j;
		}
	    }
	i = j;
	func();
	switch (i)				/*this won't count*/
	    {
	    case 1 :				/*this won't count*/
	    case 2 :				/*predicate node 4*/
		j = k;
		break;

	    case 3 :				/*this won't count*/
	    case 4 :				/*predicate node 5*/
		if (i == j)			/*predicate node 6*/
		    i = k;

	    default :				/*predicate node 7*/
		k = 1;
		break;
	    }
	i = j;
	while (j < i)				/*predicate node 8*/
	    j++;
	return (1);
}


Output from XTRAN:

demcyc-a.cyc — Cyclomatic complexity analysis
Created 1997-08-08:02:41:33 by XTRAN, LLC's XTRAN software development
  automation meta-tool using cyclo-c.xac rules, version V1.01

(n) is (arbitrary) node number in function's flow graph;
(n*) indicates a predicate node.


func()
    if (1*)
        for (2*)
            ... (3)
    ... (4)

Cyclomatic complexity of func():  2

main()
    if (1*)
        ... (2)
        for (3*)
            ... (4)
        if (5*)
            ... (6)
    ... (7)
    switch (8)
        case (9*)
            ... (10)
        case (11*)
            if (12*)
                ... (13)
        default (14*)
            ... (15)
    while (16*)
        ... (17)
    ... (18)

Cyclomatic complexity of main():  8