#define HEX(a,b) (*(a)=xdigit[((b)>>4)&15],(a)[1]=xdigit[(b)&15]);
static char listline[LIST_MAX_LEN];
-static int listlinep;
+static bool listlinep;
+
+static char listerror[LIST_MAX_LEN];
static char listdata[2 * LIST_INDENT]; /* we need less than that actually */
static int32_t listoffset;
static void list_emit(void)
{
+ int i;
+
if (!listlinep && !listdata[0])
return;
putc('\n', listfp);
listlinep = false;
listdata[0] = '\0';
+
+ if (listerror[0]) {
+ fprintf(listfp, "%6"PRId32" ", ++listlineno);
+ for (i = 0; i < LIST_HEXBIT; i++)
+ putc('*', listfp);
+
+ if (listlevel_e)
+ fprintf(listfp, " %s<%d>", (listlevel < 10 ? " " : ""),
+ listlevel_e);
+ else
+ fprintf(listfp, " ");
+
+ fprintf(listfp, " %s\n", listerror);
+ listerror[0] = '\0';
+ }
}
static void list_init(char *fname, efunc error)
{
listfp = fopen(fname, "w");
if (!listfp) {
- error(ERR_NONFATAL, "unable to open listing file `%s'", fname);
+ error(ERR_NONFATAL, "unable to open listing file `%s'",
+ fname);
return;
}
*listline = '\0';
listlineno = 0;
+ *listerror = '\0';
listp = true;
listlevel = 0;
suppress = 0;
}
}
+static void list_error(int severity, const char *pfx, const char *msg)
+{
+ if (!listfp)
+ return;
+
+ snprintf(listerror, sizeof listerror, "%s%s", pfx, msg);
+
+ if ((severity & ERR_MASK) >= ERR_FATAL)
+ list_emit();
+}
+
+
ListGen nasmlist = {
list_init,
list_cleanup,
list_output,
list_line,
list_uplevel,
- list_downlevel
+ list_downlevel,
+ list_error
};
fclose (ofile);
remove(outname);
- if (listname[0])
- remove(listname);
}
}
break;
static void report_error_common(int severity, const char *fmt,
va_list args)
{
+ char msg[1024];
+ const char *pfx;
+
switch (severity & (ERR_MASK|ERR_NO_SEVERITY)) {
case ERR_WARNING:
- fputs("warning: ", error_file);
+ pfx = "warning: ";
break;
case ERR_NONFATAL:
- fputs("error: ", error_file);
+ pfx = "error: ";
break;
case ERR_FATAL:
- fputs("fatal: ", error_file);
+ pfx = "fatal: ";
break;
case ERR_PANIC:
- fputs("panic: ", error_file);
+ pfx = "panic: ";
break;
case ERR_DEBUG:
- fputs("debug: ", error_file);
+ pfx = "debug: ";
break;
default:
+ pfx = "";
break;
}
- vfprintf(error_file, fmt, args);
- putc('\n', error_file);
+ vsnprintf(msg, sizeof msg, fmt, args);
+
+ fprintf(error_file, "%s%s\n", pfx, msg);
+
+ if (*listname)
+ nasmlist.error(severity, pfx, msg);
if (severity & ERR_USAGE)
want_usage = true;
* Reverse the effects of uplevel.
*/
void (*downlevel) (int);
+
+ /*
+ * Called on a warning or error, with the error message.
+ */
+ void (*error)(int severity, const char *pfx, const char *msg);
} ListGen;
/*
*/
struct dfmt {
-
/*
* This is a short (one-liner) description of the type of
* output generated by the driver.