/*  Copyright (C) 1987- Leon Bottou
 * 
 *  This is free documentation; you can redistribute it and/or
 *  modify it under the terms of the GNU General Public License as
 *  published by the Free Software Foundation; either version 2 of
 *  the License, or (at your option) any later version.
 * 
 *  The GNU General Public License's references to "object code"
 *  and "executables" are to be interpreted as the output of any
 *  document formatting or typesetting system, including
 *  intermediate and printed output.
 * 
 *  This manual is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 * 
 *  You should have received a copy of the GNU General Public
 *  License along with this manual. Otherwise check the web site
 *  of the Free Software Foundation at http://www.fsf.org.
 */
/*
	CRASM: xref.c
	sorties des references croisees
	LYB 9/87
*/


#include "dcl.h"
#include "label.h"
extern unsigned long pc,codelen;
extern int segment;


#define RECLEN (LABLEN+13)
char *msgs[] =
{ "Undefined","Mnemonic","Macro","Abs","Rel","Register(s)","Bit%d" };

void
printlabel(struct label *label)
{
	char buffer[RECLEN+2];
	char *s,*b;
	int newpos;
	register int i;
	
 	if ( lpos+RECLEN >= llen)
		outputEOL();
	newpos=lpos+RECLEN;
	
	if (label->type != L_ABSOLUTE && label->type != L_RELATIVE )
		if (label->flags & NOREDEF)
			return;
	if  (label->type <0 )
		label->type = 1;
	if  (label->name[0] == '*' || label->name[0] <= '9' )
		return;
	if  ((label->flags & UNDEF) && !(label->flags & FORWARD))
		label->type = 0;

	s=label->name;
	i=label->type;
	i= (i==3 || i==4 || i==6);

	if (! (label->flags & USED))
		outputcar('?');
	else if (label->flags & FORWARD)
		outputcar('^');
	else
		outputcar(' ');
		
	if ( i )
		outputaddr(label->value);

	sprintf(buffer,msgs[label->type],label->modifier);
	position(newpos-LABLEN-2-strlen(buffer));
	output(buffer);

	position(newpos-LABLEN-1);
	b=buffer;
	for (i=0; i<LABLEN && *s ; i++)
			*b++ = *s++;
	*b=0;
	output(buffer);
	position(newpos);
}


static void
xref2(struct label *label)
{
	if (label)
	{
		xref2 ( label->left );
		printlabel( label );
		xref2 ( label->right );
	};
}


void
result(void)
{
	extern int errnumber,warnnumber;
	char buffer[40];
	
	
	if ( plen-ppos < 10 )
	{	outputEOP();
		outputEOL(); outputEOL();
	};
	outputEOL();
	sprintf(buffer,"ERRORS:    %4d",errnumber);
	output(buffer); outputEOL();
	sprintf(buffer,"WARNINGS:  %4d",warnnumber);
	output(buffer); outputEOL(); outputEOL();
	if ( !errnumber )
	{	output( "Successful assembly..." );
		outputEOL();
		sprintf(buffer," Last address %8lx (%ld)",pc-1,pc-1);
		output(buffer); outputEOL();
		sprintf(buffer," Code length  %8lx (%ld)",codelen,codelen);
		output(buffer); outputEOL();
	}
	else
	{	output( "No code generated..." );
		outputEOL();
	}
}


void
xref(void)
{
	outputEOP();
	xref2(lroot);
	outputEOL();
	outputEOP();
}
