From 98b92dbacfd180f05f9a73d0e162ee97214494af Mon Sep 17 00:00:00 2001 From: Peter Johnson Date: Tue, 21 Oct 2003 03:04:56 +0000 Subject: [PATCH] Fix reporting of redefinition errors by adding a set of error/warning reporting functions that take a parameter for the line to be displayed in addition to the the line used for sorting. This allows the "previously defined" message to use the standard errwarn line resolution functions. The resulting error messages look like gcc output. Reported by: Edouard Gomez svn path=/trunk/yasm/; revision=1074 --- libyasm/errwarn.c | 57 +++++++++++++++++++++++------- libyasm/errwarn.h | 55 ++++++++++++++++++++++++++-- libyasm/symrec.c | 6 ++-- libyasm/tests/Makefile.inc | 5 +++ libyasm/tests/duplabel-err.asm | 18 ++++++++++ libyasm/tests/duplabel-err.errwarn | 4 +++ libyasm/tests/libyasm_test.sh | 4 +++ 7 files changed, 130 insertions(+), 19 deletions(-) create mode 100644 libyasm/tests/duplabel-err.asm create mode 100644 libyasm/tests/duplabel-err.errwarn create mode 100755 libyasm/tests/libyasm_test.sh diff --git a/libyasm/errwarn.c b/libyasm/errwarn.c index f62e182d..af07f2d0 100644 --- a/libyasm/errwarn.c +++ b/libyasm/errwarn.c @@ -74,6 +74,8 @@ typedef struct errwarn_data { enum { WE_UNKNOWN, WE_ERROR, WE_WARNING, WE_PARSERERROR } type; unsigned long line; + unsigned long displine; + /* FIXME: This should not be a fixed size. But we don't have vasprintf() * right now. */ char msg[MSG_MAXSIZE]; @@ -179,7 +181,8 @@ def_fatal(const char *fmt, ...) * type is WE_PARSERERROR. */ static errwarn_data * -errwarn_data_new(unsigned long line, int replace_parser_error) +errwarn_data_new(unsigned long line, unsigned long displine, + int replace_parser_error) { errwarn_data *first, *next, *ins_we, *we; enum { INS_NONE, INS_HEAD, INS_AFTER } action = INS_NONE; @@ -215,6 +218,7 @@ errwarn_data_new(unsigned long line, int replace_parser_error) we->type = WE_UNKNOWN; we->line = line; + we->displine = displine; if (action == INS_HEAD) SLIST_INSERT_HEAD(&errwarns, we, link); @@ -231,13 +235,14 @@ errwarn_data_new(unsigned long line, int replace_parser_error) return we; } -/* Register an error at line line. Does not print the error, only stores it - * for output_all() to print. +/* Register an error at line line, displaying line displine. Does not print + * the error, only stores it for output_all() to print. */ void -yasm__error_va(unsigned long line, const char *fmt, va_list va) +yasm__error_va_at(unsigned long line, unsigned long displine, const char *fmt, + va_list va) { - errwarn_data *we = errwarn_data_new(line, 1); + errwarn_data *we = errwarn_data_new(line, displine, 1); we->type = WE_ERROR; @@ -250,19 +255,19 @@ yasm__error_va(unsigned long line, const char *fmt, va_list va) error_count++; } -/* Register an warning at line line. Does not print the warning, only stores - * it for output_all() to print. +/* Register an warning at line line, displaying line displine. Does not print + * the warning, only stores it for output_all() to print. */ void -yasm__warning_va(yasm_warn_class num, unsigned long line, const char *fmt, - va_list va) +yasm__warning_va_at(yasm_warn_class num, unsigned long line, + unsigned long displine, const char *fmt, va_list va) { errwarn_data *we; if (!(warn_class_enabled & (1UL<type = WE_WARNING; @@ -283,7 +288,20 @@ yasm__error(unsigned long line, const char *fmt, ...) { va_list va; va_start(va, fmt); - yasm__error_va(line, fmt, va); + yasm__error_va_at(line, line, fmt, va); + va_end(va); +} + +/* Register an error at line line, displaying line displine. Does not print + * the error, only stores it for output_all() to print. + */ +void +yasm__error_at(unsigned long line, unsigned long displine, const char *fmt, + ...) +{ + va_list va; + va_start(va, fmt); + yasm__error_va_at(line, displine, fmt, va); va_end(va); } @@ -295,7 +313,20 @@ yasm__warning(yasm_warn_class num, unsigned long line, const char *fmt, ...) { va_list va; va_start(va, fmt); - yasm__warning_va(num, line, fmt, va); + yasm__warning_va_at(num, line, line, fmt, va); + va_end(va); +} + +/* Register an warning at line line, displaying line displine. Does not print + * the warning, only stores it for output_all() to print. + */ +void +yasm__warning_at(yasm_warn_class num, unsigned long line, + unsigned long displine, const char *fmt, ...) +{ + va_list va; + va_start(va, fmt); + yasm__warning_va_at(num, line, line, fmt, va); va_end(va); } @@ -354,7 +385,7 @@ yasm_errwarn_output_all(yasm_linemap *lm, int warning_as_error, /* Output error/warnings. */ SLIST_FOREACH(we, &errwarns, link) { /* Output error/warning */ - yasm_linemap_lookup(lm, we->line, &filename, &line); + yasm_linemap_lookup(lm, we->displine, &filename, &line); if (we->type == WE_ERROR) print_error(filename, line, we->msg); else diff --git a/libyasm/errwarn.h b/libyasm/errwarn.h index 620fc81a..8d33c253 100644 --- a/libyasm/errwarn.h +++ b/libyasm/errwarn.h @@ -75,13 +75,38 @@ extern /*@exits@*/ void (*yasm_internal_error_) */ extern /*@exits@*/ void (*yasm_fatal) (const char *message, ...); +/** Log an error at a given line, displaying a different line. va_list version + * of yasm__error_at(). + * \internal + * \param line virtual line + * \param displine displayed virtual line + * \param message printf-like-format message + * \param va argument list for message + */ +void yasm__error_va_at(unsigned long line, unsigned long displine, + const char *message, va_list va); + /** Log an error. va_list version of yasm__error(). * \internal * \param line virtual line * \param message printf-like-format message * \param va argument list for message */ -void yasm__error_va(unsigned long line, const char *message, va_list va); +#define yasm__error_va(line, message, va) \ + yasm__error_va_at(line, line, message, va) + +/** Log a warning at a given line, displaying a different line. va_list + * version of yasm__warning_at(). + * \internal + * \param wclass warning class + * \param line virtual line + * \param displine displayed virtual line + * \param message printf-like-format message + * \param va argument list for message + */ +void yasm__warning_va_at(yasm_warn_class wclass, unsigned long line, + unsigned long displine, const char *message, + va_list va); /** Log a warning. va_list version of yasm__warning(). * \internal @@ -90,8 +115,8 @@ void yasm__error_va(unsigned long line, const char *message, va_list va); * \param message printf-like-format message * \param va argument list for message */ -void yasm__warning_va(yasm_warn_class wclass, unsigned long line, - const char *message, va_list va); +#define yasm__warning_va(wclass, line, message, va) \ + yasm__warning_va_at(wclass, line, line, message, va) /** Log an error. Does not print it out immediately; yasm_errwarn_output_all() * outputs errors and warnings. @@ -103,6 +128,17 @@ void yasm__warning_va(yasm_warn_class wclass, unsigned long line, void yasm__error(unsigned long line, const char *message, ...) /*@printflike@*/; +/** Log an error at a given line, displaying a different line. Does not print + * it out immediately; yasm_errwarn_output_all() outputs errors and warnings. + * \internal + * \param line virtual line + * \param displine displayed virtual line + * \param message printf-like-format message + * \param ... argument list for message + */ +void yasm__error_at(unsigned long line, unsigned long displine, + const char *message, ...) /*@printflike@*/; + /** Log a warning. Does not print it out immediately; * yasm_errwarn_output_all() outputs errors and warnings. * \internal @@ -114,6 +150,19 @@ void yasm__error(unsigned long line, const char *message, ...) void yasm__warning(yasm_warn_class wclass, unsigned long line, const char *message, ...) /*@printflike@*/; +/** Log a warning at a given line, displaying a different line. Does not print + * it out immediately; yasm_errwarn_output_all() outputs errors and warnings. + * \internal + * \param wclass warning class + * \param line virtual line + * \param displine displayed virtual line + * \param message printf-like-format message + * \param ... argument list for message + */ +void yasm__warning_at(yasm_warn_class wclass, unsigned long line, + unsigned long displine, const char *message, ...) + /*@printflike@*/; + /** Log a parser error. Parser errors can be overwritten by non-parser errors * on the same line. * \internal diff --git a/libyasm/symrec.c b/libyasm/symrec.c index 8cc5f607..280c2233 100644 --- a/libyasm/symrec.c +++ b/libyasm/symrec.c @@ -191,9 +191,9 @@ symtab_define(yasm_symtab *symtab, const char *name, sym_type type, /* Has it been defined before (either by DEFINED or COMMON/EXTERN)? */ if ((rec->status & SYM_DEFINED) || (rec->visibility & (YASM_SYM_COMMON | YASM_SYM_EXTERN))) { - yasm__error(line, - N_("duplicate definition of `%s'; first defined on line %lu"), - name, rec->line); + yasm__error(line, N_("redefinition of `%s'"), name); + yasm__error_at(line, rec->line, N_("`%s' previously defined here"), + name); } else { rec->line = line; /* set line number of definition */ rec->type = type; diff --git a/libyasm/tests/Makefile.inc b/libyasm/tests/Makefile.inc index 79207247..61c7be0f 100644 --- a/libyasm/tests/Makefile.inc +++ b/libyasm/tests/Makefile.inc @@ -2,6 +2,11 @@ TESTS += bitvect_test TESTS += floatnum_test +TESTS += libyasm/tests/libyasm_test.sh + +EXTRA_DIST += libyasm/tests/libyasm_test.sh +EXTRA_DIST += libyasm/tests/duplabel-err.asm +EXTRA_DIST += libyasm/tests/duplabel-err.errwarn noinst_PROGRAMS += bitvect_test noinst_PROGRAMS += floatnum_test diff --git a/libyasm/tests/duplabel-err.asm b/libyasm/tests/duplabel-err.asm new file mode 100644 index 00000000..3d666b35 --- /dev/null +++ b/libyasm/tests/duplabel-err.asm @@ -0,0 +1,18 @@ +%macro TESTMAC 0 +label: + mov ax, 5 + mov dx, 4 + mov cx, 3 +%endmacro + +db 6 + +db 7 + +TESTMAC + +db 8 +db 9 +TESTMAC +db 10 +TESTMAC diff --git a/libyasm/tests/duplabel-err.errwarn b/libyasm/tests/duplabel-err.errwarn new file mode 100644 index 00000000..69014ad8 --- /dev/null +++ b/libyasm/tests/duplabel-err.errwarn @@ -0,0 +1,4 @@ +-:16: redefinition of `label' +-:12: `label' previously defined here +-:18: redefinition of `label' +-:12: `label' previously defined here diff --git a/libyasm/tests/libyasm_test.sh b/libyasm/tests/libyasm_test.sh new file mode 100755 index 00000000..de980947 --- /dev/null +++ b/libyasm/tests/libyasm_test.sh @@ -0,0 +1,4 @@ +#! /bin/sh +# $IdPath$ +${srcdir}/out_test.sh libyasm_test libyasm/tests "libyasm" "-f bin" "" +exit $?