// SPDX-License-Identifier: MIT // Copyright (c) 2024 John Watts and the LuminaSensum contributors #include "error.h" #include <stdio.h> #include <stdlib.h> struct stacktrace { int size; int depth; const char *frames[]; }; __attribute__((noreturn)) void abort_print(const char *msg) { fprintf(stderr, "ERROR: %s\n", msg); abort(); } StackTrace stacktrace_create(int frames) { size_t struct_size = sizeof(struct stacktrace); size_t frame_size = sizeof(const char *) * frames; size_t total_size = frame_size + struct_size; struct stacktrace *trace = malloc(total_size); if (trace == NULL) abort_print("stacktrace_create: unable to allocate trace"); trace->size = frames; trace->depth = 0; return (StackTrace)trace; } void stacktrace_push(StackTrace trace, const char *name) { struct stacktrace *priv = (struct stacktrace *)trace; if (priv->depth == priv->size) abort_print("stacktrace_push: overflow"); priv->frames[priv->depth++] = name; } void stacktrace_pop(StackTrace trace) { struct stacktrace *priv = (struct stacktrace *)trace; if (priv->depth == 0) abort_print("stacktrace_pop: underflow"); --priv->depth; } void stacktrace_print(StackTrace trace) { struct stacktrace *priv = (struct stacktrace *)trace; fprintf(stderr, "TRACEBACK:\n"); for (int i = 0; i < priv->depth; ++i) { const char *name = priv->frames[i]; fprintf(stderr, "%i: %s\n", i, name); } }