mirror of
https://github.com/netwide-assembler/nasm.git
synced 2025-03-31 18:20:22 +08:00
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>
This commit is contained in:
parent
c5593142f7
commit
374312cde4
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
47
asm/nasm.c
47
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? */
|
||||
|
@ -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 */
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user