diff options
Diffstat (limited to 'ext/coverage')
-rw-r--r-- | ext/coverage/coverage.c | 78 |
1 files changed, 52 insertions, 26 deletions
diff --git a/ext/coverage/coverage.c b/ext/coverage/coverage.c index 34b0849fc4..49f7ffa0f8 100644 --- a/ext/coverage/coverage.c +++ b/ext/coverage/coverage.c @@ -76,36 +76,62 @@ rb_coverage_start(int argc, VALUE *argv, VALUE klass) return Qnil; } +struct branch_coverage_result_builder +{ + int id; + VALUE result; + VALUE children; + VALUE counters; +}; + +static int +branch_coverage_ii(VALUE _key, VALUE branch, VALUE v) +{ + struct branch_coverage_result_builder *b = (struct branch_coverage_result_builder *) v; + + VALUE target_label = RARRAY_AREF(branch, 0); + VALUE target_first_lineno = RARRAY_AREF(branch, 1); + VALUE target_first_column = RARRAY_AREF(branch, 2); + VALUE target_last_lineno = RARRAY_AREF(branch, 3); + VALUE target_last_column = RARRAY_AREF(branch, 4); + long counter_idx = FIX2LONG(RARRAY_AREF(branch, 5)); + rb_hash_aset(b->children, rb_ary_new_from_args(6, target_label, LONG2FIX(b->id++), target_first_lineno, target_first_column, target_last_lineno, target_last_column), RARRAY_AREF(b->counters, counter_idx)); + + return ST_CONTINUE; +} + +static int +branch_coverage_i(VALUE _key, VALUE branch_base, VALUE v) +{ + struct branch_coverage_result_builder *b = (struct branch_coverage_result_builder *) v; + + VALUE base_type = RARRAY_AREF(branch_base, 0); + VALUE base_first_lineno = RARRAY_AREF(branch_base, 1); + VALUE base_first_column = RARRAY_AREF(branch_base, 2); + VALUE base_last_lineno = RARRAY_AREF(branch_base, 3); + VALUE base_last_column = RARRAY_AREF(branch_base, 4); + VALUE branches = RARRAY_AREF(branch_base, 5); + VALUE children = rb_hash_new(); + rb_hash_aset(b->result, rb_ary_new_from_args(6, base_type, LONG2FIX(b->id++), base_first_lineno, base_first_column, base_last_lineno, base_last_column), children); + b->children = children; + rb_hash_foreach(branches, branch_coverage_ii, v); + + return ST_CONTINUE; +} + static VALUE branch_coverage(VALUE branches) { - VALUE ret = rb_hash_new(); - VALUE structure = rb_ary_dup(RARRAY_AREF(branches, 0)); - VALUE counters = rb_ary_dup(RARRAY_AREF(branches, 1)); - int i, j; - long id = 0; - - for (i = 0; i < RARRAY_LEN(structure); i++) { - VALUE branches = RARRAY_AREF(structure, i); - VALUE base_type = RARRAY_AREF(branches, 0); - VALUE base_first_lineno = RARRAY_AREF(branches, 1); - VALUE base_first_column = RARRAY_AREF(branches, 2); - VALUE base_last_lineno = RARRAY_AREF(branches, 3); - VALUE base_last_column = RARRAY_AREF(branches, 4); - VALUE children = rb_hash_new(); - rb_hash_aset(ret, rb_ary_new_from_args(6, base_type, LONG2FIX(id++), base_first_lineno, base_first_column, base_last_lineno, base_last_column), children); - for (j = 5; j < RARRAY_LEN(branches); j += 6) { - VALUE target_label = RARRAY_AREF(branches, j); - VALUE target_first_lineno = RARRAY_AREF(branches, j + 1); - VALUE target_first_column = RARRAY_AREF(branches, j + 2); - VALUE target_last_lineno = RARRAY_AREF(branches, j + 3); - VALUE target_last_column = RARRAY_AREF(branches, j + 4); - int idx = FIX2INT(RARRAY_AREF(branches, j + 5)); - rb_hash_aset(children, rb_ary_new_from_args(6, target_label, LONG2FIX(id++), target_first_lineno, target_first_column, target_last_lineno, target_last_column), RARRAY_AREF(counters, idx)); - } - } + VALUE structure = RARRAY_AREF(branches, 0); + + struct branch_coverage_result_builder b; + b.id = 0; + b.result = rb_hash_new(); + b.counters = RARRAY_AREF(branches, 1); + + rb_hash_foreach(structure, branch_coverage_i, (VALUE)&b); - return ret; + return b.result; } static int |