X-Git-Url: https://git.draconx.ca/gitweb/cdecl99.git/blobdiff_plain/3df85155e2dbf9307dd64bd222bf74389c45a75c..0c61f9637a469ac7a28b5a329551b03e6ad14d62:/src/error.c
diff --git a/src/error.c b/src/error.c
index e18ec80..9b89bac 100644
--- a/src/error.c
+++ b/src/error.c
@@ -1,12 +1,30 @@
+/*
+ * Error handling for libcdecl.
+ * Copyright © 2011-2012, 2021 Nick Bowler
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
#include
#include
#include
#include
#include
#include
+
#include "cdecl.h"
-#include "error.h"
-#include "i18n.h"
+#include "cdecl-internal.h"
gl_once_define(static, tls_initialized);
static gl_tls_key_t tls_key;
@@ -21,51 +39,33 @@ struct err_state {
static struct err_state err_no_mem = {
.err = {
.code = CDECL_ENOMEM,
- .str = "failed to allocate memory",
+ .str = NULL,
},
};
-static void free_err(void *err)
-{
- if (err == &err_no_mem)
- return;
-
- free(err);
-}
-
-static void initialize(void)
+const char *cdecl__strerror(unsigned code)
{
- cdecl__init_i18n();
- err_no_mem.err.str = gettext(err_no_mem.err.str);
+# include "errtab.h"
- gl_tls_key_init(tls_key, free_err);
+ assert(code < sizeof offtab / sizeof offtab[0]);
+ assert(offtab[code] != 0);
- /*
- * This default error message is a stop-gap measure until all library
- * error conditions use the new interface.
- */
- cdecl__set_error(&(const struct cdecl_error){ .code = CDECL_ENOPARSE });
+ return gettext((char *)&strtab + offtab[code]);
}
-const struct cdecl_error *cdecl_get_error(void)
+static void free_err(void *err)
{
- struct err_state *state;
-
- gl_once(tls_initialized, initialize);
-
- state = gl_tls_get(tls_key);
- assert(state);
+ if (err == &err_no_mem)
+ return;
- return &state->err;
+ free(err);
}
-void cdecl__set_error(const struct cdecl_error *err)
+static void set_error(const struct cdecl_error *err)
{
struct err_state *state;
size_t need_len = 0;
- gl_once(tls_initialized, initialize);
-
if (err->str) {
need_len = strlen(err->str) + 1;
}
@@ -98,6 +98,39 @@ void cdecl__set_error(const struct cdecl_error *err)
memcpy(state->str, err->str, need_len);
state->err.str = state->str;
} else {
- state->err.str = "unknown error";
+ state->err.str = cdecl__strerror(state->err.code);
}
}
+
+static void initialize(void)
+{
+ cdecl__init_i18n();
+ err_no_mem.err.str = cdecl__strerror(CDECL_ENOMEM);
+
+ gl_tls_key_init(tls_key, free_err);
+
+ /*
+ * This default error message is a stop-gap measure until all library
+ * error conditions use the new interface.
+ */
+ set_error(&(const struct cdecl_error){ .code = CDECL_ENOPARSE });
+}
+
+const struct cdecl_error *cdecl_get_error(void)
+{
+ struct err_state *state;
+
+ gl_once(tls_initialized, initialize);
+
+ state = gl_tls_get(tls_key);
+ assert(state);
+
+ return &state->err;
+}
+
+void cdecl__set_error(const struct cdecl_error *err)
+{
+ gl_once(tls_initialized, initialize);
+
+ set_error(err);
+}