Some code is included to check and report impossible
conditions. Failure to exercise this code shouldn't
be seen as a failure of test coverage.
So mark such code as //NOTEST and exclude it
from statistics.
This brings test coverage up to 93%
Signed-off-by: NeilBrown <neil@brown.name>
@gcov -o coverage oceani.mdc > /dev/null 2> /dev/null
@mv *.gcov coverage ; [ -f .gcov ] && mv .gcov coverage
@gcov -o coverage oceani.mdc > /dev/null 2> /dev/null
@mv *.gcov coverage ; [ -f .gcov ] && mv .gcov coverage
- @ awk '/^ *[1-9]/ {ran+=1} /^ *###/ {skip+=1} \
+ @ awk '/NOTEST/ { next } /^ *[1-9]/ {ran+=1} /^ *###/ {skip+=1} \
END {printf "coverage: %6.2f%%\n", ran * 100 / (ran + skip); \
END {printf "coverage: %6.2f%%\n", ran * 100 / (ran + skip); \
- if (ran < (ran + skip) *0.90) exit(1) }' \
+ if (ran < (ran + skip) *0.93) exit(1) }' \
coverage/oceani.mdc.gcov
@rm -f .tmp*
coverage/oceani.mdc.gcov
@rm -f .tmp*
- case '%': fputc(*fmt, stderr); break;
- default: fputc('?', stderr); break;
+ case '%': fputc(*fmt, stderr); break; // NOTEST
+ default: fputc('?', stderr); break; // NOTEST
case '1':
type_print(t1, stderr);
break;
case '1':
type_print(t1, stderr);
break;
else if (type->print_type)
type->print_type(type, f);
else
else if (type->print_type)
type->print_type(type, f);
else
- fputs("*invalid*type*", f);
+ fputs("*invalid*type*", f); // NOTEST
}
static struct value val_prepare(struct type *type)
}
static struct value val_prepare(struct type *type)
if (v.type && v.type->print)
v.type->print(v);
else
if (v.type && v.type->print)
v.type->print(v);
else
+ printf("*Unknown*"); // NOTEST
}
static struct value parse_value(struct type *type, char *arg)
}
static struct value parse_value(struct type *type, char *arg)
if (type && type->parse)
return type->parse(type, arg);
if (type && type->parse)
return type->parse(type, arg);
- rv.type = NULL;
- return rv;
+ rv.type = NULL; // NOTEST
+ return rv; // NOTEST
rv.type = type;
switch(type->vtype) {
rv.type = type;
switch(type->vtype) {
+ case Vnone: // NOTEST
+ break; // NOTEST
case Vnum:
mpq_init(rv.num); break;
case Vstr:
case Vnum:
mpq_init(rv.num); break;
case Vstr:
case Vbool:
rv.bool = 0;
break;
case Vbool:
rv.bool = 0;
break;
- case Vlabel:
- rv.label = NULL;
- break;
+ case Vlabel: // NOTEST
+ rv.label = NULL; // NOTEST
+ break; // NOTEST
struct value rv;
rv.type = v.type;
switch (rv.type->vtype) {
struct value rv;
rv.type = v.type;
switch (rv.type->vtype) {
+ case Vnone: // NOTEST
+ break; // NOTEST
case Vlabel:
rv.label = v.label;
break;
case Vlabel:
rv.label = v.label;
break;
{
int cmp;
if (left.type != right.type)
{
int cmp;
if (left.type != right.type)
- return left.type - right.type;
+ return left.type - right.type; // NOTEST
switch (left.type->vtype) {
case Vlabel: cmp = left.label == right.label ? 0 : 1; break;
case Vnum: cmp = mpq_cmp(left.num, right.num); break;
case Vstr: cmp = text_cmp(left.str, right.str); break;
case Vbool: cmp = left.bool - right.bool; break;
switch (left.type->vtype) {
case Vlabel: cmp = left.label == right.label ? 0 : 1; break;
case Vnum: cmp = mpq_cmp(left.num, right.num); break;
case Vstr: cmp = text_cmp(left.str, right.str); break;
case Vbool: cmp = left.bool - right.bool; break;
+ case Vnone: cmp = 0; // NOTEST
static void _print_value(struct value v)
{
switch (v.type->vtype) {
static void _print_value(struct value v)
{
switch (v.type->vtype) {
- case Vnone:
- printf("*no-value*"); break;
- case Vlabel:
- printf("*label-%p*", v.label); break;
+ case Vnone: // NOTEST
+ printf("*no-value*"); break; // NOTEST
+ case Vlabel: // NOTEST
+ printf("*label-%p*", v.label); break; // NOTEST
case Vstr:
printf("%.*s", v.str.len, v.str.txt); break;
case Vbool:
case Vstr:
printf("%.*s", v.str.len, v.str.txt); break;
case Vbool:
val.type = type;
switch(type->vtype) {
val.type = type;
switch(type->vtype) {
- case Vlabel:
- case Vnone:
- val.type = NULL;
- break;
+ case Vlabel: // NOTEST
+ case Vnone: // NOTEST
+ val.type = NULL; // NOTEST
+ break; // NOTEST
case Vstr:
val.str.len = strlen(arg);
val.str.txt = malloc(val.str.len);
case Vstr:
val.str.len = strlen(arg);
val.str.txt = malloc(val.str.len);
static int __fput_loc(struct exec *loc, FILE *f)
{
if (!loc)
static int __fput_loc(struct exec *loc, FILE *f)
{
if (!loc)
if (loc->line >= 0) {
fprintf(f, "%d:%d: ", loc->line, loc->column);
return 1;
if (loc->line >= 0) {
fprintf(f, "%d:%d: ", loc->line, loc->column);
return 1;
static void fput_loc(struct exec *loc, FILE *f)
{
if (!__fput_loc(loc, f))
static void fput_loc(struct exec *loc, FILE *f)
{
if (!__fput_loc(loc, f))
+ fprintf(f, "??:??: "); // NOTEST
}
Each different type of `exec` node needs a number of functions
}
Each different type of `exec` node needs a number of functions
static void print_exec(struct exec *e, int indent, int bracket)
{
if (!e)
static void print_exec(struct exec *e, int indent, int bracket)
{
if (!e)
switch (e->type) {
case Xbinode:
print_binode(cast(binode, e), indent, bracket); break;
switch (e->type) {
case Xbinode:
print_binode(cast(binode, e), indent, bracket); break;
struct binding *b = v->var->name;
fprintf(stderr, "%.*s", b->name.len, b->name.txt);
} else
struct binding *b = v->var->name;
fprintf(stderr, "%.*s", b->name.len, b->name.txt);
} else
+ fputs("???", stderr); // NOTEST
- fputs("NOTVAR", stderr);
+ fputs("NOTVAR", stderr); // NOTEST
break;
###### propagate exec cases
break;
###### propagate exec cases
struct var *var = cast(var, prog);
struct variable *v = var->var;
if (!v) {
struct var *var = cast(var, prog);
struct variable *v = var->var;
if (!v) {
- type_err(c, "%d:BUG: no variable!!", prog, Tnone, 0, Tnone);
- *ok = 0;
- return Tnone;
+ type_err(c, "%d:BUG: no variable!!", prog, Tnone, 0, Tnone); // NOTEST
+ *ok = 0; // NOTEST
+ return Tnone; // NOTEST
}
if (v->merged)
v = v->merged;
}
if (v->merged)
v = v->merged;
case GtrEq: printf(" >= "); break;
case Eql: printf(" == "); break;
case NEql: printf(" != "); break;
case GtrEq: printf(" >= "); break;
case Eql: printf(" == "); break;
case NEql: printf(" != "); break;
+ default: abort(); // NOTEST
}
print_exec(b->right, -1, 0);
break;
}
print_exec(b->right, -1, 0);
break;
case GtrEq: rv.bool = cmp >= 0; break;
case Eql: rv.bool = cmp == 0; break;
case NEql: rv.bool = cmp != 0; break;
case GtrEq: rv.bool = cmp >= 0; break;
case Eql: rv.bool = cmp == 0; break;
case NEql: rv.bool = cmp != 0; break;
- default: rv.bool = 0; break;
+ default: rv.bool = 0; break; // NOTEST
case Divide: fputs(" / ", stdout); break;
case Rem: fputs(" % ", stdout); break;
case Concat: fputs(" ++ ", stdout); break;
case Divide: fputs(" / ", stdout); break;
case Rem: fputs(" % ", stdout); break;
case Concat: fputs(" ++ ", stdout); break;
+ default: abort(); // NOTEST
+ } // NOTEST
print_exec(b->right, indent, 0);
break;
case Absolute:
print_exec(b->right, indent, 0);
break;
case Absolute:
free_value(*lleft);
*lleft = right;
} else
free_value(*lleft);
*lleft = right;
} else
+ free_value(right); // NOTEST
right.type = NULL;
break;
right.type = NULL;
break;
break;
###### propagate binode cases
break;
###### propagate binode cases
+ case Program: abort(); // NOTEST
do {
ok = 1;
propagate_types(b->right, c, &ok, Tnone, 0);
do {
ok = 1;
propagate_types(b->right, c, &ok, Tnone, 0);
struct value v;
if (!prog)
struct value v;
if (!prog)
al = cast(binode, p->left);
while (al) {
struct var *v = cast(var, al->left);
al = cast(binode, p->left);
while (al) {
struct var *v = cast(var, al->left);
}
###### interp binode cases
}
###### interp binode cases
+ case Program: abort(); // NOTEST
## And now to test it out.
## And now to test it out.