 /*
 |  Stuff
*/

#include <stdarg.h>

#include <sys/hardware.h>
#include <sys/useful.h>
#include <sys/types.h>
#include <sys/unix.h>


char *memcpy( dst, src, len )
char	*src,
	*dst;
int	len;
{
	while(len--)
		*dst++=*src++;
}


int atoi( str )
char	*str;
{
	return( btoi( str, 10, "0123456789" ) );
}

int aotoi( str )
char	*str;
{
	return( btoi( str, 8, "01234567" ) );
}

static int cpos( s, c )
char	*s;
char	c;
{
	int	pos = 0;
	while( *s )
	{
		if( *s++ == c )
			return( pos );
		pos++;
	}
	return( -1 );
}

int btoi( str, base, digits )
char	*str,
	*digits;
int	base;
{
	int	sgn = 1;
	int	res = 0;
	char	c;
	int	num;

	while( *str )
	{
		c=*str++;
		if( c == '-' )
		{
			sgn = -sgn;
			continue;
		}
		num = cpos( digits, c );
		if( num != -1 )
			res = (res*base)+num;
		else
			break;
	}
	return( res*sgn );
}


int strcmp( s1, s2 )
char	*s1,
	*s2;
{
	while( *s1 == *s2 )
		if( (*s1++==0) || (*s2++==0) )
			return 0;
	if( *s1 > *s2 )
		return 1;
	return -1;
}


int strlen( s1 )
char	*s1;
{
	int	len = 0;
	while( *s1++ )
		len++;
	return( len );
}


int strcpy( s1, s2 )
char	*s1,
	*s2;
{
	while( *s2 )
		*s1++=*s2++;
	*s1=0;
}


int strcat( s1, s2 )
char	*s1,
	*s2;
{
	while( *s1 )
		s1++;
	strcpy( s1, s2 );
}


int sscanf( line, fmt )
char	*line;
char	*fmt;
{
	va_list	arg;
	char	str[32];
	char	*spos;
	char	c;

	va_start( arg, fmt );

	while( c = *fmt++ )
	{
		if( c != '%' )
		{
			if( c != *line++ )
				return;
			continue;
		}
		switch( c = *fmt++ )
		{
			case 's':
				spos = str;
				while( c=*spos=*line, c && c!=32 && c!=9 && c!=10 )
					{ spos++; line++; }
				*spos = 0;
				strcpy( va_arg(arg,char*), str );
				break;
			case 'i':
				*(va_arg(arg,int*)) = atoi( line );
				while( cins( "-0123456789", *line ) )
					line++;
				break;
		}
	}
}

/* Character in a string? */
static int cins( s, c )
char	*s;
char	c;
{
	while( *s )
		if( *s++ == c )
			return( 1 );
	return( 0 );
}



 /*
 |  Renders an integer as a string in a particular base
 |  Returns the string it creates (space provived by 2nd param)
*/
static char *itob( val, str, base )
int	val,
	base;
char	*str;
{
	char	*digits = "0123456789abcdef";
	char	*this = str+7;	/* Start at end of string */
	int	nflag = 0;	/* Add a '-' if this is set */
	*this     = 0;
	if( base<0 )
	{
		base = -base;
		if( val<0 )
		{
			val = -val;
			nflag = 1;
		}
	}
	if( base == 0 )
	{
		base = 10;
	}
	do {
		*(--this) = *(digits+val%base);
		val /= base;
	} while( val );
	if( nflag )
		*--this = '-';
		
	return( this );
}

static int puts( f, str )
int	f;
char	*str;
{
	int len=0;
	while( *str )
	{
		write( f, str++, 1 );
		len++;
	}
	return( len );
}


/* Short version of printf to save space */
int fprintf( f, fmt /* , ... */ )
int	f;
char	*fmt;
{
	va_list	arg;
	char	c;
	int	base;
	char	s[7],
		*itob();
	int	len, donelen;

	va_start( arg, fmt );

	while( c = *fmt++ )
	{
		if( c != '%' )
		{
			write( f, &c, 1 );
			continue;
		}
		if( *fmt == '%' )
		{
			c = '%';
			write( f, &c, 1 );
			fmt++;
			continue;
		}
		if( *fmt == '-' )
		{
			len = atoi( ++fmt );	/* 0 if nun-numeric */
			if(!len)
				len=1;
			while( c=*fmt++, c>47 && c<58 );
			fmt--;
		}
		else
			len=0;
		switch( c = *fmt++ )
		{
			case 'c':
				c = va_arg(arg,int);
				write( f, &c, 1 );
				donelen=1;
				break;
			case 'd':
			case 'i':
				base = -10;
				goto prt;
			case 'o':
				base = 8;
				goto prt;
			case 'u':
				base = 10;
				goto prt;
			case 'x':
				base = 16;
			prt:
				donelen = puts( f, itob( va_arg(arg,int), s, base) );
				break;
			case 's':
				donelen = puts( f, va_arg(arg,char*) );
				break;
			default:
				write( f, &c, 1 );
				donelen = 1;
				break;
		}
		while( len-(donelen++) > 0 )
		{
			c=' ';
			write( f, &c, 1 );
		}
	}
}


