NASM 0.98bf
[nasm.git] / listing.c
blobc37c15a75a3f00cbe39d23782987c0a251f66542
1 /* listing.c listing file generator for the Netwide Assembler
3 * The Netwide Assembler is copyright (C) 1996 Simon Tatham and
4 * Julian Hall. All rights reserved. The software is
5 * redistributable under the licence given in the file "Licence"
6 * distributed in the NASM archive.
8 * initial version 2/vii/97 by Simon Tatham
9 */
11 #include <stdio.h>
12 #include <stdlib.h>
13 #include <stddef.h>
14 #include <string.h>
15 #include <ctype.h>
17 #include "nasm.h"
18 #include "nasmlib.h"
19 #include "listing.h"
21 #define LIST_MAX_LEN 216 /* something sensible */
22 #define LIST_INDENT 40
23 #define LIST_HEXBIT 18
25 typedef struct MacroInhibit MacroInhibit;
27 static struct MacroInhibit {
28 MacroInhibit *next;
29 int level;
30 int inhibiting;
31 } *mistack;
33 static char xdigit[] = "0123456789ABCDEF";
35 #define HEX(a,b) (*(a)=xdigit[((b)>>4)&15],(a)[1]=xdigit[(b)&15]);
37 static char listline[LIST_MAX_LEN];
38 static int listlinep;
40 static char listdata[2*LIST_INDENT]; /* we need less than that actually */
41 static long listoffset;
43 static long listlineno;
45 static long listp;
47 static int suppress; /* for INCBIN & TIMES special cases */
49 static int listlevel, listlevel_e;
51 static FILE *listfp;
53 static void list_emit (void)
55 if (!listlinep && !listdata[0])
56 return;
58 fprintf(listfp, "%6ld ", ++listlineno);
60 if (listdata[0])
61 fprintf(listfp, "%08lX %-*s", listoffset, LIST_HEXBIT+1, listdata);
62 else
63 fprintf(listfp, "%*s", LIST_HEXBIT+10, "");
65 if (listlevel_e)
66 fprintf(listfp, "%s<%d>", (listlevel < 10 ? " " : ""), listlevel_e);
67 else if (listlinep)
68 fprintf(listfp, " ");
70 if (listlinep)
71 fprintf(listfp, " %s", listline);
73 fputc('\n', listfp);
74 listlinep = FALSE;
75 listdata[0] = '\0';
78 static void list_init (char *fname, efunc error)
80 listfp = fopen (fname, "w");
81 if (!listfp) {
82 error (ERR_NONFATAL, "unable to open listing file `%s'", fname);
83 return;
86 *listline = '\0';
87 listlineno = 0;
88 listp = TRUE;
89 listlevel = 0;
90 suppress = 0;
91 mistack = nasm_malloc(sizeof(MacroInhibit));
92 mistack->next = NULL;
93 mistack->level = 0;
94 mistack->inhibiting = TRUE;
97 static void list_cleanup (void)
99 if (!listp)
100 return;
102 while (mistack) {
103 MacroInhibit *temp = mistack;
104 mistack = temp->next;
105 nasm_free (temp);
108 list_emit();
109 fclose (listfp);
112 static void list_out (long offset, char *str)
114 if (strlen(listdata) + strlen(str) > LIST_HEXBIT) {
115 strcat(listdata, "-");
116 list_emit();
118 if (!listdata[0])
119 listoffset = offset;
120 strcat(listdata, str);
123 static void list_output (long offset, void *data, unsigned long type)
125 unsigned long typ;
126 long size;
128 if (!listp || suppress)
129 return;
131 typ = type & OUT_TYPMASK;
132 size = type & OUT_SIZMASK;
134 if (typ == OUT_RAWDATA)
136 unsigned char *p = data;
137 char q[3];
138 while (size--)
140 HEX (q, *p);
141 q[2] = '\0';
142 list_out (offset++, q);
143 p++;
146 else if (typ == OUT_ADDRESS)
148 unsigned long d = *(long *)data;
149 char q[11];
150 unsigned char p[4], *r = p;
151 if (size == 4)
153 q[0] = '['; q[9] = ']'; q[10] = '\0';
154 WRITELONG (r, d);
155 HEX (q+1, p[0]);
156 HEX (q+3, p[1]);
157 HEX (q+5, p[2]);
158 HEX (q+7, p[3]);
159 list_out (offset, q);
161 else {
162 q[0] = '['; q[5] = ']'; q[6] = '\0';
163 WRITESHORT (r, d);
164 HEX (q+1, p[0]);
165 HEX (q+3, p[1]);
166 list_out (offset, q);
169 else if (typ == OUT_REL2ADR)
171 unsigned long d = *(long *)data;
172 char q[11];
173 unsigned char p[4], *r = p;
174 q[0] = '('; q[5] = ')'; q[6] = '\0';
175 WRITESHORT (r, d);
176 HEX (q+1, p[0]);
177 HEX (q+3, p[1]);
178 list_out (offset, q);
180 else if (typ == OUT_REL4ADR)
182 unsigned long d = *(long *)data;
183 char q[11];
184 unsigned char p[4], *r = p;
185 q[0] = '('; q[9] = ')'; q[10] = '\0';
186 WRITELONG (r, d);
187 HEX (q+1, p[0]);
188 HEX (q+3, p[1]);
189 HEX (q+5, p[2]);
190 HEX (q+7, p[3]);
191 list_out (offset, q);
193 else if (typ == OUT_RESERVE)
195 char q[20];
196 sprintf(q, "<res %08lX>", size);
197 list_out (offset, q);
201 static void list_line (int type, char *line)
203 if (!listp)
204 return;
206 if (mistack && mistack->inhibiting)
208 if (type == LIST_MACRO)
209 return;
210 else { /* pop the m i stack */
211 MacroInhibit *temp = mistack;
212 mistack = temp->next;
213 nasm_free (temp);
216 list_emit();
217 listlinep = TRUE;
218 strncpy (listline, line, LIST_MAX_LEN-1);
219 listline[LIST_MAX_LEN-1] = '\0';
220 listlevel_e = listlevel;
223 static void list_uplevel (int type)
225 if (!listp)
226 return;
227 if (type == LIST_INCBIN || type == LIST_TIMES)
229 suppress |= (type == LIST_INCBIN ? 1 : 2);
230 list_out (listoffset, type == LIST_INCBIN ? "<incbin>" : "<rept>");
231 return;
234 listlevel++;
236 if (mistack && mistack->inhibiting && type == LIST_INCLUDE)
238 MacroInhibit *temp = nasm_malloc(sizeof(MacroInhibit));
239 temp->next = mistack;
240 temp->level = listlevel;
241 temp->inhibiting = FALSE;
242 mistack = temp;
244 else if (type == LIST_MACRO_NOLIST)
246 MacroInhibit *temp = nasm_malloc(sizeof(MacroInhibit));
247 temp->next = mistack;
248 temp->level = listlevel;
249 temp->inhibiting = TRUE;
250 mistack = temp;
254 static void list_downlevel (int type)
256 if (!listp)
257 return;
259 if (type == LIST_INCBIN || type == LIST_TIMES)
261 suppress &= ~(type == LIST_INCBIN ? 1 : 2);
262 return;
265 listlevel--;
266 while (mistack && mistack->level > listlevel)
268 MacroInhibit *temp = mistack;
269 mistack = temp->next;
270 nasm_free (temp);
274 ListGen nasmlist = {
275 list_init,
276 list_cleanup,
277 list_output,
278 list_line,
279 list_uplevel,
280 list_downlevel