summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>2018-12-11 00:06:29 -0800
committerH. Peter Anvin <hpa@zytor.com>2018-12-11 00:06:29 -0800
commitddb290681e52aee70fc4b3342829fb9770a089b2 (patch)
treeac1c8104604e7a11db64198ca8ea1a387a361124
parent026b62f264b86372cc596e5a035f87385931486a (diff)
downloadnasm-ddb290681e52aee70fc4b3342829fb9770a089b2.tar.gz
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. Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-rw-r--r--asm/labels.c3
-rw-r--r--asm/listing.c8
-rw-r--r--asm/listing.h2
-rw-r--r--asm/nasm.c52
-rw-r--r--asm/preproc.c11
-rw-r--r--include/error.h1
6 files changed, 52 insertions, 25 deletions
diff --git a/asm/labels.c b/asm/labels.c
index 795a7b7e..1e7301e1 100644
--- a/asm/labels.c
+++ b/asm/labels.c
@@ -506,8 +506,7 @@ void define_label(const char *label, int32_t segment,
src_get(&saved_line, &saved_fname);
src_set(lptr->defn.def_line, lptr->defn.def_file);
- nasm_note("label `%s' originally defined here",
- lptr->defn.label);
+ nasm_notef(ERR_HERE, "label `%s' originally defined", lptr->defn.label);
src_set(saved_line, saved_fname);
} else if (pass0 > 1 && lptr->defn.type != LBL_SPECIAL) {
/*
diff --git a/asm/listing.c b/asm/listing.c
index b974c46b..5484bd5d 100644
--- a/asm/listing.c
+++ b/asm/listing.c
@@ -324,12 +324,16 @@ 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, ...)
{
+ va_list ap;
+
if (!listfp)
return;
- snprintf(listerror, sizeof listerror, "%s%s", pfx, msg);
+ va_start(ap, fmt);
+ vsnprintf(listerror, sizeof listerror, fmt, ap);
+ va_end(ap);
if ((severity & ERR_MASK) >= ERR_FATAL)
list_emit();
diff --git a/asm/listing.h b/asm/listing.h
index df88e8a8..f3ddb0e0 100644
--- a/asm/listing.h
+++ b/asm/listing.h
@@ -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
diff --git a/asm/nasm.c b/asm/nasm.c
index cff4e7a6..fbcf053a 100644
--- a/asm/nasm.c
+++ b/asm/nasm.c
@@ -1767,6 +1767,8 @@ static bool skip_this_pass(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);
bool warn_is_other = WARN_IDX(severity) == ERR_WARN_OTHER;
@@ -1786,8 +1788,6 @@ 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:
@@ -1816,23 +1816,35 @@ static void nasm_verror_asm(int severity, const char *fmt, va_list args)
break;
}
- vsnprintf(msg, sizeof msg - 64, fmt, args);
+ /*
+ * 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) &&
+ ((severity & ERR_MASK) < ERR_WARNING ||
+ (is_valid_warning(severity) && !warn_is_err)))
+ return;
+
+
+ vsnprintf(msg, sizeof msg, fmt, args);
+ *warnsuf = 0;
if (is_valid_warning(severity) && (warn_is_err || !warn_is_other)) {
- char *p = strchr(msg, '\0');
- snprintf(p, 64, " [-w+%s%s]",
+ snprintf(warnsuf, sizeof warnsuf, " [-w+%s%s]",
warn_is_err ? "error=" : "",
warnings[WARN_IDX(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? */
@@ -1843,7 +1855,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;
diff --git a/asm/preproc.c b/asm/preproc.c
index 05abeae6..de0f7ce2 100644
--- a/asm/preproc.c
+++ b/asm/preproc.c
@@ -5329,22 +5329,21 @@ 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);
}
}
static void pp_error_list_macros(int severity)
{
- int32_t saved_line;
- const char *saved_fname = NULL;
+ struct src_location saved;
- severity |= ERR_PP_LISTMACRO | ERR_NO_SEVERITY;
- src_get(&saved_line, &saved_fname);
+ severity |= ERR_PP_LISTMACRO | ERR_NO_SEVERITY | ERR_HERE;
+ saved = src_where();
if (istk)
pp_list_one_macro(istk->mstk, severity);
- src_set(saved_line, saved_fname);
+ src_update(saved);
}
const struct preproc_ops nasmpp = {
diff --git a/include/error.h b/include/error.h
index 12bf7020..18b2bed7 100644
--- a/include/error.h
+++ b/include/error.h
@@ -83,6 +83,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 one */
#define ERR_PASS2 0x00000100 /* only print this error on pass one */