2026-07-27 16:18:17 -04:00
|
|
|
#include "akerror.h"
|
|
|
|
|
#include "err_capture.h"
|
|
|
|
|
#include <errno.h>
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* The library imports system errno codes and their descriptions at build time
|
|
|
|
|
* (scripts/generrno.sh -> akerr_init_errno). Verify:
|
|
|
|
|
* - a system errno (EACCES) has a registered, non-empty name;
|
2026-07-30 13:53:39 -04:00
|
|
|
* - an unregistered status returns the "Unknown Error" sentinel;
|
2026-07-27 16:18:17 -04:00
|
|
|
* - a system errno can be raised, propagated and handled like any AKERR_* code.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
static int handled = 0;
|
|
|
|
|
|
|
|
|
|
akerr_ErrorContext *boom(void)
|
|
|
|
|
{
|
|
|
|
|
PREPARE_ERROR(e);
|
|
|
|
|
FAIL_RETURN(e, EACCES, "permission denied");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int main(void)
|
|
|
|
|
{
|
|
|
|
|
akerr_capture_install();
|
|
|
|
|
akerr_init();
|
|
|
|
|
|
|
|
|
|
char *nm = akerr_name_for_status(EACCES, NULL);
|
|
|
|
|
AKERR_CHECK(nm != NULL);
|
|
|
|
|
AKERR_CHECK(nm[0] != '\0');
|
Fix the AKERR_USE_STDLIB=OFF build (issue #12)
The freestanding build (-DAKERR_USE_STDLIB=OFF) did not compile at all:
bool, PATH_MAX and NULL were used unconditionally in the public header
but only included under the stdlib branch, and the CMake option was
pasted straight into a preprocessor definition, so a non-numeric cache
spelling (-DAKERR_USE_STDLIB=ON) silently evaluated to 0.
- Normalize AKERR_USE_STDLIB to a plain 1/0 in CMake before stamping it,
and use a consistent '#if AKERR_USE_STDLIB' everywhere it is tested.
- Include <stdbool.h>/<stddef.h> unconditionally (freestanding-safe);
keep <stdlib.h>/<string.h>/<stdio.h> behind AKERR_USE_STDLIB; move
<limits.h> out of the public header into src/error.c, its only user.
- Define the freestanding runtime contract: AKERR_RUNTIME_HEADER must
name a header providing exit, memset, snprintf, strcmp, strlen and
strncpy when AKERR_USE_STDLIB is OFF, or the header #errors naming
them. Add cmake/akerr_default_runtime.h, a libc-backed convenience
default so this repo's own OFF build and tests work out of the box.
- Route ENSURE_ERROR_READY's pool-exhaustion path through akerr_exit()
instead of a direct exit(1). Deliberate behavior change: that exit
code moves from 1 to AKERR_EXIT_STATUS_UNREPRESENTABLE (125), the same
sentinel every other unrepresentable status already uses. Documented
in docs/building.md and UPGRADING.md. Not an ABI break.
- Retire PATH_MAX: AKERR_MAX_ERROR_FNAME_LENGTH is now stamped by
scripts/generrno.sh from a new AKERR_MAX_ERROR_FNAME_LENGTH cache
variable, defaulting to 4096 (PATH_MAX on Linux/glibc) so
sizeof(akerr_ErrorContext) and the soname are unchanged. Rewrite the
now-stale PATH_MAX justification in src/lock.h's feature-test-macro
comment.
- Fail the configure with a FATAL_ERROR, not a warning, when
AKERR_USE_STDLIB=OFF and AKERR_THREADS would resolve to pthread,
naming -DAKERR_THREADS=none as the fix.
- Keep the generated errno table (errno.c) out of the OFF build; skip
the 'errno --list' shellout in scripts/generrno.sh under OFF and
stamp AKERR_LAST_ERRNO_VALUE from a new fallback cache variable
(default 133, Linux's EHWPOISON) instead.
- Update docs/building.md: drop the known-defect paragraph, fix
sprintf -> snprintf, add size_t, drop PATH_MAX, and document the new
options and the exit-code change.
- Guard tests/err_errno.c's registered-name assertion behind
AKERR_USE_STDLIB: akerr_init_errno() is not called when it is OFF.
- Add a CI job that configures/builds/tests AKERR_USE_STDLIB=OFF with
AKERR_THREADS=none, plus a compile-only -nostdinc -ffreestanding
check of tests/freestanding_fixture.c against the generated header.
Bump the project version to 2.0.2 (no ABI break: soname and struct
layout are unchanged).
Verified locally: OFF+none configures and builds clean with all tests
passing; ON and the plain default build both build and pass their full
test suites (37/37); OFF with the default/auto thread backend fails
configure with a message naming -DAKERR_THREADS=none; sizeof(akerr_ErrorContext)
is unchanged (37296 bytes, fname/function still 4096 each) versus the
pre-change tree.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-05 10:29:39 -04:00
|
|
|
#if AKERR_USE_STDLIB
|
|
|
|
|
/* akerr_init_errno() -- the only thing that registers a name for a host
|
|
|
|
|
* errno -- is not called when AKERR_USE_STDLIB is OFF (see
|
|
|
|
|
* akerr_init_state() in src/error.c), so EACCES deliberately reads back
|
|
|
|
|
* as "Unknown Error" in that configuration. */
|
2026-07-27 16:18:17 -04:00
|
|
|
AKERR_CHECK(strcmp(nm, "Unknown Error") != 0);
|
Fix the AKERR_USE_STDLIB=OFF build (issue #12)
The freestanding build (-DAKERR_USE_STDLIB=OFF) did not compile at all:
bool, PATH_MAX and NULL were used unconditionally in the public header
but only included under the stdlib branch, and the CMake option was
pasted straight into a preprocessor definition, so a non-numeric cache
spelling (-DAKERR_USE_STDLIB=ON) silently evaluated to 0.
- Normalize AKERR_USE_STDLIB to a plain 1/0 in CMake before stamping it,
and use a consistent '#if AKERR_USE_STDLIB' everywhere it is tested.
- Include <stdbool.h>/<stddef.h> unconditionally (freestanding-safe);
keep <stdlib.h>/<string.h>/<stdio.h> behind AKERR_USE_STDLIB; move
<limits.h> out of the public header into src/error.c, its only user.
- Define the freestanding runtime contract: AKERR_RUNTIME_HEADER must
name a header providing exit, memset, snprintf, strcmp, strlen and
strncpy when AKERR_USE_STDLIB is OFF, or the header #errors naming
them. Add cmake/akerr_default_runtime.h, a libc-backed convenience
default so this repo's own OFF build and tests work out of the box.
- Route ENSURE_ERROR_READY's pool-exhaustion path through akerr_exit()
instead of a direct exit(1). Deliberate behavior change: that exit
code moves from 1 to AKERR_EXIT_STATUS_UNREPRESENTABLE (125), the same
sentinel every other unrepresentable status already uses. Documented
in docs/building.md and UPGRADING.md. Not an ABI break.
- Retire PATH_MAX: AKERR_MAX_ERROR_FNAME_LENGTH is now stamped by
scripts/generrno.sh from a new AKERR_MAX_ERROR_FNAME_LENGTH cache
variable, defaulting to 4096 (PATH_MAX on Linux/glibc) so
sizeof(akerr_ErrorContext) and the soname are unchanged. Rewrite the
now-stale PATH_MAX justification in src/lock.h's feature-test-macro
comment.
- Fail the configure with a FATAL_ERROR, not a warning, when
AKERR_USE_STDLIB=OFF and AKERR_THREADS would resolve to pthread,
naming -DAKERR_THREADS=none as the fix.
- Keep the generated errno table (errno.c) out of the OFF build; skip
the 'errno --list' shellout in scripts/generrno.sh under OFF and
stamp AKERR_LAST_ERRNO_VALUE from a new fallback cache variable
(default 133, Linux's EHWPOISON) instead.
- Update docs/building.md: drop the known-defect paragraph, fix
sprintf -> snprintf, add size_t, drop PATH_MAX, and document the new
options and the exit-code change.
- Guard tests/err_errno.c's registered-name assertion behind
AKERR_USE_STDLIB: akerr_init_errno() is not called when it is OFF.
- Add a CI job that configures/builds/tests AKERR_USE_STDLIB=OFF with
AKERR_THREADS=none, plus a compile-only -nostdinc -ffreestanding
check of tests/freestanding_fixture.c against the generated header.
Bump the project version to 2.0.2 (no ABI break: soname and struct
layout are unchanged).
Verified locally: OFF+none configures and builds clean with all tests
passing; ON and the plain default build both build and pass their full
test suites (37/37); OFF with the default/auto thread backend fails
configure with a message naming -DAKERR_THREADS=none; sizeof(akerr_ErrorContext)
is unchanged (37296 bytes, fname/function still 4096 each) versus the
pre-change tree.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-05 10:29:39 -04:00
|
|
|
#endif
|
2026-07-27 16:18:17 -04:00
|
|
|
|
2026-07-30 13:53:39 -04:00
|
|
|
AKERR_CHECK(strcmp(akerr_name_for_status(1000000, NULL),
|
2026-07-27 16:18:17 -04:00
|
|
|
"Unknown Error") == 0);
|
|
|
|
|
|
|
|
|
|
PREPARE_ERROR(e);
|
|
|
|
|
ATTEMPT {
|
|
|
|
|
CATCH(e, boom());
|
|
|
|
|
} CLEANUP {
|
|
|
|
|
} PROCESS(e) {
|
|
|
|
|
} HANDLE(e, EACCES) {
|
2026-07-29 17:09:45 -04:00
|
|
|
AKERR_CHECK_STATUS(e, EACCES);
|
2026-07-27 16:18:17 -04:00
|
|
|
handled = 1;
|
|
|
|
|
} FINISH_NORETURN(e);
|
|
|
|
|
|
|
|
|
|
AKERR_CHECK(handled == 1);
|
|
|
|
|
AKERR_CHECK(akerr_slots_in_use() == 0);
|
|
|
|
|
fprintf(stderr, "err_errno ok (EACCES name: \"%s\")\n", nm);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|