/* _Stoul function */
#include <stdlib.h>
#include <ctype.h>
#include <errno.h>
#include <limits.h>
#include <stddef.h>
#include <string.h>
#include "xmath.h"
 #pragma warning(disable: 4701)

 #if (ULONG_MAX >> 16) >> 16 != 0xffffffff && ULONG_MAX != 0xffffffff
  #error LONGS TOO LARGE FOR _Stoul
 #endif /* longs too large */

_C_STD_BEGIN

		/* macros */
#define BASE_MAX	36	/* largest valid base */

		/* static data */
static const char digits[] = 	/* valid digits */
	"0123456789abcdefghijklmnopqrstuvwxyz";

 #if (ULONG_MAX >> 16) >> 16 == 0xffffffff
static const char ndigs[BASE_MAX + 1] = {	/* 64-bits! */
	0, 0, 65, 41, 33, 28, 25, 23, 22, 21,
	20, 19, 18, 18, 17, 17, 17, 16, 16, 16,
	15, 15, 15, 15, 14, 14, 14, 14, 14, 14,
	14, 13, 13, 13, 13, 13, 13,};

 #else /* (ULONG_MAX >> 16) >> 16 == 0xffffffff */
static const char ndigs[BASE_MAX+1] = {	/* 32-bits! */
	0, 0, 33, 21, 17, 14, 13, 12, 11, 11,
	10, 10, 9, 9, 9, 9, 9, 8, 8, 8,
	8, 8, 8, 8, 7, 7, 7, 7, 7, 7,
	7, 7, 7, 7, 7, 7, 7,};
 #endif /* (ULONG_MAX >> 16) >> 16 == 0xffffffff */

#if defined(__cplusplus) && !defined(MRTDLL)
extern "C"
#endif
_CRTIMP2_PURE unsigned long __CLRCALL_PURE_OR_CDECL _Stoulx(const char *s, char **endptr,
	int base, int *perr)
	{	/* convert string to unsigned long, with checking */
	const char *sc, *sd;
	const char *s1, *s2;
	char dig, sign;
	ptrdiff_t n;
	unsigned long x, y;

	if (perr != 0)
		*perr = 0;
	for (sc = s; isspace((unsigned char)*sc); ++sc)
		;
	sign = *sc == '-' || *sc == '+' ? *sc++ : '+';
	if (base < 0 || base == 1 || BASE_MAX < base)
		{	/* silly base */
		if (endptr != 0)
			*endptr = (char *)s;
		return (0);
		}
	else if (0 < base)
		{	/* strip 0x or 0X */
		if (base == 16 && *sc == '0'
			&& (sc[1] == 'x' || sc[1] == 'X'))
			sc += 2;
		}
	else if (*sc != '0')
		base = 10;
	else if (sc[1] == 'x' || sc[1] == 'X')
		base = 16, sc += 2;
	else
		base = 8;
	for (s1 = sc; *sc == '0'; ++sc)
		;	/* skip leading zeros */
	x = 0;
	for (s2 = sc, y = 0; (sd = (char *)memchr(&digits[0],
		tolower(*sc), base)) != 0; ++sc)
		{	/* accumulate digits */
		y = x;
		dig = (char)(sd - digits);	/* for overflow checking */
		x = x * base + dig;
		}
	if (s1 == sc)
		{	/* check string validity */
		if (endptr != 0)
			*endptr = (char *)s;
		return (0);
		}
	n = sc - s2 - ndigs[base];
	if (n < 0)
		;
	else if (0 < n || x < x - dig || (x - dig) / base != y)
		{	/* overflow */
		errno = ERANGE;
		if (perr != 0)
			*perr = 1;
		x = ULONG_MAX, sign = '+';
		}
	if (sign == '-')	/* get final value */
		x = 0 - x;
	if (endptr != 0)
		*endptr = (char *)sc;
	return (x);
	}

_CRTIMP2_PURE unsigned long __CLRCALL_PURE_OR_CDECL _Stoul(const char *s, char **endptr, int base)
	{	/* convert string, discard error code */
	return (_Stoulx(s, endptr, base, 0));
	}
_C_STD_END

/*
 * Copyright (c) 1992-2006 by P.J. Plauger.  ALL RIGHTS RESERVED.
 * Consult your license regarding permissions and restrictions.
 V5.02:0009 */
