86 lines
2.2 KiB
C
86 lines
2.2 KiB
C
// Copyright 2022 Darwin Schuppan <darwin@nobrain.org>
|
|
// SPDX license identifier: MIT
|
|
|
|
#include <ds/error.h>
|
|
|
|
void *error_reserved_for_error = NULL;
|
|
|
|
void error_init() {
|
|
if (error_reserved_for_error != NULL) {
|
|
fprintf(stderr, "error: error_init() can only be called once.\n");
|
|
exit(1);
|
|
}
|
|
error_reserved_for_error = malloc(ERROR_RESERVATION_SIZE);
|
|
}
|
|
|
|
void error_term() {
|
|
free(error_reserved_for_error);
|
|
}
|
|
|
|
size_t error_to_string(char *buf, size_t size, Error e, bool destroy) {
|
|
size_t written = 0;
|
|
if (e.has_location) {
|
|
size_t left = size > written ? size - written : 0;
|
|
written += snprintf(buf + written, left, "%s:%zu: ", e.file, e.line);
|
|
}
|
|
switch (e.kind) {
|
|
case ErrorNone: {
|
|
size_t left = size > written ? size - written : 0;
|
|
written += snprintf(buf + written, left, "Success");
|
|
}
|
|
break;
|
|
case ErrorOutOfMemory: {
|
|
size_t left = size > written ? size - written : 0;
|
|
written += snprintf(buf + written, left, "Out of memory");
|
|
}
|
|
break;
|
|
case ErrorString: {
|
|
size_t left = size > written ? size - written : 0;
|
|
written += snprintf(buf + written, left, "%s", e.str);
|
|
if (e.str_on_heap && destroy)
|
|
free(e.str);
|
|
}
|
|
break;
|
|
}
|
|
if (e.has_annex) {
|
|
{
|
|
size_t left = size > written ? size - written : 0;
|
|
written += snprintf(buf + written, left, ": ");
|
|
}
|
|
{
|
|
size_t left = size > written ? size - written : 0;
|
|
written += error_to_string(buf + written, left, *e.annex, destroy);
|
|
}
|
|
if (destroy)
|
|
free(e.annex);
|
|
}
|
|
return written;
|
|
}
|
|
|
|
Error *_error_heapify(Error e) {
|
|
if (error_reserved_for_error == NULL) {
|
|
fprintf(stderr, "error: error_init() must be called at the beginning of the program before working with heap-allocated errors.\n");
|
|
return NULL;
|
|
}
|
|
Error *res = malloc(sizeof(*res));
|
|
if (res == NULL) {
|
|
free(error_reserved_for_error);
|
|
error_reserved_for_error = NULL;
|
|
res = malloc(sizeof(*res));
|
|
if (res == NULL) {
|
|
/* we should now have enough memory, if not we're seriously fucked */
|
|
fprintf(stderr, "error: Could not obtain enough memory to construct the appropriate error.");
|
|
return NULL;
|
|
}
|
|
}
|
|
*res = e;
|
|
return res;
|
|
}
|
|
|
|
Error _error_hereify(const char *file, size_t line, Error e) {
|
|
e.has_location = true;
|
|
e.file = file;
|
|
e.line = line;
|
|
return e;
|
|
}
|