/* diagnostics.c */
#include "codegen.h"
#include "diagnostics.h"
#include "stdlib.h"
#include "vars.h"

/*	Dump the literal pool		*/
/** Test as DB "Str",0, .. Null terminated **/
/** litptr represents next free position in table **/
/** Table Entries are null terminated strings **/
/** Strings are from litq 0 up to litptr **/
void dumplits()
{
	int j,k;

	if (litptr == 0) return;			/* if nothing there, exit...*/
	sa_dseg();					/* Put back in data segment. */
	printlabel (litlab);				/* print literal label */
	k = 0;						/* init an index... */
	while (k < litptr)				/** loop thru literal strings buffer **/
	{						/** do one line per string **/
		j = 1;					/** instring flag, reset for each DB **/
		defbyte();				/** B.O.L. pseudo-op to define byte, DB**/
		if (litq[k]) foutput_chr(34);		/** start string with quote **/

		while (j)				/** j is control flag **/
		{
			if ((litq[k] & 127) == 0)  
			{				/** next is null **/
				if (j == 1)
				{ 			/** leading null is probably an error **/
					foutput_chr(',');
					foutput_chr('0');
					nl();		/** one str per DB, next line. **/
					j = 0; k++;
					break;
				}			/** break while, to ck j **/
			}
			else if ((litq[k] & 127) < ' ')
				k++;			/** filter lo **/
			else if ((litq[k] & 127) > '~')
				k++;			/** filter hi **/
			else
			{				/** xfer chr, lookahead for next is chr**/
				foutput_chr((litq[k++] & 127));
				if ((litq[k]& 127) == 0)
					foutput_chr(34);
			}
		}	/** EO Line **/
	}						/** gone thru Literals **/
	sa_cseg();					/* Put back in code segment. */
}
/** eo dumplits **/

/*	Dump all static variables	*/
/** modified for NASM 'TIMES amt D{B|W} 0' **/
void dumpstatics()
{
	int j;

	if (glbflag == 0) return;			/* don't if user said no */

	sa_dseg();					/* Put back in data segment. */
	symbptr = startstatic;

	while (symbptr < staticptr)
	{
		if (symbptr[IDENT] != FUNCTION)		/* do if anything but function */
		{
			asm_symb(symbptr);
							/* output name as label... */
			colon();
			def_sizein();			/** TIMES Prefix **/

			/* issue amount needed. */
			j = (	(symbptr[OFFSET] & 255) + 
				((symbptr[OFFSET+1] & 255) << 8) +
				((symbptr[OFFSET+2] & 255) << 16) +
				((symbptr[OFFSET+3] & 255) << 24) );

			/**	outdec(j);	**/
			/* need that many */
			if (j)
				outdec(j);		/** prevent TIMES 0 db 0 **/
			else
				outdec(1);

			/* issue assembler defn type... */
			if (symbptr[IDENT] == POINTER)		/* Pointer */
				defstorptr();
			else
			{
				if (symbptr[TYPE] == CCHAR)	/* Character */
					defstorchr();
				if (symbptr[TYPE] == CINT)	/* Integer */
					defstorint();
			}
			nl();
		}
		symbptr = symbptr + SYMB_SIZE;
	}
	sa_cseg();					/* Put back in code segment. */
}
/** eo dumpstatics **/

/*	Dump all auto variables		*/
/** dumped as comments to each function **/
void dumpautos()
{
	int j;

	if (ctext == 0) return; 			/** User said to skip.  **/
	symbptr = startauto;				/** Start at beginning. **/
	
	/** autoptr is the end, ptr to the next free **/
	while (symbptr != autoptr)
	{
		sa_comment();
		tab();
		asm_symb(symbptr);
							/* output name as label... */
		tab();
							/* issue assembler defn ident... */
		if (symbptr[IDENT] == VARIABLE)
			outstr("VAR");
		else if (symbptr[IDENT] == ARRAY)
			outstr("ARRAY");
		else if (symbptr[IDENT] == POINTER)
			outstr("PTR");
		else if (symbptr[IDENT] == FUNCTION)
			outstr("FUNC");
		
		tab();
							/* issue assembler defn type... */
		if (symbptr[TYPE] == CCHAR)
			outstr("CHAR");
		else if (symbptr[TYPE] == CINT)
			outstr("INT");
			
		tab();
							/* issue OFFSET. */
		j = ((symbptr[OFFSET] & 255)		  +
			((symbptr[OFFSET+1] & 255) << 8)  +
			((symbptr[OFFSET+2] & 255) << 16) +
			((symbptr[OFFSET+3] & 255) << 24));
		outdec(j);
		nl();
		symbptr = symbptr + SYMB_SIZE;
	}
}