/* * tcheck.c — реализация микро-фреймворка (см. tcheck.h). * * Всё пишется в tc_result — раннер читает эту структуру из ОЗУ. Ничего * не инициализируем явно: crt0_ucsim зануляет _DATA/_BSS, и magic ставится * первым же tc_begin (правило проекта про статики — memory * sdcc_static_storage_gotcha). */ #include "tcheck.h" tc_result_t tc_result; const char *tc_curr; static void tc_putc(char c) { if (tc_result.logn < TC_LOGSZ - 1) tc_result.log[tc_result.logn++] = (uint8_t)c; } static void tc_puts(const char *s) { while (*s) tc_putc(*s++); } static void tc_puthex(uint16_t v) { const char *d = "0123456789ABCDEF"; tc_puts(" (0x"); tc_putc(d[(v >> 12) & 15]); tc_putc(d[(v >> 8) & 15]); tc_putc(d[(v >> 4) & 15]); tc_putc(d[v & 15]); tc_putc(')'); } /* Знаковое десятичное: значения тестов маленькие, но делаем честно для * всего диапазона int16_t. */ static void tc_putd(int16_t v) { char buf[7]; uint8_t n = 0; uint16_t u; if (v < 0) { tc_putc('-'); u = (uint16_t)(-v); } else { u = (uint16_t)v; } do { buf[n++] = (char)('0' + (u % 10u)); u /= 10u; } while (u); while (n) tc_putc(buf[--n]); } void tc_begin(const char *name) { tc_result.magic = TC_MAGIC; tc_curr = name; } static void tc_fail_head(const char *expr, uint16_t line) { tc_result.failed++; tc_puts("FAIL "); tc_puts(tc_curr ? tc_curr : "?"); tc_puts(":"); tc_putd((int16_t)line); tc_puts(" "); tc_puts(expr); } void tc_check(int16_t got, int16_t want, const char *expr, uint16_t line) { tc_result.magic = TC_MAGIC; tc_result.total++; if (got == want) return; tc_fail_head(expr, line); /* Печатаем и десятичное, и hex: сравнение идёт как int16_t, поэтому * беззнаковые величины (сид PRNG, координаты > 32767) в десятичном * виде выглядят отрицательными и сбивают с толку. */ tc_puts(" = "); tc_putd(got); tc_puthex((uint16_t)got); tc_puts(", ждали "); tc_putd(want); tc_puthex((uint16_t)want); tc_putc('\n'); } void tc_checkp(const void *got, const void *want, const char *expr, uint16_t line) { tc_result.magic = TC_MAGIC; tc_result.total++; if (got == want) return; tc_fail_head(expr, line); tc_puts(" — указатели различаются\n"); }