/*
....[@@@..[@@@..............[@.................. MUD++ is a written from
....[@..[@..[@..[@..[@..[@@@@@....[@......[@.... scratch multi-user swords and
....[@..[@..[@..[@..[@..[@..[@..[@@@@@..[@@@@@.. sorcery game written in C++.
....[@......[@..[@..[@..[@..[@....[@......[@.... This server is an ongoing
....[@......[@..[@@@@@..[@@@@@.................. development project.  All 
................................................ contributions are welcome. 
....Copyright(C).1995.Melvin.Smith.............. Enjoy. 
------------------------------------------------------------------------------
Melvin Smith (aka Fusion)         msmith@falcon.mercer.peachnet.edu 
MUD++ development mailing list    mudpp-list@spice.com
------------------------------------------------------------------------------
file.cc
*/


#include "file.h"


void error( char * );

void InFile::error( const char * str )
{
	Cout << fname << ':' << getLineNo() << ": " << str << endl;
	exit(0);
}


char *InFile::getstring( char *buf )
{
	char *ch = buf;

	// Dont have to check eof() here, get returns 0 if EOF which isn't space
	while( isspace( get( *ch ) ) )
		;
 
	if( eof() )
	{
		*buf = '\0';
		return buf;
	}

	if( *ch == TERM_CHAR )
	{
		*ch = '\0';
		return buf;
	} 

	ch++;

	while( !eof() && ( get( *ch ) != TERM_CHAR ) )
		ch++; 

	if( eof() && *ch != TERM_CHAR )
		error( "getstring: TERM_CHAR not found - unexpected end of file");

	*ch = '\0';
	return buf;
}


int InFile::getnum()
{ 
	char buf[256];
	char *ch = buf;

	// Dont have to check eof() here, get returns 0 if EOF which isn't space
	while( isspace( get( *ch ) ) )
		;

	if( eof() )
	{
		*(++ch) = '\0';
		return atoi( buf );
	}
	
	if( !isdigit( *ch ) && *ch != '-' && *ch != '+' )
	{
		*(++ch) = '\0';
		printf( "buf so far =[%s]\n", buf );
		error("InFile::getnum.1() - non-numeric character");
	}

	while( isdigit( get( *(++ch) ) ) )
		;

	if( !eof() )
		putback();

	if( !eof() )
		while( isspace( get( *ch ) ) )
			if( *ch == '\n' )
				break;

	if( *ch != '\n' )
		putback();

	*ch = '\0';
	return atoi( buf );
}

unsigned long InFile::getlong()
{ 
	char  buf[256];
	char *ch = buf;

	// Dont have to check eof() here, get returns 0 if EOF which isn't space
	while( isspace( get( *ch ) ) )
		;

	if( !isdigit( *ch ) && *ch != '-' && *ch != '+' )
	{
		*(++ch) = '\0';
		printf( "buf so far =[%s]\n", buf );
		error("InFile::getnum.1() - non-numeric character");
	}

	while( isdigit( get( *(++ch) ) ) )
		;

	if( !eof() )
		putback();

	if( !eof() )
		while( isspace( get( *ch ) ) )
			if( *ch == '\n' )
				break;

	if( *ch != '\n' )
		putback();

	*ch = '\0';
	return atol( buf );
}


// For my database scheme the chars '{', '}', '#', ';' are
// considered words. getword treats them that way
// getstring does not, using '~` to end strings
// This is mainly for multiline strings.

char *InFile::getword  ( char *buf )
{
	char *ch = buf;
  
	// Dont have to check eof() here, get returns 0 if EOF which isn't space
	while( isspace( get( *ch ) ) )
		;
  
	if( *ch == '{' || *ch == '}' || *ch == '#' || *ch == ';' )
	{
		*(ch+1) = '\0';
		return buf;
	}

	while( !eof() && !isspace( get( *++ch ) ) )
		if( *ch == '{' || *ch == '}' )
		{
			putback(); 
			break;
		}

	*ch = '\0';
	return buf;
}


// Bit fields are written in file in the following format:
//
// <number of fields N> <field 1> <field2> ... <fieldN>
//
void InFile::getbitfield( unsigned long * field )
{
	int fields = getnum();
	for( int i = 0; i < fields; i++ )
	{
		field[i] = getlong();
	} 
}