#pragma once #include typedef enum Error_Code { ERR_NONE = 0, ERR_SYSCALL = 1, ERR_INVALID = 2, ERR_NOT_FOUND = 3, } Error_Code; struct Syscall_Error_Detail { int err_no; }; struct Invalid_Error_Detail { /* fields added as concrete cases arise */ int placeholder; }; struct App_Error { Error_Code code; const char *file; int line; union { struct Syscall_Error_Detail syscall; struct Invalid_Error_Detail invalid; } detail; }; void app_error_print(struct App_Error *e); #define APP_OK \ ((struct App_Error){ .code = ERR_NONE }) #define APP_IS_OK(e) \ ((e).code == ERR_NONE) #define APP_SYSCALL_ERROR() \ ((struct App_Error){ \ .code = ERR_SYSCALL, \ .file = __FILE__, \ .line = __LINE__, \ .detail = { .syscall = { .err_no = errno } }, \ }) #define APP_INVALID_ERROR() \ ((struct App_Error){ \ .code = ERR_INVALID, \ .file = __FILE__, \ .line = __LINE__, \ }) #define APP_NOT_FOUND_ERROR() \ ((struct App_Error){ \ .code = ERR_NOT_FOUND, \ .file = __FILE__, \ .line = __LINE__, \ })