/* stdlib.c */
#include "ctype.h"
#include "driver.h"
#include "error.h"
#include "lex.h"
#include "preprocess.h"
#include "stdlib.h"
#include "vars.h"

/*	Abort compilation
abort()
{
	int j,k;

	if (fp_input2) endinclude();
	if (fp_input)  fclose(fp_input);
	closeout();
	toconsole();
	pl("Compilation aborted.");  nl();
	exit();
}
	End abort */

/* Print a carriage return and a string only to console */
void pl(char* str)
{
	int k;

	k = 0;
	putchar(EOL);
	while (str[k])
		putchar(str[k++]);
}

/* direct output to console */
void toconsole()
{
	saveout = fp_output;
	fp_output = 0;
}

/* direct output back to file */
void tofile()
{
	if(saveout)
		fp_output = saveout;
	saveout = 0;
}

/** FILE output **/
char foutput_chr(char c)
{
	if (c == 0)
		return 0;
	
	if (fp_output)
	{
		/** put to file, output **/
		if ((putc(c, fp_output)) <= 0)
		{
			closeout();
			error("Output file error");
			/*abort();*/
		}
	}
	else
		putchar(c);
	
	return c;
}

void outstr(char* ptr)
{
	int k;
	k = 0;
	while (foutput_chr(ptr[k++]))
		;
}

/** returns zero if no match, otherwise > 0 = str length. **/
/** str2 is null terminated, which is the limit of comparing. **/
/** in effect, str2 is contained in str1. **/
int streq(char* str1, char* str2)
{
	int k;

	k = 0;
	while (str2[k])
	{
		if ((str1[k]) != (str2[k]))
			return 0;
		k++;
	}
	return k;
}

/** alphanumeric string match, 0 is mismatch, else len **/
int astreq(char* str1, char* str2, int len)
{
	int k;
	k = 0;
	while (k < len)
	{
		if ((str1[k]) != (str2[k]))
			break;
		if (str1[k] == 0)
			break;
		if (str2[k] == 0)
			break;
		k++;
	}
	
	/** mismatch before eos **/
	if (an(str1[k]))
		return 0;
	
	/** mismatch before eos **/
	if (an(str2[k]))
		return 0;
	
	return k;
}

int match(char* lit)
{
	int k;
	deblank();
	if (k = streq(line + lptr, lit))
	{
		/** lit is null terminated, eos, for compare **/
		lptr = lptr + k;
		return 1;
	}
 	return 0;
}

int amatch(char* lit, int len)
{
	int k;
	deblank();
	if (k = astreq(line + lptr, lit, len))
	{
		lptr = lptr + k;
		while (an(inspect_chr()))
			scan_nxt();
		return 1;
	}
	return 0;
}

/* Note: added filter of CR for filesystems where NL is CR,LF.
** The parsing strategy is to make each \n into a null, so
** each line is a null terminated string.  This routine scans
** thru the line buffer removing leading space, tab, CR, and
** requests new string if a null is inlined.
*/
void deblank()
{
	int a;

	a = 1;
	while (a == 1)
	{
		while (inspect_chr()==0)
		{
			input_line();
			/** calls input_line, so? **/
			preprocess();
			if (eof_flg)
				break;
		}
		if (inspect_chr() == ' ')
			g_nxtchr();
		else if (inspect_chr() == 9)
			g_nxtchr();
		else if (inspect_chr() == CR)
			g_nxtchr();
		else
			return;
	}
}