#include "safestring.h"
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>

char *	strsafecpy( char * dest, const char * src, int size )
{
	if ( src==dest ) return dest;
	if ( size<=0 ) return dest;
	dest[0] = 0;
	if ( !src ) return dest;

	int len = strlen( src );

	if ( len>=size )
		len = size-1;		// to be safe

	strncpy( dest,  src, len );
	dest[ len ] = 0;

	return dest;
}

char *	strnsafecpy( char * dest, const char * src, int n, int size )
{
	if ( size<=0 ) return dest;
	dest[0] = 0;
	if ( !src ) return dest;

	if ( n>=size )
		n = size-1;

	strncpy( dest, src, n );
	dest[ n ] = 0;

	return dest;
}


char *	strsafecat( char * dest, const char * src, int size )
{
	int len = strlen( src );
	int start = strlen(dest);
	size -= start;

	if ( len>=size )
		len = size-1;		// to be safe

	strncat( dest,  src, len );
	dest[ start+len ] = 0;

	return dest;
}


char * strnsafecat( char * dest, const char * src, int n, int size )
{
	int len = strlen( src );
	if ( n<len ) len = n;

	int start = strlen(dest);
	size -= start;

	if ( len>=size )
		len = size-1;		// to be safe

	strncat( dest,  src, len );
	dest[ start+len ] = 0;

	return dest;
}


char *  strcatf( char * dest, int size, const char * fmt, ... )
{
	va_list ap;
	va_start( ap, fmt );

	int len = strlen( dest );

	if ( size-len > 0 )
		vsnprintf( &dest[len], size-len, fmt, ap );

	dest[ size-1 ] = 0;

	va_end( ap );

	return dest;
}


char * toupper( char * s, char * dest/*=NULL*/, int sz/*=0*/ )
{
    if (!s) return NULL;
    char *c = s;
    char *d = dest?dest:s;

    while (*c) {
	if (d-dest>=sz-1) break;
	*d = toupper(*c);
	c++; d++;
    }

    *d = 0;

    return dest?dest:s;
}

char * tolower( char * s, char * dest/*=NULL*/, int sz/*=0*/ )
{
    if (!s) return NULL;
    char *c = s;
    char *d = dest?dest:s;

    while (*c) {
        if ( dest  &&  (d-dest>=sz-1) ) break;
        *d = tolower(*c);
        c++; d++;
    }

    *d = 0;

    return dest?dest:s;
}


char * toupper( const char * s, char * dest, int sz )
{
	return toupper( (char*)s, dest, sz );
}


char * tolower( const char * s, char * dest, int sz )
{
	return tolower( (char*)s, dest, sz );
}


char * last_line( char * buf )	// find the last line and return the pointer to its beginning
{
	char * line = buf, *bufend = buf + strlen(buf);

	while ( char * c = strpbrk( line, "\r\n" ) )
	{
		c += strspn( c, "\r\n" );

		if ( c==bufend )
			return line;

		line = c;
	}

	return line;
}


char * safestrdup( const char *s )
{
	return s ? strdup( s ) : NULL;
}


char * strreverse( char *s )
{
	int len = strlen(s);
	int end = len/2;
	unsigned char c;

	for ( int i=0; i<end; i++ )
	{
		c = s[i];
		s[i] = s[len-i-1];
		s[len-i-1] = c;
	}

	return s;
}

