mirror of
https://github.com/netwide-assembler/nasm.git
synced 2025-01-18 16:25:05 +08:00
error: new flag ERR_HERE
ERR_HERE is used to mark messages of the form "... here" so that we can emit sane output to the list file with filename and line number, instead of a nonsensical "here" which could point almost anywhere. This patch contains some changes from the one in the master branch to make the code cleaner. Signed-off-by: H. Peter Anvin <hpa@zytor.com>
This commit is contained in:
parent
c0b32a3650
commit
e2f5edbb3a
@ -506,17 +506,18 @@ void define_label(const char *label, int32_t segment,
|
||||
nasm_error(ERR_NONFATAL,
|
||||
"label `%s' inconsistently redefined",
|
||||
lptr->defn.label);
|
||||
noteflags = ERR_NOTE;
|
||||
noteflags = ERR_NOTE|ERR_HERE;
|
||||
} else {
|
||||
nasm_error(ERR_WARNING|WARN_LABEL_REDEF|ERR_PASS2,
|
||||
"label `%s' redefined to an identical value",
|
||||
lptr->defn.label);
|
||||
noteflags = ERR_NOTE|WARN_LABEL_REDEF|ERR_PASS2;
|
||||
noteflags = ERR_NOTE|ERR_HERE|WARN_LABEL_REDEF|ERR_PASS2;
|
||||
}
|
||||
|
||||
src_get(&saved_line, &saved_fname);
|
||||
src_set(lptr->defn.def_line, lptr->defn.def_file);
|
||||
nasm_error(noteflags, "label `%s' originally defined here", lptr->defn.label);
|
||||
nasm_error(noteflags, "label `%s' originally defined",
|
||||
lptr->defn.label);
|
||||
src_set(saved_line, saved_fname);
|
||||
} else if (changed && pass0 > 1 && lptr->defn.type != LBL_SPECIAL) {
|
||||
/*
|
||||
|
@ -331,27 +331,27 @@ static void list_downlevel(int type)
|
||||
}
|
||||
}
|
||||
|
||||
static void list_error(int severity, const char *pfx, const char *msg)
|
||||
static void list_error(int severity, const char *fmt, ...)
|
||||
{
|
||||
size_t l1, l2;
|
||||
struct list_error *le;
|
||||
char *p;
|
||||
va_list ap;
|
||||
int len;
|
||||
|
||||
if (!listfp)
|
||||
return;
|
||||
|
||||
l1 = strlen(pfx);
|
||||
l2 = strlen(msg);
|
||||
va_start(ap, fmt);
|
||||
len = vsnprintf(NULL, 0, fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
/* sizeof(*le) already accounts for the final NULL */
|
||||
le = nasm_malloc(sizeof(*le) + l1 + l2);
|
||||
le = nasm_malloc(sizeof(*le) + len);
|
||||
|
||||
va_start(ap, fmt);
|
||||
vsnprintf(le->str, len+1, fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
le->next = NULL;
|
||||
p = le->str;
|
||||
p = mempcpy(p, pfx, l1);
|
||||
p = mempcpy(p, msg, l2);
|
||||
*p = '\0';
|
||||
|
||||
*listerr_tail = le;
|
||||
listerr_tail = &le->next;
|
||||
|
||||
|
@ -96,7 +96,7 @@ struct lfmt {
|
||||
/*
|
||||
* Called on a warning or error, with the error message.
|
||||
*/
|
||||
void (*error)(int severity, const char *pfx, const char *msg);
|
||||
void printf_func(2, 3) (*error)(int severity, const char *fmt, ...);
|
||||
|
||||
/*
|
||||
* Update the current offset. Used to give the listing generator
|
||||
|
122
asm/nasm.c
122
asm/nasm.c
@ -1768,21 +1768,35 @@ static bool skip_this_pass(int severity)
|
||||
*/
|
||||
static bool is_suppressed(int severity)
|
||||
{
|
||||
if ((severity & ERR_MASK) >= ERR_FATAL)
|
||||
return false; /* Fatal errors can never be suppressed */
|
||||
|
||||
return !(warning_state[warn_index(severity)] & WARN_ST_ENABLED);
|
||||
}
|
||||
|
||||
/**
|
||||
* check if we have a warning that should be promoted to an error
|
||||
* Return the true error type (the ERR_MASK part) of the given
|
||||
* severity, accounting for warnings that may need to be promoted to
|
||||
* error.
|
||||
*
|
||||
* @param severity the severity of the warning or error
|
||||
* @return true if we should promote to error
|
||||
* @return true if we should error out
|
||||
*/
|
||||
static bool warning_is_error(int severity)
|
||||
static int true_error_type(int severity)
|
||||
{
|
||||
if ((severity & ERR_MASK) != ERR_WARNING)
|
||||
return false; /* Other message types */
|
||||
const uint8_t warn_is_err = WARN_ST_ENABLED|WARN_ST_ERROR;
|
||||
int type;
|
||||
|
||||
return !!(warning_state[warn_index(severity)] & WARN_ST_ERROR);
|
||||
type = severity & ERR_MASK;
|
||||
|
||||
/* Promote warning to error? */
|
||||
if (type == ERR_WARNING) {
|
||||
uint8_t state = warning_state[warn_index(severity)];
|
||||
if ((state & warn_is_err) == warn_is_err)
|
||||
type = ERR_NONFATAL;
|
||||
}
|
||||
|
||||
return type;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1798,10 +1812,17 @@ static bool warning_is_error(int severity)
|
||||
static void nasm_verror_asm(int severity, const char *fmt, va_list args)
|
||||
{
|
||||
char msg[1024];
|
||||
char warnsuf[64];
|
||||
char linestr[64];
|
||||
const char *pfx;
|
||||
bool warn_is_err = warning_is_error(severity);
|
||||
int spec_type = severity & ERR_MASK; /* type originally specified */
|
||||
int true_type = true_error_type(severity);
|
||||
const char *currentfile = NULL;
|
||||
int32_t lineno = 0;
|
||||
static const char * const pfx_table[ERR_MASK+1] = {
|
||||
"debug: ", "note: ", "warning: ", "error: ",
|
||||
"", "", "fatal: ", "panic: "
|
||||
};
|
||||
|
||||
if (is_suppressed(severity))
|
||||
return;
|
||||
@ -1816,53 +1837,38 @@ static void nasm_verror_asm(int severity, const char *fmt, va_list args)
|
||||
lineno = 0;
|
||||
}
|
||||
}
|
||||
if (!currentfile)
|
||||
currentfile = "nasm";
|
||||
|
||||
switch (severity & (ERR_MASK|ERR_NO_SEVERITY)) {
|
||||
case ERR_NOTE:
|
||||
pfx = "note: ";
|
||||
break;
|
||||
case ERR_WARNING:
|
||||
if (!warn_is_err) {
|
||||
pfx = "warning: ";
|
||||
break;
|
||||
}
|
||||
/* fall through */
|
||||
case ERR_NONFATAL:
|
||||
pfx = "error: ";
|
||||
break;
|
||||
case ERR_FATAL:
|
||||
pfx = "fatal: ";
|
||||
break;
|
||||
case ERR_PANIC:
|
||||
pfx = "panic: ";
|
||||
break;
|
||||
case ERR_DEBUG:
|
||||
pfx = "debug: ";
|
||||
break;
|
||||
default:
|
||||
/*
|
||||
* For a debug/warning/note event, if ERR_HERE is set don't
|
||||
* output anything if there is no current filename available
|
||||
*/
|
||||
if (!currentfile && (severity & ERR_HERE) && true_type <= ERR_WARNING)
|
||||
return;
|
||||
|
||||
if (severity & ERR_NO_SEVERITY)
|
||||
pfx = "";
|
||||
break;
|
||||
}
|
||||
else
|
||||
pfx = pfx_table[true_type];
|
||||
|
||||
vsnprintf(msg, sizeof msg - 64, fmt, args);
|
||||
if ((severity & ERR_MASK) == ERR_WARNING && !is_suppressed(severity)) {
|
||||
char *p = strchr(msg, '\0');
|
||||
snprintf(p, 64, " [-w+%s%s]",
|
||||
warn_is_err ? "error=" : "",
|
||||
vsnprintf(msg, sizeof msg, fmt, args);
|
||||
*warnsuf = 0;
|
||||
if (spec_type == ERR_WARNING) {
|
||||
snprintf(warnsuf, sizeof warnsuf, " [-w+%s%s]",
|
||||
true_type ? "error=" : "",
|
||||
warnings[warn_index(severity)].name);
|
||||
}
|
||||
|
||||
*linestr = 0;
|
||||
if (lineno) {
|
||||
snprintf(linestr, sizeof linestr, "%s%"PRId32"%s",
|
||||
errfmt->beforeline, lineno, errfmt->afterline);
|
||||
}
|
||||
|
||||
if (!skip_this_pass(severity)) {
|
||||
if (!lineno) {
|
||||
fprintf(error_file, "%s%s%s%s\n",
|
||||
currentfile, errfmt->beforemsg, pfx, msg);
|
||||
} else {
|
||||
fprintf(error_file, "%s%s%"PRId32"%s%s%s%s\n",
|
||||
currentfile, errfmt->beforeline, lineno,
|
||||
errfmt->afterline, errfmt->beforemsg, pfx, msg);
|
||||
}
|
||||
fprintf(error_file, "%s%s%s%s%s%s%s\n",
|
||||
currentfile ? currentfile : "nasm",
|
||||
linestr, errfmt->beforemsg, pfx, msg,
|
||||
(severity & ERR_HERE) ? " here" : "", warnsuf);
|
||||
}
|
||||
|
||||
/* Are we recursing from error_list_macros? */
|
||||
@ -1873,7 +1879,19 @@ static void nasm_verror_asm(int severity, const char *fmt, va_list args)
|
||||
* Don't suppress this with skip_this_pass(), or we don't get
|
||||
* pass1 or preprocessor warnings in the list file
|
||||
*/
|
||||
lfmt->error(severity, pfx, msg);
|
||||
if (severity & ERR_HERE) {
|
||||
if (lineno)
|
||||
lfmt->error(severity, "%s%s at %s:%"PRId32"%s",
|
||||
pfx, msg, currentfile, lineno, warnsuf);
|
||||
else if (currentfile)
|
||||
lfmt->error(severity, "%s%s in file %s%s",
|
||||
pfx, msg, currentfile, warnsuf);
|
||||
else
|
||||
lfmt->error(severity, "%s%s in unknown location%s",
|
||||
pfx, msg, warnsuf);
|
||||
} else {
|
||||
lfmt->error(severity, "%s%s%s", pfx, msg, warnsuf);
|
||||
}
|
||||
|
||||
if (skip_this_pass(severity))
|
||||
return;
|
||||
@ -1883,15 +1901,11 @@ static void nasm_verror_asm(int severity, const char *fmt, va_list args)
|
||||
|
||||
preproc->error_list_macros(severity);
|
||||
|
||||
switch (severity & ERR_MASK) {
|
||||
switch (true_type) {
|
||||
case ERR_NOTE:
|
||||
case ERR_DEBUG:
|
||||
/* no further action, by definition */
|
||||
break;
|
||||
case ERR_WARNING:
|
||||
/* Treat warnings as errors */
|
||||
if (warning_is_error(severity))
|
||||
terminate_after_phase = true;
|
||||
/* no further action, by definition */
|
||||
break;
|
||||
case ERR_NONFATAL:
|
||||
terminate_after_phase = true;
|
||||
|
@ -5451,7 +5451,7 @@ static void pp_list_one_macro(MMacro *m, int severity)
|
||||
|
||||
if (m->name && !m->nolist) {
|
||||
src_set(m->xline + m->lineno, m->fname);
|
||||
nasm_error(severity, "... from macro `%s' defined here", m->name);
|
||||
nasm_error(severity, "... from macro `%s' defined", m->name);
|
||||
}
|
||||
}
|
||||
|
||||
@ -5460,7 +5460,7 @@ static void pp_error_list_macros(int severity)
|
||||
int32_t saved_line;
|
||||
const char *saved_fname = NULL;
|
||||
|
||||
severity |= ERR_PP_LISTMACRO | ERR_NO_SEVERITY;
|
||||
severity |= ERR_PP_LISTMACRO | ERR_NO_SEVERITY | ERR_HERE;
|
||||
src_get(&saved_line, &saved_fname);
|
||||
|
||||
if (istk)
|
||||
|
@ -72,6 +72,7 @@ static inline vefunc nasm_set_verror(vefunc ve)
|
||||
* and dump core for reference */
|
||||
#define ERR_MASK 0x00000007 /* mask off the above codes */
|
||||
#define ERR_NOFILE 0x00000010 /* don't give source file name/line */
|
||||
#define ERR_HERE 0x00000020 /* point to a specific source location */
|
||||
#define ERR_USAGE 0x00000040 /* print a usage message */
|
||||
#define ERR_PASS1 0x00000080 /* only print this error on pass 1 */
|
||||
#define ERR_PASS2 0x00000100 /* only print this error on pass 2 */
|
||||
|
Loading…
Reference in New Issue
Block a user