summaryrefslogtreecommitdiff
path: root/listing.c
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>2002-04-30 20:52:26 +0000
committerH. Peter Anvin <hpa@zytor.com>2002-04-30 20:52:26 +0000
commit6768eb71d8debde65562619c938b997aea1bd9f9 (patch)
tree93fc4f4a6d66891ace9494b737aa4b2c1bed37ef /listing.c
parentd7ed89eac9580f280fe0017b22c8e38ca75ed8e3 (diff)
downloadnasm-6768eb71d8debde65562619c938b997aea1bd9f9.tar.gz
NASM 0.95nasm-0.95
Diffstat (limited to 'listing.c')
-rw-r--r--listing.c240
1 files changed, 240 insertions, 0 deletions
diff --git a/listing.c b/listing.c
new file mode 100644
index 00000000..89b722a6
--- /dev/null
+++ b/listing.c
@@ -0,0 +1,240 @@
+/* listing.c listing file generator for the Netwide Assembler
+ *
+ * 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.
+ *
+ * initial version 2/vii/97 by Simon Tatham
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <string.h>
+#include <ctype.h>
+
+#include "nasm.h"
+#include "nasmlib.h"
+#include "listing.h"
+
+#define LIST_MAX_LEN 216 /* something sensible */
+#define LIST_INDENT 40
+#define LIST_HEXBIT 18
+
+typedef struct MacroInhibit MacroInhibit;
+
+static struct MacroInhibit {
+ MacroInhibit *next;
+ int level;
+ int inhibiting;
+} *mistack;
+
+static char xdigit[] = "0123456789ABCDEF";
+
+#define HEX(a,b) (*(a)=xdigit[((b)>>4)&15],(a)[1]=xdigit[(b)&15]);
+
+static char listline[LIST_MAX_LEN];
+static int listlinep;
+
+static char listdata[2*LIST_INDENT]; /* we need less than that actually */
+static long listoffset;
+
+static long listlineno;
+
+static long listp;
+
+static int suppress; /* for INCBIN & TIMES special cases */
+
+static int listlevel, listlevel_e;
+
+static FILE *listfp;
+
+static void list_emit (void) {
+ if (!listlinep && !listdata[0])
+ return;
+ fprintf(listfp, "%6ld ", ++listlineno);
+ if (listdata[0])
+ fprintf(listfp, "%08lX %-*s", listoffset, LIST_HEXBIT+1, listdata);
+ else
+ fprintf(listfp, "%*s", LIST_HEXBIT+10, "");
+ if (listlevel_e)
+ fprintf(listfp, "%s<%d>", (listlevel < 10 ? " " : ""), listlevel_e);
+ else if (listlinep)
+ fprintf(listfp, " ");
+ if (listlinep)
+ fprintf(listfp, " %s", listline);
+ fputc('\n', listfp);
+ listlinep = FALSE;
+ listdata[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);
+ return;
+ }
+ *listline = '\0';
+ listlineno = 0;
+ listp = TRUE;
+ listlevel = 0;
+ suppress = 0;
+ mistack = nasm_malloc(sizeof(MacroInhibit));
+ mistack->next = NULL;
+ mistack->level = 0;
+ mistack->inhibiting = TRUE;
+}
+
+static void list_cleanup (void) {
+ if (!listp)
+ return;
+ while (mistack) {
+ MacroInhibit *temp = mistack;
+ mistack = temp->next;
+ nasm_free (temp);
+ }
+ list_emit();
+ fclose (listfp);
+}
+
+static void list_out (long offset, char *str) {
+ if (strlen(listdata) + strlen(str) > LIST_HEXBIT) {
+ strcat(listdata, "-");
+ list_emit();
+ }
+ if (!listdata[0])
+ listoffset = offset;
+ strcat(listdata, str);
+}
+
+static void list_output (long offset, void *data, unsigned long type) {
+ long typ, size;
+
+ if (!listp || suppress)
+ return;
+
+ typ = type & OUT_TYPMASK;
+ size = type & OUT_SIZMASK;
+
+ if (typ == OUT_RAWDATA) {
+ unsigned char *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) {
+ 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) {
+ char q[20];
+ sprintf(q, "<res %08lX>", size);
+ list_out (offset, q);
+ }
+}
+
+static void list_line (int type, char *line) {
+ if (!listp)
+ 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);
+ }
+ }
+ list_emit();
+ listlinep = TRUE;
+ strncpy (listline, line, LIST_MAX_LEN-1);
+ listline[LIST_MAX_LEN-1] = '\0';
+ listlevel_e = listlevel;
+}
+
+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;
+ }
+ 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;
+ }
+}
+
+static void list_downlevel (int type) {
+ if (!listp)
+ 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);
+ }
+}
+
+ListGen nasmlist = {
+ list_init,
+ list_cleanup,
+ list_output,
+ list_line,
+ list_uplevel,
+ list_downlevel
+};