#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 { int config_line; /* source line number, or 0 if not applicable */ const char *message; /* static string describing what was wrong */ }; 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_INVALID_ERROR_MSG(cfg_line, msg) \ ((struct App_Error){ \ .code = ERR_INVALID, \ .file = __FILE__, \ .line = __LINE__, \ .detail = { .invalid = { .config_line = (cfg_line), .message = (msg) } }, \ }) #define APP_NOT_FOUND_ERROR() \ ((struct App_Error){ \ .code = ERR_NOT_FOUND, \ .file = __FILE__, \ .line = __LINE__, \ })