home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / nasm097s.zip / LISTING.C < prev    next >
C/C++ Source or Header  |  1997-10-01  |  6KB  |  241 lines

  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.     if (!listlinep && !listdata[0])
  55.     return;
  56.     fprintf(listfp, "%6ld ", ++listlineno);
  57.     if (listdata[0])
  58.     fprintf(listfp, "%08lX %-*s", listoffset, LIST_HEXBIT+1, listdata);
  59.     else
  60.     fprintf(listfp, "%*s", LIST_HEXBIT+10, "");
  61.     if (listlevel_e)
  62.     fprintf(listfp, "%s<%d>", (listlevel < 10 ? " " : ""), listlevel_e);
  63.     else if (listlinep)
  64.     fprintf(listfp, "    ");
  65.     if (listlinep)
  66.     fprintf(listfp, " %s", listline);
  67.     fputc('\n', listfp);
  68.     listlinep = FALSE;
  69.     listdata[0] = '\0';
  70. }
  71.  
  72. static void list_init (char *fname, efunc error) {
  73.     listfp = fopen (fname, "w");
  74.     if (!listfp) {
  75.     error (ERR_NONFATAL, "unable to open listing file `%s'", fname);
  76.     return;
  77.     }
  78.     *listline = '\0';
  79.     listlineno = 0;
  80.     listp = TRUE;
  81.     listlevel = 0;
  82.     suppress = 0;
  83.     mistack = nasm_malloc(sizeof(MacroInhibit));
  84.     mistack->next = NULL;
  85.     mistack->level = 0;
  86.     mistack->inhibiting = TRUE;
  87. }
  88.  
  89. static void list_cleanup (void) {
  90.     if (!listp)
  91.     return;
  92.     while (mistack) {
  93.     MacroInhibit *temp = mistack;
  94.     mistack = temp->next;
  95.     nasm_free (temp);
  96.     }
  97.     list_emit();
  98.     fclose (listfp);
  99. }
  100.  
  101. static void list_out (long offset, char *str) {
  102.     if (strlen(listdata) + strlen(str) > LIST_HEXBIT) {
  103.     strcat(listdata, "-");
  104.     list_emit();
  105.     }
  106.     if (!listdata[0])
  107.     listoffset = offset;
  108.     strcat(listdata, str);
  109. }
  110.  
  111. static void list_output (long offset, void *data, unsigned long type) {
  112.     long typ, size;
  113.  
  114.     if (!listp || suppress)
  115.     return;
  116.  
  117.     typ = type & OUT_TYPMASK;
  118.     size = type & OUT_SIZMASK;
  119.  
  120.     if (typ == OUT_RAWDATA) {
  121.     unsigned char *p = data;
  122.     char q[3];
  123.     while (size--) {
  124.         HEX (q, *p);
  125.         q[2] = '\0';
  126.         list_out (offset++, q);
  127.         p++;
  128.     }
  129.     } else if (typ == OUT_ADDRESS) {
  130.     unsigned long d = *(long *)data;
  131.     char q[11];
  132.     unsigned char p[4], *r = p;
  133.     if (size == 4) {
  134.         q[0] = '['; q[9] = ']'; q[10] = '\0';
  135.         WRITELONG (r, d);
  136.         HEX (q+1, p[0]);
  137.         HEX (q+3, p[1]);
  138.         HEX (q+5, p[2]);
  139.         HEX (q+7, p[3]);
  140.         list_out (offset, q);
  141.     } else {
  142.         q[0] = '['; q[5] = ']'; q[6] = '\0';
  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_REL2ADR) {
  149.     unsigned long d = *(long *)data;
  150.     char q[11];
  151.     unsigned char p[4], *r = p;
  152.     q[0] = '('; q[5] = ')'; q[6] = '\0';
  153.     WRITESHORT (r, d);
  154.     HEX (q+1, p[0]);
  155.     HEX (q+3, p[1]);
  156.     list_out (offset, q);
  157.     } else if (typ == OUT_REL4ADR) {
  158.     unsigned long d = *(long *)data;
  159.     char q[11];
  160.     unsigned char p[4], *r = p;
  161.     q[0] = '('; q[9] = ')'; q[10] = '\0';
  162.     WRITELONG (r, d);
  163.     HEX (q+1, p[0]);
  164.     HEX (q+3, p[1]);
  165.     HEX (q+5, p[2]);
  166.     HEX (q+7, p[3]);
  167.     list_out (offset, q);
  168.     } else if (typ == OUT_RESERVE) {
  169.     char q[20];
  170.     sprintf(q, "<res %08lX>", size);
  171.     list_out (offset, q);
  172.     }
  173. }
  174.  
  175. static void list_line (int type, char *line) {
  176.     if (!listp)
  177.     return;
  178.     if (mistack && mistack->inhibiting) {
  179.     if (type == LIST_MACRO)
  180.         return;
  181.     else {                   /* pop the m i stack */
  182.         MacroInhibit *temp = mistack;
  183.         mistack = temp->next;
  184.         nasm_free (temp);
  185.     }
  186.     }
  187.     list_emit();
  188.     listlinep = TRUE;
  189.     strncpy (listline, line, LIST_MAX_LEN-1);
  190.     listline[LIST_MAX_LEN-1] = '\0';
  191.     listlevel_e = listlevel;
  192. }
  193.  
  194. static void list_uplevel (int type) {
  195.     if (!listp)
  196.     return;
  197.     if (type == LIST_INCBIN || type == LIST_TIMES) {
  198.     suppress |= (type == LIST_INCBIN ? 1 : 2);
  199.     list_out (listoffset, type == LIST_INCBIN ? "<incbin>" : "<rept>");
  200.     return;
  201.     }
  202.     listlevel++;
  203.     if (mistack && mistack->inhibiting && type == LIST_INCLUDE) {
  204.     MacroInhibit *temp = nasm_malloc(sizeof(MacroInhibit));
  205.     temp->next = mistack;
  206.     temp->level = listlevel;
  207.     temp->inhibiting = FALSE;
  208.     mistack = temp;
  209.     } else if (type == LIST_MACRO_NOLIST) {
  210.     MacroInhibit *temp = nasm_malloc(sizeof(MacroInhibit));
  211.     temp->next = mistack;
  212.     temp->level = listlevel;
  213.     temp->inhibiting = TRUE;
  214.     mistack = temp;
  215.     }
  216. }
  217.  
  218. static void list_downlevel (int type) {
  219.     if (!listp)
  220.     return;
  221.     if (type == LIST_INCBIN || type == LIST_TIMES) {
  222.     suppress &= ~(type == LIST_INCBIN ? 1 : 2);
  223.     return;
  224.     }
  225.     listlevel--;
  226.     while (mistack && mistack->level > listlevel) {
  227.     MacroInhibit *temp = mistack;
  228.     mistack = temp->next;
  229.     nasm_free (temp);
  230.     }
  231. }
  232.  
  233. ListGen nasmlist = {
  234.     list_init,
  235.     list_cleanup,
  236.     list_output,
  237.     list_line,
  238.     list_uplevel,
  239.     list_downlevel
  240. };
  241.