#include "akerror.h" #include "err_capture.h" /* * The error pool is a fixed array of AKERR_MAX_ARRAY_ERROR slots. When every * slot is checked out, akerr_next_error() must return NULL rather than run off * the end of the array; and it must always hand back the lowest free slot. * Mutation testing showed both the terminating "return NULL" and the scan * bounds could be broken without any test noticing. */ int main(void) { akerr_init(); akerr_ErrorContext *slots[AKERR_MAX_ARRAY_ERROR]; /* Check out every slot. Each arrives holding its own reference, so the * next request cannot be handed the same one. */ for ( int i = 0; i < AKERR_MAX_ARRAY_ERROR; i++ ) { slots[i] = akerr_next_error(); AKERR_CHECK(slots[i] != NULL); AKERR_CHECK(slots[i]->refcount == 1); } /* Pool is fully exhausted: the next request must fail cleanly. */ AKERR_CHECK(akerr_next_error() == NULL); /* Free exactly the first slot; the scan must find and return it. */ slots[0]->refcount = 0; AKERR_CHECK(akerr_next_error() == slots[0]); /* Tidy up. */ for ( int i = 0; i < AKERR_MAX_ARRAY_ERROR; i++ ) { slots[i]->refcount = 0; } fprintf(stderr, "err_pool_exhaust ok\n"); return 0; }