-/* listing.c listing file generator for the Netwide Assembler
+/* ----------------------------------------------------------------------- *
+ *
+ * Copyright 1996-2009 The NASM Authors - All Rights Reserved
+ * See the file AUTHORS included with the NASM distribution for
+ * the specific copyright holders.
*
- * The Netwide Assembler is copyright (C) 1996 Simon Tatham and
- * Julian Hall. All rights reserved. The software is
- * redistributable under the licence given in the file "Licence"
- * distributed in the NASM archive.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following
+ * conditions are met:
*
- * initial version 2/vii/97 by Simon Tatham
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * listing.c listing file generator for the Netwide Assembler
*/
+#include "compiler.h"
+
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#include <string.h>
#include <ctype.h>
+#include <inttypes.h>
#include "nasm.h"
#include "nasmlib.h"
#include "listing.h"
-#define LIST_MAX_LEN 216 /* something sensible */
+#define LIST_MAX_LEN 216 /* something sensible */
#define LIST_INDENT 40
#define LIST_HEXBIT 18
#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 long listoffset;
+static char listdata[2 * LIST_INDENT]; /* we need less than that actually */
+static int32_t listoffset;
-static long listlineno;
+static int32_t listlineno;
-static long listp;
+static int32_t listp;
-static int suppress; /* for INCBIN & TIMES special cases */
+static int suppress; /* for INCBIN & TIMES special cases */
static int listlevel, listlevel_e;
static FILE *listfp;
-static void list_emit (void)
+static void list_emit(void)
{
+ int i;
+
if (!listlinep && !listdata[0])
- return;
+ return;
- fprintf(listfp, "%6ld ", ++listlineno);
+ fprintf(listfp, "%6"PRId32" ", ++listlineno);
if (listdata[0])
- fprintf(listfp, "%08lX %-*s", listoffset, LIST_HEXBIT+1, listdata);
+ fprintf(listfp, "%08"PRIX32" %-*s", listoffset, LIST_HEXBIT + 1,
+ listdata);
else
- fprintf(listfp, "%*s", LIST_HEXBIT+10, "");
+ fprintf(listfp, "%*s", LIST_HEXBIT + 10, "");
if (listlevel_e)
- fprintf(listfp, "%s<%d>", (listlevel < 10 ? " " : ""), listlevel_e);
+ fprintf(listfp, "%s<%d>", (listlevel < 10 ? " " : ""),
+ listlevel_e);
else if (listlinep)
- fprintf(listfp, " ");
+ fprintf(listfp, " ");
if (listlinep)
- fprintf(listfp, " %s", listline);
+ fprintf(listfp, " %s", listline);
- fputc('\n', listfp);
- listlinep = FALSE;
+ 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)
+static void list_init(char *fname, efunc error)
{
- listfp = fopen (fname, "w");
+ listfp = fopen(fname, "w");
if (!listfp) {
- error (ERR_NONFATAL, "unable to open listing file `%s'", fname);
- return;
+ error(ERR_NONFATAL, "unable to open listing file `%s'",
+ fname);
+ return;
}
*listline = '\0';
listlineno = 0;
- listp = TRUE;
+ *listerror = '\0';
+ listp = true;
listlevel = 0;
suppress = 0;
mistack = nasm_malloc(sizeof(MacroInhibit));
mistack->next = NULL;
mistack->level = 0;
- mistack->inhibiting = TRUE;
+ mistack->inhibiting = true;
}
-static void list_cleanup (void)
+static void list_cleanup(void)
{
if (!listp)
- return;
+ return;
while (mistack) {
- MacroInhibit *temp = mistack;
- mistack = temp->next;
- nasm_free (temp);
+ MacroInhibit *temp = mistack;
+ mistack = temp->next;
+ nasm_free(temp);
}
list_emit();
- fclose (listfp);
+ fclose(listfp);
}
-static void list_out (long offset, char *str)
+static void list_out(int32_t offset, char *str)
{
if (strlen(listdata) + strlen(str) > LIST_HEXBIT) {
- strcat(listdata, "-");
- list_emit();
+ strcat(listdata, "-");
+ list_emit();
}
if (!listdata[0])
- listoffset = offset;
+ listoffset = offset;
strcat(listdata, str);
}
-static void list_output (long offset, const void *data, unsigned long type)
+static void list_address(int32_t offset, const char *brackets,
+ int64_t addr, int size)
{
- unsigned long typ, size;
+ char q[20];
+ char *r = q;
- if (!listp || suppress || user_nolist) /* fbk - 9/2/00 */
- return;
+ nasm_assert(size <= 8);
- typ = type & OUT_TYPMASK;
- size = type & OUT_SIZMASK;
+ *r++ = brackets[0];
+ while (size--) {
+ HEX(r, addr);
+ addr >>= 8;
+ r += 2;
+ }
+ *r++ = brackets[1];
+ *r = '\0';
+ list_out(offset, q);
+}
- if (typ == OUT_RAWDATA)
- {
- unsigned char const *p = data;
- char q[3];
- while (size--)
- {
- HEX (q, *p);
- q[2] = '\0';
- list_out (offset++, q);
- p++;
- }
- }
- else if (typ == OUT_ADDRESS)
- {
- unsigned long d = *(long *)data;
- char q[11];
- unsigned char p[4], *r = p;
- if (size == 4)
- {
- q[0] = '['; q[9] = ']'; q[10] = '\0';
- WRITELONG (r, d);
- HEX (q+1, p[0]);
- HEX (q+3, p[1]);
- HEX (q+5, p[2]);
- HEX (q+7, p[3]);
- list_out (offset, q);
- }
- else {
- q[0] = '['; q[5] = ']'; q[6] = '\0';
- WRITESHORT (r, d);
- HEX (q+1, p[0]);
- HEX (q+3, p[1]);
- list_out (offset, q);
- }
- }
- else if (typ == OUT_REL2ADR)
- {
- unsigned long d = *(long *)data;
- char q[11];
- unsigned char p[4], *r = p;
- q[0] = '('; q[5] = ')'; q[6] = '\0';
- WRITESHORT (r, d);
- HEX (q+1, p[0]);
- HEX (q+3, p[1]);
- list_out (offset, q);
- }
- else if (typ == OUT_REL4ADR)
+static void list_output(int32_t offset, const void *data,
+ enum out_type type, uint64_t size)
+{
+ char q[20];
+
+ if (!listp || suppress || user_nolist) /* fbk - 9/2/00 */
+ return;
+
+ switch (type) {
+ case OUT_RAWDATA:
{
- unsigned long d = *(long *)data;
- char q[11];
- unsigned char p[4], *r = p;
- q[0] = '('; q[9] = ')'; q[10] = '\0';
- WRITELONG (r, d);
- HEX (q+1, p[0]);
- HEX (q+3, p[1]);
- HEX (q+5, p[2]);
- HEX (q+7, p[3]);
- list_out (offset, q);
- }
- else if (typ == OUT_RESERVE)
+ uint8_t const *p = data;
+
+ if (size == 0 && !listdata[0])
+ listoffset = offset;
+ while (size--) {
+ HEX(q, *p);
+ q[2] = '\0';
+ list_out(offset++, q);
+ p++;
+ }
+ break;
+ }
+ case OUT_ADDRESS:
+ list_address(offset, "[]", *(int64_t *)data, size);
+ break;
+ case OUT_REL1ADR:
+ list_address(offset, "()", *(int64_t *)data, 1);
+ break;
+ case OUT_REL2ADR:
+ list_address(offset, "()", *(int64_t *)data, 2);
+ break;
+ case OUT_REL4ADR:
+ list_address(offset, "()", *(int64_t *)data, 4);
+ break;
+ case OUT_REL8ADR:
+ list_address(offset, "()", *(int64_t *)data, 8);
+ break;
+ case OUT_RESERVE:
{
- char q[20];
- sprintf(q, "<res %08lX>", size);
- list_out (offset, q);
+ snprintf(q, sizeof(q), "<res %08"PRIX64">", size);
+ list_out(offset, q);
+ break;
+ }
}
}
-static void list_line (int type, char *line)
+static void list_line(int type, char *line)
{
if (!listp)
- return;
- if (user_nolist){ /* fbk - 9/2/00 */
+ return;
+ if (user_nolist) { /* fbk - 9/2/00 */
listlineno++;
return;
}
- if (mistack && mistack->inhibiting)
- {
- if (type == LIST_MACRO)
- return;
- else { /* pop the m i stack */
- MacroInhibit *temp = mistack;
- mistack = temp->next;
- nasm_free (temp);
- }
+ if (mistack && mistack->inhibiting) {
+ if (type == LIST_MACRO)
+ return;
+ else { /* pop the m i stack */
+ MacroInhibit *temp = mistack;
+ mistack = temp->next;
+ nasm_free(temp);
+ }
}
list_emit();
- listlinep = TRUE;
- strncpy (listline, line, LIST_MAX_LEN-1);
- listline[LIST_MAX_LEN-1] = '\0';
+ listlinep = true;
+ strncpy(listline, line, LIST_MAX_LEN - 1);
+ listline[LIST_MAX_LEN - 1] = '\0';
listlevel_e = listlevel;
}
-static void list_uplevel (int type)
+static void list_uplevel(int type)
{
if (!listp)
- return;
- if (type == LIST_INCBIN || type == LIST_TIMES)
- {
- suppress |= (type == LIST_INCBIN ? 1 : 2);
- list_out (listoffset, type == LIST_INCBIN ? "<incbin>" : "<rept>");
- return;
+ return;
+ if (type == LIST_INCBIN || type == LIST_TIMES) {
+ suppress |= (type == LIST_INCBIN ? 1 : 2);
+ list_out(listoffset, type == LIST_INCBIN ? "<incbin>" : "<rept>");
+ return;
}
listlevel++;
- if (mistack && mistack->inhibiting && type == LIST_INCLUDE)
- {
- MacroInhibit *temp = nasm_malloc(sizeof(MacroInhibit));
- temp->next = mistack;
- temp->level = listlevel;
- temp->inhibiting = FALSE;
- mistack = temp;
- }
- else if (type == LIST_MACRO_NOLIST)
- {
- MacroInhibit *temp = nasm_malloc(sizeof(MacroInhibit));
- temp->next = mistack;
- temp->level = listlevel;
- temp->inhibiting = TRUE;
- mistack = temp;
+ if (mistack && mistack->inhibiting && type == LIST_INCLUDE) {
+ MacroInhibit *temp = nasm_malloc(sizeof(MacroInhibit));
+ temp->next = mistack;
+ temp->level = listlevel;
+ temp->inhibiting = false;
+ mistack = temp;
+ } else if (type == LIST_MACRO_NOLIST) {
+ MacroInhibit *temp = nasm_malloc(sizeof(MacroInhibit));
+ temp->next = mistack;
+ temp->level = listlevel;
+ temp->inhibiting = true;
+ mistack = temp;
}
}
-static void list_downlevel (int type)
+static void list_downlevel(int type)
{
if (!listp)
- return;
+ return;
- if (type == LIST_INCBIN || type == LIST_TIMES)
- {
- suppress &= ~(type == LIST_INCBIN ? 1 : 2);
- return;
+ if (type == LIST_INCBIN || type == LIST_TIMES) {
+ suppress &= ~(type == LIST_INCBIN ? 1 : 2);
+ return;
}
listlevel--;
- while (mistack && mistack->level > listlevel)
- {
- MacroInhibit *temp = mistack;
- mistack = temp->next;
- nasm_free (temp);
+ while (mistack && mistack->level > listlevel) {
+ MacroInhibit *temp = mistack;
+ mistack = temp->next;
+ nasm_free(temp);
}
}
+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
};