/* Copyright (c) 1988 by Sozobon, Limited.  Author: Tony Andrews
 *
 * Permission is granted to anyone to use this software for any purpose
 * on any computer system, and to redistribute it freely, with the
 * following restrictions:
 * 1) No charge may be made other than reasonable charges for reproduction.
 * 2) Modified versions must be clearly marked as such.
 * 3) The authors are not responsible for any harmful consequences
 *    of using this software, even if they result from defects in it.
 */

/*
 * Changes by Jeff Lydiatt to handle Amiga-specific stuff marked Jal.
 */

#include "top.h"
/*
 * Low-level i/o routines.
 */

/*
 * mode tells what kind of stuff we're reading at the moment.
 */
static	int	mode;

#define	BSS	0
#define	DATA	1
#define	TEXT	2

static	char	*mnames[] = { /*Jal*/
	"BSS",
	"DATA",
	"CODE"
};

/*
 * Tokens from the current line...
 */
char	*t_line;		/* the entire line */
char	*t_lab;			/* label, if any */
char	*t_op;			/* opcode */
char	*t_arg;			/* arguments */

#define	ISWHITE(c)	((c) == '\t' || (c) == ' ' || (c) == '\n')

#define	LSIZE	2048	/* max. size of an input line */

/*
 * readline() - read the next line from the file
 *
 * readline passes data and bss through to the output, only returning
 * when a line of text has been read. Returns FALSE on end of file.
 */
bool
readline()
{
	char	*fgets();
	static	void	tokenize();
	static	char	buf[LSIZE];

	/*
	 * Keep looping until we get a line of text
	 */
	for (;;) {
		if (fgets(buf, LSIZE, ifp) == NULL)
			return FALSE;
	
		t_line = buf;
	
		/*
		 * Find out if the mode is changing.
		 */
		tokenize(buf);
	
		/* is it a pseudo-op? */
		if (stricmp(t_op, mnames[BSS]) == 0){
			mode = BSS;
			newBSS(t_arg);
			continue;
		}
		else if (stricmp(t_op, mnames[DATA]) == 0){
			mode = DATA;
			newDATA(t_arg);
			continue;
		}
		else if (stricmp(t_op, mnames[TEXT]) == 0) {
			mode = TEXT;
			continue;
		}
		else if (stricmp(t_op, "END") == 0) /*Jal*/
			continue; /* eat an end. */

		else if ( stricmp(t_op, "XDEF") == 0
			||stricmp(t_op, "XREF") == 0 ){
			store(-1);
			continue;
		}

		if (mode == TEXT){ /*Jal - implement noopt option */
			if ( noopt )
				fputs( buf, ofp );
			else
				return TRUE;
		}
		else
			store(mode);
	}
}

static void
tokenize(s)
register char	*s;
{
	static	char	label[LSIZE], opcode[LSIZE], args[LSIZE];
	register int	i;

	/*
	 * Grab the label, if any
	 */
	i = 0;
	while (*s && !ISWHITE(*s) && *s != ':')
		label[i++] = *s++;
	label[i] = '\0';

	if (*s == ':')
		s++;

	while (ISWHITE(*s))
		s++;

	/*
	 * Grab the opcode
	 */
	i = 0;
	while (*s && !ISWHITE(*s))
		opcode[i++] = *s++;
	opcode[i] = '\0';

	while (ISWHITE(*s))
		s++;

	/*
	 * Grab the arguments
	 */
	i = 0;
	while (*s && !ISWHITE(*s))
		args[i++] = *s++;
	args[i] = '\0';

	t_lab = label;
	t_op = opcode;
	t_arg = args;
}
