summaryrefslogtreecommitdiff
path: root/vere/ext/nasm/asm/error.c
diff options
context:
space:
mode:
Diffstat (limited to 'vere/ext/nasm/asm/error.c')
-rw-r--r--vere/ext/nasm/asm/error.c288
1 files changed, 288 insertions, 0 deletions
diff --git a/vere/ext/nasm/asm/error.c b/vere/ext/nasm/asm/error.c
new file mode 100644
index 0000000..192555d
--- /dev/null
+++ b/vere/ext/nasm/asm/error.c
@@ -0,0 +1,288 @@
+/* ----------------------------------------------------------------------- *
+ *
+ * Copyright 1996-2019 The NASM Authors - All Rights Reserved
+ * See the file AUTHORS included with the NASM distribution for
+ * the specific copyright holders.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * error.c - error message handling routines for the assembler
+ */
+
+#include "compiler.h"
+
+
+#include "nasmlib.h"
+#include "error.h"
+
+/* Common function body */
+#define nasm_do_error(_sev,_flags) \
+ va_list ap; \
+ va_start(ap, fmt); \
+ if ((_sev) >= ERR_CRITICAL) \
+ nasm_verror_critical((_sev)|(_flags), fmt, ap); \
+ else \
+ nasm_verror((_sev)|(_flags), fmt, ap); \
+ va_end(ap); \
+ if ((_sev) >= ERR_FATAL) \
+ abort();
+
+
+void nasm_error(errflags severity, const char *fmt, ...)
+{
+ nasm_do_error(severity & ERR_MASK, severity & ~ERR_MASK);
+}
+
+#define nasm_err_helpers(_type, _name, _sev) \
+_type nasm_ ## _name ## f (errflags flags, const char *fmt, ...) \
+{ \
+ nasm_do_error(_sev, flags); \
+} \
+_type nasm_ ## _name (const char *fmt, ...) \
+{ \
+ nasm_do_error(_sev, 0); \
+}
+
+nasm_err_helpers(void, listmsg, ERR_LISTMSG)
+nasm_err_helpers(void, debug, ERR_DEBUG)
+nasm_err_helpers(void, info, ERR_INFO)
+nasm_err_helpers(void, nonfatal, ERR_NONFATAL)
+nasm_err_helpers(fatal_func, fatal, ERR_FATAL)
+nasm_err_helpers(fatal_func, critical, ERR_CRITICAL)
+nasm_err_helpers(fatal_func, panic, ERR_PANIC)
+
+/*
+ * Strongly discourage warnings without level by require flags on warnings.
+ * This means nasm_warn() is the equivalent of the -f variants of the
+ * other ones.
+ */
+void nasm_warn(errflags flags, const char *fmt, ...)
+{
+ nasm_do_error(ERR_WARNING, flags);
+}
+
+fatal_func nasm_panic_from_macro(const char *file, int line)
+{
+ nasm_panic("internal error at %s:%d\n", file, line);
+}
+
+fatal_func nasm_assert_failed(const char *file, int line, const char *msg)
+{
+ nasm_panic("assertion %s failed at %s:%d", msg, file, line);
+}
+
+
+/*
+ * Warning stack management. Note that there is an implicit "push"
+ * after the command line has been parsed, but this particular push
+ * cannot be popped.
+ */
+struct warning_stack {
+ struct warning_stack *next;
+ uint8_t state[sizeof warning_state];
+};
+static struct warning_stack *warning_stack, *warning_state_init;
+
+/* Push the warning status onto the warning stack */
+void push_warnings(void)
+{
+ struct warning_stack *ws;
+
+ ws = nasm_malloc(sizeof *ws);
+ memcpy(ws->state, warning_state, sizeof warning_state);
+ ws->next = warning_stack;
+ warning_stack = ws;
+}
+
+/* Pop the warning status off the warning stack */
+void pop_warnings(void)
+{
+ struct warning_stack *ws = warning_stack;
+
+ memcpy(warning_state, ws->state, sizeof warning_state);
+ if (!ws->next) {
+ /*!
+ *!warn-stack-empty [on] warning stack empty
+ *! a [WARNING POP] directive was executed when
+ *! the warning stack is empty. This is treated
+ *! as a [WARNING *all] directive.
+ */
+ nasm_warn(WARN_WARN_STACK_EMPTY, "warning stack empty");
+ } else {
+ warning_stack = ws->next;
+ nasm_free(ws);
+ }
+}
+
+/* Call after the command line is parsed, but before the first pass */
+void init_warnings(void)
+{
+ push_warnings();
+ warning_state_init = warning_stack;
+}
+
+
+/* Call after each pass */
+void reset_warnings(void)
+{
+ struct warning_stack *ws = warning_stack;
+
+ /* Unwind the warning stack. We do NOT delete the last entry! */
+ while (ws->next) {
+ struct warning_stack *wst = ws;
+ ws = ws->next;
+ nasm_free(wst);
+ }
+ warning_stack = ws;
+ memcpy(warning_state, ws->state, sizeof warning_state);
+}
+
+/*
+ * This is called when processing a -w or -W option, or a warning directive.
+ * Returns ok if the action was successful.
+ *
+ * Special pseudo-warnings:
+ *
+ *!other [on] any warning not specifically mentioned above
+ *! specifies any warning not included in any specific warning class.
+ *
+ *!all [all] all possible warnings
+ *! is an group alias for \e{all} warning classes. Thus, \c{-w+all}
+ *! enables all available warnings, and \c{-w-all} disables warnings
+ *! entirely (since NASM 2.13).
+ */
+bool set_warning_status(const char *value)
+{
+ enum warn_action { WID_OFF, WID_ON, WID_RESET };
+ enum warn_action action;
+ const struct warning_alias *wa;
+ size_t vlen;
+ bool ok = false;
+ uint8_t mask;
+
+ value = nasm_skip_spaces(value);
+
+ switch (*value) {
+ case '-':
+ action = WID_OFF;
+ value++;
+ break;
+ case '+':
+ action = WID_ON;
+ value++;
+ break;
+ case '*':
+ action = WID_RESET;
+ value++;
+ break;
+ case 'N':
+ case 'n':
+ if (!nasm_strnicmp(value, "no-", 3)) {
+ action = WID_OFF;
+ value += 3;
+ break;
+ } else if (!nasm_stricmp(value, "none")) {
+ action = WID_OFF;
+ value = NULL;
+ break;
+ }
+ /* else fall through */
+ default:
+ action = WID_ON;
+ break;
+ }
+
+ mask = WARN_ST_ENABLED;
+
+ if (value && !nasm_strnicmp(value, "error", 5)) {
+ switch (value[5]) {
+ case '=':
+ mask = WARN_ST_ERROR;
+ value += 6;
+ break;
+ case '\0':
+ mask = WARN_ST_ERROR;
+ value = NULL;
+ break;
+ default:
+ /* Just an accidental prefix? */
+ break;
+ }
+ }
+
+ if (value && !nasm_stricmp(value, "all"))
+ value = NULL;
+
+ vlen = value ? strlen(value) : 0;
+
+ /*
+ * This is inefficient, but it shouldn't matter.
+ * Note: warning_alias[0] is "all".
+ */
+ for (wa = warning_alias+1;
+ wa < &warning_alias[NUM_WARNING_ALIAS]; wa++) {
+ enum warn_index i = wa->warning;
+
+ if (value) {
+ char sep;
+
+ if (nasm_strnicmp(value, wa->name, vlen))
+ continue; /* Not a prefix */
+
+ sep = wa->name[vlen];
+ if (sep != '\0' && sep != '-')
+ continue; /* Not a valid prefix */
+ }
+
+ ok = true; /* At least one action taken */
+ switch (action) {
+ case WID_OFF:
+ warning_state[i] &= ~mask;
+ break;
+ case WID_ON:
+ warning_state[i] |= mask;
+ break;
+ case WID_RESET:
+ warning_state[i] &= ~mask;
+ warning_state[i] |= warning_state_init->state[i] & mask;
+ break;
+ }
+ }
+
+ if (!ok && value) {
+ /*!
+ *!unknown-warning [off] unknown warning in -W/-w or warning directive
+ *! warns about a \c{-w} or \c{-W} option or a \c{[WARNING]} directive
+ *! that contains an unknown warning name or is otherwise not possible to process.
+ */
+ nasm_warn(WARN_UNKNOWN_WARNING, "unknown warning name: %s", value);
+ }
+
+ return ok;
+}