]> granicus.if.org Git - yasm/commitdiff
Change error/warning framework to store a list of errors and warnings instead
authorPeter Johnson <peter@tortall.net>
Mon, 24 Sep 2001 21:39:45 +0000 (21:39 -0000)
committerPeter Johnson <peter@tortall.net>
Mon, 24 Sep 2001 21:39:45 +0000 (21:39 -0000)
of just one at a time.  This is the groundwork for printing undefined symbol
messages, which can't be determined until after parsing has been completed
(and should be in the same line order with the other errors).

svn path=/trunk/yasm/; revision=223

frontends/yasm/yasm.c
libyasm/errwarn.c
libyasm/errwarn.h
modules/parsers/nasm/bison.y.in
modules/parsers/nasm/nasm-bison.y
src/errwarn.c
src/errwarn.h
src/main.c
src/parsers/nasm/bison.y.in
src/parsers/nasm/nasm-bison.y

index e05475ae7e44fb4b1e51e01a4cf39d3df0b93ee8..11ece76aba4f671ca613543156e98ceaddc1b0cb 100644 (file)
@@ -33,6 +33,7 @@
 #endif
 
 #include "globals.h"
+#include "errwarn.h"
 
 #include "bytecode.h"
 #include "section.h"
@@ -64,6 +65,9 @@ main(int argc, char *argv[])
 
     nasm_parser.do_parse(&nasm_parser, &dbg_objfmt, in);
 
+    if (OutputAllErrorWarning() > 0)
+       return EXIT_FAILURE;
+
     if (filename)
        free(filename);
     return EXIT_SUCCESS;
index 03c0a65717f396028af7671ce633f4967597677e..f2191f897fdcde8e791602bb932a366c8dec1563 100644 (file)
@@ -49,11 +49,11 @@ RCSID("$IdPath$");
 
 /* Total error count for entire assembler run.
  * Assembler should exit with EXIT_FAILURE if this is >= 0 on finish. */
-unsigned int error_count = 0;
+static unsigned int error_count = 0;
 
 /* Total warning count for entire assembler run.
  * Should not affect exit value of assembler. */
-unsigned int warning_count = 0;
+static unsigned int warning_count = 0;
 
 /* See errwarn.h for constants that match up to these strings.
  * When adding a string here, keep errwarn.h in sync! */
@@ -64,27 +64,30 @@ static char *fatal_msgs[] = {
     N_("out of memory")
 };
 
-/* I hate to define these strings as static buffers; a better solution would be
- * to use vasprintf() to dynamically allocate, but that's not ANSI C.
- * FIXME! */
+typedef STAILQ_HEAD(errwarnhead_s, errwarn_s) errwarnhead;
+errwarnhead *errwarns = (errwarnhead *)NULL;
 
-/* Last error message string.  Set by Error(), read by OutputError(). */
-static char last_err[1024];
+typedef struct errwarn_s {
+    STAILQ_ENTRY(errwarn_s) link;
 
-/* Last warning message string.  Set by Warning(), read by OutputWarning(). */
-static char last_warn[1024];
+    enum { WE_ERROR, WE_WARNING } type;
 
-/* Has there been an error since the last time we output one?  Set by Error(),
- * read and reset by OutputError(). */
-static int new_error = 0;
+    char *filename;
+    unsigned long line;
+    /* FIXME: This should not be a fixed size.  But we don't have vasprintf()
+     * right now. */
+    char msg[1024];
+} errwarn;
+
+/* Line number of the previous error.  Set and checked by Error(). */
+static unsigned long previous_error_line = 0;
 
 /* Is the last error a parser error?  Error() lets other errors override parser
  * errors. Set by yyerror(), read and reset by Error(). */
-static int parser_error = 0;
+static int previous_error_parser = 0;
 
-/* Has there been a warning since the last time we output one?  Set by
- * Warning(), read and reset by OutputWarning(). */
-static int new_warning = 0;
+/* Line number of the previous warning. Set and checked by Warning(). */
+static unsigned long previous_warning_line = 0;
 
 /* Static buffer for use by conv_unprint(). */
 static char unprint[5];
@@ -116,7 +119,7 @@ void
 ParserError(char *s)
 {
     Error("%s %s", _("parser error:"), s);
-    parser_error = 1;
+    previous_error_parser = 1;
 }
 
 /* Report an internal error.  Essentially a fatal error with trace info.
@@ -153,17 +156,43 @@ void
 Error(char *fmt, ...)
 {
     va_list ap;
+    errwarn *we;
 
-    if (new_error && !parser_error)
+    if ((previous_error_line == line_number) && !previous_error_parser)
        return;
 
-    new_error = 1;
-    parser_error = 0;
+    if (!errwarns) {
+       errwarns = malloc(sizeof(errwarnhead));
+       if (!errwarns)
+           Fatal(FATAL_NOMEM);
+       STAILQ_INIT(errwarns);
+    }
+
+    if (previous_error_parser) {
+       /* overwrite last (parser) error */     
+       we = STAILQ_LAST(errwarns, errwarn_s, link);
+    } else {
+       we = malloc(sizeof(errwarn));
+       if (!we)
+           Fatal(FATAL_NOMEM);
+
+       we->type = WE_ERROR;
+       we->filename = strdup(filename);
+       if (!we->filename)
+           Fatal(FATAL_NOMEM);
+       we->line = line_number;
+    }
 
     va_start(ap, fmt);
-    vsprintf(last_err, fmt, ap);
+    vsprintf(we->msg, fmt, ap);
     va_end(ap);
 
+    if (!previous_error_parser)
+       STAILQ_INSERT_TAIL(errwarns, we, link);
+
+    previous_error_line = line_number;
+    previous_error_parser = 0;
+
     error_count++;
 }
 
@@ -174,34 +203,63 @@ void
 Warning(char *fmt, ...)
 {
     va_list ap;
+    errwarn *we;
 
-    if (new_warning)
+    if (previous_warning_line == line_number)
        return;
 
-    new_warning = 1;
+    previous_warning_line = line_number;
 
+    we = malloc(sizeof(errwarn));
+    if (!we)
+       Fatal(FATAL_NOMEM);
+
+    we->type = WE_WARNING;
+    we->filename = strdup(filename);
+    if (!we->filename)
+       Fatal(FATAL_NOMEM);
+    we->line = line_number;
     va_start(ap, fmt);
-    vsprintf(last_warn, fmt, ap);
+    vsprintf(we->msg, fmt, ap);
     va_end(ap);
 
+    if (!errwarns) {
+       errwarns = malloc(sizeof(errwarnhead));
+       if (!errwarns)
+           Fatal(FATAL_NOMEM);
+       STAILQ_INIT(errwarns);
+    }
+    STAILQ_INSERT_TAIL(errwarns, we, link);
     warning_count++;
 }
 
-/* Output a previously stored error (if any) to stderr. */
-void
-OutputError(void)
+/* Output all previously stored errors and warnings to stderr. */
+unsigned int
+OutputAllErrorWarning(void)
 {
-    if (new_error)
-       fprintf(stderr, "%s:%u: %s\n", filename, line_number, last_err);
-    new_error = 0;
-}
+    errwarn *we, *we2;
+
+    /* If errwarns hasn't been initialized, there are no messages. */
+    if (!errwarns)
+       return error_count;
+
+    /* Output error and warning messages. */
+    STAILQ_FOREACH(we, errwarns, link) {
+       if (we->type == WE_ERROR)
+           fprintf(stderr, "%s:%lu: %s\n", we->filename, we->line, we->msg);
+       else
+           fprintf(stderr, "%s:%lu: %s %s\n", we->filename, we->line,
+                   _("warning:"), we->msg);
+    }
 
-/* Output a previously stored warning (if any) to stderr. */
-void
-OutputWarning(void)
-{
-    if (new_warning)
-       fprintf(stderr, "%s:%u: %s %s\n", filename, line_number,
-               _("warning:"), last_warn);
-    new_warning = 0;
+    /* Delete messages. */
+    we = STAILQ_FIRST(errwarns);
+    while (we) {
+       we2 = STAILQ_NEXT(we, link);
+       free(we);
+       we = we2;
+    }
+
+    /* Return the total error count up to this point. */
+    return error_count;
 }
index e3743508847bd435a732fe107a41685ba0f0e590..9a581272da59207ddcc92a2a2e53c3fd4be30f2c 100644 (file)
@@ -40,7 +40,7 @@ void Fatal(fatal_num);
 void Error(char *, ...);
 void Warning(char *, ...);
 
-void OutputError(void);
-void OutputWarning(void);
+/* Returns total number of errors to this point in assembly. */
+unsigned int OutputAllErrorWarning(void);
 
 #endif
index 25cd0dee805824470056c33200a50cd932715569..cb596260f8273e9b8e11cf0a911b3c21b0ea27b1 100644 (file)
@@ -130,8 +130,6 @@ extern char *nasm_parser_locallabel_base;
 %%
 input: /* empty */
     | input line    {
-       OutputError();
-       OutputWarning();
        bytecodes_append(&nasm_parser_cur_section->bc, $2);
        line_number++;
     }
index 25cd0dee805824470056c33200a50cd932715569..cb596260f8273e9b8e11cf0a911b3c21b0ea27b1 100644 (file)
@@ -130,8 +130,6 @@ extern char *nasm_parser_locallabel_base;
 %%
 input: /* empty */
     | input line    {
-       OutputError();
-       OutputWarning();
        bytecodes_append(&nasm_parser_cur_section->bc, $2);
        line_number++;
     }
index 03c0a65717f396028af7671ce633f4967597677e..f2191f897fdcde8e791602bb932a366c8dec1563 100644 (file)
@@ -49,11 +49,11 @@ RCSID("$IdPath$");
 
 /* Total error count for entire assembler run.
  * Assembler should exit with EXIT_FAILURE if this is >= 0 on finish. */
-unsigned int error_count = 0;
+static unsigned int error_count = 0;
 
 /* Total warning count for entire assembler run.
  * Should not affect exit value of assembler. */
-unsigned int warning_count = 0;
+static unsigned int warning_count = 0;
 
 /* See errwarn.h for constants that match up to these strings.
  * When adding a string here, keep errwarn.h in sync! */
@@ -64,27 +64,30 @@ static char *fatal_msgs[] = {
     N_("out of memory")
 };
 
-/* I hate to define these strings as static buffers; a better solution would be
- * to use vasprintf() to dynamically allocate, but that's not ANSI C.
- * FIXME! */
+typedef STAILQ_HEAD(errwarnhead_s, errwarn_s) errwarnhead;
+errwarnhead *errwarns = (errwarnhead *)NULL;
 
-/* Last error message string.  Set by Error(), read by OutputError(). */
-static char last_err[1024];
+typedef struct errwarn_s {
+    STAILQ_ENTRY(errwarn_s) link;
 
-/* Last warning message string.  Set by Warning(), read by OutputWarning(). */
-static char last_warn[1024];
+    enum { WE_ERROR, WE_WARNING } type;
 
-/* Has there been an error since the last time we output one?  Set by Error(),
- * read and reset by OutputError(). */
-static int new_error = 0;
+    char *filename;
+    unsigned long line;
+    /* FIXME: This should not be a fixed size.  But we don't have vasprintf()
+     * right now. */
+    char msg[1024];
+} errwarn;
+
+/* Line number of the previous error.  Set and checked by Error(). */
+static unsigned long previous_error_line = 0;
 
 /* Is the last error a parser error?  Error() lets other errors override parser
  * errors. Set by yyerror(), read and reset by Error(). */
-static int parser_error = 0;
+static int previous_error_parser = 0;
 
-/* Has there been a warning since the last time we output one?  Set by
- * Warning(), read and reset by OutputWarning(). */
-static int new_warning = 0;
+/* Line number of the previous warning. Set and checked by Warning(). */
+static unsigned long previous_warning_line = 0;
 
 /* Static buffer for use by conv_unprint(). */
 static char unprint[5];
@@ -116,7 +119,7 @@ void
 ParserError(char *s)
 {
     Error("%s %s", _("parser error:"), s);
-    parser_error = 1;
+    previous_error_parser = 1;
 }
 
 /* Report an internal error.  Essentially a fatal error with trace info.
@@ -153,17 +156,43 @@ void
 Error(char *fmt, ...)
 {
     va_list ap;
+    errwarn *we;
 
-    if (new_error && !parser_error)
+    if ((previous_error_line == line_number) && !previous_error_parser)
        return;
 
-    new_error = 1;
-    parser_error = 0;
+    if (!errwarns) {
+       errwarns = malloc(sizeof(errwarnhead));
+       if (!errwarns)
+           Fatal(FATAL_NOMEM);
+       STAILQ_INIT(errwarns);
+    }
+
+    if (previous_error_parser) {
+       /* overwrite last (parser) error */     
+       we = STAILQ_LAST(errwarns, errwarn_s, link);
+    } else {
+       we = malloc(sizeof(errwarn));
+       if (!we)
+           Fatal(FATAL_NOMEM);
+
+       we->type = WE_ERROR;
+       we->filename = strdup(filename);
+       if (!we->filename)
+           Fatal(FATAL_NOMEM);
+       we->line = line_number;
+    }
 
     va_start(ap, fmt);
-    vsprintf(last_err, fmt, ap);
+    vsprintf(we->msg, fmt, ap);
     va_end(ap);
 
+    if (!previous_error_parser)
+       STAILQ_INSERT_TAIL(errwarns, we, link);
+
+    previous_error_line = line_number;
+    previous_error_parser = 0;
+
     error_count++;
 }
 
@@ -174,34 +203,63 @@ void
 Warning(char *fmt, ...)
 {
     va_list ap;
+    errwarn *we;
 
-    if (new_warning)
+    if (previous_warning_line == line_number)
        return;
 
-    new_warning = 1;
+    previous_warning_line = line_number;
 
+    we = malloc(sizeof(errwarn));
+    if (!we)
+       Fatal(FATAL_NOMEM);
+
+    we->type = WE_WARNING;
+    we->filename = strdup(filename);
+    if (!we->filename)
+       Fatal(FATAL_NOMEM);
+    we->line = line_number;
     va_start(ap, fmt);
-    vsprintf(last_warn, fmt, ap);
+    vsprintf(we->msg, fmt, ap);
     va_end(ap);
 
+    if (!errwarns) {
+       errwarns = malloc(sizeof(errwarnhead));
+       if (!errwarns)
+           Fatal(FATAL_NOMEM);
+       STAILQ_INIT(errwarns);
+    }
+    STAILQ_INSERT_TAIL(errwarns, we, link);
     warning_count++;
 }
 
-/* Output a previously stored error (if any) to stderr. */
-void
-OutputError(void)
+/* Output all previously stored errors and warnings to stderr. */
+unsigned int
+OutputAllErrorWarning(void)
 {
-    if (new_error)
-       fprintf(stderr, "%s:%u: %s\n", filename, line_number, last_err);
-    new_error = 0;
-}
+    errwarn *we, *we2;
+
+    /* If errwarns hasn't been initialized, there are no messages. */
+    if (!errwarns)
+       return error_count;
+
+    /* Output error and warning messages. */
+    STAILQ_FOREACH(we, errwarns, link) {
+       if (we->type == WE_ERROR)
+           fprintf(stderr, "%s:%lu: %s\n", we->filename, we->line, we->msg);
+       else
+           fprintf(stderr, "%s:%lu: %s %s\n", we->filename, we->line,
+                   _("warning:"), we->msg);
+    }
 
-/* Output a previously stored warning (if any) to stderr. */
-void
-OutputWarning(void)
-{
-    if (new_warning)
-       fprintf(stderr, "%s:%u: %s %s\n", filename, line_number,
-               _("warning:"), last_warn);
-    new_warning = 0;
+    /* Delete messages. */
+    we = STAILQ_FIRST(errwarns);
+    while (we) {
+       we2 = STAILQ_NEXT(we, link);
+       free(we);
+       we = we2;
+    }
+
+    /* Return the total error count up to this point. */
+    return error_count;
 }
index e3743508847bd435a732fe107a41685ba0f0e590..9a581272da59207ddcc92a2a2e53c3fd4be30f2c 100644 (file)
@@ -40,7 +40,7 @@ void Fatal(fatal_num);
 void Error(char *, ...);
 void Warning(char *, ...);
 
-void OutputError(void);
-void OutputWarning(void);
+/* Returns total number of errors to this point in assembly. */
+unsigned int OutputAllErrorWarning(void);
 
 #endif
index e05475ae7e44fb4b1e51e01a4cf39d3df0b93ee8..11ece76aba4f671ca613543156e98ceaddc1b0cb 100644 (file)
@@ -33,6 +33,7 @@
 #endif
 
 #include "globals.h"
+#include "errwarn.h"
 
 #include "bytecode.h"
 #include "section.h"
@@ -64,6 +65,9 @@ main(int argc, char *argv[])
 
     nasm_parser.do_parse(&nasm_parser, &dbg_objfmt, in);
 
+    if (OutputAllErrorWarning() > 0)
+       return EXIT_FAILURE;
+
     if (filename)
        free(filename);
     return EXIT_SUCCESS;
index 25cd0dee805824470056c33200a50cd932715569..cb596260f8273e9b8e11cf0a911b3c21b0ea27b1 100644 (file)
@@ -130,8 +130,6 @@ extern char *nasm_parser_locallabel_base;
 %%
 input: /* empty */
     | input line    {
-       OutputError();
-       OutputWarning();
        bytecodes_append(&nasm_parser_cur_section->bc, $2);
        line_number++;
     }
index 25cd0dee805824470056c33200a50cd932715569..cb596260f8273e9b8e11cf0a911b3c21b0ea27b1 100644 (file)
@@ -130,8 +130,6 @@ extern char *nasm_parser_locallabel_base;
 %%
 input: /* empty */
     | input line    {
-       OutputError();
-       OutputWarning();
        bytecodes_append(&nasm_parser_cur_section->bc, $2);
        line_number++;
     }