/*
 * strtol - convert string to long integer.
 *
 * Written by reading the System V Interface Definition, not the code.
 *
 * Totally public domain.
 *
 * Compile with -DTEST to get short interactive main() for testing.
 */

#include <stdio.h>
#include <ctype.h>

long
strtol(s, p, b)
char	*s, **p;
int	b;
{
	int	base = 10, n = 0, sign = 1, valid = 1;

	/*
	 * leading sign?
	 */
	if (*s=='-')
		sign=(-1);
	else
		sign=1;
	if (*s=='+' || *s=='-')
		++s; /* skip sign */

	/*
	 * what base are we really using?
	 */
	if (b == 0) {
		if (strncmp(s, "0x", 2) == 0  ||
		    strncmp(s, "0X", 2) == 0) {
			s += 2;
			base = 16;
		} else
			if (*s == '0')
				base = 8;
	}

	/*
	 * convert the string to a number.
	 */
	while (isascii(*s) && valid) {
		switch(*s) {
		case '0':
		case '1':
		case '2':
		case '3':
		case '4':
		case '5':
		case '6':
		case '7':
			n = base*n  +  *s-'0';
			break;
		case '8':
		case '9':
			if (base >8)
				n = base*n  +  *s-'0';
			else
				valid = 0;
			break;
		case 'a':
		case 'b':
		case 'c':
		case 'd':
		case 'e':
		case 'f':
			if (base == 16)
				n = base*n + *s-'a'+10;
			else
				valid = 0;
			break;
		case 'A':
		case 'B':
		case 'C':
		case 'D':
		case 'E':
		case 'F':
			if (base == 16)
				n = base*n + *s-'A'+10;
			else
				valid = 0;
			break;
		default:
			valid = 0;
			break;
		}
		++s;
	}

	/*
	 * if arg `p' is not NULL, a ptr to the character
	 * terminating the scan will be returned in `p'
	 */
	if (*p != NULL)
		*p = s;

	return sign * n;
}

#ifdef	TEST
main(argc, argv)
int argc;
char **argv;
{
	int i;
	long j, strtol();

	for (i=1; i<argc; i++) {
		j = strtol(argv[i], 0, 0);
		printf("%s -> %ld(%lx)\n", argv[i], j, j);
	}
	exit(0);
}
#endif	/*TEST*/
