summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorH. Peter Anvin (Intel) <hpa@zytor.com>2018-12-14 00:17:13 -0800
committerH. Peter Anvin (Intel) <hpa@zytor.com>2018-12-14 00:17:13 -0800
commit374312cde4d44f8849d602cc5c9ea634798b9c50 (patch)
tree613d618b52059c61b6dcbaa9f8863ecd0086c0d8
parentc5593142f750bc440b2d6a0952deaeb769bc6c57 (diff)
downloadnasm-374312cde4d44f8849d602cc5c9ea634798b9c50.tar.gz
strlist, warnings: improve strlist, buffer warnings until error
Make strlist_free() take a pointer to a pointer, so we can set it to NULL. Buffer warnings on a strlist until we either get an error or we are in pass 2. Hopefully this should let us get rid of a lot of the ERR_PASS* bullshit, which far too often causes messages to get lost. asm/labels.c contains one example of a warning that cannot be made correct with a specific pass number. Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
-rw-r--r--asm/labels.c4
-rw-r--r--asm/listing.c3
-rw-r--r--asm/nasm.c47
-rw-r--r--include/strlist.h4
-rw-r--r--nasmlib/strlist.c37
5 files changed, 73 insertions, 22 deletions
diff --git a/asm/labels.c b/asm/labels.c
index 7d87503d..c8901cbf 100644
--- a/asm/labels.c
+++ b/asm/labels.c
@@ -511,9 +511,9 @@ void define_label(const char *label, int32_t segment,
*! value is identical. It is an unconditional error to
*! define the same label more than once to \e{different} values.
*/
- nasm_warnf(WARN_LABEL_REDEF|ERR_PASS2,
+ nasm_warnf(WARN_LABEL_REDEF,
"label `%s' redefined to an identical value", lptr->defn.label);
- noteflags = ERR_NOTE|ERR_HERE|WARN_LABEL_REDEF|ERR_PASS2;
+ noteflags = ERR_NOTE|ERR_HERE|WARN_LABEL_REDEF;
}
src_get(&saved_line, &saved_fname);
diff --git a/asm/listing.c b/asm/listing.c
index 10ed7249..67c07fc9 100644
--- a/asm/listing.c
+++ b/asm/listing.c
@@ -126,8 +126,7 @@ static void list_emit(void)
fprintf(listfp, " %s\n", e->str);
}
- strlist_free(list_errors);
- list_errors = NULL;
+ strlist_free(&list_errors);
}
}
diff --git a/asm/nasm.c b/asm/nasm.c
index 3c8b877c..9fcbe200 100644
--- a/asm/nasm.c
+++ b/asm/nasm.c
@@ -90,6 +90,7 @@ struct error_format {
static const struct error_format errfmt_gnu = { ":", "", ": " };
static const struct error_format errfmt_msvc = { "(", ")", " : " };
static const struct error_format *errfmt = &errfmt_gnu;
+static struct strlist *warn_list;
static bool using_debug_info, opt_verbose_info;
static const char *debug_format;
@@ -388,7 +389,7 @@ static void emit_dependencies(struct strlist *list)
}
}
- strlist_free(list);
+ strlist_free(&list);
if (deps != stdout)
fclose(deps);
@@ -635,7 +636,7 @@ int main(int argc, char **argv)
eval_cleanup();
stdscan_cleanup();
src_free();
- strlist_free(include_path);
+ strlist_free(&include_path);
return terminate_after_phase;
}
@@ -1117,6 +1118,7 @@ static bool process_arg(char *p, char *q, int pass)
break;
}
+ olen = 0; /* Placates gcc at lower optimization levels */
plen = strlen(p);
for (tx = textopts; tx->label; tx++) {
olen = strlen(tx->label);
@@ -1426,6 +1428,18 @@ static void assemble_file(const char *fname, struct strlist *depend_list)
pass2 = passn > 1 ? 2 : 1; /* 1, 2, 2, ..., 2, 2 */
/* pass0 0, 0, 0, ..., 1, 2 */
+ /*
+ * Create a warning buffer list unless we are in pass 2 (everything will be
+ * emitted immediately in pass 2.)
+ */
+ if (warn_list) {
+ if (warn_list->nstr || pass0 == 2)
+ strlist_free(&warn_list);
+ }
+
+ if (pass0 < 2 && !warn_list)
+ warn_list = strlist_alloc(false);
+
globalbits = cmd_sb; /* set 'bits' to command line default */
cpu = cmd_cpu;
if (pass0 == 2) {
@@ -1691,8 +1705,10 @@ static void assemble_file(const char *fname, struct strlist *depend_list)
}
}
+ strlist_free(&warn_list);
preproc->cleanup(0);
lfmt->cleanup();
+
if (!terminate_after_phase && opt_verbose_info) {
/* -On and -Ov switches */
fprintf(stdout, "info: assembly required 1+%"PRId64"+1 passes\n",
@@ -1844,10 +1860,29 @@ static void nasm_verror_asm(errflags severity, const char *fmt, va_list args)
}
if (!skip_this_pass(severity)) {
- fprintf(error_file, "%s%s%s%s%s%s%s\n",
- currentfile ? currentfile : "nasm",
- linestr, errfmt->beforemsg, pfx, msg,
- (severity & ERR_HERE) ? " here" : "", warnsuf);
+ const char *file = currentfile ? currentfile : "nasm";
+ const char *here = (severity & ERR_HERE) ? " here" : "";
+
+ if (warn_list && true_type < ERR_NONFATAL) {
+ /*
+ * Buffer up warnings until we either get an error
+ * or we are on the code-generation pass.
+ */
+ strlist_printf(warn_list, "%s%s%s%s%s%s%s",
+ file, linestr, errfmt->beforemsg,
+ pfx, msg, here, warnsuf);
+ } else {
+ /* If we have buffered warnings, output them now. */
+ if (warn_list) {
+ strlist_write(warn_list, "\n", error_file);
+ strlist_free(&warn_list);
+ }
+
+ fprintf(error_file, "%s%s%s%s%s%s%s\n",
+ file, linestr, errfmt->beforemsg,
+ pfx, msg, here, warnsuf);
+
+ }
}
/* Are we recursing from error_list_macros? */
diff --git a/include/strlist.h b/include/strlist.h
index b0e2919b..610aad4d 100644
--- a/include/strlist.h
+++ b/include/strlist.h
@@ -71,7 +71,6 @@ static inline size_t strlist_size(const struct strlist *list)
}
struct strlist safe_alloc *strlist_alloc(bool uniq);
-void strlist_free(struct strlist *list);
const struct strlist_entry * never_null strlist_add(struct strlist *list, const char *str);
const struct strlist_entry * printf_func(2, 3) never_null
strlist_printf(struct strlist *list, const char *fmt, ...);
@@ -80,7 +79,8 @@ const struct strlist_entry * never_null
const struct strlist_entry *
strlist_find(const struct strlist *list, const char *str);
void * safe_alloc strlist_linearize(const struct strlist *list, char sep);
-void strlist_free(struct strlist *list);
+void strlist_write(const struct strlist *list, const char *sep, FILE *f);
+void strlist_free(struct strlist **listp);
#define strlist_for_each(p,h) list_for_each((p), strlist_head(h))
#endif /* NASM_STRLIST_H */
diff --git a/nasmlib/strlist.c b/nasmlib/strlist.c
index 93a6787f..506ad50e 100644
--- a/nasmlib/strlist.c
+++ b/nasmlib/strlist.c
@@ -136,21 +136,24 @@ strlist_printf(struct strlist *list, const char *fmt, ...)
}
/*
- * Free a string list
+ * Free a string list. Sets the pointed to pointer to NULL.
*/
-void strlist_free(struct strlist *list)
+void strlist_free(struct strlist **listp)
{
- if (list) {
- struct strlist_entry *e, *tmp;
+ struct strlist *list = *listp;
+ struct strlist_entry *e, *tmp;
- if (list->uniq)
- hash_free(&list->hash);
+ if (!list)
+ return;
- list_for_each_safe(e, tmp, list->head)
- nasm_free(e);
+ if (list->uniq)
+ hash_free(&list->hash);
- nasm_free(list);
- }
+ list_for_each_safe(e, tmp, list->head)
+ nasm_free(e);
+
+ nasm_free(list);
+ *listp = NULL;
}
/*
@@ -187,3 +190,17 @@ void *strlist_linearize(const struct strlist *list, char sep)
return buf;
}
+
+/*
+ * Output a string list to a file. The separator can be any string.
+ */
+void strlist_write(const struct strlist *list, const char *sep, FILE *f)
+{
+ const struct strlist_entry *sl;
+ size_t seplen = strlen(sep);
+
+ strlist_for_each(sl, list) {
+ fwrite(sl->str, 1, sl->size - 1, f);
+ fwrite(sep, 1, seplen, f);
+ }
+}