5 #include <glthread/lock.h>
6 #include <glthread/tls.h>
11 gl_once_define(static, tls_initialized);
12 static gl_tls_key_t tls_key;
15 struct cdecl_error err;
20 /* This error is reserved for extremely dire out-of-memory conditions. */
21 static struct err_state err_no_mem = {
24 .str = "failed to allocate memory",
28 static void free_err(void *err)
30 if (err == &err_no_mem)
36 static void initialize(void)
39 err_no_mem.err.str = gettext(err_no_mem.err.str);
41 gl_tls_key_init(tls_key, free_err);
44 * This default error message is a stop-gap measure until all library
45 * error conditions use the new interface.
47 cdecl__set_error(&(const struct cdecl_error){ .code = CDECL_ENOPARSE });
50 const struct cdecl_error *cdecl_get_error(void)
52 struct err_state *state;
54 gl_once(tls_initialized, initialize);
56 state = gl_tls_get(tls_key);
62 void cdecl__set_error(const struct cdecl_error *err)
64 struct err_state *state;
67 gl_once(tls_initialized, initialize);
70 need_len = strlen(err->str) + 1;
73 state = gl_tls_get(tls_key);
74 if (state == &err_no_mem)
76 if (!state || state->nstr < need_len) {
77 struct err_state *tmp;
79 tmp = realloc(state, sizeof *state + need_len);
81 /* Re-use the existing state buffer, if any. */
83 state->err = err_no_mem.err;
87 gl_tls_set(tls_key, state);
92 state->nstr = need_len;
93 gl_tls_set(tls_key, state);
98 memcpy(state->str, err->str, need_len);
99 state->err.str = state->str;
101 state->err.str = "unknown error";