Create dummy file to test nasm-cvs list
[platform/upstream/nasm.git] / listing.c
1 /* listing.c    listing file generator for the Netwide Assembler
2  *
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.
7  *
8  * initial version 2/vii/97 by Simon Tatham
9  */
10
11 #include <stdio.h>
12 #include <stdlib.h>
13 #include <stddef.h>
14 #include <string.h>
15 #include <ctype.h>
16
17 #include "nasm.h"
18 #include "nasmlib.h"
19 #include "listing.h"
20
21 #define LIST_MAX_LEN 216               /* something sensible */
22 #define LIST_INDENT  40
23 #define LIST_HEXBIT  18
24
25 typedef struct MacroInhibit MacroInhibit;
26
27 static struct MacroInhibit {
28     MacroInhibit *next;
29     int level;
30     int inhibiting;
31 } *mistack;
32
33 static char xdigit[] = "0123456789ABCDEF";
34
35 #define HEX(a,b) (*(a)=xdigit[((b)>>4)&15],(a)[1]=xdigit[(b)&15]);
36
37 static char listline[LIST_MAX_LEN];
38 static int listlinep;
39
40 static char listdata[2*LIST_INDENT];   /* we need less than that actually */
41 static long listoffset;
42
43 static long listlineno;
44
45 static long listp;
46
47 static int suppress;                   /* for INCBIN & TIMES special cases */
48
49 static int listlevel, listlevel_e;
50
51 static FILE *listfp;
52
53 static void list_emit (void) 
54 {
55     if (!listlinep && !listdata[0])
56         return;
57
58     fprintf(listfp, "%6ld ", ++listlineno);
59
60     if (listdata[0])
61         fprintf(listfp, "%08lX %-*s", listoffset, LIST_HEXBIT+1, listdata);
62     else
63         fprintf(listfp, "%*s", LIST_HEXBIT+10, "");
64
65     if (listlevel_e)
66         fprintf(listfp, "%s<%d>", (listlevel < 10 ? " " : ""), listlevel_e);
67     else if (listlinep)
68         fprintf(listfp, "    ");
69
70     if (listlinep)
71         fprintf(listfp, " %s", listline);
72
73     fputc('\n', listfp);
74     listlinep = FALSE;
75     listdata[0] = '\0';
76 }
77
78 static void list_init (char *fname, efunc error) 
79 {
80     listfp = fopen (fname, "w");
81     if (!listfp) {
82         error (ERR_NONFATAL, "unable to open listing file `%s'", fname);
83         return;
84     }
85
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;
95 }
96
97 static void list_cleanup (void) 
98 {
99     if (!listp)
100         return;
101
102     while (mistack) {
103         MacroInhibit *temp = mistack;
104         mistack = temp->next;
105         nasm_free (temp);
106     }
107
108     list_emit();
109     fclose (listfp);
110 }
111
112 static void list_out (long offset, char *str) 
113 {
114     if (strlen(listdata) + strlen(str) > LIST_HEXBIT) {
115         strcat(listdata, "-");
116         list_emit();
117     }
118     if (!listdata[0])
119         listoffset = offset;
120     strcat(listdata, str);
121 }
122
123 static void list_output (long offset, void *data, unsigned long type) 
124 {
125     unsigned long typ, size;
126
127     if (!listp || suppress || user_nolist)    /* fbk - 9/2/00 */
128         return;
129
130     typ = type & OUT_TYPMASK;
131     size = type & OUT_SIZMASK;
132
133     if (typ == OUT_RAWDATA) 
134     {
135         unsigned char *p = data;
136         char q[3];
137         while (size--) 
138         {
139             HEX (q, *p);
140             q[2] = '\0';
141             list_out (offset++, q);
142             p++;
143         }
144     } 
145     else if (typ == OUT_ADDRESS) 
146     {
147         unsigned long d = *(long *)data;
148         char q[11];
149         unsigned char p[4], *r = p;
150         if (size == 4) 
151         {
152             q[0] = '['; q[9] = ']'; q[10] = '\0';
153             WRITELONG (r, d);
154             HEX (q+1, p[0]);
155             HEX (q+3, p[1]);
156             HEX (q+5, p[2]);
157             HEX (q+7, p[3]);
158             list_out (offset, q);
159         } 
160         else {
161             q[0] = '['; q[5] = ']'; q[6] = '\0';
162             WRITESHORT (r, d);
163             HEX (q+1, p[0]);
164             HEX (q+3, p[1]);
165             list_out (offset, q);
166         }
167     } 
168     else if (typ == OUT_REL2ADR) 
169     {
170         unsigned long d = *(long *)data;
171         char q[11];
172         unsigned char p[4], *r = p;
173         q[0] = '('; q[5] = ')'; q[6] = '\0';
174         WRITESHORT (r, d);
175         HEX (q+1, p[0]);
176         HEX (q+3, p[1]);
177         list_out (offset, q);
178     } 
179     else if (typ == OUT_REL4ADR) 
180     {
181         unsigned long d = *(long *)data;
182         char q[11];
183         unsigned char p[4], *r = p;
184         q[0] = '('; q[9] = ')'; q[10] = '\0';
185         WRITELONG (r, d);
186         HEX (q+1, p[0]);
187         HEX (q+3, p[1]);
188         HEX (q+5, p[2]);
189         HEX (q+7, p[3]);
190         list_out (offset, q);
191     } 
192     else if (typ == OUT_RESERVE) 
193     {
194         char q[20];
195         sprintf(q, "<res %08lX>", size);
196         list_out (offset, q);
197     }
198 }
199
200 static void list_line (int type, char *line) 
201 {
202     if (!listp)
203         return;
204     if (user_nolist){        /* fbk - 9/2/00 */
205         listlineno++;
206         return;
207     }
208
209     if (mistack && mistack->inhibiting) 
210     {
211         if (type == LIST_MACRO)
212             return;
213         else {                         /* pop the m i stack */
214             MacroInhibit *temp = mistack;
215             mistack = temp->next;
216             nasm_free (temp);
217         }
218     }
219     list_emit();
220     listlinep = TRUE;
221     strncpy (listline, line, LIST_MAX_LEN-1);
222     listline[LIST_MAX_LEN-1] = '\0';
223     listlevel_e = listlevel;
224 }
225
226 static void list_uplevel (int type) 
227 {
228     if (!listp)
229         return;
230     if (type == LIST_INCBIN || type == LIST_TIMES) 
231     {
232         suppress |= (type == LIST_INCBIN ? 1 : 2);
233         list_out (listoffset, type == LIST_INCBIN ? "<incbin>" : "<rept>");
234         return;
235     }
236
237     listlevel++;
238
239     if (mistack && mistack->inhibiting && type == LIST_INCLUDE) 
240     {
241         MacroInhibit *temp = nasm_malloc(sizeof(MacroInhibit));
242         temp->next = mistack;
243         temp->level = listlevel;
244         temp->inhibiting = FALSE;
245         mistack = temp;
246     } 
247     else if (type == LIST_MACRO_NOLIST) 
248     {
249         MacroInhibit *temp = nasm_malloc(sizeof(MacroInhibit));
250         temp->next = mistack;
251         temp->level = listlevel;
252         temp->inhibiting = TRUE;
253         mistack = temp;
254     }
255 }
256
257 static void list_downlevel (int type) 
258 {
259     if (!listp)
260         return;
261
262     if (type == LIST_INCBIN || type == LIST_TIMES) 
263     {
264         suppress &= ~(type == LIST_INCBIN ? 1 : 2);
265         return;
266     }
267
268     listlevel--;
269     while (mistack && mistack->level > listlevel) 
270     {
271         MacroInhibit *temp = mistack;
272         mistack = temp->next;
273         nasm_free (temp);
274     }
275 }
276
277 ListGen nasmlist = {
278     list_init,
279     list_cleanup,
280     list_output,
281     list_line,
282     list_uplevel,
283     list_downlevel
284 };