1#include <console/crash.h>
2#include <console/printf.h>
3#include <stdarg.h>
4#include <string.h>
5
6static cc_noreturn void impl_default(struct crash_payload pluh,
7 const char *file, int line,
8 const char *func, const char *prefix,
9 const char *fmt, va_list args) {
10 cc_ignore(pluh);
11 static char msg[CRASH_MSG_MAX];
12
13 int n = 0;
14 if (prefix && strlen(str: prefix) > 0) {
15 n = snprintf(msg, sizeof(msg), "%s", prefix);
16 if (n < 0)
17 n = 0;
18 if (n > (int) sizeof(msg) - 1)
19 n = (int) sizeof(msg) - 1;
20 }
21
22 if (fmt && strlen(str: fmt) > 0)
23 vsnprintf(msg + n, sizeof(msg) - n, fmt, args);
24
25 crash_full(ctx: &(struct crash_context){
26 .payload = pluh,
27 .source = CRASH_SOURCE_ENFORCE,
28 .formats = CRASH_FMT_DEFAULT,
29 .file = file,
30 .line = line,
31 .func = func,
32 .msg = msg,
33 });
34}
35
36static cc_noreturn void impl_enforce_expr(struct crash_payload pluh,
37 const char *file, int line,
38 const char *func, const char *prefix,
39 const char *expr, const char *fmt,
40 va_list args) {
41 cc_ignore(pluh);
42 static char msg[CRASH_MSG_MAX];
43
44 int n = snprintf(msg, sizeof(msg), "%s%s", prefix ? prefix : "",
45 expr ? expr : "");
46
47 if (n < 0)
48 n = 0;
49 if (n > (int) sizeof(msg) - 1)
50 n = (int) sizeof(msg) - 1;
51
52 if (fmt && strlen(str: fmt) > 0) {
53 n += snprintf(msg + n, (int) sizeof(msg) - n, ": ");
54 if (n > (int) sizeof(msg) - 1)
55 n = (int) sizeof(msg) - 1;
56
57 vsnprintf(msg + n, (int) sizeof(msg) - n, fmt, args);
58 }
59
60 crash_full(ctx: &(struct crash_context){
61 .payload = pluh,
62 .source = CRASH_SOURCE_ENFORCE,
63 .formats = CRASH_FMT_DEFAULT,
64 .file = file,
65 .line = line,
66 .func = func,
67 .msg = msg,
68 });
69}
70
71static cc_noreturn void enforce_v(struct crash_payload pluh, const char *file,
72 int line, const char *func,
73 const char *prefix, const char *expr,
74 const char *fmt, va_list args) {
75 if (expr && strlen(str: expr) > 0)
76 impl_enforce_expr(pluh, file, line, func, prefix, expr, fmt, args);
77
78 impl_default(pluh, file, line, func, prefix, fmt, args);
79}
80
81cc_noreturn void enforce_impl_msg(const char *file, int line, const char *func,
82 const char *prefix, const char *expr,
83 const char *fmt, ...) {
84 va_list args;
85 va_start(args, fmt);
86 enforce_v(CRASH_CODE_TO_PAYLOAD(NULL), file, line, func, prefix, expr, fmt,
87 args);
88 va_end(args);
89}
90
91cc_noreturn void enforce_impl_precond_msg(const char *file, int line,
92 const char *func, const char *prefix,
93 const char *expr, const char *fmt,
94 ...) {
95 va_list args;
96 va_start(args, fmt);
97 enforce_v(CRASH_CODE_TO_PAYLOAD(CRASH_CODE(global, INVALID_ARGUMENT)), file,
98 line, func, prefix, expr, fmt, args);
99 va_end(args);
100}
101
102cc_noreturn void enforce_impl_code(const char *file, int line, const char *func,
103 const char *prefix, const char *expr,
104 const struct crash_code *code,
105 const char *fmt, ...) {
106 va_list args;
107 va_start(args, fmt);
108 enforce_v(CRASH_CODE_TO_PAYLOAD(code), file, line, func, prefix, expr, fmt,
109 args);
110 va_end(args);
111}
112
113cc_noreturn void enforce_impl_code_only(const char *file, int line,
114 const char *func, const char *prefix,
115 const char *expr,
116 const struct crash_code *code) {
117 enforce_impl_code(file, line, func, prefix, expr, code, NULL);
118}
119