-
Notifications
You must be signed in to change notification settings - Fork 17
/
error.c
116 lines (97 loc) · 2.29 KB
/
error.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
#include "error.h"
#include "common.h"
#include <assert.h>
#include <stddef.h>
typedef struct tw_error
{
char file[64];
int line;
char function[64];
char msg[128];
int errno;
} tw_error;
typedef struct tw_error_threadlocals
{
tw_error errors[32];
int num_errors;
char msg[1024];
int msg_constructed;
int errno;
} tw_error_threadlocals;
static __thread tw_error_threadlocals tls;
void tw_error_msg_set_v(const char *file, int line, const char *function, int errno, const char *fmt, va_list va_args)
{
// just copy everything into our local storage
tw_error error;
if(file)
tw_str_copy(error.file, file, sizeof(error.file));
else
error.file[0] = 0;
error.line = line;
if(function)
tw_str_copy(error.function, function, sizeof(error.function));
else
error.function[0] = 0;
error.errno = errno;
if(fmt)
tw_str_format_v(error.msg, sizeof(error.msg), fmt, va_args);
else
error.msg[0] = 0;
tls.errors[tls.num_errors] = error;
tls.num_errors++;
}
void tw_error_errno_set(int errno)
{
assert(errno != 0 && "can't set errno to 0");
tls.errno = errno;
}
int tw_error_errno(void)
{
return tls.errno;
}
void tw_error_errno_clear(void)
{
tls.errno = 0;
}
void tw_error_msg_clear(void)
{
tls.num_errors = 0;
tls.msg_constructed = 0;
}
static void tw_error_msg_construct(void)
{
// no errors with string? return the stringified errno
if(tls.num_errors == 0)
{
tw_str_format(tls.msg, sizeof(tls.msg), "unknown error (%d)", tls.errno);
tls.msg_constructed = 1;
return;
}
tls.msg[0] = 0; // make msg the empty string
// construct the message the following way
// "outer func error: inner func error: innermost func error"
/*int i;
for(i = tls.num_errors - 1; i >= 0; i--)
{
tw_error *error = &tls.errors[i];
if(error->msg[0] != 0)
{
// if we aren't at the beginning of the constructed
// string, insert a ": "
if(tls.msg[0] != 0)
tw_str_append(tls.msg, ": ", sizeof(tls.msg));
tw_str_append(tls.msg, error->msg, sizeof(tls.msg));
}
}*/
tw_str_copy(tls.msg, tls.errors[tls.num_errors - 1].msg, sizeof(tls.msg));
tls.msg_constructed = 1;
}
const char *tw_error_string_impl(void)
{
if(tls.errno == 0)
return NULL;
if(tls.msg_constructed == 0)
tw_error_msg_construct();
assert(tls.msg_constructed != 0 && "msg construct didn't construct msg");
return tls.msg;
}