/****************************************************************************/
/*	Copyright (c) 2009, Bendor Research Pty. Ltd. All rights reserved.		*/
/*	This software is released under the GNU General Public License, version	*/
/*	3, with the exemptions that 1) the header files installed by this 	 	*/
/*	package can be included in closed-source code and 2) the libraries		*/
/*	built by this package can be statically linked into a closed-source 	*/
/*	binary. See the file LICENSE for the details.							*/
/*	This software is provided "AS IS", without any warranty or guarantee.	*/
/*	By using this software you acknowledge that neither Bendor Research nor	*/
/*	any of its personnel or affiliates can be held liable for any damages,	*/
/*	including, but not limited to, loss of business, loss of money, loss of */
/*	life, loss of reputation, arising out of this software being faulty or	*/
/*	not performing as advertised, even if Bendor Research was aware of such	*/
/*	faults in the software. You use this software at your own risk, any and */
/*	all liabilities that arise out of your using this software are strictly	*/
/*	yours.																	*/
/****************************************************************************/

#include <stdlib.h>
#include <blc_stdlib.h>

/** @addtogroup stdlib */
/** @{ */

/**
*	Convert a string to a signed long number.
*
*	The function is identical in semantics to the strtole() function
*	except that it does not provide a feedback on overflow conditions.
*
*	@param	nptr	Pointer to the string to convert.
*	@param	eptr	Pointer to a location to store the address of the
*					first character that was not converted. NULL is allowed.
*	@param	base	The conversion base, must be 0 or between 2 and 36.
*
*	@return			The numeric result of the conversion, if it was successful,
*					the largest 32-bit unsigned integer if there was an overflow
*					and undetermined, if there was a conversion error.
*/

long	strtol( const char *nptr, char **eptr, int base )
{
	return( strtole( nptr, eptr, base, (void *) 0 ) );
}

/**
*	Convert a string to a signed long number.
*
*	The function processes the string pointed by the \p nptr parameter.
*	Initial whitespace is skipped, then a possible '+' or '-' signum is
*	processed. Following that, characters that are valid digits in the
*	radix specified by \p base will be processed. The conversion stops
*	if a character that is not a valid digit in the givern radix is
*	encountered. The returned value is the converted number, or 0 if
*	there was an error.
*
*	If the \p eptr argument is not NULL, then a pointer to the character
*	that was rejected will be stored at the location it points to. If there
*	was no conversion, then the original pointer to the string will be
*	stored.
*
*	If the conversion overflows, then the function returns the largest
*	32-bit positive or negative (if a '-' was present) signed integer.
*	If the \p optr argument is not NULL, then a non-zero value will be
*	stored at the pointed location if there was an overflow, and 0 if
*	there was not.
*
*	The conversion radix must be between 2 and 36, inclusive. If the radix
*	is out of range, then no conversion will take place. If the conversion
*	radix is 16, then the sequence of digits can start with 0x or 0X, the
*	x character is only processed if it is actually followed by at least
*	one hexadecimal digit. A special case of the radix being 0 is also allowed.
*	In that case if the digit sequence starts with 0x or 0X, then base-16
*	conversion takes place, otherwise if the sequence starts with 0, then
*	octal conversion takes place, otherwise decimal conversion is attempted.
*
*	@param	nptr	Pointer to the string to convert.
*	@param	eptr	Pointer to a location to store the address of the
*					first character that was not converted. NULL is allowed.
*	@param	base	The conversion base, must be 0 or between 2 and 36.
*	@param	optr	Pointer to void (*)(void) function that will be called
*					if there was an overflow. NULL is allowed.
*					This facility can be used to implement errno in a
*					system dependent manner.
*
*	@return			The numeric result of the conversion, if it was successful,
*					the largest 32-bit signed integer with the relevant signum
*					if there was an overflow and 0, if there was a conversion
*					error.
*	@note
*			This function is not a standard library function.
*/

long	strtole( const char *nptr, char **eptr, int base, void (*optr)(void) )
{
char	*sptr = (char *) nptr;
BLC_S2I	stat;

	_blc_StrToInt( &stat, base );

	if ( base == 0 || ( base >= 2 && base <= 36 ) ) {

		while ( ! ( base = (*stat.func)( &stat, *nptr++ ) ) );
		if ( stat.fnum ) sptr = (char *) nptr - base;

		if ( stat.hval ||
			 ( stat.lval > 0x7fffffff &&
			   ! ( stat.lval == 0x80000000 || stat.fneg ) ) ) {

			stat.fovf = 1;
		}

		if ( stat.fovf ) {

			if ( stat.fneg == '-' )

				stat.lval = 0x80000000;
			else
				stat.lval = 0x7fffffff;
		}
		else {

			if ( stat.fneg == '-' ) stat.lval = -stat.lval;
		}

		if ( stat.fovf && optr ) (*optr)();
	}

	if ( eptr ) *eptr = sptr;
	return( (long) stat.lval );
}

/** @} */

