X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~mdw/git/mLib/blobdiff_plain/67b5031ec6d160b5cae425466a34d1be3b211dd4..c91413e6acbc8d157ff52ceb8cd78cee97403584:/test/tvec-core.c?ds=sidebyside diff --git a/test/tvec-core.c b/test/tvec-core.c index 92f31d3..51834f4 100644 --- a/test/tvec-core.c +++ b/test/tvec-core.c @@ -37,49 +37,60 @@ /*----- Output ------------------------------------------------------------*/ -/* --- @tvec_error@, @tvec_error_v@ --- * +/* --- @tvec_report@, @tvec_report_v@ --- * * * Arguments: @struct tvec_state *tv@ = test-vector state * @const char *msg@, @va_list ap@ = error message * - * Returns: @-1@. + * Returns: --- * - * Use: Report an error. Errors are distinct from test failures, - * and indicate that a problem was encountered which compromised - * the activity of testing. + * Use: Report an message with a given severity. Messages with level + * @TVLEV_ERR@ or higher force a nonzero exit code. */ -int tvec_error(struct tvec_state *tv, const char *msg, ...) +void tvec_report(struct tvec_state *tv, unsigned level, const char *msg, ...) { va_list ap; - va_start(ap, msg); tvec_error_v(tv, msg, &ap); va_end(ap); - return (-1); + va_start(ap, msg); tvec_report_v(tv, level, msg, &ap); va_end(ap); } -int tvec_error_v(struct tvec_state *tv, const char *msg, va_list *ap) + +void tvec_report_v(struct tvec_state *tv, unsigned level, + const char *msg, va_list *ap) { - tv->output->ops->error(tv->output, msg, ap); - tv->f |= TVSF_ERROR; return (-1); + tv->output->ops->report(tv->output, level, msg, ap); + if (level >= TVLEV_ERR) tv->f |= TVSF_ERROR; } -/* --- @tvec_notice@, @tvec_notice_v@ --- * +/* --- @tvec_error@, @tvec_notice@ --- * * * Arguments: @struct tvec_state *tv@ = test-vector state - * @const char *msg@, @va_list ap@ = message + * @const char *msg@, @va_list ap@ = error message * - * Returns: --- + * Returns: The @tvec_error@ function returns @-1@ as a trivial + * convenience; @tvec_notice@ does not return a value. * - * Use: Output a notice: essentially, some important information - * which doesn't fit into any of the existing categories. + * Use: Report an error or a notice. Errors are distinct from test + * failures, and indicate that a problem was encountered which + * compromised the activity of testing. Notices are important + * information which doesn't fit into any other obvious + * category. */ +int tvec_error(struct tvec_state *tv, const char *msg, ...) +{ + va_list ap; + + va_start(ap, msg); tvec_report_v(tv, TVLEV_ERR, msg, &ap); va_end(ap); + return (-1); +} + void tvec_notice(struct tvec_state *tv, const char *msg, ...) { va_list ap; - va_start(ap, msg); tvec_notice_v(tv, msg, &ap); va_end(ap); + + va_start(ap, msg); tvec_report_v(tv, TVLEV_NOTE, msg, &ap); va_end(ap); } -void tvec_notice_v(struct tvec_state *tv, const char *msg, va_list *ap) - { tv->output->ops->notice(tv->output, msg, ap); } /*----- Test processing ---------------------------------------------------*/ @@ -91,8 +102,10 @@ void tvec_skipgroup(struct tvec_state *tv, const char *excuse, ...) } void tvec_skipgroup_v(struct tvec_state *tv, const char *excuse, va_list *ap) { - tv->f |= TVSF_SKIP; tv->grps[TVOUT_SKIP]++; - tv->output->ops->skipgroup(tv->output, excuse, ap); + if (!(tv->f&TVSF_SKIP)) { + tv->f |= TVSF_SKIP; tv->grps[TVOUT_SKIP]++; + tv->output->ops->skipgroup(tv->output, excuse, ap); + } } static void set_outcome(struct tvec_state *tv, unsigned out) @@ -302,7 +315,7 @@ void tvec_resetoutputs(struct tvec_state *tv) } } -static void init_registers(struct tvec_state *tv) +void tvec_initregs(struct tvec_state *tv) { const struct tvec_regdef *rd; struct tvec_reg *r; @@ -315,7 +328,7 @@ static void init_registers(struct tvec_state *tv) } } -static void release_registers(struct tvec_state *tv) +void tvec_releaseregs(struct tvec_state *tv) { const struct tvec_regdef *rd; struct tvec_reg *r; @@ -392,18 +405,21 @@ static void check(struct tvec_state *tv, struct groupstate *g) if (!(tv->f&TVSF_SKIP)) { begin_test(tv); env = t->env; - if (env && env->before && env->before(tv, g->ctx)) - tvec_skip(tv, "test setup failed"); + if (env && env->before) env->before(tv, g->ctx); + if (!(tv->f&TVSF_ACTIVE)) + /* setup forced a skip */; + else if (env && env->run) + env->run(tv, t->fn, g->ctx); else { - if (env && env->run) env->run(tv, t->fn, g->ctx); - else { t->fn(tv->in, tv->out, g->ctx); tvec_check(tv, 0); } + t->fn(tv->in, tv->out, g->ctx); + tvec_check(tv, 0); } if (env && env->after) env->after(tv, g->ctx); tvec_endtest(tv); } end: - tv->f &= ~TVSF_OPEN; release_registers(tv); init_registers(tv); + tv->f &= ~TVSF_OPEN; tvec_releaseregs(tv); tvec_initregs(tv); } static void begin_test_group(struct tvec_state *tv, struct groupstate *g) @@ -414,13 +430,10 @@ static void begin_test_group(struct tvec_state *tv, struct groupstate *g) tv->output->ops->bgroup(tv->output); tv->f &= ~TVSF_SKIP; - init_registers(tv); + tvec_initregs(tv); for (i = 0; i < TVOUT_LIMIT; i++) tv->curr[i] = 0; if (env && env->ctxsz) g->ctx = xmalloc(env->ctxsz); - if (env && env->setup && env->setup(tv, env, 0, g->ctx)) { - tvec_skipgroup(tv, "setup failed"); - xfree(g->ctx); g->ctx = 0; - } + if (env && env->setup) env->setup(tv, env, 0, g->ctx); } static void report_group(struct tvec_state *tv) @@ -448,7 +461,7 @@ static void end_test_group(struct tvec_state *tv, struct groupstate *g) if (tv->f&TVSF_OPEN) check(tv, g); if (!(tv->f&TVSF_SKIP)) report_group(tv); env = t->env; if (env && env->teardown) env->teardown(tv, g->ctx); - release_registers(tv); tv->test = 0; xfree(g->ctx); g->ctx = 0; + tvec_releaseregs(tv); tv->test = 0; xfree(g->ctx); g->ctx = 0; } int tvec_read(struct tvec_state *tv, const char *infile, FILE *fp) @@ -611,7 +624,7 @@ int tvec_serialize(const struct tvec_reg *rv, buf *b, for (rd = regs, i = 0; rd->name; rd++, i++) { if (rd->i >= nr) continue; r = TVEC_GREG(rv, rd->i, regsz); if (!(r->f&TVRF_LIVE)) continue; - bitmap = BBASE(b) + bitoff; bitmap[rd->i/8] |= 1 << rd->i%8; + bitmap = BBASE(b) + bitoff; bitmap[i/8] |= 1 << i%8; if (rd->ty->tobuf(b, &r->v, rd)) return (-1); } return (0); @@ -632,7 +645,7 @@ int tvec_deserialize(struct tvec_reg *rv, buf *b, bitmap = buf_get(b, bitsz); if (!bitmap) return (-1); for (rd = regs, i = 0; rd->name; rd++, i++) { if (rd->i >= nr) continue; - if (!(bitmap[rd->i/8]&(1 << rd->i%8))) continue; + if (!(bitmap[i/8]&(1 << i%8))) continue; r = TVEC_GREG(rv, rd->i, regsz); if (rd->ty->frombuf(b, &r->v, rd)) return (-1); r->f |= TVRF_LIVE; @@ -750,7 +763,7 @@ int tvec_claimeq(struct tvec_state *tv, adhoc_claim_setup(tv, &ck, regs, file, lno); ok = ty->eq(&tv->in[0].v, &tv->out[0].v, ®s[0]); if (!ok) - { tvec_fail(tv, "%s", expr ); tvec_mismatch(tv, TVMF_IN | TVMF_OUT); } + { tvec_fail(tv, "%s", expr); tvec_mismatch(tv, TVMF_IN | TVMF_OUT); } adhoc_claim_teardown(tv, &ck); return (ok); }