/* driver.c */
#include "codegen.h"
#include "error.h"
#include "driver.h"
#include "lex.h"
#include "parse.h"
#include "vars.h"
#include "stdlib.h"

/*	Get options from user	*/
void ask()
{
	int k, num[1];

	kill();										/* clear input line */
	nl();
	nl();										/* print banner */
	pl(BANNER);
	nl();
	pl(AUTHOR);
	nl();
	nl();
	pl("* NASM Version, 26-Mar-2010 *");
	nl();
	pl(VERSION);
	nl();
	nl();

	/*
		see if user wants to interleave the c-text
		in form of comments (for clarity).
	*/
	pl("Do you want the c-text to appear (y,N) ? ");
	gets(line);									/* get answer */
	ctext = 0;									/* assume no */
	if ((inspect_chr()=='Y')|(inspect_chr()=='y'))
		ctext = 1;								/* user said yes */

	/* see if the user is compiling everything at once (as is usually the case) */
	pl("Are you compiling the whole program at once (Y,n) ? ");
	gets(line);
	if ((inspect_chr() != 'N') & (inspect_chr() != 'n'))
	{											/* single file - assume... */
		glbflag = 1;  							/* define globals */
		mainflg = 1;  							/* first file to assembler */
		nxtlab  = 0;  					/* start numbers at lowest possible */
	}
	else
	{		
		/* 
			one of many - ask everything.
	 		see if user wants us to allocate static
	 		variables by name in this module (pseudo external capability)
	 	*/
	 	pl("Do you want the globals to be defined (y,N) ? ");
	 	gets(line);
		glbflag = 0;
	 	if ((inspect_chr() == 'Y') | (inspect_chr() == 'y'))
	 		glbflag = 1;						/* user said yes */

	 	/* see if we should put out the stuff needed for the first asm file */
		pl("Is the output file the first one the assembler will see (y,N) ? ");
	 	gets(line);
	 	mainflg = 0;
		if ((inspect_chr() == 'Y') | (inspect_chr() == 'y'))
	 		mainflg = 1;

	 	/* get first allowable number for compiler-generated */
	 	/* labels (in case user will append modules) */
		while (1)
		{
	 		pl("Starting number for labels (0) ? ");
	 		gets(line);
	 		if (inspect_chr() == 0)
			{
				num[0] = 0;
				break;
			}
			if (k = number(num))
				break;
	 	}
	 	nxtlab = num[0];
	}

	/* see if user wants to be sure to see all errors */
	pl("Should I pause after an error (y,N) ? ");
	gets(line);
	errstop = 0;
	if ((inspect_chr() == 'Y') | (inspect_chr() == 'y'))
		errstop = 1;

	litlab = getlabel();					/* first label=literal pool */ 
	kill();									/* erase line */
}

/* Get output filename */
void openout()
{
	kill();									/* erase line */
	fp_output = 0;							/* start with none */
	pl("Output filename? ");				/* ask...*/
	gets(line);								/* get a filename */
	if (inspect_chr() == 0) return;			/* none given... */
	/* if given, open */
	if ((fp_output = fopen(line,"w")) == NULL)
	{
		fp_output = 0;						/* can't open */
		error("Open failure!");
	}
/*** TBI, else output filename to asm file, & for MAP ***/
	
	kill();									/* erase line */
}

/*	Get (next) input file	*/
void openin()
{
	fp_input = 0;							/* none to start with */
	while (fp_input == 0)					/* any above 1 allowed */
	{
		kill();								/* clear line */
		if (eof_flg) break;					/* if user said none */
		pl("Input filename? (..or just [Enter] key to finish.) > ");
		gets(line);							/* get a name */
		if (inspect_chr() == 0)
		{
			eof_flg = 1;
			break;
		} 									/* none given... */
		if ((fp_input = fopen(line,"r")) != NULL)
			newfile();
		else
		{
			fp_input = 0;					/* can't open it */
			pl("Open failure");
		}
	}
	kill();									/* erase line */
}

/*	Reset line count, etc.	*/
void newfile()
{
	lineno  = 0;							/* no lines read */
	fnstart = 0;							/* no fn. start yet. */
	currfn  = NULL;							/* because no fn. yet */
	infunc  = 0;							/* therefore not in fn. */
}

/** added tmp array for filename instead of input_line ptr to handle CR **/
/* static char fname_array[30]; */

/* Open an include file	*/
void doinclude()
{
	int i;
	char *src;

	deblank();								/* skip over to name */
	toconsole();
	outstr("#include ");
	outstr(line+lptr);

	i = 0;
	src = line+lptr;			/** copy input_line filename to prep array **/
	while (*src != CR)
	{
		fname_array[i++] = *src++;
	}
	fname_array[i] = 0;						/** null terminate str **/

	nl();
	tofile();

	if (fp_input2)
		error("Cannot nest include files");
	else if ((fp_input2 = fopen(&fname_array[0],"r")) == NULL)
	{
		fp_input2 = 0;
		error("Open failure on include file");
	}
	else
	{
		saveline = lineno;
		savecurr = currfn;
		saveinfn = infunc;
		savestart= fnstart;
		newfile();
	}
	/* clear rest of line so next read will come from new file (if opened) */
	kill();
}

/* Close an include file */
void endinclude()
{
	toconsole();
	outstr("#end include");
	nl();
	tofile();

	fp_input2  = 0;
	lineno  = saveline;
	currfn  = savecurr;
	infunc  = saveinfn;
	fnstart = savestart;
}

/* Close the output file */
void closeout()
{
	tofile();								/* if diverted, return to file */
	if (fp_output)
		fclose(fp_output);					/* if open, close it */
	fp_output = 0;							/* mark as closed */
}