/* 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.
 */
#include "top.h"

/*
 * Low-level i/o routines.
 */

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

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

static	char	*mnames[] = {
#ifdef NORTHC
	"bss",
	"data",
	"code"
#else
	".bss",
	".data",
	".text"
#endif
};

/*
 * 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 */

static	void	tokenize();

/*
 * 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.
 */

#ifdef NORTHC
static	char	buf[LSIZE];
extern  int out_code;
#endif

bool
readline()
{
	char	*fgets();
#ifndef NORTHC
	static	char	buf[LSIZE];
#endif

	/*
	 * 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);

#ifdef NORTHC
		/* is it a pseudo-op? */
                if(stricmp(t_op,"SECTION")==0)
                   {/* New section, find out what type */
                    char typeStr[5];
                    char *parser = t_arg;
                    int  i;

                    /* The section type is the second argument */
                    while(*parser!=',' && *parser!='\0')
                        parser++;
                    if(parser!='\0')
                       {parser++;
                        i = 0;
                        while(isalpha(*parser) && i<4)
                           {typeStr[i] = *parser;
                            parser++;
                            i++;
                            }
                        typeStr[i] = '\0';
   	  	        if(stricmp(typeStr,mnames[BSS])==0)
                           {mode = BSS;
/*                            out_code = 0;
			    newBSS(t_arg); */
			    continue;
                            }
		          else if(stricmp(typeStr,mnames[DATA])==0)
                           {mode = DATA;
/*                            out_code = 0;
			    newDATA(t_arg); */
			    continue;
                            }
		          else if(stricmp(typeStr,mnames[TEXT])==0)
                           {mode = TEXT;
                            continue;
                            }
                        }
                    }
		  else if(stricmp(t_op, "END" ) == 0)
		    continue;
		  else if(stricmp(t_op, "XDEF" ) == 0)
		   {fputs(buf, ofp);
                    continue;
                    }
#else
		if (t_op[0] == '.') {		/* is it a pseudo-op? */
			if (strcmp(t_op, mnames[BSS]) == 0)
				mode = BSS;
			else if (strcmp(t_op, mnames[DATA]) == 0)
				mode = DATA;
			else if (strcmp(t_op, mnames[TEXT]) == 0) {
				mode = TEXT;
				continue;
			}
		}
#endif
		if (mode == TEXT)
		    return TRUE;
/*		fputs(buf, ofp); */
		store(mode);
	}
}

#ifdef NORTHC
static	char	label[LSIZE], opcode[LSIZE], args[LSIZE];
#endif

static void
tokenize(s)
register char	*s;
{
#ifndef NORTHC
	static	char	label[LSIZE], opcode[LSIZE], args[LSIZE];
#endif
	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;
}
