57 lines
2.2 KiB
C
57 lines
2.2 KiB
C
|
|
#include "akerror.h"
|
||
|
|
#include "err_capture.h"
|
||
|
|
#include <string.h>
|
||
|
|
|
||
|
|
/*
|
||
|
|
* A library may reserve its status range from its own init() before anything in
|
||
|
|
* the process has raised an error, i.e. before akerr_init() has run. That used
|
||
|
|
* to be silently destructive: akerr_init() clears the range and name tables, so
|
||
|
|
* whichever component first triggered it (via PREPARE_ERROR) wiped the earlier
|
||
|
|
* reservation, and the *next* component to claim the same range was told OK --
|
||
|
|
* producing exactly the undetected aliasing the registry exists to prevent.
|
||
|
|
*
|
||
|
|
* Every public registry entry point now calls akerr_init() itself, so the
|
||
|
|
* tables are only ever cleared before the first reservation, never after one.
|
||
|
|
*
|
||
|
|
* Note this test must not call akerr_init() or PREPARE_ERROR first -- the
|
||
|
|
* uninitialized entry is the whole point.
|
||
|
|
*/
|
||
|
|
|
||
|
|
int main(void)
|
||
|
|
{
|
||
|
|
akerr_capture_install();
|
||
|
|
|
||
|
|
/* Cold call: no akerr_init(), no PREPARE_ERROR anywhere yet. */
|
||
|
|
AKERR_CHECK(akerr_reserve_status_range(256, 16, "early-lib") ==
|
||
|
|
AKERR_STATUS_RANGE_OK);
|
||
|
|
AKERR_CHECK(akerr_register_status_name("early-lib", 256, "Early Error") ==
|
||
|
|
AKERR_STATUS_NAME_OK);
|
||
|
|
|
||
|
|
/* Something else now uses the library for the first time. */
|
||
|
|
akerr_init();
|
||
|
|
PREPARE_ERROR(e);
|
||
|
|
(void)e;
|
||
|
|
|
||
|
|
/* The early reservation and its name must both have survived. */
|
||
|
|
AKERR_CHECK(strcmp(akerr_name_for_status(256, NULL), "Early Error") == 0);
|
||
|
|
AKERR_CHECK(akerr_reserve_status_range(256, 16, "late-lib") ==
|
||
|
|
AKERR_STATUS_RANGE_OVERLAP);
|
||
|
|
AKERR_CHECK_CONTAINS("early-lib");
|
||
|
|
AKERR_CHECK(akerr_reserve_status_range(260, 2, "late-lib") ==
|
||
|
|
AKERR_STATUS_RANGE_OVERLAP);
|
||
|
|
|
||
|
|
/* The library's own initialization still happened exactly once. */
|
||
|
|
AKERR_CHECK(strcmp(akerr_name_for_status(AKERR_NULLPOINTER, NULL),
|
||
|
|
"Null Pointer Error") == 0);
|
||
|
|
AKERR_CHECK(akerr_reserve_status_range(0, AKERR_RESERVED_STATUS_COUNT,
|
||
|
|
AKERR_LIBRARY_OWNER) ==
|
||
|
|
AKERR_STATUS_RANGE_OK);
|
||
|
|
|
||
|
|
/* An identical repeat by the original owner is still idempotent. */
|
||
|
|
AKERR_CHECK(akerr_reserve_status_range(256, 16, "early-lib") ==
|
||
|
|
AKERR_STATUS_RANGE_OK);
|
||
|
|
|
||
|
|
fprintf(stderr, "err_registry_init_order ok\n");
|
||
|
|
return 0;
|
||
|
|
}
|