blob: d4c47e8d50d5656b5de5f0b2e1d7aced4fb42e77 [file] [log] [blame]
swissChili6d02af42021-08-05 19:49:01 -07001#pragma once
2
3#include <stdbool.h>
4
5// Error handling code
6
7struct eloc
8{
9 int line;
10 char *file;
11};
12
13enum error_code
14{
15 EOK = 0,
16 /// Expected something but didn't get it. if this is in a
17 /// safe_state we should probably just re-try.
18 EEXPECTED,
19 /// An invalid token was present in the input
20 EINVALID,
21 /// A structure was malformed
22 EMALFORMED,
23 /// The arguments provided were invalid
24 EARGS,
25 /// An external resource (say, a file) was not found
26 ENOTFOUND,
27 /// This is unimplemented
28 EUNIMPL,
29};
30
31struct error
32{
33 enum error_code code;
34 // Is any state safe? I.e. can we continue or must we panic?
35 bool safe_state;
36 struct eloc loc;
37 char *message;
38};
39
40#define E_INIT() \
41 struct error __error; \
42 __error.code = EOK; \
43 __error.loc.line = 0; \
44 __error.safe_state = false; \
45 __error.message = NULL; \
46 __error.loc.file = NULL;
47#define NEARVAL(val) \
48 __error.loc.line = cons_line(val); \
49 __error.loc.file = cons_file(val)
50#define NEARIS(is) (is)->getpos((is), &__error.loc.line, &__error.loc.file)
51#define _TRY(expr, m, c) \
52 { \
53 struct error __sub = (expr); \
54 if (__sub.code) \
55 { \
56 if (!__sub.loc.file || !__sub.loc.line) \
57 __sub.loc.file = __error.loc.file, \
58 __sub.loc.line = __error.loc.line; \
59 if (c) \
60 __sub.code = c; \
61 if (m) \
62 __sub.message = m; \
63 return __sub; \
64 } \
65 }
66#define TRY(expr) _TRY(expr, NULL, 0)
67#define TRY_ELSE(expr, c, ...) _TRY(expr, ehsprintf(__VA_ARGS__), c)
68#define OKAY() return __error
69#define THROW(_c, ...) \
70 { \
71 __error.code = (_c); \
72 __error.message = ehsprintf(__VA_ARGS__); \
73 return __error; \
74 }
75#define THROWSAFE(_c) \
76 { \
77 __error.code = (_c); \
78 __error.safe_state = true; \
79 return __error; \
80 }
81
82#define IS_OKAY(e) ((e).code == EOK)
83#define OKAY_IF(val) \
84 { \
85 struct error __sub = (val); \
86 if (IS_OKAY(__sub)) \
87 OKAY(); \
88 if (!__sub.safe_state) \
89 TRY(__sub) \
90 }
91
92#define WARN_UNUSED __attribute__((warn_unused_result))
93
94// error heap string print formatted
95// returns a heap-allocated string.
96char *ehsprintf(const char *msg, ...);
97
98void ereport(struct error err);