]> granicus.if.org Git - yasm/commitdiff
Fix reporting of redefinition errors by adding a set of error/warning
authorPeter Johnson <peter@tortall.net>
Tue, 21 Oct 2003 03:04:56 +0000 (03:04 -0000)
committerPeter Johnson <peter@tortall.net>
Tue, 21 Oct 2003 03:04:56 +0000 (03:04 -0000)
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

libyasm/errwarn.c
libyasm/errwarn.h
libyasm/symrec.c
libyasm/tests/Makefile.inc
libyasm/tests/duplabel-err.asm [new file with mode: 0644]
libyasm/tests/duplabel-err.errwarn [new file with mode: 0644]
libyasm/tests/libyasm_test.sh [new file with mode: 0755]

index f62e182dbef2a3510e69c4ea39d2b2df8976854a..af07f2d01ecf0c89ddc2c2524143ea3167daf9f8 100644 (file)
@@ -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
index 620fc81addc242e38d5d2704cbd2daa051fa4467..8d33c2537500d5bec431e1540f9a20bb99b42edf 100644 (file)
@@ -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
index 8cc5f607926309b2fa0603aec2b5e71e8812e5e9..280c22333aad42a1d4a9939950849980c0b9a8b4 100644 (file)
@@ -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;
index 792072470987beba41312a90d7f2e86447ef83d8..61c7be0f2a9e00a578bead06b95ae64e25139905 100644 (file)
@@ -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 (file)
index 0000000..3d666b3
--- /dev/null
@@ -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 (file)
index 0000000..69014ad
--- /dev/null
@@ -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 (executable)
index 0000000..de98094
--- /dev/null
@@ -0,0 +1,4 @@
+#! /bin/sh
+# $IdPath$
+${srcdir}/out_test.sh libyasm_test libyasm/tests "libyasm" "-f bin" ""
+exit $?