University of Leicester

## CO7206: Tutorial #5

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

*

* 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,

*                      || (((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;

}