2026-01-04 22:56:31 -05:00
|
|
|
#include "akerror.h"
|
|
|
|
|
#if defined(AKERROR_USE_STDLIB) && AKERROR_USE_STDLIB == 1
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
#include <stdarg.h>
|
|
|
|
|
#include <stdio.h>
|
|
|
|
|
#endif // AKERROR_USE_STDLIB
|
2025-07-20 21:40:14 -04:00
|
|
|
|
|
|
|
|
ErrorContext __error_last_ditch;
|
|
|
|
|
ErrorContext *__error_last_ignored;
|
|
|
|
|
ErrorUnhandledErrorHandler error_handler_unhandled_error;
|
2026-01-04 22:56:31 -05:00
|
|
|
ErrorLogFunction error_log_method = NULL;
|
2025-07-20 21:40:14 -04:00
|
|
|
|
2025-08-02 23:03:51 -04:00
|
|
|
char __ERROR_NAMES[MAX_ERR_VALUE+1][MAX_ERROR_NAME_LENGTH];
|
2025-07-20 21:40:14 -04:00
|
|
|
|
2026-01-10 09:50:17 -05:00
|
|
|
ErrorContext ARRAY_ERROR[MAX_ARRAY_ERROR];
|
2025-07-20 21:40:14 -04:00
|
|
|
|
2026-01-04 22:56:31 -05:00
|
|
|
void error_default_logger(const char *fmt, ...)
|
|
|
|
|
{
|
|
|
|
|
#if defined(AKERROR_USE_STDLIB) && AKERROR_USE_STDLIB == 1
|
|
|
|
|
va_list ap;
|
|
|
|
|
|
|
|
|
|
va_start(ap, fmt);
|
|
|
|
|
vfprintf(stderr, fmt, ap);
|
|
|
|
|
va_end(ap);
|
|
|
|
|
#else
|
|
|
|
|
return;
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
2025-07-20 21:40:14 -04:00
|
|
|
void error_init()
|
|
|
|
|
{
|
|
|
|
|
static int inited = 0;
|
|
|
|
|
if ( inited == 0 ) {
|
2026-01-10 09:50:17 -05:00
|
|
|
for (int i = 0; i < MAX_ARRAY_ERROR; i++ ) {
|
|
|
|
|
memset((void *)&ARRAY_ERROR[i], 0x00, sizeof(ErrorContext));
|
|
|
|
|
ARRAY_ERROR[i].arrayid = i;
|
|
|
|
|
ARRAY_ERROR[i].stacktracebufptr = (char *)&ARRAY_ERROR[i].stacktracebuf;
|
2025-07-20 21:40:14 -04:00
|
|
|
}
|
|
|
|
|
__error_last_ignored = NULL;
|
|
|
|
|
memset((void *)&__error_last_ditch, 0x00, sizeof(ErrorContext));
|
|
|
|
|
__error_last_ditch.stacktracebufptr = (char *)&__error_last_ditch.stacktracebuf;
|
2026-01-04 22:56:31 -05:00
|
|
|
if ( error_log_method == NULL ) {
|
|
|
|
|
error_log_method = &error_default_logger;
|
|
|
|
|
}
|
2025-07-20 21:40:14 -04:00
|
|
|
error_handler_unhandled_error = &error_default_handler_unhandled_error;
|
2025-08-02 15:07:08 -04:00
|
|
|
memset((void *)&__ERROR_NAMES[0], 0x00, ((MAX_ERR_VALUE+1) * MAX_ERROR_NAME_LENGTH));
|
|
|
|
|
|
|
|
|
|
error_name_for_status(ERR_NULLPOINTER, "Null Pointer Error");
|
|
|
|
|
error_name_for_status(ERR_OUTOFBOUNDS, "Out Of Bounds Error");
|
2026-01-04 22:56:31 -05:00
|
|
|
error_name_for_status(ERR_API, "API Error");
|
2025-08-02 15:07:08 -04:00
|
|
|
error_name_for_status(ERR_ATTRIBUTE, "Attribute Error");
|
|
|
|
|
error_name_for_status(ERR_TYPE, "Type Error");
|
|
|
|
|
error_name_for_status(ERR_KEY, "Key Error");
|
|
|
|
|
error_name_for_status(ERR_HEAP, "Heap Error");
|
|
|
|
|
error_name_for_status(ERR_INDEX, "Index Error");
|
|
|
|
|
error_name_for_status(ERR_FORMAT, "Format Error");
|
|
|
|
|
error_name_for_status(ERR_IO, "Input Output Error");
|
|
|
|
|
error_name_for_status(ERR_REGISTRY, "Registry Error");
|
|
|
|
|
error_name_for_status(ERR_VALUE, "Value Error");
|
|
|
|
|
error_name_for_status(ERR_BEHAVIOR, "Behavior Error");
|
|
|
|
|
error_name_for_status(ERR_RELATIONSHIP, "Relationship Error");
|
|
|
|
|
|
2025-07-20 21:40:14 -04:00
|
|
|
inited = 1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void error_default_handler_unhandled_error(ErrorContext *errctx)
|
|
|
|
|
{
|
|
|
|
|
if ( errctx == NULL ) {
|
|
|
|
|
exit(1);
|
|
|
|
|
}
|
|
|
|
|
exit(errctx->status);
|
|
|
|
|
}
|
|
|
|
|
|
2026-01-10 09:50:17 -05:00
|
|
|
ErrorContext *array_next_error()
|
2025-07-20 21:40:14 -04:00
|
|
|
{
|
2026-01-10 09:50:17 -05:00
|
|
|
for (int i = 0; i < MAX_ARRAY_ERROR; i++ ) {
|
|
|
|
|
if ( ARRAY_ERROR[i].refcount == 0 ) {
|
|
|
|
|
return &ARRAY_ERROR[i];
|
2025-07-20 21:40:14 -04:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return (ErrorContext *)NULL;
|
|
|
|
|
}
|
|
|
|
|
|
2026-01-10 09:50:17 -05:00
|
|
|
ErrorContext *array_release_error(ErrorContext *err)
|
2025-07-20 21:40:14 -04:00
|
|
|
{
|
|
|
|
|
int oldid = 0;
|
|
|
|
|
if ( err == NULL ) {
|
|
|
|
|
ErrorContext *errctx = &__error_last_ditch;
|
2026-01-10 09:50:17 -05:00
|
|
|
FAIL_RETURN(errctx, ERR_NULLPOINTER, "array_release_error got NULL context pointer");
|
2025-07-20 21:40:14 -04:00
|
|
|
}
|
|
|
|
|
if ( err->refcount > 0 ) {
|
|
|
|
|
err->refcount -= 1;
|
|
|
|
|
}
|
|
|
|
|
if ( err->refcount == 0 ) {
|
2026-01-10 09:50:17 -05:00
|
|
|
oldid = err->arrayid;
|
2025-07-20 21:40:14 -04:00
|
|
|
memset(err, 0x00, sizeof(ErrorContext));
|
|
|
|
|
err->stacktracebufptr = (char *)&err->stacktracebuf;
|
2026-01-10 09:50:17 -05:00
|
|
|
err->arrayid = oldid;
|
2025-07-20 21:40:14 -04:00
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
return err;
|
|
|
|
|
}
|
|
|
|
|
|
2025-08-02 15:07:08 -04:00
|
|
|
|
|
|
|
|
// returns or sets the name for the given status.
|
|
|
|
|
// Call with name = NULL to retrieve a status.
|
|
|
|
|
char *error_name_for_status(int status, char *name)
|
2025-07-20 21:40:14 -04:00
|
|
|
{
|
2025-08-02 15:07:08 -04:00
|
|
|
if ( status > MAX_ERR_VALUE ) {
|
|
|
|
|
return "Unknown Error";
|
|
|
|
|
}
|
|
|
|
|
if ( name != NULL ) {
|
2025-08-02 23:03:51 -04:00
|
|
|
strncpy((char *)&__ERROR_NAMES[status], name, MAX_ERROR_NAME_LENGTH);
|
2025-08-02 15:07:08 -04:00
|
|
|
}
|
2025-08-02 23:03:51 -04:00
|
|
|
return (char *)&__ERROR_NAMES[status];
|
2025-07-20 21:40:14 -04:00
|
|
|
}
|