/* SPDX-License-Identifier: BSD-2-Clause */ /* Copyright 1996-2025 The NASM Authors - All Rights Reserved */ #include "compiler.h" #include "nasmlib.h" #include "error.h" struct errinfo erropt; /* Common function body */ #define nasm_do_error(_sev,_flags) \ do { \ const errflags nde_severity = (_sev); \ const errflags nde_flags = nde_severity | (_flags); \ va_list ap; \ va_start(ap, fmt); \ if (nde_severity >= ERR_CRITICAL) { \ nasm_verror_critical(nde_flags, fmt, ap); \ unreachable(); \ } else { \ nasm_verror(nde_flags, fmt, ap); \ if (nde_severity >= ERR_FATAL) \ unreachable(); \ } \ va_end(ap); \ } while (0) /* * This is the generic function to use when the error type is not * known a priori. For ERR_DEBUG and ERR_INFO the level can be * included by */ void nasm_error(errflags flags, const char *fmt, ...) { nasm_do_error(flags & ERR_MASK, flags); } #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, note, ERR_NOTE) 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. * * This is wrapped in a macro to be able to elide it if the warning is * disabled, hence the extra underscore. */ void nasm_warn_(errflags flags, const char *fmt, ...) { nasm_do_error(ERR_WARNING, flags); } /* * nasm_info() and nasm_debug() takes mandatory enabling levels. */ void nasm_info_(unsigned int level, const char *fmt, ...) { if (info_level(level)) nasm_do_error(ERR_INFO, LEVEL(level)); } void nasm_debug_(unsigned int level, const char *fmt, ...) { if (debug_level(level)) nasm_do_error(ERR_DEBUG, LEVEL(level)); } /* * Convenience function for nasm_nonfatal(ERR_HOLD, ...) */ void nasm_holderr(const char *fmt, ...) { nasm_do_error(ERR_NONFATAL, ERR_NONFATAL|ERR_HOLD); } /* * panic() and nasm_assert() */ fatal_func nasm_panic_from_macro(const char *func, const char *file, int line) { if (!func) func = ""; nasm_panic("internal error in %s at %s:%d\n", func, file, line); } fatal_func nasm_assert_failed(const char *msg, const char *func, const char *file, int line) { if (!func) func = ""; nasm_panic("assertion %s failed in %s at %s:%d", msg, func, file, line); }