diff options
author | H. Peter Anvin <hpa@zytor.com> | 2018-12-11 00:06:29 -0800 |
---|---|---|
committer | H. Peter Anvin (Intel) <hpa@zytor.com> | 2018-12-12 17:43:25 -0800 |
commit | e2f5edbb3a24db347e4f52cdf134402ab987b085 (patch) | |
tree | 2e1e18e6565a531b39f88b767d8d8a81f555a3ea | |
parent | c0b32a36503e5dd3e109c8c2b40a8c2081111430 (diff) | |
download | nasm-e2f5edbb3a24db347e4f52cdf134402ab987b085.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.
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>
-rw-r--r-- | asm/labels.c | 7 | ||||
-rw-r--r-- | asm/listing.c | 22 | ||||
-rw-r--r-- | asm/listing.h | 2 | ||||
-rw-r--r-- | asm/nasm.c | 122 | ||||
-rw-r--r-- | asm/preproc.c | 4 | ||||
-rw-r--r-- | include/error.h | 1 |
6 files changed, 87 insertions, 71 deletions
diff --git a/asm/labels.c b/asm/labels.c index d0904ad3..a3ed0066 100644 --- a/asm/labels.c +++ b/asm/labels.c @@ -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) { /* diff --git a/asm/listing.c b/asm/listing.c index fe7c5e92..4d753dbd 100644 --- a/asm/listing.c +++ b/asm/listing.c @@ -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); - le->next = NULL; - p = le->str; - p = mempcpy(p, pfx, l1); - p = mempcpy(p, msg, l2); - *p = '\0'; + va_start(ap, fmt); + vsnprintf(le->str, len+1, fmt, ap); + va_end(ap); + le->next = NULL; *listerr_tail = le; listerr_tail = &le->next; 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 @@ -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; + + 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 !!(warning_state[warn_index(severity)] & WARN_ST_ERROR); + 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, fmt, args); + *warnsuf = 0; + if (spec_type == ERR_WARNING) { + snprintf(warnsuf, sizeof warnsuf, " [-w+%s%s]", + true_type ? "error=" : "", + warnings[warn_index(severity)].name); } - 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=" : "", - 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; diff --git a/asm/preproc.c b/asm/preproc.c index 3b8de02b..b134414a 100644 --- a/asm/preproc.c +++ b/asm/preproc.c @@ -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) diff --git a/include/error.h b/include/error.h index d2f04f4c..5a676e67 100644 --- a/include/error.h +++ b/include/error.h @@ -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 */ |