University of Leicester
Nov 4th, 2003
1. For the following two functions, taken from io.c from Indent, Imagix 4D calculated the following metrics shown in the table. Try calculating these metrics by hand and see how they compare to the ones calculated by Imagix 4D. Note that Imagix 4D may be using different versions of the metrics and hence numbers may not be identical but should be close. For example, I suspect that Imagix 4D uses the “Extended Cyclomatic Complexity”, which adds extra value (I do not know how much; say 1 for each logical operator appears in the condition) if the condition in a branching statement is compound (e.g, IF condition 1 AND condition 2 OR condition 3 would add 3 to the complexity).
|
Lines |
Statements |
McCabe Complexity |
Halstead Effort |
Function 1 |
34 |
35 |
17 |
19124 |
Function 2 |
43 |
44 |
16 |
31574 |
2. After this exercise, you can amuse yourself by trying these neat sorting applets and calculating the complexity of each associated java class (source code on the same page) and comparing it against the calculated complexity given here.
/* Function #1
* Calculate
break priority.
*/
static void
set_priority (bb)
struct
buf_break_st *bb;
{
bb->priority = bb->priority_code_length;
if
(bb->priority_code == bb_semicolon)
bb->priority += 6000;
if
(bb->priority_code == bb_before_boolean_binary_op
||
(bb->priority_code == bb_after_boolean_binary_op
&& bb->priority_code_length >
2))
bb->priority += 5000;
if
(bb->priority_code == bb_after_boolean_binary_op
&& break_before_boolean_operator)
bb->priority -= 3;
if
(bb->priority_code == bb_after_equal_sign)
bb->priority += 4000;
if
(bb->priority_code == bb_attribute)
bb->priority += 3000;
if
(bb->priority_code == bb_comma)
bb->priority += 2000;
if
(bb->priority_code == bb_comparisation)
bb->priority += 1000;
if
(bb->priority_code == bb_proc_call)
bb->priority -= 1000;
if
(bb->priority_code == bb_operator6)
bb->priority += 600;
if
(bb->priority_code == bb_operator5)
bb->priority += 500;
if
(bb->priority_code == bb_operator4)
bb->priority += 400;
if
(bb->priority_code == bb_operator2)
bb->priority += 200;
if
(bb->priority_code == bb_doublecolon)
bb->priority += 100;
}
/* Function #2
* Returns `true' when `b1' is a better place
to break the code than `b2'.
* `b1' must
be newer.
*
* When
`lineup_to_parens' is true, do not break more then 1 level deeper
* unless
that doesn't cost us "too much" indentation.
* What is
"too much" is determined in a fuzzy way as follows:
* Consider
the example,
* while (!(!(!(!(!(!(mask
* ||
(((a_very_long_expression_that_cant_be_broken
* here we
prefer to break after `mask' instead of after `while'.
* This is
because the `target_col' is pretty close to the break point
* of the
`while': "mask"->target_col - "while"->col == 15 ==
"mask"->level * 2 + 1.
*/
static int
better_break (b1, b2)
struct
buf_break_st *b1;
const
struct buf_break_st *b2;
{
static int
first_level;
int
is_better;
if (!b2)
{
first_level = b1->level;
b1->first_level = first_level;
return
1;
}
if
(honour_newlines && b2->priority_newline)
is_better
= false;
else if
(honour_newlines && b1->priority_newline)
is_better
= true;
else
{
int
only_parens_till_b2 = 0;
is_better = (b1->priority > b2->priority);
if
(is_better)
{
char *p;
for (p = &s_code[b2->offset]; p >=
s_code; --p)
{
if (*p == '!')
--p;
if (*p != '(')
break;
}
if (p < s_code)
only_parens_till_b2 = 1;
}
if
(lineup_to_parens
&& b1->level > first_level + 1
&& !(only_parens_till_b2
&& b1->target_col <= b2->col + (1 + 2 *
b1->level)))
is_better
= false;
}
if
(is_better)
b1->first_level = first_level;
return
is_better;
}