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 <ed.gomez@free.fr>

svn path=/trunk/yasm/; revision=1074
0.4
Peter Johnson 21 years ago
parent 38654f318e
commit 98b92dbacf
  1. 57
      libyasm/errwarn.c
  2. 55
      libyasm/errwarn.h
  3. 6
      libyasm/symrec.c
  4. 5
      libyasm/tests/Makefile.inc
  5. 18
      libyasm/tests/duplabel-err.asm
  6. 4
      libyasm/tests/duplabel-err.errwarn
  7. 4
      libyasm/tests/libyasm_test.sh

@ -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<<num)))
return; /* warning is part of disabled class */
we = errwarn_data_new(line, 0);
we = errwarn_data_new(line, displine, 0);
we->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

@ -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

@ -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;

@ -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

@ -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

@ -0,0 +1,4 @@
-:16: redefinition of `label'
-:12: `label' previously defined here
-:18: redefinition of `label'
-:12: `label' previously defined here

@ -0,0 +1,4 @@
#! /bin/sh
# $IdPath$
${srcdir}/out_test.sh libyasm_test libyasm/tests "libyasm" "-f bin" ""
exit $?
Loading…
Cancel
Save