listing.c
上传用户:yuppie_zhu
上传日期:2007-01-08
资源大小:535k
文件大小:6k
源码类别:

编译器/解释器

开发平台:

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